Ad

How To Implement Search With Two Terms For A Collection?

- 1 answer

So, currently I have a collection of items where I want the user to be able to search using the name and some random text from the collection.

Here's what I have done so far:

    public IEnumerable<Item> items = new[]
    {
        new Item { ItemId = 1, ItemName = "Apple", ItemDescription = "crispy, sweet", ItemPairing = "Walnut"},
        new Item { ItemId = 2, ItemName = "Pear", ItemDescription = "slightly tart", ItemPairing = "Cheese"},
        new Item { ItemId = 3, ItemName = "Banana", ItemDescription = "good source of potassium", ItemPairing = "Honey" },
        new Item { ItemId = 4, ItemName = "Chocolate", ItemDescription = "Sweet and rich melting flavor", ItemPairing = "Wine"}
    };


    public ActionResult Index()
    {
        return View("Index");
    }

    public ActionResult Search(string search)
    {
        return View("Index", items.Where(n => n.ItemName.StartsWith(search))); 
    }

Here's the search part on the view:

<p>
    <b>Search for Name:</b> 
    @Html.TextBox("ItemName", "", new { @class = "form-control" })  
    <b>Search for Text:</b>
    @Html.TextBox("ItemText", "", new { @class = "form-control" })

    <input id="search" type="submit" value="Search" onclick="search(ItemName,ItemText)" />
</p>

<script>
    function search(ItemName, ItemText) {
        $("search").click(function () {

            $.ajax({
                type: "POST",
                url: "/Items/Search",
                data: {ItemName, ItemText},
                datatype: "html",
                success: function (data) {
                    $('#result').html(data);
                }
            });
        });
    }
</script>

So that it can look something like this:

SearchPage

I want it so that when the user types in Apple for Name and Crispy for text, they can find the Apple item from my collection. I also want it so that if they type in either Name or Text, it will still return a matched item.

I'm not sure how to do that.

Ad

Answer

Remove the onclick attribute from the submit button and change it to

<button type="button" id="searon and change it to

<button type="button" id="search">Search</button>

and change the script to

var url = '@Url.Action("Search", "Items")';
$("#search").click(function () {
  $.post(url, { ItemName: $('#ItemName').val(), ItemText: $('#ItemText').val() }, function(data) {
    $('#result').html(data);
  });
})

Note you may want to consider making it $.get() rather than $.post()

and change the controller method to accept the inputs from both textboxes

public PartialViewResult Search(string itemName, string itemText)
{
  var items = ??
  // filter the data (adjust to suit your needs)
  if (itemName != null)
  {
    items = items.Where(x => x.ItemName.ToUpperInveriant().Contains(itemName.ToUpperInveriant()) 
  }
  if (itemText != null)
  {
    items = items.Where(x => x.ItemDescription.ToUpperInveriant().Contains(itemText.ToUpperInveriant()) 
  }
  // query you data
    return PartialView("_Search", items); 
}

Side note: Its not clear what the logic for search is - i.e. if you enter search text in both textboxes, do you want an and or an or search

Assuming the view in the view in the question is Index.cshtml, then it will include the following html

<div id="result">
  @Html.Action("Search") // assumes you want to initially display all items
</div>

and the _Search.cshtml partial would be something like

@model IEnumerable<Item>
@foreach (var item in Model)
{
  // html to display the item properties
}
Ad
source: stackoverflow.com
Ad