Dlaczego przyciski radiowe nie mogą być „tylko do odczytu”?

213

Chciałbym wyświetlić przycisk opcji, podać jego wartość, ale w zależności od okoliczności, nie można go edytować. Wyłączone nie działa, ponieważ nie przesyła wartości (czy robi to?) I wyszarza przycisk opcji. Tylko do odczytu jest naprawdę tym, czego szukam, ale z jakiegoś tajemniczego powodu nie działa.

Czy jest jakaś dziwna sztuczka, którą muszę wyciągnąć, aby tylko do odczytu działała zgodnie z oczekiwaniami? Czy zamiast tego powinienem to zrobić w JavaScript?

Nawiasem mówiąc, czy ktoś wie, dlaczego tylko do odczytu nie działa w przyciskach opcji, podczas gdy działa w innych znacznikach wejściowych? Czy to jedno z niezrozumiałych pominięć w specyfikacjach HTML?

Mcv
źródło
5
„Czy to jedno z niezrozumiałych pominięć w specyfikacjach HTML?” Pomyśl o tym z punktu widzenia użytkownika. Po co wyświetlać przycisk, którego nie mogą kliknąć?
Paul D. Waite,
67
Po co wyświetlać przycisk, którego nie mogą kliknąć? Ponieważ chcę, aby wiedzieli, że przycisk jest dostępny, ale nie chcę, aby mogli go teraz kliknąć. Ale może później. W końcu jest to forma dynamiczna. Dlaczego przycisk radiowy miałby się różnić od jakiegokolwiek innego pola wprowadzania?
mcv,
7
Oto specyfikacja: w3.org/TR/html401/interact/forms.html#h-17.12.2 „Następujące elementy obsługują atrybut tylko do odczytu: INPUT i TEXTAREA.” Co oczywiście jest złe. Wracamy tutaj jednak dokładniejsze podsumowanie: w3.org/TR/WD-forms-970402#readonly „TYLKO dotyczy elementów WEJŚCIA typu TEKST lub HASŁO oraz elementu TEXTAREA”. Wygląda na to, że wymknęło się to między lukami specyfikacji i specyfikacji.
graphicdivine
Jeszcze bardziej ciekawy. Według tego starożytnego dokumentu „Na przykład w polach wyboru możesz je zaznaczyć lub wyłączyć (ustawiając w ten sposób stan SPRAWDZONY), ale nie zmieniasz wartości pola”. ( htmlcodetutorial.com/forms/_INPUT_DISABLED.html ) Czy to prawda? Czy ustawienie TYLKO na pole wyboru / radio blokuje wartość, nawet jeśli użytkownik może ją zmienić?
graphicdivine
sprawdź mój post [tutaj] [1] daje czyste, proste rozwiązanie problemu [1]: stackoverflow.com/a/15513256/1861389
Driv4ward

Odpowiedzi:

149

Sfałszowałem tylko do odczytu przycisk opcji, wyłączając tylko niezaznaczone przyciski opcji. Uniemożliwia to użytkownikowi wybranie innej wartości, a sprawdzona wartość zawsze będzie wysyłana po przesłaniu.

Używanie jQuery do odczytu:

$(':radio:not(:checked)').attr('disabled', true);

Podejście to działało również w przypadku tworzenia listy wyboru tylko do odczytu, z tym wyjątkiem, że musisz wyłączyć każdą niewybraną opcję.

Megan
źródło
2
Dzięki @Megan, to świetne rozwiązanie
Michael La Voie
9
Odmiana tego, aby umożliwić ci korzystanie z readonlynieruchomości, ponieważ OP spodziewał się, że zadziała:$(':radio[readonly]:not(:checked)').attr('disabled', true);
wodow
1
Spośród poniższych rozwiązań to rozwiązanie zapewnia najczystszy kod i działa dobrze z walidatorem Jquery, ponieważ nie muszę włączać / wyłączać pól ani zajmować się rozłączaniem zdarzeń kliknięcia i ponownym wiązaniem ich podczas przesyłania formularza.
Kristianne Nerona
Działa dokładnie Dzięki
Hassan Farooq
Sprytny! Używając .not (..), jeśli masz już zestaw wybranych pól wejściowych: var myRadios = $ ('# specific-radios'); myRadios.not (': selected'). prop ('disabled', true); api.jquery.com/not
JoePC
206

Przyciski opcji będą musiały być tylko do odczytu, jeśli istnieją inne opcje. Jeśli nie masz żadnych innych opcji, zaznaczonego przycisku opcji nie można odznaczyć. Jeśli masz inne opcje, możesz uniemożliwić użytkownikowi zmianę wartości poprzez wyłączenie innych opcji:

<input type="radio" name="foo" value="Y" checked>
<input type="radio" name="foo" value="N" disabled>

Fiddle: http://jsfiddle.net/qqVGu/

