I have an MVC application in which I create a search page to find projects I've created. Once the user enters the search criteria, the data is passed back to the controller as a model object and I take this data to search for any projects that match. The search page is redisplayed with the original criteria the user entered plus any projects that were found.
The user can now go an click on a row (the results of their search) and edit that data on another page. When the user hits the save button (on the other page), I save the data and go back to the search page. I don't have the original data (the search model object) to redisplay. How do I get it back? I'm thinking that I should just thorugh my model object that I got when the method was called through the controller into my session object and then retrieve it when I come back to the search page. Is there a more elegant solution to getting the data from the model object back when I return to the search page?
You can use TempData["whatevever"]= yourObject and the data there will exist until it is read the next time and then it is removed. Its like the session object, but is removed after you read it.
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 have a view that allows data entry for submission to the database. In the process of entering data in this view, the requirement is that I link to another view, select a particular row of data, then return with said data to the original view without losing any of the previous edits in the original view.
I am using #Html.ActionLink() to get to the other view and the same sort of link to return to view 1. I've attempted session, TempData, etc. and all entries are lost, I believe, due to not actually doing a form post.
These two views are managed by two separate controllers.
I have a MVC5 page that is shows Customer's information in Text box then you can update some of the data and push Update button. it is going to update info but it is not showing the new value after pushing the update button, you have to leave a page and comeback to see a new value.
UpdateCustomer and (presumably) UpdatePassword should not return a View but instead should return a RedirectResponse back to the [HttpGet] version of the Edit action. This is known as a Post-Redirect-Get pattern and is the preferred way of redisplaying the same page the user just edited. By returning the view with the same model that was posted you're just showing the user what they originally typed in. You're also leaving yourself open to multi-postback situations if the user tries refreshing their browser.
You also seem to be fighting the framework. If you've got two buttons on the page that perform two different actions you should have two forms that each POST to a different controller action.
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
Question:-
Page is a typical search page with few filters on it. When search for records based on filters, it shows result in Gridview. From grid view records, user can click on any record to see the details which takes the focus on new page.
Its working fine so far.
Now when user comes back from details page to search page. I am loosing selected filters values and no result in grid view.
How can i display selected filters and its results in gridview when user is coming back on search page? Any example etc.?
FYI, I am using sessions to pass parameters to the ObjectDatasource.
Store the search parameters in either a cookie or a session variable. When the user returns to the search screen, use those parameters.
If you're losing the values when you return to the search page, I assume your having the user navigate to the search page via a link, menu, etc.? In this case when the URL is loaded in the browser the search page loads for the first time (expected behavior).
You have a few options to persist the information:
1. Session: When the initial search form is filled out and the page posts back, persist/store the form values in session. Then modify the page such that it looks for those session values on initial load and binds the grid. This would allow the values to persist.
Loose Example:
protected void btnSearchButton_Click(object sender, EventArgs e)
{
//store the values of the form in session
}
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
//check if the values are in session.
//If so, remove them and use them to bind the grid.
}
}
The only issue with the above is that you will lose client-state in your grid, so if the grid has paging, etc. and the user was on page 4 originally, when the above binds it'll be back on page 1. You could get around this by also storing state information in session when the user clicks a link in the grid (assuming the grid causes a postback and not a direct client-side navigation to the details page). You could store page #, sort column, etc. and apply these when the user returns.
2. History/Javascript: If the navigation structure of your search -> details pages is such that you have a 'back to search' link on the details page, and you are confident that the only time the details page is loaded is through search -> details, then you could rely on javascript to step back one step in history. I believe the browser would then retain the state of the previous page (the search page) and allow the user to continue using it.
Loose Example (details page markup):
Return to Search Page
or
Return to Search Page
The above is untested but in theory may work. It would allow the user to click the link, or use the back button in their browser to the same effect. Again it would only work in theory if you have a very controlled workflow where you can guarantee the person arrived at the details page from the search page.
Just some ideas...