Чи вводить прапорець лише ті дані, якщо вони встановлені?


184

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

І якщо дані про значення не надаються, чи завжди значення за замовчуванням "увімкнено"?

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

Відповіді:


187

Так, стандартна поведінка - це значення, яке надсилається лише у тому випадку, якщо прапорець встановлений. Зазвичай це означає, що вам потрібно мати спосіб запам'ятати, які прапорці ви очікуєте на стороні сервера, оскільки не всі дані повертаються з форми.

Значення за замовчуванням завжди "увімкнено", це повинно відповідати веб-переглядачам.

Це стосується рекомендації W3C HTML 4 :

Поле прапорців (і радіо кнопки) - це перемикачі вмикання / вимикання, які користувач може перемикати. Перемикач "включений", коли встановлений перевірений атрибут елемента керування. При надсиланні форми, лише "on" елементи керування можуть стати успішними.


18
На жаль, це болісна правда, на сервер надсилаються лише встановлені прапорці, а не відмічені. Якщо ви заздалегідь знаєте, які прапорці знаходяться на сторінці, то керувати ними на серверній скрипті не проблема. Проблема полягає в тому, що ви цього не знаєте заздалегідь - динамічно створюються прапорці на сторінці залежно від певної логіки бізнесу. Тоді вам доведеться робити хитрощі та використовувати паралельні приховані поля введення для цих прапорців і виконувати їх за допомогою JavaScript.
sbrbot

Ключ до створення послідовного валідатора з "дозволеними невдалими елементами управління (тобто type =" checkbox ") полягає в призначенні цих елементів керування форми як перехідних . Коли вони не мають успіху, динамічно змініть ваш дезіннізатор і валідатор відповідно
Anthony Rutledge

3
Вирішення проблеми: використовувати <select>два варіанти onта off:-)
Енді

83

У HTML кожен <input />елемент асоціюється з одним (але не унікальним) іменем і цінністю пари. Ця пара надсилається у наступному запиті (у цьому випадку орган запиту POST), лише якщо <input />"успішна".

Отже, якщо ви маєте ці дані у своєму <form>DOM:

<input type="text"     name="one"   value="foo"                        />
<input type="text"     name="two"   value="bar"    disabled="disabled" />
<input type="text"     name="three" value="first"                      />
<input type="text"     name="three" value="second"                     />

<input type="checkbox" name="four"  value="baz"                        />
<input type="checkbox" name="five"  value="baz"    checked="checked"   />
<input type="checkbox" name="six"   value="qux"    checked="checked" disabled="disabled" />
<input type="checkbox" name=""      value="seven"  checked="checked"   />

<input type="radio"    name="eight" value="corge"                      />
<input type="radio"    name="eight" value="grault" checked="checked"   />
<input type="radio"    name="eight" value="garply"                     />

Згенерує ці пари + name + value, які будуть надіслані на сервер:

one=foo
three=first
three=second
five=baz
eight=grault

Зауважте, що:

  • twoі sixбули виключені, оскільки вони мали disabledнабір атрибутів.
  • three був надісланий двічі, оскільки він мав два дійсних введення з однаковою назвою.
  • fourне було надіслано, тому що це таке, checkboxщо не булоchecked
  • sixне було надіслано, незважаючи на те, checkedщо disabledатрибут має вищий пріоритет.
  • sevenне name=""надісланий атрибут, тому він не подається.

Що стосується вашого запитання: ви можете бачити, що прапорець, який не встановлений, не матиме імені + пара значень, надісланий серверу, але з ним будуть надіслані інші входи, які мають те саме ім'я.

Такі рамки, як ASP.NET MVC, обробляють це шляхом (приховано) з'єднання кожного checkboxвходу з hiddenвходом у виведений HTML, наприклад:

@Html.CheckBoxFor( m => m.SomeBooleanProperty )

Візуалізації:

<input type="checkbox" name="SomeBooleanProperty" value="true" />
<input type="hidden"   name="SomeBooleanProperty" value="false" />

Якщо користувач не встановив прапорець, на сервер буде надіслано наступне:

SomeBooleanProperty=false

Якщо користувач перевірить прапорець, то обидва будуть надіслані:

