0

tengo una ventana emergente en donde tengo una serie de artículos; a su vez, tengo un select (si el artículo está asociado a más de un almacén) para seleccionar el almacén del que se requiera pedir y una función para que al seleccionar te muestre la cantidad disponible en ese artículo.

Tabla

El problema es que si yo me coloco en otra página de la tabla que no sea la primera, el select no me realiza ninguna acción, si yo selecciono para que me muestre todos los artículos en una página lo hace sin problemas, pero al estar en otra ya no funciona, ¿Qué estoy haciendo mal?

Acá está mi tabla:

<table class="table table-striped mt-0.5 table-bordered shadow-lg mt-4" id="articulo">
    <thead class="bg-primary text-white">
        <tr>
            <th scope="col" width="60px">Código</th>
            <th scope="col">Imagen</th>
            <th scope="col">Nombre</th>
            <th scope="col">Categoría</th>
            <th scope="col">Almacén</th>
            <th scope="col">Disponible</th>
            <th scope="col">Cantidad</th>
            <th scope="col">Acciones</th>
        </tr>
    </thead>
    <tbody>
        @foreach ($articulos as $articulo)
            <tr>
                <td>{{ $articulo->codigo }}</td>
                @if (isset($articulo->imagen))
                    <td class="text-center">
                        <img src="/imagen/{{ $articulo->imagen }}" style="height: 50px; width: 50px; border-radius: 20%;">
                    </td>
                @else
                    <td class="text-center">
                        <img src="/imagen/caja.png" alt="" width="70" height="70">
                    </td>
                @endif
                <td>{{ Str::ucfirst($articulo->nombre) }}</td>
                <td>{{ Str::ucfirst($articulo->categoria->nombre) }}</td>
                @if ($articulo->detallearticulos()->count() > 1)
                    <td>
                        <select class="form-control js-almacen-id" name="almacen_id" id="almacen_id" lang="es" index={{ $loop->index }} data-articulo-id={{ $articulo->id }}>
                            <option value="" data-icon="fas fa-box" disabled selected>Buscar almacén</option>
                            @foreach ($detallearticulos as $detallearticulo)
                                @if ($detallearticulo->articulo_id == $articulo->id)
                                    <option value="{{ $detallearticulo->almacen_id }}">{{ $detallearticulo->almacen_id }} - {{ $detallearticulo->almacen->nom_alm }}</option>
                                @endif
                            @endforeach
                        </select>
                    </td>
                    <td style="width: 50px;">
                        <input type="text" name="stock" id="stock" class="form-control js-stock" disabled>
                    </td>
                @elseif ($articulo->detallearticulos()->count() == 1)
                    <td>
                        @foreach ($detallearticulos as $detallearticulo)
                            @if ($detallearticulo->articulo_id == $articulo->id)
                                <input type="text" class="form-control js-almacen-nombre" name="almacen_id" id="almacen_id" readonly value="{{$detallearticulo->almacen->nom_alm}}">
                                <input type="hidden" class="form-control js-almacen-id" name="almacen_id" id="almacen_id" readonly value="{{$detallearticulo->almacen_id}}">
                            @endif
                        @endforeach
                    </td>
                    <td>
                        @foreach ($detallearticulos as $detallearticulo)
                            @if ($detallearticulo->articulo_id == $articulo->id)
                               <input type="text" value="{{ $detallearticulo->disponible }}" name="stock" id="stock" class="form-control js-stock" disabled>
                            @endif
                        @endforeach
                    </td>
                @endif
                <td>
                    <input type="number" class="form-control js-cantidad" min="0" max="1000" name="cantidad" step="1" oninput="validity.valid || (value = '')">
                    @if ($errors->has('cantidad'))
                        <div class="alert alert-danger">
                            <span class="error text-danger">{{ $errors->first('cantidad') }}</span>
                        </div>
                    @endif
                </td>
                <td class="text-right">
                    <input type="hidden" class="form-control js-articulo-id" name="articulo_id" value="{{ $articulo->id }}">
                    <input type="hidden" class="form-control js-articulo-nombre" name="articulo_nombre" value="{{ $articulo->nombre }}">
                    <div class="form-group">
                        <button type="button" class="btn btn-info float-right mt-1 js-agregar">
                            <i class="fas fa-check"></i>Agregar
                        </button>
                    </div>
                </td>
            </tr>
        @endforeach
    </tbody>
</table>

y mi función de buscar:

$('.table').on('change', '.js-almacen-id', mostrarValores);

function mostrarValores() {
    datosProducto = document.getElementById('almacen_id').value.split('_');
    $('.js-stock').fila.val(datosProducto[1]);
};

var almacen_id = $('.js-almacen-id');

