Following this post and the other posts that it links to, I have successfully built a page with a variable legnth editable list.
Now, I need to do another page with similar functionality, but going a step further. Basically I need to create a variable length list of objects as I have already done, but in this case each object in the list needs to have its own variable length editable sub list.
I can build the view with no problem but I guess I am lost as to how I will handle this in my POST controller method to save the objects.
Will my controller take 2 IEnumerable parameters?
I.E.
public ActionResult SaveList(IEnumerable<MainList>, IEnumerable<Sublist>)
{
}
It seems like this would work but I have no way of associatiing the objects in the sublist collection with the appropriate object in the main list collection.
What am I missing?
Summing up the results of our comment-discussions as an answer:
The sublists should be members of your MainList elements. In the View you will have a nested foreach loop to work with the Sublist elements. In the controller you just accept the MainList as a parameter (it should already have the sublists as members). In order for the ModelBinder to pick up the sublists correctly, the names of the inputs should include the names of main list first (and not just the properties inside the sublist item).
I think you need to build a ModelBinder class to accept these parameters the way you want into your controller object.
Related
Working on a project that will display hierarchies of "tasks". I'm running into a problem where it will not allow for multiple entries of the same object. From what I can tell, the "duplicate" item is under a different parent.
The domain data allows for this - a given task may appear in lots of places.
It would seem that this is intentional (maybe), but is there a way around this?
It's intentional to a degree; each Grid and TreeGrid data item is expected to be unique. You could work around this by creating your own implementation of the hierarchical DataProvider class (for example extend AbstractHierarchicalDataProvider) which overrides the getId method along with the other required methods. The return value of this method needs to be unique per item, as it's used as a hash key.
Well, this is probably not the best solution, but it works.
I added a field to the abstract super class that is initialized with the current time (long ms). When I am adding items to the tree grid, I check to see if the tree contains the item and if so, I randomize the field and then add it. The new field is marked #Transient so it's not persisted.
How can we pass a list from JSP to the action in Struts 2?
The list is a list of strings set from the same action when the JSP page gets loaded (there is a hidden field in the JSP which is being set).
All that I need is when again the form is submitted and the control goes to the action, I need that list again.
Make an array of strings and submit it using json or make a # seperated string of all strings and associate it with some hidden variable and submit it to action class. then in action class you needs to parse it back to original form.
you can use the hidden tag name attribute to refer to the list name that is being used in the class. Now when the form is submitted it will automatically map to the list in your action.
You need to have list as your instance variable in the action class
If you are setting a single hidden field with the contents of a list then you'll need to parse it back into a list again. Whether or not this is a good idea depends on the contents of the list, and how good you are at parsing.
Another option is to use Struts 2's default list-building mechanism and use multiple hidden fields and OGNL's array notation, e.g., name="foo[0]", name="foo[1]", and so on.
I'd start, however, by examining the need to reconstruct the list from the JSP like this.
If you're just serializing/deserializing the same list, why bother? Either keep it in session, or reconstruct it on the Java side. If it's backed by a DB then your caching mechanism should reduce any overhead.
I am trying to conceive of a way to store a list of selected items to the session, for later use. I've googled and read examples for 2 hours now, and haven't found any examples that work.
The basic idea is this. User sees a list of items to act upon. User selects a number of them. User chooses action to perform. Controller takes list of selected items, and begins to act on them.
Am I thinking about this wrong? It makes sense to me to use an Ajax action to store the 'select/unselect' action on the session object. I really don't want an entire database object to handle this. I just want a simple list of selected objects. In classic ASP, I'd just have reacted to the selected items in a form post, but that doesn't seem right in asp.net mvc....
How do I construct this behavior (with or without the Ajax, but preferable without the DB access)?
I don't get it, why not bind directly an array of bools or something directly to your view's list of checkboxes? You can get them as parameters in your controller function and act upon them directly, with no middleman, they'd just be another POST value.
Or even better when you send in your list of items as part of your model, make them a structure that has a bool selected=false field that is bound to the checkbox next to the label, and you'll get the results back in your model directly.
I have a Client dto that contains a bunch of fields and also contains a List.
Now, I can bind to it quite easy, and it will display the Client with all of his addresses. The thing is that the user can delete and add addresses dynamically.
I thought about adding forms surrounding each address but then I end up with inner forms and I know browsers don't play well with that.
Then I thought about using javascript but if an address is removed, I have to go over all addresses and change their indexes (addresses[0].City )because I noticed that if the indexes are not in order, and the action takes a ClientForm as a parameter, then only the addresses that have consecutive indexes and they start at 0 - will get in the ClientForm.Addresses list.
Any other solutions that are easy to implement ? Am I missing something ?
If you place a submit button with a different name on each of the addresses but no form tags, your outer form can check for the existence of a specific button and redirect to the right action (e.g edit address number 1, delete address 3 etc)
If you are using jquery validation one caveat is that the type of all the "child" submit buttons must be set to "cancel" so on pressing them validation does not occur.
HTH,
Dan
For each address on your page provide a hidden form field called addresses.Index, this will take an integer value. The ASP.NET MVC model binder (in version 2 and above) will receive the multiple values of the addresses.Index form field, and use the integer values to determine which addresses[index].property field values logically belong together.
E.g.
addresses.Index = 0
addresses.Index = 3
Would prompt the model binder to go looking for...
addresses[0].City
addresses[0].Street
addresses[3].City
addresses[3].Street
...and populate an ICollection<Address> in your controller action with two elements.
Of course if you can delete and insert these records on your page, your Javascript will need to track the next index to use in a global variable, to avoid re-using the same index for multiple rows (i.e. don't just rely on the length of a table that holds the address elements, etc).
This solution described in further detail by Phil Haack here.
I want to use an example to explain what I want.
Assume I've following DB design:
Item (id, name, categoryID);
Category (id, name);
When user wants to create an Item (fill in form), I'll give a list of categories in a dropdownlist, and when user chooses one of the categories ASP.NET MVC will automatically bind categoryID, to the selected one. I need to present same dropdown list when editing the item with correct selected one.
Question:
But my DB is very big, and it requires around 30-40 (maybe even more) category-like tables, that contain just "id" and "name", and all tables need to be shown in dropdown list while creating some other object, and also needs to be presented while editing the object. Definitely above schema doesn't work, because it's tedious to write same logic 100 times with just different table names. (I'm using Linq2SQL)
Currently my solution is:
Make a view that's based in all such tables and in application I just call a function that construction dropdownlist from that single view. But it's still tedious to change view definition everytime I add a new table.
Do you guys think of a better solution for this tedious work, possibly using reflection or some other tecnologies.
It is not a problem "Definitely above schema doesn't work, because it's tedious to write same logic 100 times with just different table names."
If I were you, I will mark an addition interface on these class using "partial class" feature.
Then, I will write few extension method for the partial class.
If anyone interested in the solution:
I've used reflection to solve this problem.
I use reflection over DataContext to get the Table (by string name), and get its fields and construct the optionlist.