Eemq07
Eemq07

Reputation: 45

Filtering Data Table with two models in single view using multiple dropdown

I started to created my project using MVC and it's really enjoying to create different projects using mvc.

So I created awhile ago the data table that filters data when you selected value in single dropdown

But I'm still curious about filtering data using multiple dropdown and two models in a single view

What I did... first, I created a class that I can be used to display my two data table using two models

This is my class in mvc

 public class MyData
  {
    public IEnumerable<pmTA_ProjectCategory> ProjectCategory { get; set; }
    public IEnumerable<pmTA_FundCategory> FundCategory { get; set; }
  }

After creating my class, I created a code for two data table using one view for Index and view for partial view to call the two data table

this is the codes for view of Index and view of Partial View which the name is "MyPartialView"

For view of Index:

  @using myProject.Models;
  @model MyData


  <div id="myPartialView">
   @Html.Partial("MyPartialView",Model)
  </div>

  @if (Model.ProjectCategory != null) {
  <table class="table table-bordered table-hover ">
<thead>
    <tr>
        <th>id</th>
        <th>title </th>
        <th>
            description
        </th>

    </tr>
</thead>
<tbody>
    @foreach (var item in Model.ProjectCategory)
    {

        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.id)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.description)
            </td>

        </tr>
    }
</tbody>
 </table>
}

For view of Partial View

      <table id="myDataTable" class="table table-bordered table-hover ">
      <thead>
        <tr>
            <th>id</th>
            <th>code</th>
            <th>
                title
            </th>
            <th>
                description
            </th>
            <th>--</th>
            <th>--</th>
        </tr>
       </thead>
       <tbody>
        @foreach (var item in Model.FundCategory)

        {
            string selectedRow = "";
            if (item.id == ViewBag.fund)
            {
                selectedRow = "success";
            }
            <tr class="@selectedRow">
                <td>
                    @Html.DisplayFor(modelItem => item.id)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.code)
                </td>
                <td>

                    @Html.DisplayFor(modelItem => item.title)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.description)
                </td>
                <td>
                    @Html.ActionLink("Edit", "FundCategoryEdit", new { id = 
          item.id }, new { @class = "btn btn-primary" })
                </td>
                <td>
                    @Html.ActionLink("Select", "Index", new { 
            fund_category_id = item.id }, null)
                </td>
            </tr>
        }
      </tbody>
       </table>

Inorder to Function my view I created codes in controller to display two data table, I declared the name of my class in the controller

this the codes in my controller, the first code is for the partial view datatable and the second code is for the View Index

for partial:

      var viewModel = new MyData();
        viewModel.FundCategory = (from p in db.pmTA_FundCategory

                                  select new
                                  {
                                      id = p.id,
                                      code = p.code,
                                      title = p.title,
                                      description = p.description,
                                      status = p.status
                                  }).ToList()
                  .Select(x => new pmTA_FundCategory()
                  {
                      id = x.id,
                      code = x.code,
                      title = x.title,
                      description = x.description,
                      status = x.status
                  });

For View of Index

    if (fund_category_id != null)
        {

            ViewBag.fund = fund_category_id.Value;
            viewModel.ProjectCategory = (from p in db.pmTA_ProjectCategory
                          join g in db.pmTA_FundCategory
                           on p.fund_category_id equals g.id
                          where p.fund_category_id == fund_category_id
                          select new
                          {
                              id = p.id,
                              title = p.title,
                              description = p.description,
                              title1 = g.title,
                              status = p.status
                          }).ToList()
               .Select(x => new pmTA_ProjectCategory()
               {
                   id = x.id,
                   title = x.title,
                   description = x.description,
                   title1 = x.title1,
                   status = x.status

               });

        }

        return View(viewModel);

They are together in the Index controller but I seperated it in order you to understand my codes

The purpose of the if condition there is for the displaying of my View Index Data table when click the "Select" button of the partial data table based on there ID, you can use the codes above as your reference for showing another data table using other data table...

To display my multiple drop down I always used this codes

