How to pass data from the controller to itself?
Consider this example:
I have a page that consists of two parts: (1) a simple html form with a couple of text boxes and a submit button and (2) a table that is updated when the button from part (1) is pressed. When it happens, the data from the form has to be appended to the end of the table.
As I see it, there should exist a List of objects. Every time the button is pressed, the controller is called with two parameters: the old list of objects and textbox values. Then, the controller generates the object, adds it to the list and passes the new list to the view. The view is rendered with the new data and rows are successfully added to the table.
However, that requires reloading of the page and that feels kinda wrong.
The problem is, that there is no static object that can contain the list permanently, or at least that exists during these controller-self-calls. If there was such, I would not have to pass the whole list (which, as I said, I can't even do) but just new textbox values.
I have heard that partial views can solve the problem, but I can't see how.
What can I do?
For starters, as you said you'd like to achieve this without javascript, I see no way of avoiding: reloading of the page and that feels kinda wrong.
Not sure as well how partial views will make things work since they're rendered from your main view and require the same or part of your model, so you'll need to have that data there.
You have to get the information back from the controller, and the controller must get this information somehow so as I see it, these are your options:
Keep part (2) inside your form, thus making both parts available when you hit the controller. Model will get populated with the values you need and then the data is available for you when you're back at the View.
Keep a hidden input field inside part (1) containing the data you require to create the list. It's similar in concept to option #1 but I don't like this method too much, you'll have to do some parsing on that input field and this is not very elegant.
You could also try use Session or database but I think the latter is an overkill and a hit on performance so I wouldn't go with that.
If you don't have a database backing the form data, you could use Session data to hold the List.
In the controller, do something like this:
[HttpPost]
public ActionResult AddToList(object newObject)
{
var list = Sesssion["List"] as List<Object>;
if (list == null) {
list = new List<Object>();
Session["List"] = list;
}
list.add(newObject);
return View(list); // Assuming the view is a strong-typed view with List<Object> as model
}
As for partial views, they do not alone solve the problem of reloading the page. The solve the problem of a reusable, self-containing component of the page. If you don't like the reload of the page, you can use partial views together with Ajax calls though, in order to refetch the table whenever a new item is added. Here is an example
Related
in my controller, I have Create actions for Get and Post.
On Get action, I load dropdown data list and show it in view, while I keep only value of selected item. Then I click on submit and call Post action of Create and logic is finished.
But when I call Create action, and model isn't valid, I go back to Get. And here starts the problem, because my dropdown data no longer exists. So I can on my Create action, when model is not valid, again load dropdown data from database, but my idea is to keep and move dropdown data list from Get to Post action, like I sometimes did with "hidden input id". But i have no idea what html tag or helper use for data List.
Something like:
<Select type="hidden" value="#Model.DataList">
I think that transfert the DropDownlist elements between get and post actions is not the right approach. It could make the server calls too long, especially if you have several elements.
I suggest you to create a cache (session cache for example) of your DropDownList items and use it during the get action.
With this system, when you have an invalid model, the get will reload the data without calling the database.
I am very new to MVC and I am not too conversant with the best practices here. I am facing a design issue which may be common or uncommon to newbies like me. My problem is the following:
I have a page with two parts in it.
Grid Control (with Employee basic info in it)
Employee Details (When someone clicks on Grid row, it loads all the details about the employee)
I am using KendoGrid and it is getting all its data from an ActionMethod from my controller.
Now, when I click on the row, I have the following options:
I call some ActionMethod in Controller and return all the Details
Should I use partial View with a separate model so that ActionMethod in response calls RenderPartialView()?
Should I NOT create a partial View, have Actionmethod return JSON and parse it in the Model?
3.1 If I go for this option then would the JSON be part of model?
3.2 If it is not going to be part of model, how can I use JSON to render the View?
Or probably I am missing something basic here?
Yes you can use action method returning JsonResult. what needs to be done is keep the uielements you need to show on the click of grid row in the page itself. initiate a ajax call to the action method and on success update the values of the UI elements from the values received in JSON and make the entire DIV as visible which holds the total information.
Instead of passing entire HTML over the network I think you can opt for json.
An example you can find at following location
example
I am working on a project which has a requirement to build "pages" on the fly. A page can consist of various controls like textboxes, checkbox etc. Currently when the user wants to add a new textbox I make a ajax request and render partial view and return the HTML and show it on client side. This works but I also want to handle the data properly when these dynamic controls are filled up by user. In a way if I am not wrong I need to be able to make array of HTML controls. Now if we give static List to our view and generate textboxes using Html.TextboxFor we see that the name generated is something:
[0].FruitName
[1].FruitName
[2].FruitName
How do I handle this index part when making a Jquery Ajax request so that I always get the correct indexes and render it on client.
If anybody has any better solution than making ajax request then also please let me know. I need to handle the dynamic rendering of HTML controls and also access their values properly when posted back to server.
Take a look at Non-Sequential Indices at http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx.
He introduced a helper method to generate it as well.
Also, I think you can just pass an index with your ajax call which then gets passed from Controller to your partial view and use it to generate a proper indexed TextBox.
Update:
I've asked a very similar question at Submit javascript dynamically added elements to controller method like Stackoverflow
First off, I'm new to MVVM, so please help me out on this :)
Suppose I have multiple views in my app. In my case, I have an editor view, and a browser view.
Both of them have to work with a viewmodel of a "node" I'm editing.
So where does the viewmodel actually get created ?
Suppose the Editor is told to edit a certain node - It could create a new "NodeViewModel" and work with that. But at the same time, there's a NodeBrowserView, which allows people to shortcut-select a different node.
Basicly - I need the EditorView to work with the same ViewModel as the BrowserView, so I need a generic "GetViewModelfor(X)" method.
So how is this supposed to work ? :)
Cheers :)
Both your editor view and browser view should operate on some kind of NodeViewModel. You shouldn't need separate view models just for the different view scenario.
Now, can you edit not-yet-shown-to-user node? If no (as in, user decides what is edited), view models should be created at the very first time their content needs to be presented to user. In most cases this would in some browser/details views, so that user can select element and then chose to edit it.
Edit:
Regarding your comment. NodeViewModel should be provided for editor view.
The providing part can be done for example via constructor injection or by setting view's data context manually. For example, when user browses all nodes in the browser view, he can double click on the list item and editor view will pop-up:
// this will probably be done in response to event
private void ListItemDoubleClick(object sender, EventArgs e)
{
NodeViewModel currentItem = // extract current list item
EditorView editorView = new EditorView(currentItem);
editorView.Show();
}
Alternatively, if you want to avoid this kind of strong coupling between CompositeView and EditorView you can always use events, however it's not always necessary.
One more thing I was thinking of in terms of design would be adding extra view model, call it NodesListViewModel. How the program flow might look like:
At application startup, get your nodes (be it from DB, file, service, anything)
Create instance of NodeListViewModel which takes dependency on IList<Node> (list of node entities)
NodeListViewModel will build and expose collection of NodeViewModel elements
Create instance of your main program window, which uses composite view. It needs NodeListViewModel as its data context.
Whenever user decides he needs to edit item, it's all ready. Browser has a list of all NodeViewModels, it can easily pick up current and pass it to dedicated view.
In cases like this I prefer to use a single main view model and have a "current item" that the view connects to instead. This is a lot easier to do instead of passing / creating new view models around each time a user clicks a different node / grid row / etc. I really see no need to a separate view model either when the same operations can be achieved in the overall view model. It reduces complexity and reduces the change of creating objects (view models) and leaving them hanging around because a reference to them was not released until the application is closed.
I am using Multiview. And I am switching between views. Each view contains lots of fields. I am going to another view from the current view to add some data. And after adding data from the new view, I am returning to the previous view. Now on this view I want to populate fields which I have entered before switching.
Currently I am using ViewState to retain previous values. But this costs lot as there are lots of fields on a single view. Is there any other way to do this task?
This isn't too far off from what viewstate is designed for--I'd stick with that.
Other less-desirable alternatives include sessions, database tables, and httpcontext.
You can store those values in a temporary table otherwise i dont think there is any problem with Viewstate.. better make a structure, store your values in that structure and store the structure in one viewstates...
Another possiblity is to use the Server.Transfer("url", true) which allows you to pass the previous form along with the data that was contained in the form to the next page.
Check out http://www.developer.com/net/asp/article.php/3299641 for usage examples.