SomeBooleanProperty=true
SomeBooleanProperty=false

Але сервер буде ігнорувати =falseверсію, тому що вона бачить =trueверсію, і тому, якщо вона не бачить, =trueвона може визначити, що прапорець було надано і що користувач не перевірив його - на відміну від того, що SomeBooleanPropertyвходи взагалі не надаються.


Варто зауважити, що якщо у вас є кілька полів, наприклад, із додатковим прихованим текстовим полем, тоді бекенд отримає масив значень.
Саламі

Він отримує масив лише в тому випадку, якщо ви використовуєте []в кінці імені введення, поведінка за замовчуванням полягає лише в тому, щоб подати останній елемент з цим ім'ям, так що, поки прихований вхід знаходиться перед прапорцем, він буде працювати.
beeglebug

Маючи два поля з однаковим іменем (приховане поле + поле прапорець) та встановивши прапорець, значення пошти - це розділений комою рядок значень, тобто. щось на кшталт "0,1"
ʞᴉɯ

1
@beeglebug Те, що ви описуєте, це те, як PHP обробляє імена та значення, []суфікс не входить до специфікації HTML, і браузери не ставляться до цього спеціально. Без []PHP дозволять отримати доступ лише до одного значення (останнього значення) замість усіх значень.
Дай

1
Використання прихованого властивості перед тим, як прапорець працює для мене у всіх браузерах, які я перевірив, використовуючи GET та POST з PHP. Коли я розмістив її після керування, завжди результат відображався помилковим.
adrianwadey

16

Якщо прапорець не встановлений, він не сприяє передачі даних при надсиланні форми.

Розділ HTML5 4.10.22.4 Побудова набору даних форми описує спосіб побудови даних форми:

Якщо виконується будь-яка з наведених нижче умов, пропустіть ці підзаготівки для цього елемента: [...]

Елемент поля - це вхідний елемент, атрибут типу якого знаходиться у стані прапорця і чия перевірка помилкова.

а потім визначається значення за замовчуванням on, якщо valueйого немає:

В іншому випадку, якщо елемент поля є вхідним елементом, атрибут типу якого знаходиться у стані прапорця або стан радіо кнопки, тоді запустіть ці додаткові вкладені підкрокавки:

Якщо елемент поля має вказаний атрибут значення, то нехай значення буде значенням цього атрибута; в іншому випадку нехай значенням є рядок "on".

Таким чином, невірно встановлені прапорці пропускаються під час створення даних форми.

Аналогічна поведінка потрібна в HTML4 . Доцільно очікувати такої поведінки від усіх сумісних браузерів.


10

Поле прапорців розміщує значення "увімкнено", якщо і тільки якщо прапорець встановлений. Незважаючи на введення значення прапорця, ви можете використовувати приховані введення

JS :

var chk = $('input[type="checkbox"]');
    chk.each(function(){
        var v = $(this).attr('checked') == 'checked'?1:0;
        $(this).after('<input type="hidden" name="'+$(this).attr('rel')+'" value="'+v+'" />');
    });

chk.change(function(){ 
        var v = $(this).is(':checked')?1:0;
        $(this).next('input[type="hidden"]').val(v);
    });

HTML :

<label>Active</label><input rel="active" type="checkbox" />

8

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

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

І якщо дані про значення не надаються, чи завжди значення за замовчуванням "увімкнено"?

Інші відповіді підтверджують, що "увімкнено" є типовим. Однак якщо цінність вас не цікавить, просто використовуйте:

if (isset($_POST['the_checkbox'])){
    // name="the_checkbox" is checked
}

7

Від специфікації HTML 4, яка має відповідати майже всім браузерам:

http://www.w3.org/TR/html401/interact/forms.html#checkbox

Поле прапорців (і радіо кнопки) - це перемикачі вмикання / вимикання, які користувач може перемикати. Перемикач "включений", коли встановлений перевірений атрибут елемента керування. При надсиланні форми, лише "on" елементи керування можуть стати успішними.

Успішне визначається наступним чином:

Успішний контроль є "дійсним" для подання. Кожен успішний елемент керування має ім'я контролю, сполучене з його поточним значенням як частина поданого набору даних форми. Успішний елемент керування повинен бути визначений в елементі FORM і повинен мати ім'я керування.


