简体   繁体   中英

Client-server searching with jQuery and MVC

I have a view with two drop downlist which is used to search the description. The list of results are displayed in another view for now. I wish to generate the results in the same search view. I assume some AJAX or Jquery can be used to sort this out but don't know how. So, in this case how can the search result be displayed in the same view page?

Moreover, i have some doubt in Search controller . I want at least one drop down list to be selected (Both drop down list shouldn't be allowed null). How can i validate that part?

View

@using (Html.BeginForm("Search","Work",FormMethod.Get))
{

    <fieldset>
        <legend>Search</legend>
    <div class="editor-label">
            @Html.LabelFor(model => model.JobTypeID, "Job Type")
        </div>
        <div class="editor-field">
            @Html.DropDownList("JobTypeID", "Select Job Type")
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.JobPriorityID, "Job Priority")
        </div>
        <div class="editor-field">
            @Html.DropDownList("JobPriorityID", "Select Job Priority")
        </div>
         <p>
            <input type="submit" value="Search" />
        </p>
        </fieldset>
}

Controller:

 [HttpGet]
        public ActionResult Search(int? jobtypeid, int? jobpriorityid)
        {
            var vJobDescriptions = new List<JobDescription>();

            if (jobtypeid != null && jobpriorityid != null )
            {
                 vJobDescriptions = (from description in db.JobDescriptions
                                        where (description.JobTypeID == jobtypeid && description.JobPriorityID == jobpriorityid)
                                        select description).ToList();
            }
            else if (jobtypeid == null && jobpriorityid != null)
            {
                 vJobDescriptions = (from description in db.JobDescriptions
                                        where (description.JobPriorityID == jobpriorityid)
                                        select description).ToList();

            }
            else if (jobtypeid != null && jobpriorityid == null)
            {
                vJobDescriptions = (from description in db.JobDescriptions
                                    where (description.JobTypeID == jobtypeid)
                                    select description).ToList();
            }
            else
            {
                vJobDescriptions = (from description in db.JobDescriptions
                                    select description).ToList();
            }


            return View(vJobDescriptions);
        }

One possibility is to use an Ajax.BeginForm instead of a normal form (don't forget to include jquery.js and jquery.unobtrusive-ajax.js scripts to your page):

@using (Ajax.BeginForm("Search", "Work", new AjaxOptions { UpdateTargetId = "results" }))

then you could have a placeholder for the results that we specified in the UpdateTargetId :

<div id="results"></div>

Now all that's left is to have your Search controller action return a PartialView and pass it the model containing the results of the search:

public ActionResult Search(int? jobtypeid, int? jobpriorityid)
{
    var model = ...
    return PartialView("_Result", model);
}

and of course the corresponding _Result.cshtml partial:

@model IEnumerable<MyViewModel>
...

Moreover, i have some doubt in Search controller. I want at least one drop down list to be selected (Both drop down list shouldn't be allowed null). How can i validate that part?

I would recommend you FluentValidation.NET but if you don't want to use third party libraries you could write a custom validation attribute that will perform this validation and then decorate one of the 2 view model properties that are bound to your dropdown lists with it.

Unfortunately if you decide to go the AJAX route, you will have to be able to display validation errors coming from the server in case there was something wrong. So it is the entire form that has to be put inside the partial.

Another approach that you could use is to simply reload the entire page using a standard form without AJAX. The results will be part of your initial view model as a collection property which will initially be null and after performing the search you will populate it with the results. Then inside the view you will test if the property is not null and if it isn't include the Partial that will take care of rendering the results:

@using (Html.BeginForm("Search", "Work", FormMethod.Get))
{
    ...
}

<div id="results">
    @if (Model.Results != null)
    {
        @Html.Partial("_Results", Model.Results)
    }
</div>

A basic approach to this would be to place the markup for your search results into a partial view, and return that from your Search ActionMethod. This would require you to change the last line of your search method to

return Partial(vJobDescriptions)

In your client-side script, you would do something along the lines of this:

var data = $("form").serialize();
$.get("/Search", data)
 .complete(function(results) { 
     $("form").replace(results) };

With regards to the validation aspect you're looking for, I would consider separating your read model from the search command parameters.

public ActionResult Search(SearchModel search)
{
     if (!ModelState.IsValid) // return view w/ invalid model
}

where your search params model would be along these lines:

[CustomValidation(typeof(SearchModel), 
                  "OneNotNullValidator", 
                  "One option must be selected"]
public class SearchModel 
{

     public int? JobTypeID { get; set;}
     public int? JobPriorityID { get; set;}

     public bool OneNotNullValidator()
     {
          return JobTypeID.HasValue || JobPriorityID.HasValue;
     }
}

The CustomValidation attribute I've applied to the class may not be 100% correct on the specific syntax and name(s), but I hope the gist of it comes across.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM