0

I fill the table with a ADODB.Recordset. I have 25 rows. But it can change. And last column is checkboxes.

enter image description here

Only one checkbox can select. Check one and uncheck others automatic.

<input class="cb" id="txtdurum_<%=counter%>" name="txtdurum" type="checkbox" />

Help please :)

5
  • 7
    You should use type="radio" for these, as this is the Radio buttons default funcitonality. Commented May 28, 2015 at 10:53
  • But user, nothing can choose. Commented May 28, 2015 at 10:55
  • the user can also choose nothing Commented May 28, 2015 at 10:58
  • So provide an option for 'nothing,' this is still the wrong use-case for a check-box. Commented May 28, 2015 at 11:01
  • @EmrahŞentürk look at my anwer. I updated my code, so the user could also uncheck all checkboxes. Commented May 28, 2015 at 11:08

3 Answers 3

1

Try this code. Add an onchange event to each input checkbox.

<input class="cb" id="txtdurum_<%=counter%>" name="txtdurum" type="checkbox" onchange="check(this)"/>

JS:

function check(element){
    if(element.checked){
      var checkboxes = document.getElementsByClassName('cb');
        for(var i=0;i<checkboxes.length;i++){
           if(checkboxes[i]!=element)
             checkboxes[i].checked = false;
        }
    }
}

Example Fiddle.

Sign up to request clarification or add additional context in comments.

3 Comments

You ruled out IE8 compatibility with document.getElementsByClassName('cb');, if you'd used document.querySelectorAll('.cb'), however, this (should) be compatible with IE* and above.
Error : Undefined or can not get the property empty reference ' marked
I did. This code works. But I use getElementsById with different method instead getElementsByClassName. Thank you.
1

You can use jQuery:

$('.cb').change(function(){
   $('.cb').prop('checked',false);
   $(this).prop('checked',true); 
});

This adds a change-listener to all checkboxes with the "cb" class-Attribute. Place that code-fragment into the jquery-ready-function.

Example: JSFiddle

UPDATE1: If you also want to enable, that the user can uncheck all:

$('.cb').change(function(){
    var checkState = $(this).prop('checked');
    $('.cb').prop('checked',false);
    $(this).prop('checked', checkState);
});

Example: JSFiddle2

But: better use radiobuttons

Comments

0

