skip to Main Content

My problem is that I have found a solution for one group of checkboxes and shows the selected data in a text field in my dynamic formula.

But I think the line $('input:checkbox').change((e) does not make sense if I want to use a different, or new, group of checkboxes.

My idea is that the two different groups of checkboxes get a unique id to handle with them.

                        <tr>
                            <td>
                                Entsperrcode:
                            </td>
                            <td>
                                    <script src="inc/jquery-3.7.0.min.js"></script>
                                    <br>
                                    <table border="1"cellspacing="0" cellpadding="0">
                                        <tr>
                                            <td><center>1</center></td>
                                            <td><center>2</center></td>
                                            <td><center>3</center></td>
                                        </tr>
                                        <tr>
                                            <td><input type="checkbox" id="entsperrcodewisch1" value="1"></td>
                                            <td><input type="checkbox" id="entsperrcodewisch2" value="2"></td>
                                            <td><input type="checkbox" id="entsperrcodewisch3" value="3"></td>
                                        </tr>
                                            <td><center>4</center></td>
                                            <td><center>5</center></td>
                                            <td><center>6</center></td>
                                        </tr>
                                        <tr>
                                            <td><input type="checkbox" id="entsperrcodewisch4" value="4"></td>
                                            <td><input type="checkbox" id="entsperrcodewisch5" value="5"></td>
                                            <td><input type="checkbox" id="entsperrcodewisch6" value="6"></td>
                                        </tr>
                                        <tr>
                                            <td><center>7</center></td>
                                            <td><center>8</center></td>
                                            <td><center>9</center></td>
                                        </tr>
                                        <tr>
                                            <td><input type="checkbox" id="entsperrcodewisch7" value="7"></td>
                                            <td><input type="checkbox" id="entsperrcodewisch8" value="8"></td>
                                            <td><input type="checkbox" id="entsperrcodewisch9" value="9"></td>
                                        </tr>
                                </table>
                                    <input type="text" id="selected" name="entsperrcode"/><br><br>


                                    <script>
                                    (function() {
                                    $('input:checkbox').change((e) => {
                                        if ($(e.currentTarget).is(':checked')) {
                                        var curVal = $('#selected').val();
                                        if (curVal) {
                                            $('#selected').val(curVal + '-' + e.currentTarget.value);
                                        } else {

                                            $('#selected').val(e.currentTarget.value);
                                        }
                                        } else {
                                        var curVal = $('#selected').val().split('-');
                                        var filteredVal = curVal.filter(el => el.trim() !== e.currentTarget.value)
                                        $('#selected').val(filteredVal.join('-'));
                                        }
                                    });
                                    })();
                                    </script>
                            </td>
                        </tr>
                        <tr>
                            <td>
                                Beschädigungen:
                            </td>
                            <td>
                                    <script src="inc/jquery-3.7.0.min.js"></script>
                                    <br>
                                    <input type="checkbox" id="beschaedingung1" value="Display"><br>
                                    <input type="checkbox" id="beschaedingung2" value="Rückseite"><br>
                                    <input type="checkbox" id="beschaedingung3" value="Rand"><br>

                                    <input type="text" id="beschaedig" name="beschaedig"/><br><br>


                                    <script>
                                    (function() {
                                    $('input:checkbox').change((e) => {
                                        if ($(e.currentTarget).is(':checked')) {
                                        var curVal = $('#beschaedig').val();
                                        if (curVal) {
                                            $('#beschaedig').val(curVal + '-' + e.currentTarget.value);
                                        } else {

                                            $('#beschaedig').val(e.currentTarget.value);
                                        }
                                        } else {
                                        var curVal = $('#beschaedig').val().split('-');
                                        var filteredVal = curVal.filter(el => el.trim() !== e.currentTarget.value)
                                        $('#beschaedig').val(filteredVal.join('-'));
                                        }
                                    });
                                    })();
                                    </script>
                            </td>
                        </tr>

2

Answers


  1. Here is an example with closest (https://api.jquery.com/closest/) and each (https://api.jquery.com/each/).

    In the case of a change, the parent element (table) is found. The output field is set as a data attribute in the table (data-output-id="#output1").

    $('input:checkbox').change((e) => {
      var parent = e.currentTarget.closest('table');
      var outputId = parent.dataset.outputId;
      if ($(e.currentTarget).is(':checked')) {
        var curVal = $(outputId).val();
        if (curVal) {
          $(outputId).val(curVal + '-' + e.currentTarget.value);
        } else {
          $(outputId).val(e.currentTarget.value);
        }
      } else {
        var curVal = $(outputId).val().split('-');
        var filteredVal = curVal.filter(el => el.trim() !== e.currentTarget.value)
        $(outputId).val(filteredVal.join('-'));
      }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="inc/jquery-3.7.0.min.js"></script>
    <br>
    <table data-output-id="#output1" border="1" cellspacing="0" cellpadding="0">
      <tr>
        <td align="center">1</td>
        <td align="center">2</td>
        <td align="center">3</td>
      </tr>
      <tr>
        <td><input type="checkbox" value="1"></td>
        <td><input type="checkbox" value="2"></td>
        <td><input type="checkbox" value="3"></td>
      </tr>
      <tr>
        <td align="center">4</td>
        <td align="center">5</td>
        <td align="center">6</td>
      </tr>
      <tr>
        <td><input type="checkbox" value="4"></td>
        <td><input type="checkbox" value="5"></td>
        <td><input type="checkbox" value="6"></td>
      </tr>
      <tr>
        <td align="center">7</td>
        <td align="center">8</td>
        <td align="center">9</td>
      </tr>
      <tr>
        <td><input type="checkbox" value="7"></td>
        <td><input type="checkbox" value="8"></td>
        <td><input type="checkbox" value="9"></td>
      </tr>
    </table>
    <input type="text" id="output1" name="entsperrcode" /><br><br>
    <br>
    <table data-output-id="#output2" border="1" cellspacing="0" cellpadding="0">
      <tr>
        <td align="center">1</td>
        <td align="center">2</td>
        <td align="center">3</td>
      </tr>
      <tr>
        <td><input type="checkbox" value="1"></td>
        <td><input type="checkbox" value="2"></td>
        <td><input type="checkbox" value="3"></td>
      </tr>
      <tr>
        <td align="center">4</td>
        <td align="center">5</td>
        <td align="center">6</td>
      </tr>
      <tr>
        <td><input type="checkbox" value="4"></td>
        <td><input type="checkbox" value="5"></td>
        <td><input type="checkbox" value="6"></td>
      </tr>
      <tr>
        <td align="center">7</td>
        <td align="center">8</td>
        <td align="center">9</td>
      </tr>
      <tr>
        <td><input type="checkbox" value="7"></td>
        <td><input type="checkbox" value="8"></td>
        <td><input type="checkbox" value="9"></td>
      </tr>
    </table>
    <input type="text" id="output2" name="entsperrcode" /><br><br>
    Login or Signup to reply.
  2. The way I’d approach this is as below, with explanatory comments in the code:

    // simple utility variable and functions to reduce some of the repetitive typing:
    const D = document,
      // here we have means of creating an element, and passing various properties
      // to that new element (className, textContent, borderColor...):
      create = (tag, props) => Object.assign(D.createElement(tag), props),
      // an alias for document, and element, querySelector(), which is used
      // depends on the context which is the document by default:
      get = (selector, context = D) => context.querySelector(selector),
      // as above, but an alias for querySelectorAll(), this explicitly returns
      // an Array instead of a NodeList in order to allow for Array methods to be
      // used (map(), filter()...):
      getAll = (selector, context = D) => [...context.querySelectorAll(selector)];
    
    // named function to handle the events on the <input type="checkbox">
    // elements, this is bound later using EventTarget.addEventListener();
    // this function takes one argument - 'evt', a reference to the Event Object -
    // passed from EventTarget.addEventListener():
    const checkboxHandler = (evt) => {
    
        // this is the element to which the event-handling function is bound:
        let changed = evt.currentTarget,
          // the 'output' is the element in which I'll be showing the results,
          // and uses Element.querySelector() to find the first (if any) element
          // matching the selector which is found within the closest ancestor
          // <fieldset> element:
          output = get('.result', changed.closest('fieldset')),
          // this retrieves the delimiter custom property defined in the CSS,
          // whether via the stylesheet or the inline "style" attribute:
          delimiter = window.getComputedStyle(output,null).getPropertyValue("--delimiter"),
          // we retrieve the value of the changed element (removing leading/trailing
          // white-space; this may or may not be necessary depending on your use-case):
          result = changed.value.trim(),
          // here we use a template-literal string to concatenate the various
          // variables together to create an identifier for the created element
          // (an id could be used, given that this is likely to be unique, but I
          // chose to assume that conflicts may happen across the document):
          resultClass = `${changed.name}${delimiter}${result}`,
          // we create a <span> element with the given textContent and className:
          resultWrapper = create('span', {
              textContent: result,
              className: resultClass,
          }),
          // creating another element - an <em> - to wrap the delimiter character:
          delimiterWrapper = create('em', {
          textContent: delimiter,
          className: "delimiter"
        });
        
        // a checkbox may fire the change event both when it's checked or
        // unchecked by the user; therefore we first test to see whether it
        // was checked (this returns a Boolean true or false):
        if (changed.checked) {
          // if it was checked we append both the created <em> element, along
          // with the created <span> element to the output element:
            output.append(delimiterWrapper, resultWrapper);
        } else {
          // or if it was unchecked, we retrieve the existing element via
          // the class we created created earlier and looking within the
          // output element, using the alias (above) of element.querySelector()
          // by passing a context:
        let toRemove = get(`.${resultClass}`, output);
        
        // we then use an Array literal, passing in both the previous element
        // sibling of the element we wish to remove and the element itself:
        [toRemove.previousElementSibling, toRemove]
          // we then use Array.prototype.forEach() to iterate over the Array:
          .forEach(
            // passing in a reference to the current Array element 'el',
            // and removing that element:
            (el) => el.remove()
          );
        }
    };
      
    // here we selector all checkbox <input> elements in the document, and
    // iterate over that Array:
    getAll('input[type=checkbox]').forEach(
      // passing in a reference - 'el' - to the current Node of the
      // Array of Nodes, and using EventTargetTarget.addEventListener()
      // to bind the named function checkboxHandler() (note the deliberately
      // missing parentheses) as the event-handler for the 'change' event:
        (el) => el.addEventListener('change', checkboxHandler)
    );
    /* setting a custom property to use later as a basic
       demonstration of how custom properties might be
       used: */
    form {
      --labelSize: 3rem;
    }
    
    fieldset {
      /* allows us to easily style the <input> elements
         into a grid, tabular-style, format: */
      display: inline grid;
      /* defining the space between adjacent elements: */
      gap: 0.5rem;
      /* defining the size of the various rows: */
      grid-auto-rows: var(--labelSize);
      /* defining the size of the various columns, using
         repeat() to create a number of columns stored in
         the --columnCount custom variable, with a default
         value of 3: */
      grid-template-columns: repeat(var(--columnCount, 3), var(--labelSize));
    }
    
    label {
      border: 1px solid currentColor;
      display: grid;
      padding: 0.25rem;
      text-align: center;
    }
    
    /* this moves the <input> children of the <label>
       element after their next sibling element in order
       that the DOM allows for a checked <input> to style
       the following <span>, despite that <span> visually
       appearing before the <input>: */
    label > input {
      order: 1;
    }
    
    /* styling the adjacent <span> of the checked <input>: */
    input:checked + span {
      /* this isn't particularly great example, but serves
         only to demonstrate how the <span> may be styled
         based on the state of the check-box: */
      background-image:
        radial-gradient(
          at 0 0,
          lightskyblue,
          palegreen
        );
      font-weight: bold;
    }
    
    .result {
      border: 1px solid currentColor;
      /* using flex layout: */
      display: flex;
      /* shorthand for:
          flex-direction: row;
          flex-wrap: wrap;
         adjust to your preferences: */
      flex-flow: row wrap;
      gap: 0.25rem;
      /* positioning the element so that it
         starts in grid-column: 1 (the first)
         and finishes in grid-column: -1
         (the last) */
      grid-column: 1 / -1;
      padding-block: 0.25rem;
      padding-inline: 0.5rem;
    }
    
    /* within the JavaScript we add the .result
       elements along with a previous .delimiter
       element, so here we style a .delimiter
       when it's the first child so that it's not
       visible in the document: */
    .result .delimiter:first-child {
      display: none;
    }
    <form action="#">
      <!-- I opted to wrap each "group" of <input> elements within
           a <fieldset> element within a <form>, as your demo didn't
           look tabular (the element choices aren't really important
           changes require only minor adjustments to the JavaScript: -->
      <fieldset>
        <!-- provides a "title" to the grouped <input> elements: -->
        <legend>Group 1</legend>
        <!-- wrapping the <input> within the <label> so that clicking
             either the <input> or the text will update the checked
             state of the <input> and trigger the change event: -->
        <label><input type="checkbox" value="1" name="group-1">
          <span class="labelText">1</span>
          <!-- to associate the <input> elements together in their
               "groups" I've taken advantage of the "name"
               attribute in place of the (invalid duplication of
               "id" attributes) -->
          
        </label>
        <label><input type="checkbox" value="2" name="group-1">
          <span class="labelText">2</span>
          
        </label>
        <label><input type="checkbox" value="3" name="group-1">
          <span class="labelText">3</span>
          
        </label>
        <label><input type="checkbox" value="4" name="group-1">
          <span class="labelText">4</span>
          
        </label>
        <label><input type="checkbox" value="5" name="group-1">
          <span class="labelText">5</span>
          
        </label>
        <label><input type="checkbox" value="6" name="group-1">
          <span class="labelText">6</span>
          
        </label>
        <label><input type="checkbox" value="7" name="group-1">
          <span class="labelText">7</span>
          
        </label>
        <label><input type="checkbox" value="8" name="group-1">
          <span class="labelText">8</span>
          
        </label>
        <label><input type="checkbox" value="9" name="group-1">
          <span class="labelText">9</span>
          
        </label>
        <output class="result" style="--delimiter: -;"></output>
      </fieldset>
      <fieldset>
        <legend>Group 2</legend>
        <label><input type="checkbox" value="1" name="group-2">
          <span class="labelText">1</span>
          </label>
        <label><input type="checkbox" value="2" name="group-2">
          <span class="labelText">2</span>
          
        </label>
        <label><input type="checkbox" value="3" name="group-2">
          <span class="labelText">3</span>
          
        </label>
        <label><input type="checkbox" value="4" name="group-2">
          <span class="labelText">4</span>
          
        </label>
        <label><input type="checkbox" value="5" name="group-2">
          <span class="labelText">5</span>
          
        </label>
        <label><input type="checkbox" value="6" name="group-2">
          <span class="labelText">6</span>
          
        </label>
        <label><input type="checkbox" value="7" name="group-2">
          <span class="labelText">7</span>
          
        </label>
        <label><input type="checkbox" value="8" name="group-2">
          <span class="labelText">8</span>
          
        </label>
        <label><input type="checkbox" value="9" name="group-2">
          <span class="labelText">9</span>
          
        </label>
        <output class="result" style="--delimiter: -;"></output>
      </fieldset>
      <fieldset>
        <legend>Group 3</legend>
        <label><input type="checkbox" value="1" name="group-3">
          <span class="labelText">1</span>
          </label>
        <label><input type="checkbox" value="2" name="group-3">
          <span class="labelText">2</span>
          
        </label>
        <label><input type="checkbox" value="3" name="group-3">
          <span class="labelText">3</span>
          
        </label>
        <label><input type="checkbox" value="4" name="group-3">
          <span class="labelText">4</span>
          
        </label>
        <label><input type="checkbox" value="5" name="group-3">
          <span class="labelText">5</span>
          
        </label>
        <label><input type="checkbox" value="6" name="group-3">
          <span class="labelText">6</span>
          
        </label>
        <label><input type="checkbox" value="7" name="group-3">
          <span class="labelText">7</span>
          
        </label>
        <label><input type="checkbox" value="8" name="group-3">
          <span class="labelText">8</span>
          
        </label>
        <label><input type="checkbox" value="9" name="group-3">
          <span class="labelText">9</span>
          
        </label>
        <output class="result" style="--delimiter: -;"></output>
      </fieldset>
      <fieldset>
        <legend>Group 4</legend>
        <label><input type="checkbox" value="1" name="group-4">
          <span class="labelText">1</span>
          </label>
        <label><input type="checkbox" value="2" name="group-4">
          <span class="labelText">2</span>
          
        </label>
        <label><input type="checkbox" value="3" name="group-4">
          <span class="labelText">3</span>
          
        </label>
        <label><input type="checkbox" value="4" name="group-4">
          <span class="labelText">4</span>
          
        </label>
        <label><input type="checkbox" value="5" name="group-4">
          <span class="labelText">5</span>
          
        </label>
        <label><input type="checkbox" value="6" name="group-4">
          <span class="labelText">6</span>
          
        </label>
        <label><input type="checkbox" value="7" name="group-4">
          <span class="labelText">7</span>
          
        </label>
        <label><input type="checkbox" value="8" name="group-4">
          <span class="labelText">8</span>
          
        </label>
        <label><input type="checkbox" value="9" name="group-4">
          <span class="labelText">9</span>
          
        </label>
        <output class="result" style="--delimiter: -;"></output>
      </fieldset>
    </form>

    JS Fiddle demo.

    References:

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search