Переключение чекбоксов с помощью jQuery

Владимир | | HTML, JavaScript, Web разработка.

toggle checkboxes

На днях мне нужно было написать небольшую JavaScript функцию (на jQuery), которая переключала бы группу чекбоксов. Т.е. все отмеченные чекбоксы должны были стать неотмеченными и наоборот.

Кстати, это довольно широкораспространенная задача.

Количество чекбоксов изменялось динамически и некоторые из них могли быть не активными (их трогать нельзя).

Вобщем, уложился я в шесть строк (включая объявление функции).

function toggleAll() {
	var allCheckboxes = $("#checkboxes input:checkbox:enabled");
	var notChecked = allCheckboxes.not(':checked');
	allCheckboxes.removeAttr('checked');
	notChecked.attr('checked', 'checked');
}

Наверное, код можно еще подсократить, но, честно говоря, думать дальше не хочется 🙂 .

Вкратце поясню, как это работает.

Прежде всего, разметка:

Обычная группа чекбоксов, которые находятся внутри тега div. В принципе, разметка большой роли не играет. Главное, чтобы вы могли выбрать необходимые чекбоксы.

Алгоритм работы функции.

1) Находим все активные чекбоксы (input:checkbox:enabled).

2) Из них выбираем не отмеченные (not(':checked')).

3) Снимаем отметку у всех чекбоксов (для этого просто удаляем атрибут checked).

4) Отмечаем те чекбоксы, которые были раньше не отмечены (attr('checked', 'checked')).

Как видите, функция получилась довольно короткая.

Если есть идеи как её сократить, буду рад выслушать 😉

Интересно почитать:

Какова ваша отдача от инвестиций в час?

  • Как насчет такого:
    function togCheck(){
    $('#checkboxes input:checkbox').each(function(){this.checked = !this.checked;});
    }

    • Отлично!
      Ваш вариант читается легче, да и короче.
      Остается только добавить :enabled, чтобы пропустить не активные чекбоксы.

      • Да, забыл о таком условии.

        А исправляется это все вот так:
        function togCheck(){
        $('#checkboxes input:checkbox').each(function(){this.checked = !this.checked && !this.disabled;});
        }

  • Как насчет такого:
    function togCheck(){
    $('#checkboxes input:checkbox').each(function(){this.checked = !this.checked;});
    }

    • Отлично!
      Ваш вариант читается легче, да и короче.
      Остается только добавить :enabled, чтобы пропустить не активные чекбоксы.

      • Да, забыл о таком условии.

        А исправляется это все вот так:
        function togCheck(){
        $('#checkboxes input:checkbox').each(function(){this.checked = !this.checked && !this.disabled;});
        }

  • Тогда уж лучше сразу:
    function togCheck(){
    $('#checkboxes input:checkbox:enabled').each(function(){this.checked = !this.checked});
    }

    Есть еще вариант, используя attr, где в качестве второго параметра передается функция:
    function togCheck(){
    $('#checkboxes input:checkbox:enabled').attr
    (
    "checked",
    function()
    {
    return !this.checked;
    }
    );
    }

    PS. Код не тестился, но логику понять можно.

    • А вот это решение мне действительно понравилось. Кстати, у меня заработало 🙂
      Единственно, вызывает сомнение второй параметр.
      По стандарту должно быть checked=»checked», а здесь checked=true, похоже jQuery сама вносит исправления.

  • Тогда уж лучше сразу:
    function togCheck(){
    $('#checkboxes input:checkbox:enabled').each(function(){this.checked = !this.checked});
    }

    Есть еще вариант, используя attr, где в качестве второго параметра передается функция:
    function togCheck(){
    $('#checkboxes input:checkbox:enabled').attr
    (
    "checked",
    function()
    {
    return !this.checked;
    }
    );
    }

    PS. Код не тестился, но логику понять можно.

    • А вот это решение мне действительно понравилось. Кстати, у меня заработало 🙂
      Единственно, вызывает сомнение второй параметр.
      По стандарту должно быть checked=»checked», а здесь checked=true, похоже jQuery сама вносит исправления.

  • Слишком намудрили, Евгений предлогает код попроще.

  • Слишком намудрили, Евгений предлогает код попроще.

  • test

    function VipSeances(){
    $('input.vip').each(function(){
    $(this).attr('disabled',false);

    $('input.vip:checked').each(function(){
    $('input.vip').attr('disabled',true);
    $(this).attr('disabled',false);
    });
    });
    }

  • test

    function VipSeances(){
    $('input.vip').each(function(){
    $(this).attr('disabled',false);

    $('input.vip:checked').each(function(){
    $('input.vip').attr('disabled',true);
    $(this).attr('disabled',false);
    });
    });
    }

  • test

    код выше допускает только 1 выбранный чекбокс, остальные выключаем

    • Спасибо, интересный пример.

    • Румата

      Подскажите как лаконичнее (короче) реализовать ситуацию когда может быть отмечен только один чекбокс или ни одного?
      $("td.set input:checkbox").change(function(){
      var id=$(this).attr("id");
      $("td.set input:checked").each(function() {
      if ($(this).attr("id")!=id) $(this).attr("checked",false);
      });
      });

      • Как лаконичнее — не подскажу. Но ваш пример с виду рабочий (не проверял) и еще есть пример тремя комментариями выше.

        • Румата

          Да, он у меня используется… Просто не эстетично смотрится промежуточная переменная var id

        • Вы, наверное, видели фильм «Бриллиантовая рука»? 😉

          — Это не эстетично.
          — Зато дёшево, надёжно и практично.

          🙂

          А если серьезно, то переменную убрать, скорее всего, получится, но читать при этом код будет наверняка тяжелее.

      • max0s

         пользуйтесь радиобаттоном. Нужно добавить кнопку снятия активности всех радиобаттонов, если необходимо, или добавить функцию, которая будет снимать активность при клике по активному радиобаттону.

  • test

    код выше допускает только 1 выбранный чекбокс, остальные выключаем

    • Спасибо, интересный пример.

    • Румата

      Подскажите как лаконичнее (короче) реализовать ситуацию когда может быть отмечен только один чекбокс или ни одного?
      $("td.set input:checkbox").change(function(){
      var id=$(this).attr("id");
      $("td.set input:checked").each(function() {
      if ($(this).attr("id")!=id) $(this).attr("checked",false);
      });
      });

      • Как лаконичнее — не подскажу. Но ваш пример с виду рабочий (не проверял) и еще есть пример тремя комментариями выше.

        • Румата

          Да, он у меня используется… Просто не эстетично смотрится промежуточная переменная var id

        • Вы, наверное, видели фильм «Бриллиантовая рука»? 😉

          — Это не эстетично.
          — Зато дёшево, надёжно и практично.

          🙂

          А если серьезно, то переменную убрать, скорее всего, получится, но читать при этом код будет наверняка тяжелее.

  • axel

    вот здесь еще норм чекбоксы http://prootime.ru/beauty-checkboxes
    правда картинки использованы

    • Отличный пример!
      А использовать картинки или нет, каждый решает сам. В любом случае чекбоксы должны вписываться в дизайн.

  • axel

    вот здесь еще норм чекбоксы http://prootime.ru/beauty-checkboxes
    правда картинки использованы

    • Отличный пример!
      А использовать картинки или нет, каждый решает сам. В любом случае чекбоксы должны вписываться в дизайн.

  • Никита

    Не совсем понятно, зачем такая функция нужна. Часто встречается, что нужно всем проставить чекед или наоборот — у всех убрать, в зависимости от состояния главного. А для такой фигни можно и $('#checkboxes input:checkbox').click(); написать.

    • Включить или отключить все чекбоксы гораздо проще

      $('input:checkbox').each(function(){this.checked = true;});

      • Евгений

        или
        $('input:checkbox').prop('checked', true);

  • ms

    Спасибо за пример!
    есть один вопрос: у меня группа checkbox вкл/откл отедльным checkbox — ом
    но на сам переключатель галочка не ставится, что нужно дописать в код? заранее спасибо

    • Всегда, пожалуйста 🙂

      Насчет вашего вопроса.
      Если чекбокс не отмечается, то, скорее всего, он заблокирован с
      помощью JS (или есть обработчик, который сразу снимает отметку после
      ее установки). Поэтому не видя кода, ответить сложно.

      Если можете, выложите где-нибудь вашу страницу или хотябы js код
      (можно на этом сервисе http://snipt.org/).

      • ms

        Вот выложил к себе на сервер
        http://muztop.info/

        • У вас на чекбокс, который переключает все остальные установлен обработчик

          function CheckAll(){
          $('input:checkbox').each(function(){this.checked = !this.checked});
          }

          При этом
          $('input:checkbox')
          выберет все чекбоксы на странице, включая и чекбокс, который служит
          глобальным переключателем.
          Поэтому как только вы выбираете этот чекбокс запускается функция
          CheckAll() и изменяет его состояние на противоположное.

          Решение — пропустить глобальный чекбокс.

          Присвойте глобальному чекбоксу id=»global» и уберите его из результатов поиска

          function CheckAll(){
          $(«input:checkbox[id!='global']»).each(function(){
          this.checked = !this.checked;
          });
          }

        • ms

          Спасибо огромное, теперь все работает, очень помогли!

  • Nullweb
  • гость

    хм, интересная статья, спасибо))

    Не подскажете как реализовать подобное?
    нужно нажатые кнопки на странице нажать на другой странице при переходе (таже самая форма).

    Как я понимаю через переменные полученные через GET…

    • Уточните, каким образом страницы связаны между собой? Если новое окно открывается с помощью window.open, то этот метод вернет указатель на новое окно, с помощью которого можно получить доступ к его содержимому.

  • Ребят, я в этом совсем ничего не понимаю. У меня на фотохостинге стоит окошко, там галочка, мол с правилами согласен. Галочка постоянно стоит. Как сделать чтоб надо было самому ставить? Надо uncheked поставить? И как думаете, стоит ли? Или это пользователся будет раздражжать?
     

    • Галочка не стоитГалочка стоит

      Правильнее будет ее снять. Тогда можно будет с уверенностью сказать, что пользователь осознанно согласился с правилами.

  • Александр General

    Инвертирует чекбоксы без глюков

    $(«#check_all»).click(function(){
    if($(this).is(':checked')){
    $('input:checkbox').not(':checked').trigger('click');
    }
    else{
    $('input:checkbox:checked').trigger('click');
    }
    })

    • Можно заменить
      $('input:checkbox').not(':checked').trigger('click');
      на
      $(this).parent().find('input:checkbox').not(':checked').trigger('click');

      (вместо $(this).parent() можно использовать селектор списка чекбоксов)

      так должно быстрее работать. И не будет проблем с чекбоксами, которые находятся на пределами данного списка.

  • Читайте также: jQuery checkbox

  • Читайте также: jQuery checkbox