While I would – strongly – recommend that you use <input> elements of type="radio" (with a 'choose nothing' option, if that's required), I was intrigued enough to spend the last few hours putting together this approach.

This is one way of doing it, it feels little over-the-top and it's not quite as streamlined as I'd like, but it does suffice to meet your requirements. I've provided a simple demo for the introduction, and the JavaScript is commented throughout:

var Limit = (function () {
    // private to this function, but shared by all instances:

    // simple 'closest' function;
    // start: DOM Node,
    // needle: String, the tagName of the ancestor to find.

    // if no ancestor exists (we stop at the <body> element)
    // function returns null:
    var closest = function (start, needle) {
        // we begin at the 'start' node, but use
        // the 'current' variable as a pointer as
        // we move through the ancestors:
        var current = start,

            // converting the tagName to lower-case,
            // for predictable comparisons:
            find = needle.toLowerCase();

        // while the tagName of the current element-node is not
        // what we're looking for AND the current element-node is
        // not the <body> element:
        while (current.tagName.toLowerCase() !== find && current.tagName.toLowerCase() !== 'body') {
            // we set the current node to its parentNode,
            // thereby ascending through the DOM:
            current = current.parentNode;
        }

        // if the tagName of the current element-node is 'body'
        // we return null, otherwise we return that current node:
        return current.tagName.toLowerCase() === 'body' ? null : current;
    };

    return function (groupSelector) {
        // protected variables, available on a
        // per-instance basis:

        // the array in which we'll hold the selected
        // <input> elements as they're checked:
        var checked = [],

            // the group of elements to which this instance
            // will apply:
            group = document.querySelectorAll(groupSelector),

            // the defaults:
            // allowInvalidity, Boolean:
            //    true:  allows the user to select more than
            //           the maximum number of choices.
            //    false: prevents the selection of options
            //           beyond the maxumum number.
            // fifo, Boolean:
            //    true:  should the user try to select more
            //           than the maximum number of choices
            //           the first element in the array is
            //           removed.
            //    false: should the user try to select more
            //           than the maximum number of choices
            //           subsequent choices are prevented.
            // maxChoices, Number:
            //           defines the maximum number of choices
            //           that can be made.
            // parentErrorClass, String:
            //           the class-name to be applied to the
            //           parent of the <input> elements when
            //           the user chooses more than the maximum
            //           number of options (requires
            //           settings.invalidity to be true).

            defaults = {
                'allowInvalidity': false,
                    'fifo': true,
                    'maxChoices': 1,
                    'parentErrorClass': 'error'
            };

        // the object containing the function(s) we
        // make available:
        return {

            // opts is the user-defined settings
            // passed in:
            'nOnly': function (opts) {

                // a simple, though potentially costly,
                // means of avoiding JavaScript's
                // pass-by-reference (which prevents
                // settings = dafaults from working),
                // here creating a copy via the JSON functions:
                var settings = JSON.parse(JSON.stringify(defaults));

                // iterating over the user-defined settings in the
                // supplied opts object:
                for (var setting in opts) {

                    // avoiding iterating over inherited properties
                    // from the Object.prototype:
                    if (opts.hasOwnProperty(setting)) {

                        // setting the settings options to
                        // those supplied in the opts object:
                        settings[setting] = opts[setting];
                    }
                }

                // iterating over the Array-like NodeList returned by
                // document.querySelectorAll() (when we retrieved the
                // nodes for this 'group'), using Function.prototype.call()
                // to apply Array.prototype.forEach():
                Array.prototype.forEach.call(group, function (input) {
                    // there are three arguments available to
                    // Array.prototype.forEach(), the names are
                    // user-defined (within variable-naming constraints);
                    // the first (here: 'input') the current array-element
                    // from the array over which we're iterating,
                    // the second (not used) is the index of that array-element,
                    // the third (not used) is the full array over which
                    // we iterate.

                    // here we bind the anonymous function as the 'change'
                    // event-handler on each of the <input> elements in
                    // the parent group:
                    input.addEventListener('change', function (event) {

                        if (input.checked && settings.allowInvalidity === false) {
                            // add the <input> to the checked array:
                            checked.push(input);

                            // if too many choices have been made:
                            if (checked.length > settings.maxChoices) {

                                // we call Array.prototype.pop() (if
                                // settings.fifo is true) or
                                // Array.prototype.shift() (if
                                // settings.fifo is not exactly-true)
                                // to select the first element of the
                                // checked Array (shift()) or the last
                                // element (pop()) and set that element's
                                // checked property to false. Using shift()
                                // or pop() also removes it from the array:
                                checked[settings.fifo === true ? 'shift' : 'pop']().checked = false;
                            }

                        } else if (input.checked && settings.allowInvalidity === true) {
                            // we simply add the <input> to the array:
                            checked.push(input)
                        } else {

                            // we test that the <input> element is in
                            // the checked Array:
                            if (checked.indexOf(input) > -1) {

                                // using Array.prototype.splice() to
                                // remove it from the Array; using
                                // Array.prototype.indexOf() (again) 
                                // to retrieve its index in the Array:
                                checked.splice(checked.indexOf(input), 1);
                            }
                        }

                        // iterating over the group, with Array.prototype.forEach():
                        Array.prototype.forEach.call(group, function (input) {

                            // if the <input> is not checked, or the number of choices
                            // is less than the permitted maximum:
                            if (!input.checked || checked.length <= settings.maxChoices) {

                                // we remove the parentErrorClass from the parentNode:
                                input.parentNode.classList.remove(settings.parentErrorClass);

                                // otherwise if the <input> is checked, AND
                                // there are too many choices:
                            } else if (input.checked && checked.length > settings.maxChoices) {

                                // we add the parentErrorClass to the parentNode:
                                input.parentNode.classList.add(settings.parentErrorClass);
                            }
                        });

                    });
                });
            }
        };
    };
})();

new Limit('.group1 input').nOnly({
    'allowInvalidity': true,
        'maxChoices': 3
});
new Limit('.group2 input').nOnly({
    'maxChoices': 1,
        'fifo': false
});
new Limit('.group3 input').nOnly({
    'allowInvalidity': true,
    'maxChoices' : 2,
    'parentErrorClass' : 'oops'
});

var Limit = (function() {
  var closest = function(start, needle) {
    var current = start,
      find = needle.toLowerCase();
    while (current.tagName.toLowerCase() !== find && current.tagName.toLowerCase() !== 'body') {
      current = current.parentNode;
    }
    return current.tagName.toLowerCase() === 'body' ? null : current;
  };

  return function(groupSelector) {
    var checked = [],
      group = document.querySelectorAll(groupSelector),
      defaults = {
        'allowInvalidity': false,
        'fifo': true,
        'maxChoices': 1,
        'parentErrorClass': 'error'
      };
    return {
      'nOnly': function(opts) {
        var settings = JSON.parse(JSON.stringify(defaults));
        for (var setting in opts) {
          if (opts.hasOwnProperty(setting)) {
            settings[setting] = opts[setting];
          }
        }
        Array.prototype.forEach.call(group, function(input) {
          input.addEventListener('change', function(event) {

            if (input.checked && settings.allowInvalidity === false) {

              checked.push(input);
              if (checked.length > settings.maxChoices) {
                checked[settings.fifo === true ? 'shift' : 'pop']().checked = false;
              }

            } else if (input.checked && settings.allowInvalidity === true) {
              checked.push(input)
            } else {
              if (checked.indexOf(input) > -1) {
                checked.splice(checked.indexOf(input), 1);
              }
            }
            Array.prototype.forEach.call(group, function(input) {
              if (!input.checked || checked.length <= settings.maxChoices) {
                input.parentNode.classList.remove(settings.parentErrorClass);
              } else if (input.checked && checked.length > settings.maxChoices) {
                input.parentNode.classList.add(settings.parentErrorClass);
              }
            });

          });
        });
      }
    };
  };
})();

new Limit('.group1 input').nOnly({
  'allowInvalidity': true,
  'maxChoices': 3
});
new Limit('.group2 input').nOnly({
  'maxChoices': 1,
  'fifo': false
});
new Limit('.group3 input').nOnly({
  'allowInvalidity': true,
  'maxChoices': 2,
  'parentErrorClass': 'oops'
});
form {
  -moz-column-count: 3;
  -webkit-column-count: 3;
  column-count: 3;
  -moz-break-inside: avoid-column;
  -webkit-break-inside: avoid-column;
  break-inside: avoid-column;
}
label {
  display: block;
  border: 2px solid transparent;
  transition: all 0.5s linear;
}
.error {
  border: 2px solid #f00;
}
.oops {
  background-color: #f90;
}
<form action="#" method="post">
  <fieldset>
    <legend>Group 1</legend>
    <label class="group1">input 1
      <input type="checkbox" />
    </label>
    <label class="group1">input 2
      <input type="checkbox" />
    </label>
    <label class="group1">input 3
      <input type="checkbox" />
    </label>
    <label class="group1">input 4
      <input type="checkbox" />
    </label>
    <label class="group1">input 5
      <input type="checkbox" />
    </label>
  </fieldset>
  <fieldset>
    <legend>Group 2</legend>
    <label class="group2">input 1
      <input type="checkbox" />
    </label>
    <label class="group2">input 2
      <input type="checkbox" />
    </label>
    <label class="group2">input 3
      <input type="checkbox" />
    </label>
    <label class="group2">input 4
      <input type="checkbox" />
    </label>
    <label class="group2">input 5
      <input type="checkbox" />
    </label>
  </fieldset>
  <fieldset>
    <legend>Group 3</legend>
    <label class="group3">input 1
      <input type="checkbox" />
    </label>
    <label class="group3">input 2
      <input type="checkbox" />
    </label>
    <label class="group3">input 3
      <input type="checkbox" />
    </label>
    <label class="group3">input 4
      <input type="checkbox" />
    </label>
    <label class="group3">input 5
      <input type="checkbox" />
    </label>
  </fieldset>
</form>

External JS Fiddle demo, for experimentation.

To apply this to your own situation, the function can be called like so:

// here, the only difference is the CSS selector
// passed to the Constructor:
new Limit('table input[type=checkbox]').nOnly({
    'maxChoices': 1
});

var Limit = (function() {
  var closest = function(start, needle) {
    var current = start,
      find = needle.toLowerCase();
    while (current.tagName.toLowerCase() !== find && current.tagName.toLowerCase() !== 'body') {
      current = current.parentNode;
    }
    return current.tagName.toLowerCase() === 'body' ? null : current;
  };

  return function(groupSelector) {
    var checked = [],
      group = document.querySelectorAll(groupSelector),
      defaults = {
        'allowInvalidity': false,
        'fifo': true,
        'maxChoices': 1,
        'parentErrorClass': 'error'
      };
    return {
      'nOnly': function(opts) {
        var settings = JSON.parse(JSON.stringify(defaults));
        for (var setting in opts) {
          if (opts.hasOwnProperty(setting)) {
            settings[setting] = opts[setting];
          }
        }
        Array.prototype.forEach.call(group, function(input) {
          input.addEventListener('change', function(event) {

            if (input.checked && settings.allowInvalidity === false) {

              checked.push(input);
              if (checked.length > settings.maxChoices) {
                checked[settings.fifo === true ? 'shift' : 'pop']().checked = false;
              }

            } else if (input.checked && settings.allowInvalidity === true) {
              checked.push(input)
            } else {
              if (checked.indexOf(input) > -1) {
                checked.splice(checked.indexOf(input), 1);
              }
            }
            Array.prototype.forEach.call(group, function(input) {
              if (!input.checked || checked.length <= settings.maxChoices) {
                input.parentNode.classList.remove(settings.parentErrorClass);
              } else if (input.checked && checked.length > settings.maxChoices) {
                input.parentNode.classList.add(settings.parentErrorClass);
              }
            });

          });
        });
      }
    };
  };
})();

new Limit('table input[type=checkbox]').nOnly({
  'maxChoices': 1
});
<table>
  <tr>
    <td>row 1</td>
    <td>
      <input type="checkbox" />
    </td>
  </tr>
  <tr>
    <td>row 2</td>
    <td>
      <input type="checkbox" />
    </td>
  </tr>
  <tr>
    <td>row 3</td>
    <td>
      <input type="checkbox" />
    </td>
  </tr>
  <tr>
    <td>row 4</td>
    <td>
      <input type="checkbox" />
    </td>
  </tr>
  <tr>
    <td>row 5</td>
    <td>
      <input type="checkbox" />
    </td>
  </tr>
  <tr>
    <td>row 6</td>
    <td>
      <input type="checkbox" />
    </td>
  </tr>
  <tr>
    <td>row 7</td>
    <td>
      <input type="checkbox" />
    </td>
  </tr>
  <tr>
    <td>row 8</td>
    <td>
      <input type="checkbox" />
    </td>
  </tr>
  <tr>
    <td>row 9</td>
    <td>
      <input type="checkbox" />
    </td>
  </tr>
  <tr>
    <td>row 10</td>
    <td>
      <input type="checkbox" />
    </td>
  </tr>
</table>

External JS Fiddle demo, for experimentation.

This is, obviously, a representative demonstration since you neglected to provide the relevant (mcve) HTML, however since it relies only on an appropriate selector it should be easily applicable to your situation.

References:

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.