I am new to the MVC so excuse me for asking this basic question. My requirement is simple, I have got a view where user can provide the search criteria and then clicks the 'Search' button. If no matching records found for the entered search criteria then I need to show a message box to the user and stay at the same view.
How to do this?
Your Search action method can pass an IEnumerable<T> into the corresponding view. If the model's Count() method returns zero, you can display a message box; otherwise, you display the search results.
Sounds like AJAX is the way to go, but without specifics regarding language or framework it's hard to say more.
Related
I am building a search form for my web application using MVC3. My form is basically divided in two sections.
1st Section has 3 search criteria. First Name, Last Name and Zip code and beneath that section there is a "Search" button which I can click and it should do a client side validation and give me an error message if any of the fields are blank.
2nd section on the same page has just one textbox - to search by "Quote Number". So that section has one textbox to enter quote number and beneath there is another button called "Search". When I click on this search button it should only validate that the Quote Number field is not empty.
I have a viewmodel which has all 4 properties (FName,LName,Zip,Quote Number) and I am binding that on the page. Both the button will post back the page (I know that there is a way to identify which button was clicked on postback). The problem I am facing is on postback everything is posting back and if I use datannotations to do RequiredField check, it does validation on all the 4 fields but I should check for which button is clicked and based on that only fire validation on either 3 fields or only on 1 fields. How do I achieve this functionality? I hope I clearly explained the issue.
Thanks
Since this is MVC, don't think of these as postbacks, think of them as submits. As they are searching by different criteria, they should really be two different forms submitting to two different actions. As they are separate actions, each can have it's own view with it's own ViewModel and validation. Then to combine them into one physical page to present to the user just use partial rendering to put them both into the same view.
Basically the view you present to the user would have something like:
#{
Html.RenderAction("SearchByName");
}
<!-- maybe some markup to visually separate them -->
#{
Html.RenderAction("SearchByQuote");
}
Also gives you the added benefit of having each action be responsible for a single task and you don't have to put in code to figure out which button was clicked, etc.
And just in case you think to yourself "Hey, since both are search, just with different number of parameters, can't I overload the Search action?" No.
Kevin,
Change your page so that you have two different forms, one for each search type. When you click submit in one form, only that form's child fields will be validated.
Then, as R0MANARMY suggested, have two separate actions, one for each search form.
counsellorben
Is there a way to return to the previous view without having to record all the parameters that were used to get to the view in question. Consider this situation. You have a search screen with input parameters, you press search and get results displayed on the page. You click on one item to get a detailed look which redirects you to a new view. Does MVC have the ability to get the previous query string that contains the search parameters?
Not that I know of. You could save it in the session, but how about using JS history.back()
Wouldn't the user just use the back button on the browser? Are you wanting to present a "Back to results" link on the detail page? Also look at Request.UrlReferrer if you don't want to save the search parameters in session or a cookie.
You can use Request.UrlReferrer
In my ASP.NET MVC application I have a view that displays a list of Products in the system. I would like to implement an option for users to filter the list of Products by selecting parametes, similar to the way it's done on www.codeplex.com. I would like to know how you would go about doing this in the most efficient and simple way? Any links to tutorials or guides are appreciated.
In our application we load up a list of all of the products into the web page, and use the Quicksearch jQuery plugin to filter the list. This allows the user to enter a word or two into a textbox, which collapses the list to only those entries matching what the user typed.
Basically, for a search of this type (server-side), you need:
Fields in a <form> for the user to fill out to perform the search request.
A button to post the form fields to your controller method
A repository for the Linq queries that will return the proper records.
A Method in the repository that accepts the parameters you have captured, and executes a linq query returning your filtered result, using Where clauses to filter the returned records.
The result of the query gets returned to the view for display.
If you need dynamic capabilities (i.e. the user may omit one or more parameters, and you need the flexibility to specify those parameters in the Linq query at runtime), then have a look at Dynamic Linq.
I have two forms on one page: a results form and a search form. The search form uses a partial view because it is displayed on several different pages. I want to be able to persist the data in the search form regardles of which button on which form the user clicks. The problem is that when the user clicks on a link or button from the results form, only the form values from the results form are posted, the values from the search form are not included. How can I maintain the values in the search form even when it is not the form that is submitted? I do not want to use any type of session state to maintain the form and I dont want to write the search values in hidden fields in the results form. I just want to be able to post them with the form values of the results form so that the users search criteria can be maintained accross any page that displays the search partial view. What am I missing?
The first thought that occured to me is to remove the form wrapping the search control and just let it be rendered into the form with the results data. I worry here about naming conflicts. What happens when the search from has a control with the same name as the results form, wouldn't this cause a naming conflict? I suppose that this could just be managed manually to ensure that there are unique names whenever rendering partial views into other views, perhaps even going so far as to prefix values with the partial view name, but that reminds me of the ugliness that is INamingContainer in web forms - plus makes for cumbersome field names in your model.
Is there some sort of elegant solution that will allow a form to persist state that I am missing? Thanks!
Normally, I persist the search criteria on the server side when the search is performed. If the user changes the search criteria after performing the search, then posts the form any changes are, of course, lost but that's arguably correct behavior since the search wasn't invoked. This is true whether the search is performed from a full post or via ajax. Handling it this way keeps the actions cleaner, I think as you don't need to handle the search data in the other actions.
If you absolutely need to have the search parameters included, you could consider having the second form post via javascript, pick up the search field values dynamically and add them to the second form (as hidden fields) prior to posting the second form. You wouldn't have to maintain the values in two places in synchronization, but you would have to copy them to the second form before posting.
At the moment i got it like this:
Forms which has search box, posts query (and additional data if needed) to search controller which then renders search view. Search view is made from search box and search results partial views. During this - search box form is reconstructed by posted data.
If i need search results form to perform another search request (for example, with specified page index), it goes through ajax, which posts search box form + page index from search results form. Take a look here for ideas (update that JS method with targetId parameter for updating specified div/form and post additional data if needed here like this:
form.serialize()+"&pageIndex=5"
In short: if you need to maintain state of form + update another in one page - consider using partial updates, otherwise you will end up inventing ViewState 2.0.
One caveat with this way - it's tricky to make search box contain something what is related with search results (i.e. - total count of found items). Before i managed to handle this, our designer did that - i just need to add div with appropriate class name ("sbsubst" or something) and it looks that it's inside search box. :)
When you have few forms at your page each form sends only its own data. In WebForms you had only one form (at least server-side) and each control was included into this form. In ASP.NET MVC you can use the same scenario and I'm afraid you will have to if you want to have the described behavior. Don't forget - partial forms don't have to be real forms. Moreover, RenderPartial is mostly used for "control-like" layout creation.
As for the second part of your question I would suggest naming your text boxes in search form with some normal prefix like "search" or something like that. For instance, if you have text box "text" and "language" in the form, you will have "searchText" and "searchLanguage". These names are quite unique and you will have normal names in your parameters.
I am not suggesting you populating the hidden values in your results form on POST event since you said it's not an option for you but still it may be the only way if you want to have two forms.
I think the best approach will be storing the text from search input when it changes in the query part of your second form action url. For example (not tested):
$('input#yourSearchInput').change(function()
{
var searchText = $(this).val();
// or? var searchText = encodeURIComponent($(this).val());
var secondForm = $('form#secondFormId');
var action = secondForm.attr('action');
var queryStart = action.lastIndexOf('?search=');
if(queryStart > -1) {
action = action.substring(1, queryStart);
}
action = action + "?search=" + searchText;
secondForm.attr('action', action);
});
In Controller (or custom filter):
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
var search = Request.QueryString["search"];
if(!String.IsNullOrEmpty(search)) {
ViewData["SearchFromPOST"] = search;
}
base.OnActionExecuting(filterContext);
}
In your Search Control:
<%= TextBox("yourSearchInputId", ViewData["SearchFromPOST"]) %>
In my MVC application for booking accommodation I have the following:
Action to display the selected room with input-forms for extra info GET:"Details"
This view has multiple forms on it, each posting to a different action.
Examples:
Action to update the number of guests POST:"UpdateGuests"
Action to select start date POST:"SelectStartDate"
Action to add breakfast POST:"AddBreakfast"
Action to delete room POST:"RemoveProductFromCart"
Action to proceed to next step POST:"Proceed"
Most of these actions will redirect back to the GET:"Details" view so the user can perform another action if required, in the case of the proceed, this will redirect to the next view OR if there is some reason they cannot proceed it will display the validation message as to why on the "Details" view.
I'm not sure of the best way to deal with validation, here's some options I've thought of.
use TempData[] to store validation messages and REDIRECT to "Details" view where we add any TempData errors so the ModelState.
in the POST:"xxxxxx" Action populate the ModelState and RENDER the "Details"
This is not a high volume site so TempData is an option.
Any ideas gratefully welcomed.
Edit:
Additional info:
I'm using DataAnnotations for validation rules in some places.
adding Ajax as progressive enhancement is planned, but it should work without.
I think that your second option is the best : each post actions will do the required validations, populate the ModelState with the error messages and every post will return the same view, rebuilt using your model.
Another option, a little bit harder but giving a much better user experience is to do some actions (like update number of people, select start date, add breakfast) using an ajax call. That way, you can return only the little bit of informations required by this action, refresh only that part of the screen and add some error messages if needed.
I hope it will help.
Have you taken a look at how nerd Dinner does validation? I've used this approach with forms that contain several Partial Views and it works great.
You can even modify to validate using jQuery on the fly if that's what you want to do.