User Tag List

Página 1 de 5 12345 ÚltimoÚltimo
Resultados 1 al 15 de 73

Tema: Serializando con tag-helpers

  1. #1

    Fecha de ingreso
    Sep 2005
    Mensajes
    15,164
    Mencionado
    248 Post(s)
    Tagged
    1 Tema(s)
    Agradecer Thanks Given 
    665
    Agradecer Thanks Received 
    1,842
    Thanked in
    Agradecido 1,260 veces en [ARG:2 UNDEFINED] posts

    Serializando con tag-helpers

    Hola a todos:

    A ver si alguien me puede echar una mano, porque parece que esté escribiendo MacBeth en alemán sin usar traductor automático.

    Estoy creando una página con ASP.NET Core, en la que tengo que crear una tabla con datos que se pueden editar. La idea es que las celdas de la tabla, casi todas, son editables, y al final de la línea, hay un botón para enviar la información a mi Controller, que coge esos datos de la línea y los actualiza en la BBDD.
    Mi modelo de datos es algo parecido a esto:

    Código:
    class Empresa {
    List<Empleado> lista;
    }
    
    class Empleado {
    string Id;
    string nombre;
    string apellidos;
    int edad;
    bool activo;
    }
    Bueno, pues en mi vista, he podido crear la tabla. Simplificando las cosas quedaría algo así:

    Código:
    <div class="table-responsive">
                            <table class="table table-striped table-bordered table-hover" id="dataTable">
    
                                <thead>
                                    <tr>
                                        <th>
                                            <label>Nombre</label>
                                        </th>
                                        (...)
                                    </tr>
                                </thead>
    
                                <tbody>
                                    @if ((Model != null) && (Model.lista != null))
                                    {
                                        @for (int i = 0; i < Model.lista.Count(); i++)
                                        {
                                            <tr>
                                                <td style="display:none"><input readonly="readonly" asp-for="@Model.lista[i].Id"> </td>
                                                
                                                <td style="vertical-align: middle; text-align: center">@Model.lista[i].Id</td>
                                                
                                                <td style="vertical-align: middle; text-align: center">
                                                    <input class="form-control" asp-for="@Model.lista[i].nombre">
                                                </td>
                                                <td style="vertical-align: middle; text-align: center">
                                                    <input class="form-control" asp-for="@Model.lista[i].apellidos">
                                                </td>
                                                <td style="vertical-align: middle; text-align: center">
                                                    <input class="form-control" readonly="readonly" asp-for="@Model.lista[i].edad">
                                                </td>
                                                
                                                <td style="vertical-align: middle; text-align: center">
                                                    <input type="checkbox" class="form-control" asp-for="@Model.lista[i].activo">
                                                </td>
    
                                                <td style="vertical-align: middle; text-align: center">
                                                    <a class="btn btn-primary form-control w-25 p-1 submit" href="#" data-action="Update">@ViewBag.localize["ButtonUpdate"]</a>
                                                    
                                                </td>
                                                
    
                                            </tr>
                                        }
                                    }
                                </tbody>
                            </table>
                        </div>
    Y más adelante, defino el siguiente script en JS para el botón:

    Código:
    <!-- Script para botón de líneas de tabla -->
    <script type="text/javascript" src="https://code.jquery.com/jquery-1.7.1.min.js"></script>
    
    <script>
        $(document).ready(function () {
            $(".submit").on("click", function (event) {
                console.log("Prueba 1");
                event.preventDefault();
                var url = '@Url.Action("Update", "Employee")';
                var row = $(this).parents("tr").first();
                var data = row.find("input, select, textarea").serialize();
                window.location.href = url + '?' + data;
            });
        });
    </script>
    No sé si me estoy complicando mucho, pero como no puedo meter un formulario dentro de una tabla, y los intentos por enviar los datos de la línea usando Model.lista[\i] en el botón me han devuelto los valores sin editar, pues he leído que lo suyo es usar JS, y obtener los datos de los inputs directamente.

    Esto me funciona, y me genera la llamada con lo que necesito... pero tiene una pega. Cuando la llamada debería ser algo tipo:
    Código:
    http://miweb/Employee?Id='1'&nombre='Dolores'&apellidos='Fuertes DeBarriga'&edad=30&activo=true
    lo que obtengo es:
    Código:
    http://miweb/Employee?lista[i].Id='1'&lista[i].nombre='Dolores'&lista[i].apellidos='Fuertes DeBarriga'&lista[i].edad=30&lista[i].activo=true
    Esto se lo achaco a que asp-for me cambia el name del elemento por el mismo que el nombre de la variable. He leído que se puede forzar el nombre, y eso creo que lo arreglaría, pero es una mala práctica.
    La otra opción es arreglar el "serialize" del javascript, pero para mi JS es como hablar en catalán (puedo entender lo que se dice, pero ni papa de hablarlo), y no sé qué opciones habría para evitar la primera parte del nombre, de coger sólo lo que haya después del punto del nombre, o borrar "lista[\i]." (con un extra de caracteres raros que no sé reproducir) de toda la cadena.

    Como sé que aquí hay gente que pilota de diseño web mil veces más que yo, a ver si me podéis echar una manita, por favor. Gracias.
    PROYECTOS REALIZADOS: FrikiMusic, Motor Scroll Tileado v3.2, Venturer2X (GP2X/WIZ), Echo, Screen Break Time
    PROYECTOS EN MARCHA (algunos): Bennu GP2X: 95% (necesito ayuda) ¡Antes de Halloween!: 92% SpaceH2H: 8%

  2. #2

    Fecha de ingreso
    Nov 2005
    Ubicación
    Excartagenero
    Mensajes
    23,620
    Mencionado
    276 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    5,962
    Agradecer Thanks Received 
    5,808
    Thanked in
    Agradecido 3,795 veces en [ARG:2 UNDEFINED] posts
    Entradas de blog
    1
    JQuery, que ajco... este foro debería aplicar ciertos filtros a sus usuarios...

    -----Actualizado-----

    Asi comentando por arribita, yo creo que estas fallando en lo que le das al serialize. Yo iría haciendo paso por paso cada una de esas cosas que tienes encadenada, metiendolo cada paso en una variable para poder mostrarlo via console.log y asi entender donde esta la metida de pata.

  3. #3

    Fecha de ingreso
    Mar 2007
    Ubicación
    Barna
    Mensajes
    10,349
    Mencionado
    93 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    371
    Agradecer Thanks Received 
    1,791
    Thanked in
    Agradecido 947 veces en [ARG:2 UNDEFINED] posts
    sí, es lo que dice josepzin, serialize() hace exactmente lo que estás mostrando: meter todas las variables con su nombre en una larga línea.

    Yo lo que haría si por alguna razón me metiese en una máquina que me hace retroceder 10 años a cuando se usaba jquery es algo así:

    Código:
    <input class="form-control" asp-for="@Model.lista[i].nombre" id="nombre">
    <input class="form-control" asp-for="@Model.lista[i].apellidos" id="apellidos">
    
    ...
    
    var data = {
       nombre: $('#nombre').val(),
       apellidos: $('#apellidos').val(),
    }
    window.location.href = url + '?' + data.serialize();
    Fíjate:

    - No sé si puedes meter un formulario en una tabla, me extraña, quizá no pero no recuerdo. Estoy bastante seguro de que sí que puedes meter una tabla en un formulario y en el onclick() simplemente hacer un submit(), que es lo más limpio de todo con diferencia.
    - Si esas tablas las usas para maquetar... tío... 2023... flexbox (https://css-tricks.com/snippets/css/a-guide-to-flexbox/) y grid (https://www.w3schools.com/css/css_grid.asp) llevan muchos años entre nosotros... Úsalos y deja que tu página sea accesible desde móviles sin hacer nada más.
    - Con jquery, no hace falta que obtengas una referencia a la la tabla y luego al tr y luego la td y luego busques cosas ahí dentro. Ponle al control un identificador único y podrás referenciarlo directamente sin liarte: $("#nombre"). Que se encargue jQuery de buscar dónde está, que por algo se llama así: haz una query y ya encuentra qué quieres!
    Última edición por juanvvc; 13/04/2023 a las 21:49
    "Todo es absolutamente falso, salvo alguna cosa"

  4. El siguiente usuario agradece a juanvvc este mensaje:

    josepzin (13/04/2023)

  5. #4

    Fecha de ingreso
    Nov 2005
    Ubicación
    Excartagenero
    Mensajes
    23,620
    Mencionado
    276 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    5,962
    Agradecer Thanks Received 
    5,808
    Thanked in
    Agradecido 3,795 veces en [ARG:2 UNDEFINED] posts
    Entradas de blog
    1
    En realidad se puede poner un formulario que ocupe toda la web, basta con poner un FORM al principio y /FORM al final. Cuando se haga el SUBMIT se enviará todo lo que haya al medio esté donde esté, ya sea dentro de una tabla como dentro de divs o parrafos.

    Lo que quizas quiere decir nuestro amante de JQuery es que dentro de la estructura de una tabla no se puede intercalar un FORM, este tendría que estar "alrededor" de la tabla.

    Sobre las tablas, si, son una cosa retro pero cuando hay tablas de datos un TABLE es lo que se debe usar :P

    -----Actualizado-----

    Hace unos años yo me propuse dejar de usar JQuery y al final con Javascritp vainilla se puede hacer casi todo mas o menos igual de simple pero en todo caso sin depender de una librería kilométrica, que teniendo en cuenta las webs actuales que cargan todo cristo de forma mastodónica como que da igual... :P pero queda bien decir que no se usa JQuery y humillar al que lo sigue usando muahahah

  6. #5

    Fecha de ingreso
    Mar 2007
    Ubicación
    Barna
    Mensajes
    10,349
    Mencionado
    93 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    371
    Agradecer Thanks Received 
    1,791
    Thanked in
    Agradecido 947 veces en [ARG:2 UNDEFINED] posts
    ah, vale, sí, eso sí, no se pueden intermezclar tablas y formularios porque ambos son contenedores que tienen que cerrarse y abrirse en orden. Como los paréntesis de una expresión matemática. O mete todo el formulario dentro de una celda, o toda la tabla dentro del formulario. Pero no se puede hacer html-fusión

    -----Actualizado-----

    Por cierto, sí, reconozco que me he hecho el interesante. jquery puede usarse perfectamente si la web es sencilla y sin complicaciones.

    Pero enseguida querrás hacer algo más, y jquery incentiva a una programación muy "espagueti" y difícil de mantener.
    "Todo es absolutamente falso, salvo alguna cosa"

  7. #6

    Fecha de ingreso
    Nov 2005
    Ubicación
    Excartagenero
    Mensajes
    23,620
    Mencionado
    276 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    5,962
    Agradecer Thanks Received 
    5,808
    Thanked in
    Agradecido 3,795 veces en [ARG:2 UNDEFINED] posts
    Entradas de blog
    1
    Yo dejé de usar JQuery cuando vi las comparativas de rendimiento con vanilla, que es HENORME, aunque como dije antes en el contexto actual de webs sobre-mega-ultra-hiper-re-cargadas que use JQuery es un grano mas de arena en un océano de tsunamis.

    Luego aprendiendo a reemplazar de a poco los selectores y todo lo que podía con JS estándar. Al final de Jquery me quedaba poco y nada, además me terminé acostumbrando y dejé de usarlo.

  8. #7

    Fecha de ingreso
    Sep 2005
    Mensajes
    15,164
    Mencionado
    248 Post(s)
    Tagged
    1 Tema(s)
    Agradecer Thanks Given 
    665
    Agradecer Thanks Received 
    1,842
    Thanked in
    Agradecido 1,260 veces en [ARG:2 UNDEFINED] posts
    A ver, no puedo poner el form a toda la página porque ya hay otro form. Esto que os muestro es de una vista parcial, ya hay otra en la que está el formulario para añadir un nuevo elemento.

    Tampoco puedo meter la tabla en un form porque cada línea tiene un botón update, y sólo quiero los datos de esa línea, no tendría forma de saber qué botón es el que ha generado la llamada.
    Y es que no habéis tenido en cuenta que las líneas se generan de forma dinámica, no hay una forma (que yo sepa) de poner un identificador único a cada input, que pueda usar directamente en JS.

    No parece mala idea la de crear una estructura anónima, y ponerle los nombres que yo quiera. Incluso, si por mi fuera, quitaría el serialize del "data", y lo recorrería, asignando a cada nombre el valor del último split('.')... pero es que, encima, el debuger de VS no me funciona, y no puedo saber qué tipo es data, ni puedo hacer una ejecución paso a paso para ver lo que estoy haciendo... por no decir que estoy programando en JS sin haber dado jamás un curso de JS, o como se llame, y "eso" es el resultado de fusionar tres ideas que he encontrado por internet ^^U

    Si hay otra forma más sencilla, por favor, soy todo oídos. No quería asustar a nadie, pero la vista es una Razor Page, no HTML... pero es que si digo eso, con el odio que hay a .NET, lo mismo ni respondéis
    PROYECTOS REALIZADOS: FrikiMusic, Motor Scroll Tileado v3.2, Venturer2X (GP2X/WIZ), Echo, Screen Break Time
    PROYECTOS EN MARCHA (algunos): Bennu GP2X: 95% (necesito ayuda) ¡Antes de Halloween!: 92% SpaceH2H: 8%

  9. #8

    Fecha de ingreso
    Mar 2007
    Ubicación
    Barna
    Mensajes
    10,349
    Mencionado
    93 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    371
    Agradecer Thanks Received 
    1,791
    Thanked in
    Agradecido 947 veces en [ARG:2 UNDEFINED] posts
    No tengo ni idea de .net o de qué es una razor page, así que no puedo odiarla

    Una idea: si tus líneas son así:

    Código:
    <td id="i">...<input class="nombre" ....>
    (es decir, que identifiques el tr simplemente con el contador y añades una clase "nombre" o similar en los input

    Entonces podrás acceder a los controles así:

    Código:
    var nombre = $("#i > .nombre").val()
    ">" significa "descendiente de..." incluso si hay varios niveles de descendencia

    https://api.jquery.com/category/selectors/

    -----Actualizado-----

    Así podría quedaría tu código, creo, pero tendrás que verificarlo:

    Código:
    <input class="form-control nombre" asp-for="@Model.lista[i].nombre">
    <input class="form-control apellidos" asp-for="@Model.lista[i].nombre">
    
    ...
    
    // lo de antes igual, incluso para obtener la referencia a la row si no quieres usar identificadores por alguna razón
    var data = {
       nombre: row.find(".nombre").val(),
       apellidos: row.find(".apellidos").val(),
    }
    window.location.href = url + '?' + data.serialize();
    Recuerda que en JavasScript un elemento puede tener cualquier número de clases. Aquí hemos asignado varias clases a los input
    "Todo es absolutamente falso, salvo alguna cosa"

  10. #9

    Fecha de ingreso
    Sep 2005
    Mensajes
    15,164
    Mencionado
    248 Post(s)
    Tagged
    1 Tema(s)
    Agradecer Thanks Given 
    665
    Agradecer Thanks Received 
    1,842
    Thanked in
    Agradecido 1,260 veces en [ARG:2 UNDEFINED] posts
    Creía que eso ya quedaba cubierto con las líneas:
    Código:
    var row = $(this).parents("tr").first();
    var data = row.find("input, select, textarea").serialize();
    Si quito el "serialize()", debería tener una lista con todos los elementos de la línea... si es que eso existe en JS.
    El problema es, para cada elemento, cambiar su nombre, quedarme sólo con el final (lo que va detrás del último punto), y después serializarlo.
    O bien, crear una clase anónima, con el nombre modificado y el valor de cada elemento.
    Pero no sé hacer ni una cosa ni otra.
    PROYECTOS REALIZADOS: FrikiMusic, Motor Scroll Tileado v3.2, Venturer2X (GP2X/WIZ), Echo, Screen Break Time
    PROYECTOS EN MARCHA (algunos): Bennu GP2X: 95% (necesito ayuda) ¡Antes de Halloween!: 92% SpaceH2H: 8%

  11. #10

    Fecha de ingreso
    Mar 2007
    Ubicación
    Barna
    Mensajes
    10,349
    Mencionado
    93 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    371
    Agradecer Thanks Received 
    1,791
    Thanked in
    Agradecido 947 veces en [ARG:2 UNDEFINED] posts
    pero no separes tú con el split(), va a ser una pesadilla y además con enorme probabilidad una fuente de vulnerabilidades

    Saca los datos uno a uno que ya sabes cómo son en vez de todos a la vez.
    "Todo es absolutamente falso, salvo alguna cosa"

  12. #11

    Fecha de ingreso
    Sep 2005
    Mensajes
    15,164
    Mencionado
    248 Post(s)
    Tagged
    1 Tema(s)
    Agradecer Thanks Given 
    665
    Agradecer Thanks Received 
    1,842
    Thanked in
    Agradecido 1,260 veces en [ARG:2 UNDEFINED] posts
    No entiendo.
    ¿Separar qué con split? Mi idea era un bucle for a data, y en todo caso, hace split al name y quedarme con el último elemento, o algo así.
    Lo que no sé es cómo hacerlo :P
    PROYECTOS REALIZADOS: FrikiMusic, Motor Scroll Tileado v3.2, Venturer2X (GP2X/WIZ), Echo, Screen Break Time
    PROYECTOS EN MARCHA (algunos): Bennu GP2X: 95% (necesito ayuda) ¡Antes de Halloween!: 92% SpaceH2H: 8%

  13. #12

    Fecha de ingreso
    Mar 2007
    Ubicación
    Barna
    Mensajes
    10,349
    Mencionado
    93 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    371
    Agradecer Thanks Received 
    1,791
    Thanked in
    Agradecido 947 veces en [ARG:2 UNDEFINED] posts
    split() es una función para separar cadenas por tokens. En tu caso había imaginado que harías un split() con & y después otro split con = y así tendrías nombre y valor separados. Ahora veo que reinventar eso pero a un nivel aún más bajo, con un bucle for. Aprovecha la potencia de las librerías, especialmente si ya las tienes importadas como jquery!

    Te puse un ejemplo en mi último comentario, pero creo que lo he editado después de que comentases y puede que se te haya pasado. Esto:

    Código:
    <input class="form-control nombre" asp-for="@Model.lista[i].nombre">
    <input class="form-control apellidos" asp-for="@Model.lista[i].nombre">
    
    ...
    
    // lo de antes igual, incluso para obtener la referencia a la row si no quieres usar identificadores por alguna razón
    
    // aquí lo realmente nuevo: saca los datos uno a uno, no todos a la vez:
    var data = {
       nombre: row.find(".nombre").val(),
       apellidos: row.find(".apellidos").val(),
       apellidos: row.find(".otracosa").val(),
    }
    window.location.href = url + '?' + data.serialize();
    "Todo es absolutamente falso, salvo alguna cosa"

  14. #13

    Fecha de ingreso
    Sep 2005
    Mensajes
    15,164
    Mencionado
    248 Post(s)
    Tagged
    1 Tema(s)
    Agradecer Thanks Given 
    665
    Agradecer Thanks Received 
    1,842
    Thanked in
    Agradecido 1,260 veces en [ARG:2 UNDEFINED] posts
    No sé si puedo darle identificadores a los campos. Ten en cuenta que las líneas están dentro de un bucle, y si al primero le pongo id="nombre", cada línea va a tener un elemento con ese id, y por lo que tengo entendido, los identificadores deben ser únicos para toda la página.
    Podría hacer algo del estilo
    Código:
    id = "nombre_" + @i
    Pero luego en la parte de Java, a ver cómo busco el elemento, porque puede llamarse "nombre_1", "nombre_2, "nombre_7"... ¿Podría pasarle "i" como parámetro al JS? ¿Y cómo lo uso para el identificador?

    Por eso, me parece más fácil buscarlo como dices, por un nombre de la class (ya me buscaré la forma de poner un identificador que no se confunda con otro existente).
    Y, bueno, si hay que ir elemento por elemento, pues nada.
    El handicap que tengo es que en html y JS estoy peor que Selecter en su primer mensaje del curso que hizo ^^U

    Voy a probarlo y luego os cuento. Antes, debo atender otra tarea más urgente.
    PROYECTOS REALIZADOS: FrikiMusic, Motor Scroll Tileado v3.2, Venturer2X (GP2X/WIZ), Echo, Screen Break Time
    PROYECTOS EN MARCHA (algunos): Bennu GP2X: 95% (necesito ayuda) ¡Antes de Halloween!: 92% SpaceH2H: 8%

  15. #14

    Fecha de ingreso
    Mar 2007
    Ubicación
    Barna
    Mensajes
    10,349
    Mencionado
    93 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    371
    Agradecer Thanks Received 
    1,791
    Thanked in
    Agradecido 947 veces en [ARG:2 UNDEFINED] posts
    Puedes añadir información adicional a un campo data de html, que están precisamente para eso. Ahí irían los identificadores. También puedes modificar la función a la que llama ante el evento onclick y ahí pasar los identificadores de tus controles.

    Aún así, fíjate que te planteo algo más sencillo y con cambios mínimos en tu código. La idea de usar clases no es para darle un identificador diferente a cada campo nombre, al revés: todos los input nombre tendrán la clase nombre. Tú lo que puedes hacer es buscar el input con clase nombre dentro de una row, que solo debería ser uno. La row la sacas exactamente como ya has hecho, con padre de padre

    Vamos, que te planteo que uses ".nombre", ".apellidos" por separado como selector del css en vez de tu actual selector conjunto "input,textarea". Todo el resto, igual que ha hecho hasta ahora

    Mira el ejemplo que te puse

  16. #15

    Fecha de ingreso
    Sep 2005
    Mensajes
    15,164
    Mencionado
    248 Post(s)
    Tagged
    1 Tema(s)
    Agradecer Thanks Given 
    665
    Agradecer Thanks Received 
    1,842
    Thanked in
    Agradecido 1,260 veces en [ARG:2 UNDEFINED] posts
    Sé que es mucho pedir, pero me gustaría que, cuando hables de una cosa, pongas un ejemplo... más que nada porque... lo dicho, ando tan pez que no sé dónde buscar siquiera información ^^U
    ¿Cómo funciona lo del "campo data"? He visto un html tag llamado data-, no sé si es eso.

    Pero sí, lo que voy a usar es lo del nombre en el class... es que habías dicho que era una forma arcaica de hacerlo, y claro ^^U Pero me dices de usar Flexbox y:
    1- No tengo ni idea de lo que es ni cómo se usa.
    2- Las vistas las hago en Razor, que si ya me cuesta pelearme entre C#, HTML, Bootstrap y lo poquito que uso de Java, tener que meterle eso que ni siquiera sé si es compatible con la ensalada que ya tengo montada, es rizar el rizo para los dos telediarios que llevo peleándome con esto.
    Ni siquiera estoy seguro de estar usando las herramientas que nos han enseñado correctamente ^^U
    PROYECTOS REALIZADOS: FrikiMusic, Motor Scroll Tileado v3.2, Venturer2X (GP2X/WIZ), Echo, Screen Break Time
    PROYECTOS EN MARCHA (algunos): Bennu GP2X: 95% (necesito ayuda) ¡Antes de Halloween!: 92% SpaceH2H: 8%

Página 1 de 5 12345 ÚltimoÚltimo

Permisos de publicación

  • No puedes crear nuevos temas
  • No puedes responder temas
  • No puedes subir archivos adjuntos
  • No puedes editar tus mensajes
  •