Sampson
źródło
3
Problem z twoim pierwszym rozwiązaniem polega na tym, że jeśli chcę włączyć przycisk radiowy za pomocą javascript, nagle mam dwa pola o tej samej nazwie, więc muszę wyczyścić jedno z nich. Lub użyj ukrytego do realnego, a przycisk radiowy po prostu ustaw wartość ukrytego pola. Eter, to trochę bardziej kłopotliwe niż chciałbym mieć przycisk radiowy. Twoje drugie rozwiązanie, choć nie wątpię, że działa, brzmi jak naprawdę brzydki hack. Sądzę więc, że rozwiązanie javascript jest jedynym, które spełnia moje kryteria. Pójdę z tym.
mcv,
7
Rozwiązanie 1, proszę! To jedyny właściwie dostępny. A jeśli musisz go napisać, to tylko jedna linia ustawia włączanie ukrytego pola na przeciwne do włączania radia.
bobince
5
Właśnie zauważyłem, że rozwiązania 2 i 3 zmieniły miejsca w odpowiedzi Jonathana, więc teraz komentarze nie wydają się mieć większego sensu.
mcv
1
Chcesz zauważyć, że JavaScript nie działa, po prostu odznacza przycisk. Przypuszczam, że trzeba onclick="return false"zapobiegać zmianom.
dmitry
2
Kiedy ustawiam „wyłączone” radio, dodaję „style = kursor: domyślny”, aby usunąć „wyłączony kursor”.
Joao Paulo
24

To jest sztuczka, którą możesz zastosować.

<input type="radio" name="name" onclick="this.checked = false;" />
Sarfraz
źródło
4
Dokładnie to, o czym myślałem, ale najlepiej byłoby, gdybyś wyjaśnił, że powinno to być onClick="this.checked = <%=value%>"jakieś odmiany :)
JustLoren,
to dobrze wiedzieć. zaznaczone może mieć wartość true lub false.
Sarfraz
Tylko ostrzeżenie, że to nie zadziała dla tych z nas, którzy przeglądają z włączonym javascript.
tloach
3
Nie ma problemu w mojej sprawie. Używamy już ton jQuery i Ajax.
mcv,
1
Warto zauważyć, że możesz po prostu zrobić, onclick="return false;"aby utrzymać tę samą wartość dla grupy
Zach
12

Mam długi formularz (ponad 250 pól), który wysyła posty do bazy danych. Jest to internetowy wniosek o zatrudnienie. Gdy administrator idzie do aplikacji, która została złożona, formularz jest wypełniany danymi z bazy danych. Teksty wejściowe i obszary tekstowe są zastępowane tekstem, który przesłały, ale radia i pola wyboru są przydatne jako elementy formularza. Wyłączenie ich utrudnia czytanie. Ustawienie właściwości .checked na false przy kliknięciu nie będzie działać, ponieważ mogły zostać sprawdzone przez użytkownika wypełniającego aplikację. W każdym razie...

onclick="return false;"

działa jak urok dla „wyłączających” radiotelefonów i pól wyboru ipso facto.

humbolight
źródło
8

Najlepszym rozwiązaniem jest ustawienie stanu zaznaczonego lub niezaznaczonego (z poziomu klienta lub serwera) i niedopuszczenie, aby użytkownik zmienił go po totemach (tj. Uczynił to tylko do odczytu):

<input type="radio" name="name" onclick="javascript: return false;" />
Vipresh
źródło
Nie! w takim przypadku użytkownik może edytować HTML w przeglądarce, zaznaczyć potrzebną opcję jako wybraną i opublikować formularz.
błąd1009
2

Wymyśliłem sposób na javascript, aby osiągnąć stan tylko do odczytu dla pól wyboru i przycisków opcji. Jest testowany z bieżącymi wersjami Firefox, Opera, Safari, Google Chrome, a także z bieżącymi i poprzednimi wersjami IE (do IE7).

Dlaczego po prostu nie skorzystasz z właściwości niepełnosprawnych, o którą pytasz? Podczas drukowania strony wyłączone elementy wejściowe są wyświetlane w szarym kolorze. Klient, dla którego zostało to wdrożone, chciał, aby wszystkie elementy miały ten sam kolor.

Nie jestem pewien, czy wolno mi opublikować kod źródłowy tutaj, ponieważ opracowałem go podczas pracy dla firmy, ale z pewnością mogę podzielić się koncepcjami.

W przypadku zdarzeń onmousedown możesz odczytać stan zaznaczenia, zanim zmieni go działanie kliknięcia. Więc przechowujesz te informacje, a następnie przywracasz te stany za pomocą zdarzenia onclick.

<input id="r1" type="radio" name="group1" value="r1" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);" checked="checked">Option 1</input>
<input id="r2" type="radio" name="group1" value="r2" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);">Option 2</input>
<input id="r3" type="radio" name="group1" value="r3" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);">Option 3</input>

<input id="c1" type="checkbox" name="group2" value="c1" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);" checked="checked">Option 1</input>
<input id="c2" type="checkbox" name="group2" value="c2" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);">Option 2</input>
<input id="c3" type="checkbox" name="group2" value="c3" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);" checked="checked">Option 3</input>

Część javascript będzie działać w ten sposób (ponownie tylko pojęcia):

var selectionStore = new Object();  // keep the currently selected items' ids in a store