Codes for View of Index to display dropdowns

     <div>
     @Html.DropDownList("id", ViewBag.funds as SelectList, "Select...", new 
     { @class = "form-control" })
     </div>
     <div>
     @Html.DropDownList("projectcat", ViewBag.proj as SelectList, 
    "Select...", new 
     { @class = "form-control" })
      </div>

Codes for dropdown in controller to display the data inside of it based on the database data

for first and second dropdown

     var data1 = from p in db.pmTA_FundCategory

                    select new
                    {
                        id = p.id,
                        code = p.code,
                        title = p.title,
                        description = p.description
                    };

        SelectList list = new SelectList(data1, "id", "title");
         ViewBag.funds = list;

     var data2 = from p in db.pmTA_ProjectCategory

                    select new
                    {
                        id = p.id,
                        title = p.title,
                        description = p.description
                    };

        SelectList list1 = new SelectList(data2, "id", "title");
        ViewBag.proj = list1;

The problem is... How I gonna filter my Partial Data table using multiple drop down without using any plugins but with the help of javascript or any method to filter the data of data table?

Once I selected the value of my multiple dropdown my Partial Data table will display the data corresponds to the multiple dropdown selected...

Upvotes: 1

Views: 1243

Answers (1)

er-sho
er-sho

Reputation: 9771

Multiple Table with Multiple Drop Down

1) Add two drop down in your main view like

<div class="dropdown">
    @Html.DropDownList("id", (List<SelectListItem>)ViewBag.proj, "--Select id--", new { @onchange = "CallChangefunc1(this.value)" })
</div>

<div class="dropdown">
    @Html.DropDownList("id", (List<SelectListItem>)ViewBag.funds, "--Select id--", new { @onchange = "CallChangefunc2(this.value)" })
</div>

2) Add two partial view 1st with name _GetProjectCategory.cshtml and 2nd with name _GetFundCategory.cshtml

Make sure that

1st partial view @model will be of type @model IEnumerable<WebApplicationMVC1.Controllers.ProjectCategory>

2nd partial view @model will be of type @model IEnumerable<WebApplicationMVC1.Controllers.FundCategory>

Simply add your content in respective partial view.

Make sure both of your partial view contains.

@foreach (var item in Model) { //You table contents }

3) Call both partial view in your main view like

<div id="myPartialView1">
    @{Html.RenderPartial("_GetProjectCategory", Model.ProjectCategories);}
</div>

<div id="myPartialView2">
    @{Html.RenderPartial("_GetFundCategory", Model.FundCategories);}
</div>

4) Then create a view model like

public class ProjectFundViewModel
{
    public List<ProjectCategory> ProjectCategories { get; set; }
    public List<FundCategory> FundCategories { get; set; }
}

5) Your action method will be (Its sample code and replace by your code).

public ActionResult Index()
{
    //The below query replace by yours
    var projects = db.ProjectCategories.ToList();

    List<SelectListItem> dropDownItems1 = projects.Select(c => new SelectListItem { Text = c.title, Value = c.id.ToString() }).ToList();
    ViewBag.proj = dropDownItems1;

    //The below query replace by yours
    var funds = db.FundCategories.ToList();

    List<SelectListItem> dropDownItems2 = funds.Select(c => new SelectListItem { Text = c.title, Value = c.id.ToString() }).ToList();
    ViewBag.funds = dropDownItems2;

    ProjectFundViewModel viewModel = new ProjectFundViewModel
    {
        ProjectCategories = projects,
        FundCategories = funds
    };

    return View(viewModel);
}

6) Add ajax call to your main view that called when you change any option in respective drop down

