Add paging links to View using multiple search strings ASP.NET Core Visual Studio 2017 - search string is not taken over

asp.net-core-1.1 asp.net-core-mvc entity-framework-core razor visual-studio-2017

Question

I'm developing a paginated Index view referring to the example Sorting, filtering, paging, and grouping - EF Core with ASP.NET Core MVC tutorial (3 of 10)

On my Index page I use 3 search strings.

Sorting works very well, but without searching parameters. As soon as I try to sort after having entered a search string, nothing works. The search string should be taken over. It does not happaen.

Also paging after having inserted a search string does not work properly. The ViewData elements named CurrentFilterxxx provides the view with the current filter string. This value must be included in the paging links in order to maintain the filter settings during paging, and it must be restored to the text box when the page is redisplayed. In my case it does not work.

Here my Index method of the Controller Class:

public async Task<IActionResult> Index(
        string sortOrder, 
        string searchStringComune, 
        string searchStringProvincia, 
        string searchStringRegione,
        string searchString,
        string currentFilter,
        int? page)
    {
        ViewData["CurrentSort"] = sortOrder;
        ViewData["ComuneSortParm"] = String.IsNullOrEmpty(sortOrder) ? "comune" : "";
        ViewData["ProvinciaSortParm"] = String.IsNullOrEmpty(sortOrder) ? "provincia" : "";
        ViewData["RegioneSortParm"] = String.IsNullOrEmpty(sortOrder) ? "regione" : "";
        ViewData["PostalCodeSortParm"] = String.IsNullOrEmpty(sortOrder) ? "CAP" : "";
        ViewData["AbitantsSortParm"] = String.IsNullOrEmpty(sortOrder) ? "abitanti" : "";

        if (searchStringComune != null ||
            searchStringProvincia != null ||
            searchStringRegione != null ||
            searchString != null)
        {
            page = 1;
            if (searchStringComune != null)
            {
                searchString = searchStringComune;
            }
            if (searchStringProvincia != null)
            {
                searchString = searchStringProvincia;
            }
            if (searchStringRegione != null)
            {
                searchString = searchStringRegione;
            }
        }
        else
        {
            searchString = currentFilter;
        }

        ViewData["CurrentFilterComune"] = searchStringComune;
        ViewData["CurrentFilterProvincia"] = searchStringProvincia;
        ViewData["CurrentFilterRegione"] = searchStringRegione;
        ViewData["CurrentFilter"] = searchString;

        var comuni = from s in _context.Listacomuniitaliani
                       select s;

        if (!String.IsNullOrEmpty(searchStringComune) ||
            !String.IsNullOrEmpty(searchStringProvincia) ||
            !String.IsNullOrEmpty(searchStringRegione))
        {

            comuni = comuni.Where(s => s.Comune.Equals(searchStringComune) ||
                                       s.Provincia.Equals(searchStringProvincia) ||
                                       s.Regione.Equals(searchStringRegione));
        }

        switch (sortOrder)
        {
            case "comune":
                comuni = comuni.OrderByDescending(s => s.Comune);
                break;
            case "provincia":
                comuni = comuni.OrderBy(s => s.Provincia);
                break;
            case "regione":
                comuni = comuni.OrderBy(s => s.Regione);
                break;
            case "CAP":
                comuni = comuni.OrderBy(s => s.Cap);
                break;
            case "abitanti":
                comuni = comuni.OrderBy(s => s.Abitanti);
                break;
            default:
                comuni = comuni.OrderBy(s => s.Comune);
                break;
        }

        int pageSize = 7;
        return View(await PaginatedList<Listacomuniitaliani>.CreateAsync(comuni.AsNoTracking(), page ?? 1, pageSize));
    }

And here my Index code:

@model PaginatedList<MyProjectName.Models.Listacomuniitaliani>

@{ViewData["Title"] = "Index";}

<h2>Index</h2>

<p>
<a asp-action="Create">Create New</a>
</p>

<form asp-action="Index" method="get">
    <div class="form-actions no-color">
        <p>
            Cerca un comune: <input type="text" name="SearchStringComune" value="@ViewData["currentFilterComune"]" />
            <input type="submit" value="trova" class="btn btn-default" />
        </p>
    </div>
</form>

<form asp-action="Index" method="get">
<div class="form-actions no-color">
    <p>
        Seleziona una provincia: <input type="text" name="SearchStringProvincia" value="@ViewData["currentFilterProvincia"]" />
        <input type="submit" value="trova" class="btn btn-default" />
    </p>
</div>

<form asp-action="Index" method="get">
<div class="form-actions no-color">
    <p>
        Seleziona una regione: <input type="text" name="SearchStringRegione" value="@ViewData["currentFilterRegione"]" />
        <input type="submit" value="trova" class="btn btn-default" />
    </p>
</div>

<form asp-action="Index" method="get">
<div class="form-actions no-color">
    <p>
        <a asp-action="Index">Torna indietro alla lista</a>
    </p>
</div>