5

type type = "приховано" name = "is_main" value = "0"

type type = "checkbox" name = "is_main" value = "1"

тож ви можете керувати так, як я робив у додатку. якщо він перевіряє, то відправте значення 1, інакше 0


3

Жодна з наведених відповідей мене не влаштовувала. Я знайшов найкраще рішення - включити прихований вхід перед кожним входом прапорця з тим самим іменем.

<input type="hidden" name="foo[]" value="off"/>

<input type="checkbox" name="foo[]"/>

Потім на стороні сервера, використовуючи невеликий алгоритм, ви можете отримати щось більше, на зразок HTML.

function checkboxHack(array $checkbox_input): array
{
    $foo = [];
    foreach($checkbox_input as $value) {
        if($value === 'on') {
            array_pop($foo);
        }
        $foo[] = $value;
    }
    return $foo;
}

Це буде вихідний внесок

array (
    0 => 'off',
    1 => 'on',
    2 => 'off',
    3 => 'off',
    4 => 'on',
    5 => 'off',
    6 => 'on',
),

І функція повернеться

array (
    0 => 'on',
    1 => 'off',
    2 => 'on',
    3 => 'on',
)  

1

У мене є сторінка (форма), яка динамічно генерує прапорець, тому ці відповіді були чудовою допомогою. Моє рішення дуже схоже на багатьох тут, але я не можу не думати, що це легше здійснити.

Спочатку я ставлю приховане поле введення у відповідність зі своїм прапором, тобто

 <td><input class = "chkhide" type="hidden" name="delete_milestone[]" value="off"/><input type="checkbox" name="delete_milestone[]"   class="chk_milestone" ></td>

Тепер, якщо всі checkboxesзнаки не вибрані, значення, повернені прихованим полем, усі будуть вимкнені.

Наприклад, тут з п'ятьма динамічно вставленими прапорцями формують POSTSтакі значення:

  'delete_milestone' => 
array (size=7)
  0 => string 'off' (length=3)
  1 => string 'off' (length=3)
  2 => string 'off' (length=3)
  3 => string 'on' (length=2)
  4 => string 'off' (length=3)
  5 => string 'on' (length=2)
  6 => string 'off' (length=3)

Це показує, що лише 3-й та 4-й прапорці є onабо checked.

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

.


0

Так само, як і варіант ASP.NET, за винятком того, що слід поставити прихований вхід з тим самим іменем перед фактичним прапорцем (з тим самим іменем). Буде надіслано лише останні значення. Таким чином, якщо прапорець позначено, його ім'я та значення "увімкнено" буде надіслано, тоді як якщо це не встановлено, то буде надіслано ім'я відповідного прихованого вводу та будь-яке значення, яке ви хочете надати. Зрештою, ви отримаєте масив $ _POST для читання, з усіма перевіреними та неперевіреними елементами в ньому значеннями "on" та "false", без повторних ключів. Легко обробляти в PHP.


0

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

Отримання всіх відмічених прапорців за допомогою

var checkboxQueryString;

$form.find ("input[type=\"checkbox\"]:not( \":checked\")" ).each(function( i, e ) {
  checkboxQueryString += "&" + $( e ).attr( "name" ) + "=N"
});

-2

Я вирішив проблему з цим кодом:

Форма HTML

<input type="checkbox" id="is-business" name="is-business" value="off" onclick="changeValueCheckbox(this)" >
<label for="is-business">Soy empresa</label>

і функцію javascript, змінивши форму значень прапорця:

//change value of checkbox element
function changeValueCheckbox(element){
   if(element.checked){
    element.value='on';
  }else{
    element.value='off';
  }
}

і сервер перевіряв, чи повідомлення "ввімкнено" чи "вимкнено". Я використовував javaframework java

        final Map<String, String[]> data = request().body().asFormUrlEncoded();

        if (data.get("is-business")[0].equals('on')) {
            login.setType(new MasterValue(Login.BUSINESS_TYPE));
        } else {
            login.setType(new MasterValue(Login.USER_TYPE));
        }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.