Dynamically create 2 self-excluding check boxes for each row of a table

0

I have two columns with checkboxes that are created when linking the records of an SQL table, as id of the checkboxs I assign them the id of the record to identify them in a more individual way, what I am doing is validating that only a checkbox of the two columns this activated (or "checked") for each row, I already have the operation so that only one of the checkboxes is activated, but how can I do it so that it works for each row if the checkboxes are dynamic?

JS

    $(document).ready(function () {

        $('.chkAutoriza').change(function () {
            if ($(this).prop('checked')) {
                $('.chkRechaza').prop('checked', false);
            }
        });

        $('.chkRechaza').change(function () {
            if ($(this).prop('checked')) {
                $('.chkAutoriza').prop('checked', false);
            }
        });
    });
<div class="jumbotron" style="font-size:small">
    <table class="table responsive shopex-table table-hover no-margin">
        <thead>
            <tr>
                <th>Id Pago</th>
                <th style="display:none">Id Cliente</th>
                <th>Nombre cliente</th>
                <th>Monto</th>
                <th>Monto en Dólares</th>
                <th>% comisión cliente</th>
                <th>% comisión a pagar</th>
                <th>Autorización</th>
                <th>Rechazo</th>
                <th>Comentario Rechazo</th>
                <th>Fecha</th>

            </tr>
        </thead>
        <tbody>

            @foreach (var item in noAutorizados)
            {
                double montoDolares = Convert.ToDouble(item.Pagos.Monto) * 13.25;
                decimal comisionPagar = Convert.ToInt32(item.Cliente.Comision) * item.Pagos.Monto;

                <tr>
                    <td class="idPago">
                        @item.Pagos.IdPago
                    </td>
                    <td class="vcenter" style="display:none">
                        @item.Pagos.IdCliente
                    </td>
                    <td class="vcenter">
                        @item.Cliente.Nombre
                    </td>
                    <td class="vcenter">
                        @string.Format("{0:n}", item.Pagos.Monto)
                    </td>
                    <td class="vcenter">
                        @string.Format("{0:n}", montoDolares)
                    </td>
                    <td class="vcenter">
                        @item.Cliente.Comision
                    </td>
                    <td class="vcenter">
                        @string.Format("{0:n}", comisionPagar)
                    </td>
                    <td style="text-align:center">
                        @Html.CheckBox("chkAutoriza", false, htmlAttributes: new { @class = "chkAutoriza", id = "chkAutoriza" + item.Pagos.IdPago })
                    </td>
                    <td style="text-align:center">
                        @Html.CheckBox("chkRechaza", false, htmlAttributes: new { @class = "chkRechaza", id = "chkRechaza" + item.Pagos.IdPago })
                    </td>
                    <td class="vcenter">
                        @Html.TextBox("StudentName", null, new { @class = "form-control txtComentario", id = "txtComentario" + item.Pagos.IdPago })
                    </td>
                    <td id="[email protected]">
                        @item.Pagos.Fecha.ToString("dd/MM/yyyy")
                    </td>

                    <td class="vcenter text-right"></td>
                </tr>
            }
        </tbody>
    </table>

    <button class="btn btn-success" id="btnGuardar">Autorizar</button>

</div>
    
asked by Ivxn 22.07.2018 в 20:23
source

3 answers

2

The problem is in this code:

$(document).ready(function () {

    $('.chkAutoriza').change(function () {
        if ($(this).prop('checked')) {
            $('.chkRechaza').prop('checked', false);
        }
    });

    $('.chkRechaza').change(function () {
        if ($(this).prop('checked')) {
            $('.chkAutoriza').prop('checked', false);
        }
    });
});

As it is set, what is done is that every time chkAutoriza is pressed, all the chkRechaza (or vice versa) are marked or unchecked, regardless of which row they belong to. That is going to make only one or the other activated.

If you want to be controlled by rows, you can use .closest() to select a common ancestor (eg the tr of the row) and then make a .find() for the specific class. In this way, the mark / uncheck will only affect the same row and not all of the table.

The change is simple:

$(document).ready(function () {

    $('.chkAutoriza').change(function () {
        if ($(this).prop('checked')) {
            $(this).closest("tr").find('.chkRechaza').prop('checked', false);
        }
    });

    $('.chkRechaza').change(function () {
        if ($(this).prop('checked')) {
            $(this).closest("tr").find('.chkAutoriza').prop('checked', false);
        }
    });
});
    
answered by 22.07.2018 / 21:06
source
1

I propose that instead of handling it as an anonymous function that listens permanently to the onChange of the check, you better add an onClick event to each check that calls a JavaScript function that verifies the checked and disables the other. And to that function you will pass the id of the check, so that each check will make a call to this function and with id the check of that row is identified:

<td style="text-align:center">
        @Html.CheckBox("chkAutoriza", false, htmlAttributes: new { @class = "chkAutoriza", id = "chkAutoriza" + item.Pagos.IdPago, onClick="hab_desh("+item.Pagos.IdPago+")"})
</td>
<td style="text-align:center">
        @Html.CheckBox("chkRechaza", false, htmlAttributes: new { @class = "chkRechaza", id = "chkRechaza" + item.Pagos.IdPago, onClick="hab_desh("+item.Pagos.IdPago+")" })
</td>


<script>

    function hab_desh(idCheck){
        if ($('#chkRechaza'+idCheck).prop('checked')) {
                $('#chkRechaza'+idCheck).prop('checked', false);
        }

        if ($('#chkRechaza'+idCheck).prop('checked')) {
                $('#chkRechaza'+idCheck).prop('checked', false);
        }
    }
</script>

I hope you understand the logic of what I propose, since I'm not familiar with that way of generating the html, so you should check the syntax. But the logic of the code could help you in your case. I remain attentive

    
answered by 22.07.2018 в 21:04
0

Unfortunately we will not use Jquery (that with $ ) nor the commands with @ so I can not improve your existing code.

Radiobuttons

But I know that with checkboxs you will not get very far, the best would be to use radiobuttons

<body>
  <input type="radio" name="grupo1" value="a"> a<br>
  <input type="radio" name="grupo1" value="b"> b<br>
</body>

Using the name property you can assign them exclusive groups. Simply add a way to generate name groups programmatically within the loop in your code.

Checkboxs

But if you really want to do it with checkboxs look at this example.

<body>
  <input type="checkbox" id="a" onclick="document.getElementById('b').checked = false">a</input>
  <input type="checkbox" id="b" onclick="document.getElementById('a').checked = false">b</input>
</body>

Simply create the event onclick so that inside your loop always deactivate the id of the corresponding box.

Multiple Checkboxes

For the later I leave this code that serves when there are more than 2 checkboxs per group:

<body>
  <input type="checkbox" id="a" name="grupo1" onclick="document.getElementsByName('grupo1').forEach((item) => {if (item.id != this.id) item.checked = false})">a</input>
  <input type="checkbox" id="b" name="grupo1" onclick="document.getElementsByName('grupo1').forEach((item) => {if (item.id != this.id) item.checked = false})">b</input>
</body>

As you can see, the function onclick of each checkbox is always the same, which implies that just having a function for all the checkboxes is sufficient, it does not need to be modified.

    
answered by 22.07.2018 в 20:52