<table class="table">
<thead>
    <tr>
            <th>
                Istat
            </th>
            <th>
                    <a asp-action="Index" asp-route-sortOrder="@ViewData["ComuneSortParm"]"
                       asp-route-currentFilterComune="@ViewData["CurrentFilterComune"]">Comune</a>                       
    </th>
            <th>
                <a asp-action="Index" asp-route-sortOrder="@ViewData["ProvinciaSortParm"]"
                   asp-route-currentFilterProvincia="@ViewData["CurrentFilterProvincia"]">Provincia</a>
            </th>
            <th>
                <a asp-action="Index" asp-route-sortOrder="@ViewData["RegioneSortParm"]"
                   asp-route-currentFilterRegione="@ViewData["CurrentFilterRegione"]">Regione</a>
            </th>
            <th>
                Prefisso
            </th>
            <th>
                <a asp-action="Index" asp-route-sortOrder="@ViewData["PostalCodeSortParm"]">CAP</a>
            </th>
            <th>
                CodFisco
            </th>
            <th>
                <a asp-action="Index" asp-route-sortOrder="@ViewData["AbitantsSortParm"]">Abitanti</a>
            </th>
            <th>
                Link
            </th>
        <th></th>
    </tr>
</thead>
<tbody>
@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Istat)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Comune)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Provincia)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Regione)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Prefisso)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Cap)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.CodFisco)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Abitanti)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Link)
        </td>
        <td>
            <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
            <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
            <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
        </td>
    </tr>
     }
</tbody>
</table>

@{
var prevDisabled = !Model.HasPreviousPage ? "disabled" : "";
var nextDisabled = !Model.HasNextPage ? "disabled" : "";
}


<a asp-action="Index"
asp-route-sortOrder="@ViewData["CurrentSort"]"
asp-route-page="@(Model.PageIndex - 1)"
@*asp-route-currentFilter="@ViewData["CurrentFilter"]"*@
asp-route-currentFilterComune="@ViewData["CurrentFilterComune"]"
asp-route-currentFilterRegione="@ViewData["CurrentFilterRegione"]"
asp-route-currentFilterProvincia="@ViewData["CurrentFilterProvincia"]"
class="btn btn-default @prevDisabled">
Previous
</a>

<a asp-action="Index"
asp-route-sortOrder="@ViewData["CurrentSort"]"
asp-route-page="@(Model.PageIndex + 1)"
@*asp-route-currentFilter="@ViewData["CurrentFilter"]"*@
asp-route-currentFilterComune="@ViewData["CurrentFilterComune"]"
asp-route-currentFilterRegione="@ViewData["CurrentFilterRegione"]"
asp-route-currentFilterProvincia="@ViewData["CurrentFilterProvincia"]"
class="btn btn-default ifextDisabled">
Next
</a>

The tag helper asp-route-currentFilter has not been used.Instead, I have used more specific tag helpers; for instance asp-route-currentFilterComune.

Any help is appreciated.

1
1
7/14/2017 11:34:20 AM

Accepted Answer

I've got it working. To do that i had to redesign a part of the controller and made some modifications on the view code. Handling more than one search string has been for me quite challenging.

Here my new controller index method:

public async Task<IActionResult> Index(
        string sortOrder, 
        string searchStringComune, 
        string searchStringProvincia, 
        string searchStringRegione,
        string searchString,
        string currentFilter,
        int? page)
    {
        ViewData["CurrentSort"] = sortOrder;
        ViewData["ComuneSortParm"] = String.IsNullOrEmpty(sortOrder) ? "comune" : "";
        ViewData["ProvinciaSortParm"] = String.IsNullOrEmpty(sortOrder) ? "provincia" : "";
        ViewData["RegioneSortParm"] = String.IsNullOrEmpty(sortOrder) ? "regione" : "";
        ViewData["PostalCodeSortParm"] = String.IsNullOrEmpty(sortOrder) ? "CAP" : "";
        ViewData["AbitantsSortParm"] = String.IsNullOrEmpty(sortOrder) ? "abitanti" : "";


        if (searchStringComune != null ||
            searchStringProvincia != null ||
            searchStringRegione != null ||
            searchString != null)
        {
            page = 1;
        }
        else
        {
            searchStringProvincia = currentFilter;
            searchStringRegione = currentFilter;

            foreach (ItalianRegions itemRegion in Enum.GetValues(typeof(ItalianRegions)))
            {
                if (searchStringRegione == itemRegion.ToString())
                {
                    searchStringProvincia = null;
                }
            }

            foreach (ItalianComunes itemComune in Enum.GetValues(typeof(ItalianComunes)))
            {
                if (searchStringProvincia == itemComune.ToString())
                {
                    searchStringRegione = null;
                }
            }

        }


        ViewData["CurrentFilterComune"] = searchStringComune;
        ViewData["CurrentFilterProvincia"] = searchStringProvincia;
        ViewData["CurrentFilterRegione"] = searchStringRegione;
        ViewData["CurrentFilter"] = searchString;

        var comuni = from s in _context.Listacomuniitaliani
                       select s;

        if (!String.IsNullOrEmpty(searchStringComune) ||
            !String.IsNullOrEmpty(searchStringProvincia) ||
            !String.IsNullOrEmpty(searchStringRegione))
        {
            comuni = comuni.Where(s => s.Comune.Equals(searchStringComune) ||
                                       s.Provincia.Equals(searchStringProvincia) ||
                                       s.Regione.Equals(searchStringRegione));
        }

        switch (sortOrder)
        {
            case "comune":
                comuni = comuni.OrderByDescending(s => s.Comune);
                break;
            case "provincia":
                comuni = comuni.OrderBy(s => s.Provincia);
                break;
            case "regione":
                comuni = comuni.OrderBy(s => s.Regione);
                break;
            case "CAP":
                comuni = comuni.OrderBy(s => s.Cap);
                break;
            case "abitanti":
                comuni = comuni.OrderBy(s => s.Abitanti);
                break;
            default:
                comuni = comuni.OrderBy(s => s.Comune);
                break;
        }


        int pageSize = 7;
        return View(await PaginatedList<Listacomuniitaliani>.CreateAsync(comuni.AsNoTracking(), page ?? 1, pageSize));
    }