almacen_id.change(function(event) {
    const index = $(event.target).attr('index');
    const articulo_id = $(event.target).attr('data-articulo-id');

    $.ajax({
        url: "{{ route('get_products_by_id') }}",
        method: 'GET',
        data: {
            almacen_id: event.target.value,
            //Añades tu el id de tu articulo a tu solicitud HTTP
            articulo_id: articulo_id
        },
        success: function(data) {
            $('.js-stock').eq(index).val(data.disponible);
            $('.js-almacen-id').eq(index).val(data.almacen_id);
            $('.js-articulo-id').eq(index).val(data.articulo_id);
        }
    });
});

El área del almacén te da el almacen_id que es lo que busca en la base de datos la cantidad que hay disponible del artículo, y luego te lo escribe en la parte de 'disponible'

Creo que el problema está en que yo tengo un loop->index en la tabla y el $('.js-almacen-id').eq(index).val(data.almacen_id); me está escribiendo el stock en esa 'posición' en la tabla, ¿cómo puedo hacer que el index lo tome como la fila en la que está puesto?

7
  • 2
    Este es otro caso de los id deben ser únicos en el DOM...
    – padaleiana
    Commented el 1 sept. 2022 a las 19:15
  • pero estoy usando clases para hacer eso Commented el 1 sept. 2022 a las 19:31
  • 1
    Mirá de nuevo tu código, tenés esto: <select class="form-control js-almacen-id" name="almacen_id" id="almacen_id"(...)
    – padaleiana
    Commented el 1 sept. 2022 a las 19:36
  • claro, ya borré eso, ¿pero cómo entonces puedo hacer para que no importe la página en la que estoy? no estoy tomando ese dato como referencia Commented el 1 sept. 2022 a las 20:02
  • El cambio de página en el datatable provoca una recarga completa o sólo hace una rotación de las filas visibles?
    – ffflabs
    Commented el 3 sept. 2022 a las 6:22

2 respuestas 2

1

El problema probablemente se deba a que tenés hecho el bind directamente sobre $('.js-almacen-id') pero esos elementos son dinámicos, no estáticos. Es decir, al cambiar de página se borran los actuales y aparecen nuevos. Esos nuevos no tienen el bind hecho y por eso no funcionan.

Tendrías que hacer algo parecido a lo que tenés hecho al final de tu código con el keyup. jQuery .on():

$('.table').on('change', '.js-almacen-id', mostrarValores);

Elijo .table porque asumo que ese elemento no se vuelve a dibujar al cambiar de página, pero si así lo fuera, tal vez tengas que usar document o algún elemento padre.

5
  • ¿Cómo implemento eso en el código, lo reemplazo en algún lado o solo lo agrego? Commented el 5 sept. 2022 a las 12:32
  • creo que el problema está en $("#stock").val(datosProducto[1]) porque tipo, me escribe el stock en el row en el que se encuentra el producto Commented el 5 sept. 2022 a las 14:06
  • 1
    Tenés que reemplazar la primera línea del código que tenés publicado acá. Pero si, seguro tenés otros problemas porque estás usando IDs para todo. Dejame revisar el código y veo que más deberías modificar. Vendría bien que expliques bien que hace cada input y que necesitás que hagan.
    – azeós
    Commented el 5 sept. 2022 a las 15:04
  • Ya había reemplazado lo que usted comentó; me sigue dando el problema de que si estoy en la primera página todo bien, pero si la cambio o uso el buscador no me trae el disponible del artículo en el almacén Commented el 5 sept. 2022 a las 15:11
  • el problema está en que yo tengo un loop->index en la tabla y el $('.js-almacen-id').eq(index).val(data.almacen_id); me está escribiendo el stock en esa 'posición' en la tabla, ¿cómo puedo hacer que el index lo tome como la fila en la que está puesto? Commented el 6 sept. 2022 a las 18:31
0

el problema era que estaba utilizando un $loop->index dentro de mi tabla, por lo que me estaba tomando ese número como la fila en la que tenía que escribir el stock disponible, y como DataTables tiene la paginación, obviamente la fila no estaba ahí; lo solucioné con .closest("tr)"

almacen_id.change(function(event) {

        fila = $(this).closest("tr");

    $.ajax({
        url: "{{ route('get_products_by_id') }}",
        method: 'GET',
        data: {
        almacen_id: event.target.value,
        articulo_id: articulo_id
        },
        success: function(data) {

        fila.find(".js-stock").val(data.disponible);
        fila.find(".js-almacen-id").val(data.almacen_id);
        fila.find(".js-articulo-id").val(data.articulo_id);
        }
    });

¿No es la respuesta que buscas? Examina otras preguntas con la etiqueta o formula tu propia pregunta.