Czy pola wyboru wprowadzają dane tylko wtedy, gdy są zaznaczone?


184

Czy to standardowe zachowanie przeglądarek, aby wysyłać dane wartości wejściowej pola wyboru tylko wtedy, gdy są one sprawdzane po przesłaniu formularza?

A jeśli nie podano danych wartości, czy wartość domyślna jest zawsze „włączona”?

Zakładając, że powyższe jest prawidłowe, czy to spójne zachowanie we wszystkich przeglądarkach?

Odpowiedzi:


187

Tak, standardowe zachowanie oznacza, że ​​wartość jest wysyłana tylko wtedy, gdy pole wyboru jest zaznaczone. Zazwyczaj oznacza to, że musisz mieć sposób na zapamiętanie, jakich pól wyboru oczekujesz po stronie serwera, ponieważ nie wszystkie dane wracają z formularza.

Domyślna wartość jest zawsze „włączona”, powinna być spójna w różnych przeglądarkach.

Jest to opisane w zaleceniu W3C HTML 4 :

Pola wyboru (i przyciski opcji) to przełączniki on / off, które mogą być przełączane przez użytkownika. Przełącznik jest „włączony”, gdy ustawiony jest sprawdzony atrybut elementu sterującego. Po przesłaniu formularza tylko formanty „on” mogą się powieść.


18
Niestety to bolesna prawda, tylko zaznaczone pola wyboru są wysyłane na serwer, a nie odznaczone. Jeśli wiesz z góry, jakie pola wyboru znajdują się na stronie, zarządzanie skryptami po stronie serwera nie stanowi problemu. Problem polega na tym, że nie wiesz tego z góry - dynamicznie tworzone pola wyboru na stronie w zależności od logiki biznesowej. Następnie musisz wykonać sztuczki i użyć równoległych pól ukrytych dla tych pól wyboru i wypełnić je za pomocą JavaScript.
sbrbot

Kluczem do stworzenia spójnego walidatora z „dozwolonymi nieudanymi kontrolami (tj. Type =„ checkbox ”) jest wyznaczenie tych kontrolek formularzy jako przejściowe . Jeśli nie są skuteczne, dynamicznie odpowiednio modyfikuj swój dezynfekator i weryfikator.
Anthony Rutledge

3
Obejście: użyj <select>z dwiema opcjami oni off:-)
andy

83

W HTML każdy <input />element jest powiązany z jedną (ale nie unikalną) parą nazwa i wartość. Ta para jest wysyłana w kolejnym żądaniu (w tym przypadku w treści żądania POST) tylko wtedy, gdy <input />jest „udana”.

Więc jeśli masz te dane wejściowe w swoim <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"                     />

Wygeneruje te pary nazwa + wartość, które zostaną przesłane do serwera:

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

Zauważ, że:

  • twoi sixzostali wykluczeni, ponieważ mieli disabledustawiony atrybut.
  • three został wysłany dwukrotnie, ponieważ miał dwa prawidłowe dane wejściowe o tej samej nazwie.
  • fournie zostało wysłane, ponieważ to checkboxnie byłochecked
  • sixnie został wysłany pomimo tego, checkedże disabledatrybut ma wyższy priorytet.
  • sevennie ma name=""przesłanego atrybutu, więc nie został przesłany.

W odniesieniu do twojego pytania: możesz zobaczyć, że pole wyboru, które nie jest zaznaczone, nie będzie w związku z tym przesyłane do serwera para nazwa-wartość - ale zostaną do niego wysłane inne dane wejściowe o tej samej nazwie.

Frameworki takie jak ASP.NET MVC działają w tym celu (ukradkowo) łącząc każde checkboxwejście z hiddenwejściem w renderowanym HTML, w następujący sposób:

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

Renderuje:

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

Jeśli użytkownik nie zaznaczy pola wyboru, na serwer zostaną wysłane następujące informacje:

SomeBooleanProperty=false

Jeśli użytkownik zaznaczy pole wyboru, oba zostaną wysłane:

SomeBooleanProperty=true
SomeBooleanProperty=false

Ale serwer zignoruje =falsewersję, ponieważ ją widzi =true, a więc jeśli jej nie widzi =true, może stwierdzić, że pole wyboru zostało zrenderowane i że użytkownik go nie sprawdził - w przeciwieństwie do SomeBooleanPropertybraku renderowania danych wejściowych.


Warto zauważyć, że jeśli masz wiele pól, na przykład z dodatkowym ukrytym polem tekstowym, backend otrzyma tablicę wartości.
Salami,

Otrzymuje tablicę tylko, jeśli użyjesz jej []na końcu nazwy wejściowej, domyślnym zachowaniem jest przesłanie tylko ostatniego elementu o tej nazwie, tak długo, jak ukryte dane wejściowe znajdują się przed polem wyboru, będzie działać.
beeglebug

Dzięki posiadaniu dwóch pól o tej samej nazwie (pole ukryte + pole wyboru) i zaznaczeniu pola wyboru wartość wpisu jest ciągiem wartości oddzielonych przecinkami, tj. coś w stylu „0,1”
ʞᴉɯ

1
@beeglebug Opisujesz, jak PHP obsługuje nazwy i wartości, []sufiks nie jest częścią specyfikacji HTML, a przeglądarki nie traktują tego specjalnie. Bez []PHP pozwoli na dostęp tylko do jednej wartości (ostatniej wartości) zamiast wszystkich wartości.
Dai

1
Używanie ukrytej właściwości, zanim pole wyboru działa dla mnie we wszystkich przeglądarkach, które testowałem przy użyciu GET i POST z PHP. Kiedy umieściłem go za kontrolką pola wyboru, zawsze powodowało, że wynik był fałszywy.
adrianwadey,

16

Jeśli pole wyboru nie jest zaznaczone, nie ma wpływu na dane przesyłane przy składaniu formularza.

Sekcja HTML5 4.10.22.4 Konstruowanie zestawu danych formularza opisuje sposób konstruowania danych formularza:

Jeśli którykolwiek z poniższych warunków jest spełniony, pomiń te kroki dla tego elementu: [...]

Element pola jest elementem wejściowym, którego atrybut typu znajduje się w stanie Checkbox i którego sprawdzanie jest fałszywe.

a następnie onokreślana jest wartość domyślna, jeśli jej valuebrakuje:

W przeciwnym razie, jeśli element pola jest elementem wejściowym, którego atrybut type znajduje się w stanie Checkbox lub Radio Button, uruchom następujące zagnieżdżone podetapy:

Jeśli element pola ma określony atrybut wartości, niech wartość będzie wartością tego atrybutu; w przeciwnym razie wartość powinna być ciągiem „on”.

W ten sposób niezaznaczone pola wyboru są pomijane podczas budowy danych formularza.

Podobne zachowanie jest wymagane w HTML4 . Można oczekiwać tego zachowania od wszystkich zgodnych przeglądarek.


10

Pola wyboru wysyłają wartość „on” tylko wtedy, gdy pole wyboru jest zaznaczone. Zaraz po złapaniu wartości pola wyboru możesz użyć ukrytych danych wejściowych

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

Czy to standardowe zachowanie przeglądarek, aby wysyłać dane wartości wejściowej pola wyboru tylko wtedy, gdy są one sprawdzane po przesłaniu formularza?

Tak, ponieważ w przeciwnym razie nie byłoby solidnego sposobu ustalenia, czy pole wyboru zostało faktycznie zaznaczone, czy nie (jeśli zmieniłoby to wartość, może istnieć przypadek, gdy żądana wartość, jeśli została sprawdzona, byłaby taka sama jak ta, którą była zamieniony na).

A jeśli nie podano danych wartości, czy wartość domyślna jest zawsze „włączona”?

Inne odpowiedzi potwierdzają, że „włączone” jest ustawieniem domyślnym. Jeśli jednak nie jesteś zainteresowany tą wartością, po prostu użyj:

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