I have looped into the search string using 2 different enumto be able to set correctly the sear string text in the search field while paging.

Here the Index code:

@model PaginatedList<MyProject.Models.Listacomuniitaliani>

@{
 ViewData["Title"] = "Index";
}

<h2>Index</h2>

<p>
 <a asp-action="Create">Create New</a>
</p>

<form asp-action="Index" method="get">
    <div class="form-actions no-color">
        <p>
            Cerca un comune: <input type="text" name="searchStringComune"    value="@ViewData["CurrentFilterComune"]" />
            <input type="submit" value="trova" class="btn btn-default" />
        </p>
    </div>
</form>


<form asp-action="Index" method="get">
 <div class="form-actions no-color">
    <p>
        Seleziona una provincia: <input type="text" name="searchStringProvincia" value="@ViewData["CurrentFilterProvincia"]" />
        <input type="submit" value="trova" class="btn btn-default" />
    </p>
  </div>
</form>

<form asp-action="Index" method="get">
  <div class="form-actions no-color">
    <p>
        Seleziona una regione: <input type="text" name="searchStringRegione" value="@ViewData["CurrentFilterRegione"]" />
        <input type="submit" value="trova" class="btn btn-default" />
    </p>
  </div>
</form>

<form asp-action="Index" method="get">
  <div class="form-actions no-color">
    <p>
        <a asp-action="Index">Torna indietro alla lista</a>
    </p>
  </div>
 </form>


 <table class="table">
  <thead>
    <tr>
            <th>
                Istat
            </th>
            <th>
                    <a asp-action="Index" asp-route-sortOrder="@ViewData["ComuneSortParm"]">Comune</a>
            </th>
            <th>
                <a asp-action="Index" asp-route-sortOrder="@ViewData["ProvinciaSortParm"]"
                   asp-route-currentFilter="@ViewData["CurrentFilterProvincia"]">Provincia</a>
            </th>
            <th>
                <a asp-action="Index" asp-route-sortOrder="@ViewData["RegioneSortParm"]"
                   asp-route-currentFilter="@ViewData["CurrentFilterRegione"]">Regione</a>
            </th>
            <th>
                Prefisso
            </th>
            <th>
                <a asp-action="Index" asp-route-sortOrder="@ViewData["PostalCodeSortParm"]">CAP</a>
            </th>
            <th>
                CodFisco
            </th>
            <th>
                <a asp-action="Index" asp-route-sortOrder="@ViewData["AbitantsSortParm"]">Abitanti</a>
            </th>
            <th>
                Link
            </th>
        <th></th>
     </tr>
    </thead>
  <tbody>

   @foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Istat)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Comune)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Provincia)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Regione)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Prefisso)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Cap)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.CodFisco)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Abitanti)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Link)
        </td>
        <td>
            <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
            <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
            <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
        </td>
    </tr>
     }
   </tbody>
  </table>

   @{
     var prevDisabled = !Model.HasPreviousPage ? "disabled" : "";
     var nextDisabled = !Model.HasNextPage ? "disabled" : "";
    }


 <a asp-action="Index"
    asp-route-sortOrder="@ViewData["CurrentSort"]"
    asp-route-page="@(Model.PageIndex - 1)"
    asp-route-currentFilter=@if (@ViewData["CurrentFilterRegione"] != null)
    {
      @ViewData["CurrentFilterRegione"]
    } else
    {
      @ViewData["CurrentFilterProvincia"]
    }
    class="btn btn-default @prevDisabled">
    Previous
 </a>
 <a asp-action="Index"
    asp-route-sortOrder="@ViewData["CurrentSort"]"
    asp-route-page="@(Model.PageIndex + 1)"
    asp-route-currentFilter=@if (@ViewData["CurrentFilterRegione"] != null)
    {
      @ViewData["CurrentFilterRegione"]
    } else
    {
    @ViewData["CurrentFilterProvincia"]
    }
    class="btn btn-default @nextDisabled">
    Next
</a>

Now it works perfectly. Sorting works. Paging works as well, maintaining the search string text.

1
7/18/2017 4:29:18 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow