Тривісний прапорець у HTML?


163

Немає можливості у тривимірній кнопці перевірки (так, ні, нуль) у HTML, правда?

Чи є якісь прості хитрощі або непрості роботи, не викладаючи всю цю справу самостійно?


У функціональному відношенні, в чому різниця між "ні" і "нуль" у вашому використанні?
Девід каже повернути Моніку

5
Подивіться на відповіді нижче (крім моїх). "Недійсне" означає щось на кшталт "Без відповіді" ...
Франц

2
Саме так. Це предмет з предками, а "null" означає "використовувати батьківське значення".
Pekka

7
Альтернативне використання для тривісного прапорця - це під час пошуку / фільтрації. Наприклад, припустимо, у мене є інтерфейс для пошуку списку вживаних автомобілів. Одним із варіантів пошуку може бути, чи має автомобіль люк чи ні. Три штати можна використати так: Показуйте автомобілі лише з люком. Показуйте автомобілі ВІДКРИТИ люк Показуйте обидва. Тепер, безумовно, це можна вирішити різними способами ... з трьох радіо кнопок ... але тривісний прапорець (який або порожній, має зелену галочку, або червоний х у ньому) - також приємне рішення.
Мир

2
Було б корисно встановити список прапорців, з одним прапором на чолі списку, щоб встановити прапорець або зняти всі інші поля. Якщо все позначено, то прапорець заголовка може це відображати. Якщо все не встановлено, то прапорець заголовка також може відображати це. Якщо список містить комбінацію прапорець і галочок, то показ вікна заголовка у проміжному стані забезпечить візуальний зворотній зв'язок. Цей прапорець заголовка ніколи не матиме значення - це лише візуальна сигналізація та допомога в інтерфейсі. Бути в нагоді також можна переключити прапорець між усіма трьома станами.
Джейсон

Відповіді:


119

Редагувати - Завдяки коментарю Януса Троельсена я знайшов краще рішення:

HTML5 визначає властивість для вказаних прапорців indeterminate

Див. Посібник з w3c . Щоб прапорець виглядав візуально невизначеним, встановіть його на "true":

element.indeterminate = true;

Ось загадка Януса Троельсена . Однак зауважте, що:

  • indeterminateСтан не може бути встановлено в HTML - розмітки, це може бути зроблено тільки з допомогою Javascript (див цього тесту JSfiddle і цієї докладної статті в CSS трюках )

  • Цей стан не змінює значення прапорця, це лише візуальна сигналізація, яка маскує реальний стан введення.

  • Тест браузера: працював для мене в Chrome 22, Firefox 15, Opera 12 і назад в IE7. Що стосується мобільних браузерів, браузер Android 2.0 та Safari mobile на iOS 3.1 не підтримують його.

Попередня відповідь

Ще одна альтернатива - грати з прозорістю прапорця для стану "деякий вибраний" (як це робив Gmail у попередніх версіях). Для цього знадобиться деякий JavaScript та клас CSS. Тут я прикладаю конкретний приклад, який обробляє список із пунктируеми елементами та прапорець, що дозволяє вибрати всі / жодні з них. Цей прапорець показує стан "деякий вибраний", коли вибрано деякі елементи списку.

Дано прапорець з ідентифікатором #select_allта декількома прапорцями з класом.select_one ,

Клас CSS, який вимикає прапорець "вибрати все", буде таким:

.some_selected {
    opacity: 0.5;
    filter: alpha(opacity=50);
}

А JS-код, який обробляє тривісний прапорець "Вибрати всі", такий:

$('#select_all').change (function ()
{
    //Check/uncheck all the list's checkboxes
    $('.select_one').attr('checked', $(this).is(':checked'));
    //Remove the faded state
    $(this).removeClass('some_selected');
});

$('.select_one').change (function ()
{
  if ($('.select_one:checked').length == 0)
      $('#select_all').removeClass('some_selected').attr('checked', false);
  else if ($('.select_one:not(:checked)').length == 0)
      $('#select_all').removeClass('some_selected').attr('checked', true);
  else
      $('#select_all').addClass('some_selected').attr('checked', true);
});

Ви можете спробувати тут: http://jsfiddle.net/98BMK/

Сподіваюся, що це допомагає!



1
Тестований у chrome v35 та прапорець "all" перевіряє лише інші вікна, які вперше натиснули. Після цього це працює лише для того, щоб зняти галочки з інших прапорців. Виправлено у цій версії: jsfiddle.net/CHRSb/1
rdans

2
.prop('checked', ...)слід використовувати замість .attr('checked', ...).
Луна

Я виправив помилок, які вказував Росс; нова скрипка тут .
Майк Десімоне

48

Ви можете використовувати HTML в indeterminateатрибут IDL на inputелементи.


3
За повідомленням Берта Боса в електронному листі від 2002 року (< списки.w3.org/Archives/Public/www-dom/2002JanMar/0014.html> ), IE / Win та IE / Mac підтримують його з версії 4. Firefox, як видається, реалізували його у версії 3.6. Схоже, це було впроваджено в Safari у 2008 році. Я думаю, що це не дуже багато кінцевих користувачів.
Ms2ger

використовуйте замість цього URL ( help.dottoro.com/ljuocesd.php ). Він показує, хто його підтримує (всі бар-опера), з тих пір, коли візуально відображає, що це таке. Люди лякаються сторінок специфікацій. +1 для цього непридатного рішення
Hashbrown

15

Моя пропозиція буде використовувати

  • три відповідних символи unicode для трьох станів, наприклад ❓, ✅, ❌
  • поле для введення тексту (розмір = 1)
  • немає кордону
  • лише для читання
  • не показувати курсор
  • onclick обробник для перемикання через три стани

Дивіться приклади на:

/**
 *  loops thru the given 3 values for the given control
 */
function tristate(control, value1, value2, value3) {
  switch (control.value.charAt(0)) {
    case value1:
      control.value = value2;
    break;
    case value2:
      control.value = value3;
    break;
    case value3:
      control.value = value1;
    break;
    default:
      // display the current value if it's unexpected
      alert(control.value);
  }
}
function tristate_Marks(control) {
  tristate(control,'\u2753', '\u2705', '\u274C');
}
function tristate_Circles(control) {
  tristate(control,'\u25EF', '\u25CE', '\u25C9');
}
function tristate_Ballot(control) {
  tristate(control,'\u2610', '\u2611', '\u2612');
}
function tristate_Check(control) {
  tristate(control,'\u25A1', '\u2754', '\u2714');
}
<input type='text' 
       style='border: none;' 
       onfocus='this.blur()' 
       readonly='true' 
       size='1' 
       value='&#x2753;' onclick='tristate_Marks(this)' />

<input style="border: none;"
       id="tristate" 
       type="text"  
       readonly="true" 
       size="1" 
       value="&#x2753;"  
       onclick="switch(this.form.tristate.value.charAt(0)) { 
     case '&#x2753': this.form.tristate.value='&#x2705;'; break;  
     case '&#x2705': this.form.tristate.value='&#x274C;'; break; 
     case '&#x274C': this.form.tristate.value='&#x2753;'; break; 
       };" />  



3

Для досягнення цієї функціональності можна використовувати радіогрупи:

<input type="radio" name="choice" value="yes" />Yes
<input type="radio" name="choice" value="No" />No
<input type="radio" name="choice" value="null" />null

1
Я це знаю, дякую. :) Зараз я використовую вибрані, але форма трохи забивається.
Pekka

1
Що ж, як би виглядав третій стан взагалі? Як і коли вимкнено прапорець? Як би ви хотіли це зробити?
Франц

3

Я думаю, що найбільш семантичним способом є використання readonlyатрибутів, якими можуть бути вхідні прапорці. Без css, без зображень тощо; вбудована властивість HTML!

Дивіться Fiddle:
http://jsfiddle.net/chriscoyier/mGg85/2/

Як описано тут у останньому фокусі: http://css-tricks.com/indeterminate-checkboxes/


Приємне рішення, але, на жаль, це не працює в IE (тест з версією 11), оскільки більш швидкі кліки вже не розпізнаються.
ViRuSTriNiTy

3

Ось приклад для запуску із використанням згаданого indeterminateатрибута :