<script>

    function CallChangefunc1(id) {
         $.ajax({
             url: "@Url.Action("GetProjectCategory", "Default")",
             data: { id: id },
            type: "Get",
            dataType: "html",    
             success: function (data) {
                 console.log(data);
                //Whatever result you have got from your controller with html partial view replace with a specific html.
                $("#myPartialView1").html( data ); // HTML DOM replace
            }
        });
    }

    function CallChangefunc2(id) {
         $.ajax({
             url: "@Url.Action("GetFundCategory", "Default")",
             data: { id: id },
            type: "Get",
            dataType: "html",    
             success: function (data) {
                 console.log(data);
                //Whatever result you have got from your controller with html partial view replace with a specific html.
                $("#myPartialView2").html( data ); // HTML DOM replace
            }
        });
    }

</script>

7) And finally your ajax call hit below action method that can render respective partial view.

public PartialViewResult GetProjectCategory(int id)
{
    var projects = db.ProjectCategories.ToList();
    var model = projects.Where(x => x.id == id).ToList();
    return PartialView("_GetProjectCategory", model);
}

public PartialViewResult GetFundCategory(int id)
{
    var funds = db.FundCategories.ToList();
    var model = funds.Where(x => x.id == id).ToList();
    return PartialView("_GetFundCategory", model);
}

8) Make sure your main view @model is @model WebApplicationMVC1.Controllers.ProjectFundViewModel not IEnumerable.

Single Table with Multiple Drop Down

1) Add two drop down in your main view with id

<div class="dropdown">
    @Html.DropDownList("id", (List<SelectListItem>)ViewBag.ids, "--Select id--", new { @onchange = "CallChangefunc1(this.value)", @id = "dropdown1" })
</div>

<div class="dropdown">
    @Html.DropDownList("title", (List<SelectListItem>)ViewBag.titles, "--Select title--", new { @onchange = "CallChangefunc2(this.value)", @id = "dropdown2" })
</div>

2) Add partial view with name GetFilteredData.cshtml with model @model IEnumerable<WebApplicationMVC1.Controllers.ProjectCategory>.

Make sure your partial view contains.

@foreach (var item in Model) { //You table contents }

3) Call your partial view in main view like

<div id="myPartialView">
    @{Html.RenderPartial("GetFilteredData", Model.ProjectCategories);}
</div>

4) Now your first drop down contains ids and second drop down contains titles from projects category.

public ActionResult Index()
{
    var projects = db.ProjectCategories.ToList();

    List<SelectListItem> dropDownItems1 = projects.Select(c => new SelectListItem { Text = c.id.ToString(), Value = c.id.ToString() }).ToList();
    ViewBag.ids = dropDownItems1;

    List<SelectListItem> dropDownItems2 = projects.Select(c => new SelectListItem { Text = c.title, Value = c.title }).ToList();
    ViewBag.titles = dropDownItems2;

    ProjectFundViewModel viewModel = new ProjectFundViewModel
    {
        ProjectCategories = projects,
    };

    return View(viewModel);
}

5) Add ajax call from main view like

<script>

    function CallChangefunc1(id) {

        var title = $("#dropdown2").val();

         $.ajax({
             url: "@Url.Action("GetFilteredData", "Default2")",
             data: { id: id, title: title },
            type: "Get",
            dataType: "html",
             success: function (data) {
                 console.log(data);
                //Whatever result you have got from your controller with html partial view replace with a specific html.
                 $("#myPartialView").html( data ); // HTML DOM replace
            }
        });
    }

    function CallChangefunc2(title) {

        var id = $("#dropdown1").val();

         $.ajax({
             url: "@Url.Action("GetFilteredData", "Default2")",
             data: { id: id, title: title },
            type: "Get",
            dataType: "html",
             success: function (data) {
                 console.log(data);
                //Whatever result you have got from your controller with html partial view replace with a specific html.
                 $("#myPartialView").html( data ); // HTML DOM replace
            }
        });
    }

</script>

6) And finally your ajax call hit below action method with 2 parameters.

public PartialViewResult GetFilteredData(int? id, string title)
{
    var query = db.ProjectCategories.ToList();

    if (id != null)
        query = query.Where(x => x.id == id).ToList();

    if (!string.IsNullOrEmpty(title))
        query = query.Where(x => x.title == title).ToList();

    return PartialView("GetFilteredData", query);
}

Upvotes: 1

Related Questions