I have an issue with JTable integration to Spring MVC
****** JSP code ***********
<link href="http://www.jtable.org/Scripts/jtable/themes/metro/blue/jtable.css" rel="stylesheet" type="text/css" />
<link href="http://www.jtable.org/Content/themes/metroblue/jquery-ui.css" rel="stylesheet" type="text/css" />
<script src="http://www.jtable.org/Scripts/jquery-1.8.3.min.js" type="text/javascript"></script>
<script src="http://www.jtable.org/Scripts/jquery-ui-1.9.2.min.js" type="text/javascript"></script>
<script src="http://www.jtable.org/Scripts/jtable/jquery.jtable.js" type="text/javascript"></script>
<script>
$(document).ready(function() {
//setup the jtable that will display the results
$('#PeopleTableContainer').jtable({
title: 'Table of people',
actions: {
listAction: '/admin/getalltherole',
createAction: '/admin/addRole',
updateAction: '/admin/updateRole',
deleteAction: '/admin/deleteRole'
},
fields: {
custId: {
key: true,
list: false
},
name: {
title: 'Full Name',
width: '30%'
},
birthYear: {
title: 'Birth Year',
width: '15%'
},
employer: {
title: 'Employer',
width: '25%'
},
infoAsOfDate: {
title: 'As Of Date',
width: '15%'
},
disabled: {
title: 'Status',
width: '15%'
}
}
});
$('#PeopleTableContainer').jtable('load');
});
</script>
<div id="PeopleTableContainer" style="width: 600px;"></div>
***** Spring controller ************
#RequestMapping(value = "/admin/getalltherole", method = RequestMethod.POST)
#ResponseBody
public JsonJtableResponse getalltherole(){
JsonJtableResponse jstr = new JsonJtableResponse();
jstr.setResult("OK");
List<Role> roleList = testService.getAllRoles();
jstr.setRecords(roleList);
return jstr;
}
#RequestMapping(value = "/admin/addRole", method = RequestMethod.POST)
#ResponseBody
public JsonJtableResponse insert(#ModelAttribute Role role, BindingResult result) {
JsonJtableResponse jsonJtableResponse = new JsonJtableResponse();
if (result.hasErrors()) {
jsonJtableResponse.setResult("ERROR");
}
try {
Role newRole = testService.saveRole(role);
//jsonJtableResponse.setRole(newRole);
} catch (Exception e) {
jsonJtableResponse.setResult(e.getMessage());
}
return jsonJtableResponse;
}
#RequestMapping(value = "/admin/updateRole", method = RequestMethod.POST)
#ResponseBody
public JsonJtableResponse update(#ModelAttribute Role role, BindingResult result) {
JsonJtableResponse jsonJtableResponse = new JsonJtableResponse();
if (result.hasErrors()) {
jsonJtableResponse.setResult("Error");
return jsonJtableResponse;
}
try {
testService.updateRole(role);
jsonJtableResponse.setResult("OK");
} catch (Exception e) {
jsonJtableResponse.setResult(e.getMessage());
}
return jsonJtableResponse;
}
#RequestMapping(value = "/admin/deleteRole", method = RequestMethod.POST)
#ResponseBody
public JsonJtableResponse delete(#RequestParam Integer custId) {
JsonJtableResponse jsonJtableResponse = new JsonJtableResponse();
try {
testService.deleteRole(custId);
jsonJtableResponse.setResult("OK");
} catch (Exception e) {
jsonJtableResponse.setResult(e.getMessage());
}
return jsonJtableResponse;
}
JSON response object
public class JsonJtableResponse {
private String Result;
private List<Role> Records;
public String getResult() {
return Result;
}
public void setResult(String Result) {
this.Result = Result;
}
public List<Role> getRecords() {
return Records;
}
public void setRecords(List<Role> Records) {
this.Records = Records;
}
}
****** obtained JSON response *********
{
"result":"OK",
"records":[
{
"custId":"1",
"name":"aaa",
"birthYear":"1982",
"employer":"xxx",
"infoAsOfDate":"20130110",
"disabled":"true"
},
{
"custId":"2",
"name":"bbb",
"birthYear":"1982",
"employer":"xxx",
"infoAsOfDate":"20130111",
"disabled":"true"
},
{
"custId":"3",
"name":"ccc",
"birthYear":"1982",
"employer":"xxx",
"infoAsOfDate":"20130108",
"disabled":"false"
},
{
"custId":"4",
"name":"ddd",
"birthYear":"1981",
"employer":"xxx",
"infoAsOfDate":"20130107",
"disabled":"true"
}
]
}
ISSUE *****************
I can obtain the given JSON response using firebug console.
but when page loads it throws this error on firebug console, even though JSON data properly gets loaded,
"NO Data available"
message is displayed on the data table.
and there is an error on the console as well.
"TypeError: this._$errorDialogDiv.html(message).dialog is not a function"
As I have searched, this error is typically due to jquery UI libs not properly being added.
when I change - listAction: '/admin/getalltherole' to some non existent URL
"An error occured while communicating to the server." is displayed in a dialog box.
jquery-ui-1.9.2.min.js includes all the required jquery UI libs and I tried adding all the libs individually as well, without any luck.
any suggessions?
Add Jackson library, maven dependency in your pom.xml:
<properties>
<jackson.version>1.9.10</jackson.version>
</properties>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>${jackson.version}</version>
</dependency>
Now you can add json property annotation to your fields in the class so that the json output is rendered as you expect. You may write a generic class (JsonJtableResponse in your question) as given below:
public class JTableJSONResponse<T> {
#JsonProperty("Result")
private String result;
#JsonProperty("Records")
private List<T> records;
#JsonProperty("Message")
private String message;
#JsonProperty("TotalRecordCount")
private int totalRecordCount;
public JTableJSONResponse(String result, List<T> records, int totalRecordCount) {
super();
this.result = result;
this.records = records;
this.totalRecordCount = totalRecordCount;
}
//getters and setters
}
Now, your controller may say
List<Role> roleList = roleService.getAllRoles();
return new JTableJSONResponse<Role>("OK",roleList,roleList.size());
Hope this helps.
JSON is case-sensitive. So it would not be able to match "result" with "Result". I had faced the same issue with my app as well.
So please ensure that your JSON response returns Result and Records in the correct case.
The problem was that JSON response which was required for JTable to be case sensitive.
NOT
{
"result":"OK",
"records":[
.......
]}
but
{
"Result":"OK",
"Records":[
.......
]}
From the type of error you are facing you are missing some js file to be imported .
have you added the json2.js which is an external dependency for jtable
https://github.com/hikalkan/jtable/tree/master/lib/external
it is mentioned in the following example for jtable and it is missing in your code
http://www.jtable.org/Tutorials/UsingWithAspNetWebFormsPageMethods#CreatePage
also check with the help of firebug that all the js file are loaded or not.
Related
I am new to Asp.net MVC Core. I am working on Server-side loading of JQuery Datatables.net using Asp.Net Core MVC Middleware.
I have used this tutorial to learn how to create a handler and then this article to migrate to middleware but are running into some issues that I hope you can help me with.
I have refined using this tutorial
I get error
"InvalidOperationException: Incorrect Content-Type: Microsoft.AspNetCore.Http.Features.FormFeature.ReadForm()"
when I run the solution.
Here is my code:
View
<script type="text/javascript">
$(document).ready(function () {
$('#datatable').DataTable({
//"paging": true,
//"ordering": true,
//"info": true,
'columns' : [
{ 'data': 'InsertedDateUtc' },
//{ 'data': 'EventId' },
{ 'data': 'UserId' },
{ 'data': 'Action' },
{ 'data': 'Context' },
{ 'data': 'RecordId' },
{ 'data': 'Property' },
{ 'data': 'OldValue' },
{ 'data': 'NewValue' },
],
'processing': true,
'serverSide': true,
'ajax' : {
'type' : 'POST',
'url' : '../AuditEventData.cs',
//'url': '../APIController/GetAuditEvents'
//'url' : '#Url.Action("GetAuditEvents", "APIController")'
'datatype': 'json',
}
});
});
</script>
Middleware
public class AuditEventData
{
private readonly RequestDelegate _next;
private readonly IDataGet _dataGet;
public AuditEventData(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext httpContext)
{
string result = null;
int filteredCount = 0;
var draw = httpContext.Request.Form["draw"].FirstOrDefault();
var start = int.Parse(httpContext.Request.Form["start"].FirstOrDefault());
var length = int.Parse(httpContext.Request.Form["length"].FirstOrDefault());
var sortCol = int.Parse(httpContext.Request.Form["columns[" + httpContext.Request.Form["order[0][column]"].FirstOrDefault() + "][name]"].FirstOrDefault());
var sortDir = httpContext.Request.Form["order[0][dir]"].FirstOrDefault();
var search = httpContext.Request.Form["search[value]"].FirstOrDefault();
try
{
var auditEvents = await _dataGet.GetServerSideAuditEvents(length, start, sortCol, sortDir, search);
filteredCount = auditEvents.Count();
var data = new
{
iTotalRecords = await _dataGet.GetTotalAuditEventCount(),
iTotalDisplayRecords = filteredCount,
aaData = auditEvents
};
result = JsonConvert.SerializeObject(data);
await httpContext.Response.WriteAsync(result);
}
catch (Exception e)
{
await ErrorHandler.HandleException(e);
}
await _next(httpContext);
}
}
// Extension method used to add the middleware to the HTTP request pipeline.
public static class MiddlewareExtensions
{
public static IApplicationBuilder UseAuditEventDataMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<AuditEventData>();
}
}
Startup.cs
app.MapWhen(
context => context.Request.Path.ToString().EndsWith("ViewAudit"),
appBranch =>
{
appBranch.UseAuditEventDataMiddleware();
});
In the middleware class the line
var start = int.Parse(httpContext.Request.Form["start"].FirstOrDefault());
gives me the error - the tutorials and Microsoft documentation here seem to indicate that I do not need to use the ".Form" and should be able to just use
var start = int.Parse(httpContext.Request["start"].FirstOrDefault());
however, when I do that, I get this error
cannot apply indexing with [] to an expression of type 'HttpRequest'
I cannot find any examples on how to do this and any help will be appreciated
Thanks
In order to expect to have a Form in your HttpContext.Request you must change your ajax datatype to 'application/x-www-form-urlencoded'. Now whether you want to do that is another question.
From here: https://developer.mozilla.org/en-US/docs/Learn/Forms/Sending_and_retrieving_form_data
I need to build a chat using signalr and I am new in this.
So far I got only the chat by reading some others codes and tutorials and this is what I got:
on my ChatApp.Hubs I got the following code
public static class UserHandler
{
public static HashSet<string> ConnectedIds = new HashSet<string>();
}
public class ChatHub : Hub
{
public void Send(string name, string message)
{
// Call the addNewMessageToPage method to update clients.
Clients.All.addNewMessageToPage(name, message);
}
public override Task OnConnected()
{
UserHandler.ConnectedIds.Add(Context.ConnectionId);
return base.OnConnected();
}
public override Task OnDisconnected(bool stopCalled)
{
UserHandler.ConnectedIds.Remove(Context.ConnectionId);
return base.OnDisconnected(stopCalled);
}
}
and my view I copy past from a tutorial
#{
ViewBag.Title = "Chat";
}
<h2>Chat</h2>
<div class="container">
<input type="text" id="message" />
<input type="button" id="sendmessage" value="Send" />
<input type="hidden" id="displayname" />
<ul id="discussion">
</ul>
</div>
#section scripts {
<!--Script references. -->
<!--The jQuery library is required and is referenced by default in _Layout.cshtml. -->
<!--Reference the SignalR library. -->
<script src="~/Scripts/jquery.signalR-2.1.0.min.js"></script>
<!--Reference the autogenerated SignalR hub script. -->
<script src="~/signalr/hubs"></script>
<!--SignalR script to update the chat page and send messages.-->
<script>
$(function () {
// Reference the auto-generated proxy for the hub.
var chat = $.connection.chatHub;
// Create a function that the hub can call back to display messages.
chat.client.addNewMessageToPage = function (name, message) {
// Add the message to the page.
$('#discussion').append('<li><strong>' + htmlEncode(name)
+ '</strong>: ' + htmlEncode(message) + '</li>');
};
// Get the user name and store it to prepend to messages.
$('#displayname').val(prompt('Enter your name:', ''));
// Set initial focus to message input box.
$('#message').focus();
// Start the connection.
$.connection.hub.start().done(function () {
$('#sendmessage').click(function () {
// Call the Send method on the hub.
chat.server.send($('#displayname').val(), $('#message').val());
// Clear text box and reset focus for next comment.
$('#message').val('').focus();
});
});
});
// This optional function html-encodes messages for display in the page.
function htmlEncode(value) {
var encodedValue = $('<div />').text(value).html();
return encodedValue;
}
</script>
}
what I need now is to display all the connected users in the view
Appriciate your help
Thanks in advance
So, you pretty much either want to just store all 'Active' connections in some kind of database/storage or a static hashset/dictionary.
You save the ConnectionIds when the user connects and remove them when they disconnect :
Hub
public class ChatHub : Hub
{
static HashSet<string> CurrentConnections = new HashSet<string>();
public override Task OnConnected()
{
var id = Context.ConnectionId;
CurrentConnections.Add(id);
return base.OnConnected();
}
public override System.Threading.Tasks.Task OnDisconnected()
{
var connection = CurrentConnections.FirstOrDefault(x => x == Context.ConnectionId);
if (connection != null)
{
CurrentConnections.Remove(connection);
}
return base.OnDisconnected();
}
//return list of all active connections
public List<string> GetAllActiveConnections()
{
return CurrentConnections.ToList();
}
}
Client
I added a button and an unordered list.
HTML
<button id="show-all-connections">Show Connections</button>
<ul id="user-list">
</ul>
And added this javascript (using jQuery)
$("#show-all-connections").on("click", function () {
debugger;
chatHub.server.getAllActiveConnections().done(function (connections) {
$.map(connections, function (item) {
$("#user-list").append("<li>Connection ID : " + item + "</li>");
});
});
});
Hope this helps.
Update
In your scenario, I don't see any hooks into using a custom UserId Provider or anything, so you're going to have to ask the User for a User Name and save the Connection ID with that.
HTML
JavaScript
$("#add-connection").click(function () {
var name = $("#user-name").val();
if (name.length > 0) {
chatHub.server.connect(name);
}
else {
alert("Please enter your user name");
}
});
Hub
static List<Users> SignalRUsers = new List<Users>();
public void Connect(string userName)
{
var id = Context.ConnectionId;
if (SignalRUsers .Count(x => x.ConnectionId == id) == 0)
{
SignalRUsers .Add(new Users{ ConnectionId = id, UserName = userName });
}
}
public override System.Threading.Tasks.Task OnDisconnected()
{
var item = SignalRUsers.FirstOrDefault(x => x.ConnectionId == Context.ConnectionId);
if (item != null)
{
SignalRUsers.Remove(item);
}
return base.OnDisconnected();
}
Users.cs
public class Users
{
public string ConnectionId { get; set; }
public string UserName { get; set; }
}
This is psuedo code since I am not able to run this code at the moment. Hope it helps and gives you a clear enough direction.
I'm trying to pass data from JQuery to an MVC 4 controller. The controller gets invoked, but no data is passed. In the past I always just used form serialization, but that's not appropriate here.
My Controller:
[HttpPost]
public ActionResult Write(VideoSessionEnvelope envelope)
{
if (ModelState.IsValid)
{
envelope = Log.Write(envelope);
}
var result = Json(envelope);
return result;
}
We use an envelope class as a container for all view models
public class VideoSessionEnvelope : BaseEnvelope
{
public VideoSessionEnvelope()
{
SessionStart = new VideoSessionStartViewModel();
}
public Guid? LogEntryID { get; set; }
public VideoSessionStartViewModel SessionStart { get; set; }
}
}
The view model
public class VideoSessionStartViewModel: IViewModel
{
public string SessionId { get; set; }
public int UserId { get; set; }
public string Message { get; set; }
}
And finally the javascript
var Logging = Logging || {};
Logging.VideoSession = function () {
var Start = function (sessionId, userId, message) {
var envelope = {
SessionStart: {
"SessionId": sessionId,
"UserId": userId,
"Message": message
}
}
var data = JSON.stringify(envelope);
$.ajax({
type: "POST",
url: "/Logging/Write",
data: data,
datatype: "application/json",
success: function (result) {
return result;
},
error: function (request, status, error) {
return error;
}
});
};
return {
Start: Start
};
}();
According to Firebug the data is passed as
JSON
SessionStart Object { SessionId="sessionIdVal", UserId=123, Message="messageValue"}
Message "messageValue"
SessionId "sessionIdVal"
UserId 123
The controller gets called, but the properties in the view model are always null. I've tried several variations on the theme, nothing seems to work.
Try wrapping your data in a literal with the name as envelope so it will be picked up by the Model Binder:
data: { envelope: data },
UPDATE
Remove the call to JSON.stringify(), it is not strictly necessary to serialize the object literal.
I am working on a Spring application which runs on mobile and web. On web everything runs fine but on mobile when the form is posted, its hits the controller and the controller is redirecting to other application.
#RequestMapping(value = "/common", method = RequestMethod.GET)
public String showLandingPage(HttpServletRequest req, HttpServletResponse response, Model model) {
logger.debug("Received request to set partner info");
Device currentDevice = DeviceUtils.getCurrentDevice(req);
setCookies(response);
Properties props = new Properties();
try {
props.load(getClass().getClassLoader().getResourceAsStream( "sampleApp.properties"));
} catch (IOException e) {
logger.fatal(new StringBuilder("MainController : setCookies() : Error while reading sampleApp.properties "+e));
}catch (Exception e) {
logger.fatal(new StringBuilder("MainController : setCookies() : Error while reading sampleApp.properties "+e));
}
if(currentDevice.isMobile() || currentDevice.isTablet()){
return "redirect:"+props.getProperty("popcorn-mobile-url");
} else {
return "redirect:"+props.getProperty("popcorn-web-url");
}
}
When the control goes to the redirect location I get "error loading page" on the screen.
In JSP I am using following jQuery libraries.
<script src="${pageContext.request.contextPath}/js/mobile/mobile-config.js"></script>
<script src="${pageContext.request.contextPath}/js/mobile/jquery.mobile-1.2.0.min.js"></script>
<script src="${pageContext.request.contextPath}/js/mobile/plugins.js"></script>
I woul duse a deviceinterceptor, somethign like below :
public class DeviceInterceptor extends HandlerInterceptorAdapter {
private final DeviceResolver deviceResolver;
private Device device;
/**
* Create a device resolving {#link HandlerInterceptor} that defaults to a
* {#link LiteDeviceResolver} implementation.
*/
public DeviceInterceptor() {
this(new LiteDeviceResolver());
}
public DeviceInterceptor(DeviceResolver deviceResolver) {
this.deviceResolver = deviceResolver;
}
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
device = deviceResolver.resolveDevice(request);
request.setAttribute(DeviceUtils.CURRENT_DEVICE_ATTRIBUTE, device);
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView) throws Exception {
if (device.isMobile()) {
modelAndView.setViewName("/mobile/" + modelAndView.getViewName());
}else {
modelAndView.setViewName("/jsp/" + modelAndView.getViewName());
}
}
I have a POJO named "FlashCard" which has a field named "links" which is collection (set) of Link objects. When I submit a FORM to my Action all the POJO fields are populated with values from the form except the collection of "links". I have no idea why this isn't getting populated.
Any advice on how to resolve this problem or how to better troubleshoot it would be much appreciated.
Also, my POJO's collection is a Set. Does it matter (or complicate things) that I'm using a Set and not a List?
I'm including a simplified version of my code below.
Here's my POJO:
public class FlashCard implements java.io.Serializable {
private int flashCardId;
private String question;
private String answer;
private Set<Link> links = new HashSet<Link>(0);
public FlashCard() {
}
public FlashCard(String question, String answer) {
this.question = question;
this.answer = answer;
}
public FlashCard(String question, String answer, Set<Link> links) {
this.question = question;
this.answer = answer;
this.links = links;
}
public int getFlashCardId() {
return this.flashCardId;
}
public void setFlashCardId(int flashCardId) {
this.flashCardId = flashCardId;
}
public String getQuestion() {
return this.question;
}
public void setQuestion(String question) {
this.question = question;
}
public String getAnswer() {
return this.answer;
}
public void setAnswer(String answer) {
this.answer = answer;
}
public Set<Link> getLinks() {
return this.links;
}
public void setLinks(Set<Link> links) {
this.links = links;
}
}
Here's the POJO for the Link object:
public class Link implements java.io.Serializable {
private int linkId;
private String url;
private Set<FlashCard> flashcards = new HashSet<FlashCard>(0);
public Link() {
}
public Link(String url) {
this.url = url;
}
public Link(String url, Set<FlashCard> flashcards) {
this.url = url;
this.flashcards = flashcards;
}
public int getLinkId() {
return this.linkId;
}
public void setLinkId(int linkId) {
this.linkId = linkId;
}
public String getUrl() {
return this.url;
}
public void setUrl(String url) {
this.url = url;
}
public Set<FlashCard> getFlashcards() {
return this.flashcards;
}
public void setFlashcards(Set<FlashCard> flashcards) {
this.flashcards = flashcards;
}
}
Here's the relevant part of the Action
public class FlashCardAction extends FlashCardsAppBaseAction implements ModelDriven<FlashCard>, Preparable, SessionAware {
static Logger logger = Logger.getLogger(FlashCardAction.class);
FlashCard flashCard = new FlashCard();
Map <String,Object> httpSession;
Session session;
FlashCardPersister fcPersister;
public Map<String, Object> getHttpSession() {
return httpSession;
}
public FlashCard getFlashCard() {
return this.flashCard;
}
public void setFlashCard(FlashCard flashCard) {
this.flashCard = flashCard;
}
public void validate() {
logger.debug("Entering validate()");
if ( flashCard.getQuestion().length() == 0 ){
addFieldError("flashCard.question", getText("error.flashcard.question"));
}
if ( flashCard.getAnswer().length() == 0 ) {
addFieldError("flashCard.answer", getText("error.flashcard.answer"));
}
}
public String saveOrUpdate() {
logger.debug("Entering saveOrUpdate()");
// assume we'll fail
boolean result = false;
// are we creating a New Flash Card or Updating and existing one
// for now, let's assume we are creating a New Flash Card
boolean newFlashCard = true;
// if this is an Update of an existing Flash CArd then we'll have a Flash Card Id other than 0
if (this.flashCard.getFlashCardId() != 0) {
newFlashCard = false;
}
try {
result = fcPersister.saveOrUpdateFlashCard(this.flashCard, session);
// did we save a new FlashCard successfully?
if (result == true && newFlashCard) {
logger.debug("Flash Card created successfully");
this.addActionMessage(getText("actionmessage.flashcard.created"));
}
// did we update an existing Flash Card successfully?
else if (result == true && newFlashCard == false) {
logger.debug("Flash Card updated successfully");
this.addActionMessage(getText("actionmessage.flashcard.updated"));
}
// such a failure
else {
logger.error("unable to create or update FlashCard");
return "error";
}
return "success";
} catch (Exception e) {
logger.error("Exception in createFlashCard():", e);
return "error";
}
}
#Override
public FlashCard getModel() {
return this.flashCard;
}
#Override
public void setSession(Map<String, Object> httpSession) {
this.httpSession = httpSession;
}
#Override
public void prepare() throws Exception {
logger.debug("Entering prepare()");
// get a handle to a Hibernate session
session = getHibernateSession();
// get a handle to the FlashCard persistance utility class
fcPersister = new FlashCardPersister();
}
}
And lastly here's the JSP
<%#page import="com.opensymphony.xwork2.ActionContext"%>
<%#page import="com.opensymphony.xwork2.ActionSupport"%>
<%# page contentType="text/html; charset=UTF-8"%>
<%# taglib prefix="s" uri="/struts-tags"%>
<%# taglib prefix="sjr" uri="/struts-jquery-richtext-tags"%>
<h3><s:text name="label.flashcard.title"/></h3>
<s:actionerror theme="jquery" />
<s:actionmessage theme="jquery"/>
<s:fielderror theme="jquery"/>
<s:form action="saveOrUpdate" method="post">
<s:hidden name="flashCard.flashCardId" />
<s:textfield name="flashCard.question" key="label.flashcard.question" size="66" />
<sjr:tinymce
id="flashCard.answer"
name="flashCard.answer"
key="label.flashcard.answer"
rows="20"
cols="50"
editorTheme="simple"
/>
<s:textfield name="flashCard.links.url" key="label.flashcard.link" size="66" />
<tr>
<td>
<s:submit label="label.flashcard.submit" align="center" theme="simple" />
</td>
<td>
<s:submit key="label.flashcard.cancel" name="redirectAction:list" theme="simple" />
</td>
</tr>
</s:form>
<%((ActionSupport)ActionContext.getContext().getActionInvocation().getAction()).clearErrorsAndMessages();%>
First of all I don't think you can use Set here, because Sets are unordered and you can't get an item from a set by an index or key like List and Map. The only way is to iterate through the set and get the items.
Second assuming you're using a collection other than set, in:
<s:textfield name="flashCard.links.url" key="label.flashcard.link" size="66"/>
You try to set the value of the text field to url field of links which is a collection and doesn't have such a field. So you need to get the specific item from the collection you're editing and pass the value. Like:
<s:textfield name="flashCard.links[0].url" key="label.flashcard.link" size="66"/>
But since you can't get the specific item you are editing I suggest you create a link field in your Action and set the updated link to it. Then you can perform a logic to relace the updated link with obsolete one in you flashcards. Hope this helps.
Since you are using modeldriven and the model is FlashCard, i think the following
<sjr:tinymce
id="flashCard.answer"
name="flashCard.answer"
key="label.flashcard.answer"
rows="20"
cols="50"
editorTheme="simple"/>
should be changed to
<sjr:tinymce
id="flashCard.answer"
name="answer"
key="label.flashcard.answer"
rows="20"
cols="50"
value="answer"
editorTheme="simple"/>
the name field should be given without the prefix flashcard.also you should provide the 'value' attribute in order for it to be pre-populated.