Save and send selected item id in dropdowlinst

Asked

Viewed 701 times

11

I’m trying to do a search, filtering through a dropdowlist. In short, I select a level of instruction in a list and when I click 'Search' I want to return to the list of people who have that level of education. My problem is the identification of the selected item in the dropdownlist. If I select anything the search does not return me anything. But if I pass a value to the id as in the example below, when I click on Search I get back all the people who have that level equal to the informed id. What I need to do to get the id of the selected item?

My Controller

public class FormacaoController : Controller
{
    private DataContext db = new DataContext();

    public ActionResult Index()
    {
        ViewBag.NívelId = new SelectList(db.Escolaridades, "Id", "Nome");
        return View();
    }

    [HttpPost]
    public ActionResult Pesquisa(int id = 3) // 'setando' um valor, ao clicar em buscar, retorna as informaçãos. Se não passar um valor aqui para o id, a consulta não retorna nada.
    {
        var resultado = db.Cursos.Include(c => c.Perfil).Where(c => c.NívelId == id);
        ViewBag.Perfil = db.Perfis.AsEnumerable();
        ViewBag.NívelId = new SelectList(db.Escolaridades, "Id", "Nome");

        return View(resultado);
    }
    }

View Index

    <div> 
 @using (Html.BeginForm("Pesquisa", "Formacao", FormMethod.Post))
 {
     IEnumerable<MinhaBase.Models.Perfil> modelPerfil = (IEnumerable<MinhaBase.Models.Perfil>)ViewBag.Perfil;

     <div class="form-group">
         @Html.DropDownList("NívelId")

     </div> 

     <button type="submit" id="pesquisar" class="btn btn-primary btn-xs">Buscar</button>
 }

View Pesquisa

<div> 
 @using (Html.BeginForm("Pesquisa", "Formacao"))
 {
     IEnumerable<MinhaBase.Models.Perfil> modelPerfil = (IEnumerable<MinhaBase.Models.Perfil>)ViewBag.Perfil;
     <div class="form-group">
         @Html.DropDownList("NívelId")

     </div> 

     <button type="submit" id="pesquisar" class="btn btn-primary btn-xs">Buscar</button>
 }

   <table>

    @{
        if (Model != null)
        {
            foreach (var item in Model)
            {
        <tr>
        <th>Nome <b>&nbsp; &nbsp; &nbsp;</b></th>


    </tr>
                <tr>
                   <td width="30%">@item.Nome></td> 
                    <td width="30%">@item.Instituição</td> 
                    <td width="30%">@item.Perfil.Nome</td> 
                </tr>
                }
            }
        }
</table>

2 answers

7

Gypsy Method of Implementing a Research Form

This is the method I use in my applications, and it has several advantages:

  • Search parameters in the URL. No need form to repeat the search. A simple F5 or [Ctrl/Command] + R already does this;
  • SEO friendly;
  • Search parameters are filled in the search form;
  • Search form can appear on any screen.

1. The search form shall have FormMethod.GET

If it is search, the parameters should be in the request address, so you can easily call the search without needing a form.

For that, make a Partial with the following:

_Pesquisa.cshtml

 @using (Html.BeginForm("Pesquisa", "Formacao", FormMethod.GET))
 {
     IEnumerable<MinhaBase.Models.Perfil> modelPerfil = (IEnumerable<MinhaBase.Models.Perfil>)ViewBag.Perfil;

     <div class="form-group">
         @Html.DropDownList("NivelId")
     </div> 

     <button type="submit" id="pesquisar" class="btn btn-primary btn-xs">Buscar</button>
 }

2. The search form shall be a Partial

This is because possibly it will appear in N Views of your code.

3. Create a Viewmodel that contains the search parameters and its result

That is to say:

public class PesquisaViewModel
{
    public int NivelId { get; set; }

    public virtual IEnumerable<Curso> Cursos { get; set; }
}

4. The Controller must accept the Viewmodel in research

He can accept POST also, but as far as I can see.

[HttpGet]
public ActionResult Pesquisa(PesquisaViewModel viewModel)
{
    if (viewModel != null) 
    {
        viewModel.Cursos = db.Cursos.Include(c => c.Perfil).Where(c => c.NivelId == viewModel.NivelId);
    }

    ViewBag.Perfil = db.Perfis;
    ViewBag.Niveis = db.Escolaridades;

    return View(viewModel);
}

5. _Pesquisa and the View search result must be typed by Viewmodel

_Pesquisa.cshtml

 @model MeuProjeto.ViewModels.PesquisaViewModel

 @using (Html.BeginForm("Pesquisa", "Formacao", FormMethod.GET))
 {
     <div class="form-group">
         @Html.DropDownListFor(model => model.NivelId, ((IEnumerable<Escolaridade>)ViewBag.Niveis).Select(option => new SelectListItem 
         {
             Text = option.Nome,
             Value = option.NivelId.ToString(),
             Selected = (Model != null) && (Model.NivelId == option.NivelId)
         }), "Selecione...")
     </div> 

     <button type="submit" id="pesquisar" class="btn btn-primary btn-xs">Buscar</button>
 }

Pesquisa.cshtml

If the name is ambiguous, use ResultadoPesquisa.cshtml.

 @model MeuProjeto.ViewModels.PesquisaViewModel

 ...

6. Canvas not using this Viewmodel can call the Partial hassle-free

Thus:

@Html.Partial("_Pesquisa", new PesquisaViewModel())
  • let me get this straight. I create a Partial call _Search that can be used on multiple screens. Ok. Create viewModel ok. Item 4, the controller you refer to is what I create to do some research right? And in item 5, 'Search.cshtml is a reference to the previously created controller.

  • If I create 'Searchviewmodel' as a model, instead of a viewModel folder it makes a difference?

  • On the 4, yes, it is the Controller which will receive the survey. Item 5 is the outworking research. You can even call ResultadoPesquisa.cshtml, if you want.

  • Better you separate Viewmodel of Model. Viewmodels are not bank mapped.

  • Do I have to reference then in the controllers? 'using Minhabase.ViewModel.Pesquisaviewmodel' ?

  • Surely you must.

Show 1 more comment

2

I do not advise using this form that I will show, the gypsy response expresses a better way of doing the search. I am posting only for knowledge purposes.

Like the @Gypsy explained, there is no need to use POST for a search, you lose the "reuse" or even disadvantage in Search Engine Optimization(SEO).

Now, to answer your question, you could use jQuery or javascript to get the selected item and redirect to the page you want. An example would be like this:

   $('#pesquisar').click(function () {
            var nivel = $('#NivelId').find(":selected").val();
            location.href = '@Url.Action("Pesquisa","Formacao")?id=' + nivel;
        });

This way you will get the selected value and send to your Action. Remember that you only want to use the filter when changing the value of DropDownList, just use the .change() in place of .click().

  • would just add this script inside my Search view?

  • @Victor Yes. would have to remove the @html.BeginForm()

Browser other questions tagged

You are not signed in. Login or sign up in order to post.