I have an Controller X which which has an action new.
As part of the creation process, I would like to handle multiple things before the form is submitted.
Three operations I would like to do is Search, Evaluate and Create.
So when the view is first loaded, it will have the form to input some fields. Based on the input, I need to call some ruby utils to build the "data" object and then display those results back to the page. I think I have this part figured out, I have a form_for('/x/new') tag in my view and I check in my controller if request.post? then calculate data object.
But when the search is done and the data is rendered back to the page, user can evaluate it which is another operation call that can grab some additional data. When the user clicks on evaluate/search or create button, how do I figure out which button was clicked?
It's best practise (because its more RESTfull) if you split up your action in different action/views!
Related
I have a requirement to ask a question when a certain scenario happens on my MVC 4 view.
When that scenario is true, I simply want to have a jQuery UI dialog pop up modally. That dialog will simply have two radio buttons for "WidgetType" (Purple or Blue).
The viewModel has a property for SelectedWidgetType (that has a default value).
I simple am looking for the best way to handle updating the underlying model with the selection a user picks in the dialog.
Thanks in advance for any replies.
NOTE: I am using this overly simple example as the basis for other dialogs that will have more fields on them that also update the underlying model.
Creating the dialog isn't the hard part, but I am struggling with getting the values.
User jQuery's AJAX post method.
Create a view model JavaScript object on the front end that maps to the parameters of your data model. This view model object can be triggered to get updated each time the user changes his selected options by calling an update method via the change event handles of each form element.
Pass it back to the server controller by packing it into a JSON object using json2.js
If you want a full framework/elegant solution look at using knockout.js which simulates most of this for you... !
On Telerik demo site we can see an example of how to implement kind of functionality: "check all checkbox in a grid's column". But in my case it has 2 disadvantages:
It didn't check all checkbox on all pages.
It didn't save a state of checkboxes on different pages.
Is anybody know how to resolve these issues? Thanks in advance.
As long as I know there's no built-in functionality to do so. The same problem happens when you select records on page one and change to page two, you loose whatever you selected before.
To achieve that functionality you have 2 options (I've used both on previous projects)
1) On each check make an Ajax call to one of your controllers and store whatever you selected on a Session Variable (This can be inefficient if you have a lot of records)
2) Create a javascript variable and store your selections there, and send back to the controller using a json variable or a comma separated values string
As I said, I've used both approachs so it depends on if this works for you or not
Hope it helps
I can't test this, so I'm not 100% sure, but looking at Telerik's example, one reason it's not persisted is because every "page" of the grid requires a postback, and in the controller action result method, they aren't passing in the model (or view model) for the items that are bound to the grid, they're only returning that list of items back to the view, so it will never "save" which items are checked/selected and which ones aren't. You should be able to get around this by making your view model a parameter into the HttpPost action result method and then passing that list back to the view after the post so that it retains which items are selected instead of creating a new one. This won't solve the issue with not selecting all the items, but it should at least retain which ones are selected throughout the pages. I think the reason for it not working with all items is it can only select the ones that are actually being displayed at the time. You may want to do a post (or ajax) to select "all" items.
One of the major reasons for using paging in grids is so that you don't have to retrieve all of the data from the data store and generate a lot of HTML to push to the client.
It's been my experience that most users understand that a "select all" check box only checks the items on the current page. I've not seen a site where checking such a check box would actually check all records, even those I can't see.
If you have an action which will affect more than the current page of records, I would suggest that you add a button which clearly indicates that the action will affect all records, then send a command to your data layer which will perform that action. This will perform better (you don't have to send a potentially long list of ids across the wire) and allow users to understand the repercussions of their action.
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.
This question is an extension of / is similar too the question I asked here. The specific issue I was having in that question was solved, but I am having another very similar issue.
The issue is that the "Cargo Destination" and "Cargo Source" values entered in the create view do not show up in the save view. For instance, when a user forgets to enter a necessary bit of information in the create view and presses the "Create" button, the values the user entered should show up in the save view. All fields except the "Cargo Destination" and "Cargo Scource" show up in the save view when this scenario occurs.
When I put a println statement in my save controller, I can see that the parameters in question did indeed make it to the save controller from the create view.
The two fields in question are chained to other fields and populated by an AJAX that goes to a closure in the Load controller. I believe this closure is where my problem is, in the render statement:
def getAccountUserCargoDestinations = {
if(params.id == ""){
render g.select(name: 'cargoDestination.id')
return
}
def user = Account.find("from Account as account where account.id=:id", [id:Long.valueOf(params.id)]).user
def addresses = Address.find("from Address as addresses where addresses.user=:user and addresses.cargoDestination=true", [user:user])
render g.select(optionKey: 'id', from: addresses, name: 'cargoDestination.id')
}
If that is not where the problem is, then it is probably in the corresponding field of the create view itself:
<g:select name="cargoDestination.id" optionKey="id" value="${loadInstance?.cargoDestination?.id}" />
Two more things:
1.) Grails is not giving me any errors
2.) A cargoDestination and a cargoSource are both instances of the Address class which I made.
Any help would be appreciated.
UPDATE:
Continuing to look for a solution I noticed several interesting things. First I put the following code in my create view (which is rendered by the create closure in the Load controller, and re-rendered by the save closure in the Load controller IF the user leaves any fields blank):
<g:if test="${loadInstance?.cargoDestination?.id != null}">
${loadInstance?.cargoDestination}
</g:if>
By doing this I can see that the parameter is making it all the way to the create view when it is called by the save closure. I guess I could use <g:if> tags to get the desired results, but that just seems messy, and I doubt that is the "correct" way to solve this problem. I also wrapped my AJAX in a similartag to make sure it was not changing the field value when thesaveclosure rendered thecreateview, and I can confirm that the AJAX is indeed not changing the field value. Other than the AJAX, the only thing different about my problem fields is that I do not have afromattribute in their corresponding` tags (as can be seen by the code I posted originally in this question). I know the solution is something simple... What am I missing here?
The two fields in question are chained to other fields and populated
by an AJAX that goes to a closure in the Load controller.
hm. Is the object saved in between? It reads as if
the data is sent to the save controller which does not save because there are missing fields
the save controller displays the save view and println's the field (which are available to the controller)
the view invokes the load controller which tries to retrieve two fields from an object which isn't saved yet. There is no connection to the intermediate request data of the save controller.
if it's not this problem, I guess you'll have to post more code in order to get your problem analyzed.
hm. just taken a look at your other question. I see no chance for the Ajax load controller to get the data since the save controller did not persist the data to the database.
Why don't you output these values directly through the save view?
Finally figured it out through process of elimination, but now that I see the solution it should have been very evident.
All I needed to do was add the from attribute to the affected <g:select> tags, like so:
<g:select from="${loadInstance?.cargoDestination}" name="cargoDestination.id" optionKey="id" value="${loadInstance?.cargoDestination?.id}" />
Works exactly as expected now.
Is there a way to refresh several partial view from the controller ? (return View())
Thanks,
Update1:
Example, the content pârt of my screen is divided in 2 parts, on the left a customer list on the right the details customer, the details of the customers selected in the list of the left. If I create an new customer, when I save, I'd lile refresh the list (left part) and see the details (right part)
Kris,
the only way i can think to do this simply is by having multiple partialviews embeded within the main 'view' to be refreshed. these would then be refreshed in the same cycle. alternatively, you could have custom html helpers embedded within the main view that ran approprite code when the view was refreshed.
As for multiple views from a single action, i don't think this is both a good idea or in any way possible.
of course, rules are there to be broken :)
I don't think there is any automatic way to do this, but you could use some convention and:
Create a custom view result that takes in multiple partial view results i.e. a MultiplePartialViewResult
In the execute of the custom view result, call each the execute method of each of the supplied views'. Make sure to wrap each in a div or some other container for ease of retrieval at the client script
Upon receiving the response on the AJAX call in the client script, grab the value from each container and replace it in the corresponding elements matching the partial views initially rendered
For the last step you could use a convention. A simple one would be (if there is only one instance for each partial view) to put the id of target html element to update in the div/container you used to wrap it in the second step.
Based on what you're saying, I think using javascript and ajax to refresh from the server would be best.
You could use Html.RenderPartialAction to achieve DRY by putting it on the page, and then loading it using ajax and javascript.
If you were using jQuery, then something like this would work:
jQuery("#divToReload1").load('Url/To/PartialAction')...
jQuery("#divToReload2").load('Url/To/PartialAction')...
Just put that all inside one function and you'll reload all your partials at once.
You can send data through using the data parameter and catch the callback function to do as you wish.