sábado, 28 de diciembre de 2013

[ASP.NET MVC] Carga DropDownList dependientes - Usando un único action

 

Introducción


Este articulo propone una versión diferente a la planteada en el anterior

[ASP.NET MVC] Carga DropDownList dependientes

En este caso definiremos un único action para recibir la selección que realice el usuario.

La funcionalidad de la pantalla se conserva idéntico al articulo anterior, al igual que el modelo de datos.

 

Modelo de Vista


Para el modelo se define una clase que recibirá las propiedades con la selección del usuario, además de propiedades que permitirán cargar los controles de listas en la view

image

 

Definición de la View


La vista esta formada por un solo Form, el cual realiza el post al action Index() el cual se encuantra marcado con el atributo [HttpPost]

SNAGHTML19f9df10

 

Tanto si se selecciona un ítem combo, o se presiona el botón del submit (el cual selecciona los empleados) todas las acciones invocan al único action

A diferencia del articulo anterior ya no se requieren de hidden para conservar la selección de la acción anterior.

 

Definición del action


El action implementar bastante mas lógica que la usada en el articulo anterior, ya que deberá determinar que propiedades vienen con datos y cargar las listas en consecuencia.

 

[HttpPost]
public ActionResult Index(EmployeeModel model)
{
    //se carga la lista de regiones
    var regionList = regionRepository.GetAll();

    List<Territory> territoryList = null;
    List<Employee> employeeList = null;

    //si hay una region seleccionada 
    if (model.RegionId != null)
    {
        //se carga la lista de territorios
        territoryList = territoryRepository.Filter(x => x.RegionID == model.RegionId);

        //si hay un territorio seleccionado
        if (!string.IsNullOrEmpty(model.TerritoryId))
        {
            //se recupera el territorio, para poder obtener los empleados asociados
            employeeList = territoryRepository.GetEmployees(model.TerritoryId);
        }

    }


    model.RegionList = new SelectList(regionList, "RegionID", "Description");

    if (territoryList != null && territoryList.Count > 0)
    {
        model.TerritoryList = new SelectList(territoryList, "TerritoryID", "Description");
    }

    if (employeeList != null && employeeList.Count > 0)
    {
        model.EmployeeList = new SelectList(employeeList, "EmployeeID", "FullName");
    }


    return View("Index", model);

}

 

Si se selecciona una región se recibirá el valor en el parámetro del modelo

SNAGHTML1a04b6aa

 

Si luego se selecciona un territorio

SNAGHTML1a08bf80

 

Y al marcar empleados sobre el listbox y presionar el botón de submit se carga la lista

SNAGHTML1a0b84e0

 

En cada invocación al acción será necesario volver a cargar las listas del model utilizadas para definir los ítems de los controles la la view, ya que estas no participan en el proceso de binding donde son asignados los valores que se envían en al post a las propiedades del parámetro del action.

 

Model Binding


Para entender como se produce la asignación de la selección de los controles con las propiedades del modelo es necesario evaluar el html

Si las propiedades “name” de los controles que se renderizan en el html coinciden con los nombres de las propiedades de la clase definida como modelo la asignación del valor es automáticamente.

 

SNAGHTML1a315f77

si algún control no llegara a tener esta coincidencia se puede redefinir el name utilizando

image

 

Código


 

[C#]
 

16 comentarios:

  1. Hola Leandro, soy nuevo en esto del asp y estaba haciendo un formulario con 3 dropdownlist dependientes, la primera vez que entro y cambio algo de cualquier lista se actualiza el resto con los updatepanel pero si lo hago una segunda vez ya no funciona.
    Sigo el codigo y veo como la lista se carga bien pero no se ve reflejado los cambios.
    ¿Me podrias ayudar o asesorar donde buscar?
    Gracias

    ResponderEliminar
  2. hola Emilio

    la verdad sin poder ver el codigo no sabria decirte que podra estar pasando

    quizas no se este actualizando el updatePanel por eso aunque asignes los datos al dropdownlist no se vean reflejados en el cliente

    podrias ver de quitar los updatepanel y que actualice la pagina para ver si de esa forma funciona, con eso sabria que el problema no es de tu codigo sino que esta en la definicion de los updatepanel

    debas plantear el tema en el foro

    foro asp.net

    saludos

    ResponderEliminar
  3. hola Leandro Master, quisiera preguntarte si en tus ejemplos no tienes un Login en Asp.net c# con conexion a base de datos , gracias de antemano.

    ResponderEliminar
  4. Leandro, queria pedirte un favor, no podrias publicar un tema sobre

    Inyeccion de dependias y uno de Control de inversion IoC

    es que estado buscando informacion pero no encuentro nada concreto

    ResponderEliminar
  5. hola Noe

    pero esto tiene que ver con mvc, o solo es asp.net
    porque sino quizas algo como esto

    Login – Usando Password con Hash

    podria ser de utilidad
    saludos

    ResponderEliminar
  6. hola Gustavo

    la verdad tenia ganas de publicar algo del tema, pero estoy complicado con los proyectos del laburo

    pero quizas algo como esto
    Setup Ninject for ASP.NET MVC
    Using Ninject with ASP.NET MVC 3 dependency injection
    ayude un poco

    como veras alli se implementa la injection usando ninject

    saludos

    ResponderEliminar
  7. Hola nesesito ayuda sobre la creación de un mapa, me pueden contactar Aqui
    yovagoodboy@gmail.com

    ResponderEliminar
  8. hola Yovany

    podrias plantear el problema aqui mismo o sino en el foro donde brindo ayuda

    Foro asp.net mvc

    saludos

    ResponderEliminar
  9. Hola Leandro como estas? tenes alguna articulo de razor?

    vengo haciendo ejemplos y tengo un error y no entiendo pq tampoco entiendo el código de la demo q estoy haciendo asi q difícil resolverlo.

    esto te suena? graciastotales

    cannot be requested directly because it calls the \"RenderBody\" method."

    ResponderEliminar
  10. hola Ariel

    este articulo

    ASP.NET MVC 3: Layouts and Sections with Razor

    muy completo sobre el tema

    alli veo que llamas a un RenderBody() pero recuerda que esto implicas que tienes una view y un layout pero es la view la que debes devolver como respuesta del action

    saludos

    ResponderEliminar
  11. Hola Leandro como estas? tenes algo de CustomBinder?

    tengo el problema q al obtener el valor de un chek me devuelve true;false... y no el valor del check..

    gracias

    ResponderEliminar
    Respuestas
    1. hola
      es que el check en definitiva su valor es true\false porque ese es su valor solo que deberia estar atado a una key con el name de ese checkbox

      si inspeccionas el Response que llega al action deberias poder ver esto que comento

      si en los parametros del action defines uno con el "name" que toma el check en html entonces se deberia asignar alli el true\false que tome el control

      saludos

      Eliminar
  12. Hola Leandro y resto de los participantes ..tengo un problema quiero llamar a un get jason con un action link a trabes de una funcion js pero el action link por si solo quier ir a una accion determinada . una vez q invoco c ajax yo quiero hacer cosas c la el jason.

    @Html.ActionLink("text","PEPE", null, new { id = 1, @class = "LinkRubroClass" })

    $('.LinkRubroClass').click(
    function ()
    {
    alert("LinkRubroClass click");

    var vl_Url = '@Url.Action("GetAsJason", "Producto", null, Request.Url.Scheme, null)';


    $.ajax({
    type: "GET",
    url: vl_Url,
    data: { p_Id : 2 },
    datatype: "json",
    traditional: true,
    success: successGet,
    error: errorGet
    });

    function successGet(jsonRes)
    {
    alert(vl_Url);
    }

    function errorGet() {
    alert('errorGet');
    }

    ejecuta al funciones pero quiere ir a Productos/PEPE
    ya llame c ajax NO QUIERO Q LLAME A NADA MAS
    COMO SE RESUELVE?
    GRACIAS

    ResponderEliminar
  13. de pronto, mi solucion sea la que buscas en la parte del controller sea la que se necesite para tu modelo.
    tengo el siguiente problema, lo que pasa es que si le doy a departamento y despues a ciudad, la primera vez me sale bien pero al ir a grabar, no me permite ya que me dice q no podria guardar un valor de cero (what ever), estoy juicioso tomando las lecciones pero no he podido solucionar esta parte.
    @section Scripts {
    @Scr ipts.Render("~/bundles/jqueryval")
    $(document).ready(function () { $("#DepartamentID").change(function () { $("#CityID").empty(); $("#CityID").append('[Select a City]'); $.ajax({ type: 'PO ST', url: '@Url.Action("GetC ities")', data Type: 'json', data: { departmentId: $("#DepartamentID").val() }, s uccess: function (data) { $.each(data, function (i, data) { $("#CityID").append('' + data.Name + ''); }); }, error: function (ex) { alert('Failed to retrieve Cities.' + ex); } });
    ret urn false; })
    });
    }

    estoy pensando que es en el Name (data.Name) que no me la reconoce la p'agina... pues asi es como la llame (yo por defecto sempre dejo la inicial con may'uscula, y ID es mayuscula) pero no se que abre hecho mal....

    Ariel, pilas con lo siguiente... de promto te hace falta
    en el controlador de UserController.. //DropDownList -> cascate //Cundinamarca -> (los Municipios de este departamento, nada mas)
    public JsonResult GetCities(int departmentId)
    {
    db.Configuration.ProxyCreationEnabled = false;
    var cities = db.Cities.Where(c => c.DepartamentID == departmentId);
    return Json(cities);
    }

    y despues em la vista...
    [Required(ErrorMessage = "The field {0} is required")]
    [MaxLength(50, ErrorMessage = "The field {0} must be maximum {1} Character length")] [Display(Name = "Name")] //Cambio para pruebas
    [Index("City_Name_Index", 2, IsUnique = true)]
    public string Name { get; set;
    }
    y me sigue saliendo el error:::

    The value 'undefined' is not valid for City.

    y si visualizo yo tengo tanto departamentos (5) como ciudades (15).... y existe relacion entre ellos, yo los tengo en Base de datos y estoy trabajando con Visual Studio 2015, sql server 2014, entity framework, se que esta parte es irrelevante pero para constatar que tengo todo lo correcto.

    ResponderEliminar
    Respuestas
    1. hola Oscar

      No entendi del todo el planteo, estas consultando por un problema o le estas respondiendo a Ariel ?

      saludos

      Eliminar
  14. Podrías Volver a subir el ejemplo, no esta disponible este ni el anterior en OneDrive.

    ResponderEliminar