const indeterminates = document.getElementsByClassName('indeterminate');
indeterminates['0'].indeterminate  = true;
<form>
  <div>
    <input type="checkbox" checked="checked" />True
  </div>
  <div>
    <input type="checkbox" />False
  </div>
  <div>
    <input type="checkbox" class="indeterminate" />Indeterminate
  </div>
</form>

Просто запустіть фрагмент коду, щоб побачити, як він виглядає.


2

Як і у відповіді @Franz, ви також можете зробити це з вибором. Наприклад:

<select>
  <option></option>
  <option value="Yes">Yes</option>
  <option value="No">No</option>
</select>

За допомогою цього ви можете також дати конкретне значення, яке буде надіслано разом із формою, я думаю, що з невизначеною версією javascript версією прапорця буде надіслане підкреслене значення прапорця.

Принаймні, ви можете використовувати його як зворотний дзвінок, коли JavaScript відключений. Наприклад, дайте йому ідентифікатор і у випадку завантаження змініть його на версію javascript у галочці з невизначеним статусом.


2

Крім усіх цитованих вище, є додатки jQuery, які також можуть допомогти:

для окремих прапорців:

для дерев яної поведінки прапорці:

EDIT Обидві бібліотеки використовують атрибут " невизначений ", оскільки цей атрибут у Html5 призначений лише для стилізації ( https://www.w3.org/TR/2011/WD-html5-20110113/number-state.html#checkbox-state ), нульове значення ніколи не надсилається серверу (прапорці можуть мати лише два значення).

Щоб мати змогу подати це значення на сервер, я створив приховані поля аналогів, які заповнюються під час подання форми за допомогою деякого JavaScript. З боку сервера, звичайно, потрібно буде встановити ці поля аналогів замість оригінальних прапорців.

Я використав першу бібліотеку (автономні прапорці), де важливо:

  • Ініціалізуйте перевірені, неперевірені, невизначені значення
  • використовуйте функцію .val (), щоб отримати фактичне значення
  • Не можу зробити роботу .state (можливо, моя помилка)

Сподіваюся, що це допомагає.


2

Ось інший приклад з простим jQuery та властивістю data-checked:

 $("#checkbox")
  .click(function(e) {
    var el = $(this);

    switch (el.data('checked')) {

      // unchecked, going indeterminate
      case 0:
        el.data('checked', 1);
        el.prop('indeterminate', true);
        break;

        // indeterminate, going checked
      case 1:
        el.data('checked', 2);
        el.prop('indeterminate', false);
        el.prop('checked', true);
        break;

        // checked, going unchecked
      default:
        el.data('checked', 0);
        el.prop('indeterminate', false);
        el.prop('checked', false);

    }
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label><input type="checkbox" name="checkbox" value="" checked id="checkbox"> Tri-State Checkbox </label>


1

Посилаючись на відповідь @BoltClock , ось моє рішення для більш складного рекурсивного методу:

http://jsfiddle.net/gx7so2tq/2/

Це може бути не найкрасивішим рішенням, але воно прекрасно працює для мене і є досить гнучким.

Я використовую два об'єкти даних, що визначають контейнер:

data-select-all="chapter1"

і самі елементи:

data-select-some="chapter1"

Обидва мають однакове значення. Поєднання обох об'єктів даних у межах одного прапорця дозволяє підрівні, які скануються рекурсивно. Тому необхідні дві функції "помічник" для запобігання тригеру змін.



0

Можливо, вимкнено елементи форми HTML - чи не так? Ваші користувачі бачитимуть його в одному з трьох станів, тобто перевіреному, невірно встановленому та відключеному, яке буде сірим та не натисканням. Мені це здається схожим на "null" чи "не застосовується" або все, що ви шукаєте в тому третьому стані.


Дуже гарна ідея, але мені потрібен користувач, щоб він міг натиснути його ще раз. Я побоююся, що у відключеному прапорець у мене виникнуть проблеми із запуском подій тощо.
Pekka

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

Я думаю, що "null" - це означає представляти користувача, який не надає відповіді на питання. Це не обов'язково означає, що питання не застосовується.
bdsl


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.