function storeSelectedRadiosForThisGroup(elementName) {
    // get all the elements for this group
    var radioOrSelectGroup = document.getElementsByName(elementName);

    // iterate over the group to find the selected values and store the selected ids in the selectionStore
    // ((radioOrSelectGroup[i].checked == true) tells you that)
    // remember checkbox groups can have multiple checked items, so you you might need an array for the ids
    ...
}

function setSelectedStateForEachElementOfThisGroup(elementName) {
    // iterate over the group and set the elements checked property to true/false, depending on whether their id is in the selectionStore
    ...

    // make sure you return false here
    return false;
}

Możesz teraz włączyć / wyłączyć przyciski opcji / pola wyboru, zmieniając właściwości onclick i onmousedown elementów wejściowych.

Tomek
źródło
2

W przypadku niewybranych przycisków opcji oflaguj je jako wyłączone. Zapobiega to reagowaniu na dane wprowadzone przez użytkownika i usuwaniu zaznaczonego przycisku opcji. Na przykład:

<input type="radio" name="var" checked="yes" value="Yes"></input>
<input type="radio" name="var" disabled="yes" value="No"></input>
dpolican
źródło
4
checked="yes"? Co to za specyfikacja? Użyj checked="checked"albo po prostu atrybut checkedbez wartości. To samo dotyczy disabled.
Robin van Baalen
2

Sposób JavaScript - to zadziałało dla mnie.

<script>
$(document).ready(function() {
   $('#YourTableId').find('*').each(function () { $(this).attr("disabled", true); });
});
</script>

Powód:

  1. $('#YourTableId').find('*') -> zwraca wszystkie tagi.

  2. $('#YourTableId').find('*').each(function () { $(this).attr("disabled", true); }); iteruje wszystkie przechwycone obiekty i wyłącza znaczniki wejściowe.

Analiza (debugowanie):

  1. form:radiobutton jest wewnętrznie uważany za tag „wejściowy”.

  2. Podobnie jak w powyższej funkcji (), jeśli spróbujesz wydrukować document.write(this.tagName);

  3. Gdziekolwiek w tagach znajduje przyciski radiowe, zwraca tag wejściowy.

Tak więc powyższą linię kodu można bardziej zoptymalizować dla tagów przycisków opcji, zastępując * wejściem: $('#YourTableId').find('input').each(function () { $(this).attr("disabled", true); });

użytkownik3702798
źródło
1

Dość prostą opcją byłoby utworzenie funkcji javascript wywoływanej w zdarzeniu „onsubmit” formularza, aby umożliwić powrót przycisku radiowego, aby jego wartość była księgowana wraz z resztą formularza.
Wydaje się, że nie jest to pominięcie w specyfikacji HTML, ale wybór projektu (logiczny, IMHO), przycisk radiowy nie może być odczytany tylko jako przycisk, nie może być, jeśli nie chcesz go użyć, to wyłącz to.

Wintermute
źródło
1

Odkryłem, że użycie onclick='this.checked = false;'działało do pewnego stopnia. Kliknięty przycisk opcji nie zostanie wybrany. Jeśli jednak był już wybrany przycisk opcji (np. Wartość domyślna), ten przycisk opcji nie byłby zaznaczony.

<!-- didn't completely work -->
<input type="radio" name="r1" id="r1" value="N" checked="checked" onclick='this.checked = false;'>N</input>
<input type="radio" name="r1" id="r1" value="Y" onclick='this.checked = false;'>Y</input>

W tym scenariuszu pozostawienie wartości domyślnej w spokoju i wyłączenie innych przycisków opcji zachowuje już wybrany przycisk opcji i zapobiega jego odznaczeniu.

<!-- preserves pre-selected value -->
<input type="radio" name="r1" id="r1" value="N" checked="checked">N</input>
<input type="radio" name="r1" id="r1" value="Y" disabled>Y</input>

To rozwiązanie nie jest najbardziej eleganckim sposobem zapobiegania zmianie wartości domyślnej, ale zadziała bez względu na to, czy włączono javascript.

JW8
źródło
1

Wypróbuj ten atrybut disabled, ale myślę, że nie dostaniesz wartości przycisków opcji. Lub ustaw obrazy zamiast:

<img src="itischecked.gif" alt="[x]" />radio button option

Z poważaniem.

Tim
źródło
1
och, mój kod HTML został usunięty: img src = "itIsChecked.gif" alt = "[x]" OptionChecked
Tim
0

Korzystam z wtyczki JS, która stylizuje pola wyboru / elementy wejściowe radia i użyłem następującego jQuery, aby ustalić „stan tylko do odczytu”, w którym podstawowa wartość jest nadal księgowana, ale element wejściowy wydaje się niedostępny dla użytkownika, co jest moim zdaniem zamierzonym powodem użylibyśmy atrybutu wejściowego tylko do odczytu ...

if ($(node).prop('readonly')) {
    $(node).parent('div').addClass('disabled'); // just styling, appears greyed out
    $(node).on('click', function (e) {
        e.preventDefault();
    });
}
chopstik
źródło