7

Ze specyfikacji HTML 4, która powinna być spójna w prawie wszystkich przeglądarkach:

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

Pola wyboru (i przyciski opcji) to przełączniki on / off, które mogą być przełączane przez użytkownika. Przełącznik jest „włączony”, gdy ustawiony jest sprawdzony atrybut elementu sterującego. Po przesłaniu formularza tylko formanty „on” mogą się powieść.

Sukces definiuje się następująco:

Pomyślna kontrola jest „ważna” do złożenia. Każda udana kontrola ma powiązaną nazwę z bieżącą wartością jako część zestawu danych przesłanych formularzy. Pomyślna kontrola musi być zdefiniowana w elemencie FORM i musi mieć nazwę kontrolną.


5

typ wejścia = „ukryty” nazwa = „is_main” wartość = „0”

typ wejścia = „pole wyboru” nazwa = „is_main” wartość = „1”

więc możesz kontrolować tak jak ja w aplikacji. jeśli sprawdzi, wyślij wartość 1 w przeciwnym razie 0


3

Żadna z powyższych odpowiedzi mnie nie zadowoliła. Odkryłem, że najlepszym rozwiązaniem jest włączenie ukrytego wejścia przed każdym wejściem pola wyboru o tej samej nazwie.

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

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

Następnie po stronie serwera, używając małego algorytmu, możesz uzyskać coś więcej niż HTML powinien zapewnić.

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

To będzie surowe wejście

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

Funkcja powróci

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

1

Mam stronę (formularz), która dynamicznie generuje pole wyboru, więc te odpowiedzi były bardzo pomocne. Moje rozwiązanie jest bardzo podobne do wielu tutaj, ale nie mogę przestać myśleć, że łatwiej jest je wdrożyć.

Najpierw ustawiam ukryte pole wprowadzania zgodnie z moim polem wyboru, tj

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

Teraz, jeśli wszystkie checkboxeszostaną odznaczone, wartości zwrócone przez ukryte pole zostaną wyłączone.

Na przykład tutaj, z pięcioma dynamicznie wstawionymi polami wyboru, tworzą POSTSnastępujące wartości:

  '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)

To pokazuje, że tylko trzecie i czwarte pole wyboru to onlub checked.

Zasadniczo lub ukryte pole wejściowe wskazuje po prostu, że wszystko jest wyłączone, chyba że pod indeksem wyłączenia znajduje się „on” , co daje indeks, którego potrzebujesz bez jednego wiersza kodu po stronie klienta.

.


0

Podobnie jak wariant ASP.NET, z tym wyjątkiem, że ukryte dane wejściowe o tej samej nazwie znajdują się przed rzeczywistym polem wyboru (o tej samej nazwie). Zostaną wysłane tylko ostatnie wartości. W ten sposób, jeśli pole jest zaznaczone, wówczas wysyłana jest jego nazwa i wartość „on”, natomiast jeśli nie jest zaznaczone, nazwa odpowiedniego ukrytego wejścia i dowolna wartość, jaką chcesz mu nadać, zostanie wysłana. Na koniec dostaniesz tablicę $ _POST do odczytu, ze wszystkimi zaznaczonymi i niezaznaczonymi elementami, wartościami „on” i „false”, bez duplikatów kluczy. Łatwy do przetworzenia w PHP.


0

Mając ten sam problem z niezaznaczonymi polami wyboru, które nie będą wysyłane przy przesyłaniu formularzy, wyszedłem z innym rozwiązaniem niż dublowanie elementów pola wyboru.

Pobieranie wszystkich niezaznaczonych pól wyboru z

var checkboxQueryString;

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

-2

Rozwiązałem problem z tym kodem:

Formularz HTML

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

i funkcję javascript, zmieniając formularz wartości pola wyboru:

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

a serwer sprawdził, czy wpis danych jest „włączony” czy „wyłączony”. Użyłem Playframework 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));
        }
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.