Jak upewnić się, że pole formularza <select> jest przesyłane, gdy jest wyłączone?

180

Mam selectpole formularza, które chcę oznaczyć jako „tylko do odczytu”, ponieważ użytkownik nie może modyfikować wartości, ale wartość jest nadal przesyłana wraz z formularzem. Użycie tego disabledatrybutu uniemożliwia użytkownikowi zmianę wartości, ale nie przesyła wartości wraz z formularzem.

readonlyAtrybut jest dostępny tylko dla inputi textareapól, ale to w zasadzie to, co chcę. Czy jest jakiś sposób, żeby to zadziałało?

Rozważam dwie możliwości:

  • Zamiast selectwyłączać, wyłącz wszystkie optioni użyj CSS, aby wyszarzyć zaznaczenie, aby wyglądało na wyłączone.
  • Dodaj moduł obsługi zdarzeń kliknięcia do przycisku przesyłania, aby umożliwić włączenie wszystkich wyłączonych menu rozwijanych przed przesłaniem formularza.
Markiz Wang
źródło
2
przepraszam za spóźnienie, jednak rozwiązania dostarczone przez @ trafalmadorianworkest są najlepsze. Wyłącza wszystkie wejścia, które nie są wybrane. Działałoby to również, jeśli zaznaczono, że włączono wiele opcji. $('#toSelect')find(':not(:selected)').prop('disabled',true);
Abhishek Madhani,
Alternatywnie możesz pozostawić kontrolę jako wyłączoną w interfejsie użytkownika, ale odzyskać wartość w metodzie akcji: public ActionResult InsertRecord (model MyType) {if (model.MyProperty == null) {model.MyProperty = Request ["MyProperty"]; }}
beastieboy

Odpowiedzi:

118
<select disabled="disabled">
    ....
</select>
<input type="hidden" name="select_name" value="selected value" />

Gdzie select_namejest nazwa, którą normalnie byś nadał <select>.

Inna opcja.

<select name="myselect" disabled="disabled">
    <option value="myselectedvalue" selected="selected">My Value</option>
    ....
</select>
<input type="hidden" name="myselect" value="myselectedvalue" />

Teraz z tym jednym zauważyłem, że w zależności od używanego serwera WWW może być konieczne wprowadzenie hiddendanych wejściowych przed lub po <select>.

Jeśli moja pamięć służy mi poprawnie, w IIS umieścisz ją wcześniej, w Apache umieścisz ją później. Jak zawsze testowanie jest kluczowe.

Jordan S. Jones
źródło
3
Jak miałoby to zależeć od serwera WWW ? Czy to nie klient renderuje stronę z polem wyboru, a zatem w przypadku takiego konfliktu to klient decyduje, czy wysłać wartość na serwer, czy nie?
Ilari Kajaste
8
Zależy to od tego, jak serwer obsługuje wiele danych wejściowych o tej samej nazwie.
Jordan S. Jones
1
Lepiej nie polegać na konkretnym typie serwera, więc myślę, że pierwsze podejście jest czystsze i mniej podatne na błędy ..
Luke
5
@Jordan: Przeglądarki nie wysyłają wyłączonych wartości pól do serwera, dlatego są one puste, gdy próbujesz obsłużyć je po stronie serwera. Jeśli masz ukryte pole o żądanej wartości, a widoczne pola są wyłączone, tylko pole ukryte zostanie wysłane na serwer. Ergo, ukryte pole powinno zostać utworzone (za pomocą JS lub kodu po stronie serwera) tylko wtedy, gdy widoczne pola są wyłączone i nie ma problemu z priorytetem.
Matt van Andel
1
Jest to opcja tylko wtedy, gdy potrzebujesz formularza działającego bez javascript.
Andrew
224

Wyłącz pola, a następnie włącz je przed przesłaniem formularza:

Kod jQuery:

jQuery(function ($) {        
  $('form').bind('submit', function () {
    $(this).find(':input').prop('disabled', false);
  });
});
Tres
źródło
15
Całkiem niezłe rozwiązanie!
Chris
2
To jest ten, na którym się zdecydowałem, głównie dlatego, że jest najmniej natrętny.
Jonathan
3
Dokumenty jQuery zalecają użycie .prop i .removeProp dla „zaznaczone”, „wybrane” i „wyłączone” zamiast .attr i .removeAttr patrz http://api.jquery.com/prop/
Jim Bergman
2
Odpowiedni fragment komentarza @ JimBergman - „Właściwości ogólnie wpływają na stan dynamiczny elementu DOM bez zmiany serializowanego atrybutu HTML. Przykłady obejmują właściwość value elementów wejściowych, wyłączoną właściwość danych wejściowych i przycisków lub sprawdzoną właściwość pola wyboru. Należy użyć metody .prop (), aby ustawić wyłączone i zaznaczone zamiast metody .attr (). Do uzyskania i ustawienia wartości należy użyć metody .val (). " - z api.jquery.com/prop
Joshua Dance
2
Jesteś genialny (T)
TommyDo
13

Szukałem rozwiązania tego problemu, a ponieważ nie znalazłem rozwiązania w tym wątku, zrobiłem to sam.

// With jQuery
$('#selectbox').focus(function(e) {
    $(this).blur();
});

Proste, po prostu zamazujesz pole, gdy się na nim skupisz, coś w rodzaju wyłączenia, ale w rzeczywistości wysyłasz jego dane.

Jean Paul Rumeau
źródło
Wow Świetne i łatwe rozwiązanie. Dzięki .. +1 ode mnie :)
Naeem Ul Wahhab
Bardzo mi się to podoba ... w zależności od interakcji w mojej formie, elementy stają się włączone / wyłączone back-n-forward ... jak ponownie włączyć „rozmyte” pole w tym scenariuszu?
bkwdesign,
Z googlingu wygląda jak $ ('# selectbox'). Off ('focus'); zrobiłby sztuczkę ponownego włączenia
bkwdesign
2
działa w przypadku pól tekstowych, nie działa w przypadku wybranych pól, a także bardzo łatwo się porusza, klikając i przytrzymując przycisk
Andrew
7

Miałem do czynienia z nieco innym scenariuszem, w którym chciałem tylko nie pozwolić użytkownikowi na zmianę wybranej wartości na podstawie wcześniejszego pola wyboru. Skończyło się to na wyłączeniu wszystkich innych niewybranych opcji w selectbox przy użyciu

$('#toSelect')find(':not(:selected)').attr('disabled','disabled');
trafalmadorian
źródło
Dzięki, znalazłem twój najprostszy logicznie. Jednak attrpowinien się zmienić prop, wyglądałby $('#toSelect')find(':not(:selected)').prop('disabled',true);
mniej więcej
6

To samo rozwiązanie zaproponowane przez Tres bez użycia jQuery

<form onsubmit="document.getElementById('mysel').disabled = false;" action="..." method="GET">

   <select id="mysel" disabled="disabled">....</select>

   <input name="submit" id="submit" type="submit" value="SEND FORM">
</form>

Może to pomóc komuś lepiej zrozumieć, ale oczywiście jest mniej elastyczny niż jQuery.

Marco Demaio
źródło
Ale nie jest to przyjemne dla wielu selektorów. Czy możemy użyć getElementsByTagName('select')?
Lucky
6

nie działa z selektorem: input dla wybranych pól, użyj tego:

    jQuery(function() {

    jQuery('form').bind('submit', function() {
        jQuery(this).find(':disabled').removeAttr('disabled');
    });

    });
chhalpha
źródło
5

Używam następnego kodu do wyłączania opcji w selekcjach

<select class="sel big" id="form_code" name="code" readonly="readonly">
   <option value="user_played_game" selected="true">1 Game</option>
   <option value="coins" disabled="">2 Object</option>
   <option value="event" disabled="">3 Object</option>
   <option value="level" disabled="">4 Object</option>
   <option value="game" disabled="">5 Object</option>
</select>

// Disable selection for options
$('select option:not(:selected)').each(function(){
 $(this).attr('disabled', 'disabled');
});
Aleks
źródło
4

Najprostszym sposobem, jaki znalazłem, było stworzenie małej funkcji javascript powiązanej z twoją formą:

function enablePath() {
    document.getElementById('select_name').disabled= "";
}

i nazywacie to tutaj w formularzu:

<form action="act.php" method="POST" name="form_name" onSubmit="enablePath();">

Lub możesz to wywołać w funkcji, której używasz do sprawdzania formularza :)

Alex PARISOT
źródło
4

Po prostu dodaj wiersz przed przesłaniem.

$ („# XYZ”). RemoveAttr („disabled”);

PPB
źródło
2

Lub użyj JavaScript, aby zmienić nazwę zaznaczenia i ustawić go na wyłączony. W ten sposób zaznaczenie jest nadal przesyłane, ale przy użyciu nazwy, której nie sprawdzasz.

Byron Whitlock
źródło
2

Podniosłem szybką wtyczkę (tylko Jquery), która zapisuje wartość w polu danych, gdy wejście jest wyłączone. Oznacza to tylko, że dopóki pole jest wyłączane programowo poprzez jquery za pomocą .prop () lub .attr () ... to dostęp do wartości przez .val (), .serialize () lub .serializeArra () zawsze zwróci właściwość wartość, nawet jeśli wyłączona :)

Bezwstydna wtyczka: https://github.com/Jezternz/jq-disabled-inputs

Josh Mc
źródło
2

W oparciu o rozwiązanie Jordana stworzyłem funkcję, która automatycznie tworzy ukryte dane wejściowe o tej samej nazwie i tej samej wartości zaznaczenia, które chcesz unieważnić. Pierwszym parametrem może być id lub element jquery; drugi to logiczny parametr opcjonalny, w którym „prawda” wyłącza, a „fałsz” włącza dane wejściowe. Jeśli zostanie pominięty, drugi parametr przełącza wybór pomiędzy „włączony” i „wyłączony”.

function changeSelectUserManipulation(obj, disable){
    var $obj = ( typeof obj === 'string' )? $('#'+obj) : obj;
    disable = disable? !!disable : !$obj.is(':disabled');

    if(disable){
        $obj.prop('disabled', true)
            .after("<input type='hidden' id='select_user_manipulation_hidden_"+$obj.attr('id')+"' name='"+$obj.attr('name')+"' value='"+$obj.val()+"'>");
    }else{
        $obj.prop('disabled', false)
            .next("#select_user_manipulation_hidden_"+$obj.attr('id')).remove();
    }
}

changeSelectUserManipulation("select_id");
Doglas
źródło
parametr „obj” musi być obiektem jquery
Doglas
1

Znalazłem wykonalne rozwiązanie: usuń wszystkie elementy oprócz wybranego. Następnie możesz zmienić styl na coś, co również wygląda na wyłączone. Korzystanie z jQuery:

jQuery(function($) {
    $('form').submit(function(){
        $('select option:not(:selected)', this).remove();
    });
});
Alftheo
źródło
0
<select id="example">
    <option value="">please select</option>
    <option value="0" >one</option>
    <option value="1">two</option>
</select>



if (condition){
    //you can't select
    $("#example").find("option").css("display","none");
}else{
   //you can select
   $("#example").find("option").css("display","block");
}
Thxopen
źródło
-8

Inną opcją jest użycie atrybutu tylko do odczytu.

<select readonly="readonly">
    ....
</select>

W przypadku odczytu tylko wartość jest nadal przesyłana, pole wprowadzania jest wyszarzone i użytkownik nie może go edytować.

Edytować:

Cytat z http://www.w3.org/TR/html401/interact/forms.html#adef-readonly :

  • Elementy tylko do odczytu są aktywowane, ale użytkownik nie może ich modyfikować.
  • Elementy tylko do odczytu są zawarte w nawigacji po kartach.
  • Elementy tylko do odczytu mogą się powieść.

Kiedy mówi, że element może się powieść, oznacza to, że można go przesłać, jak stwierdzono tutaj: http://www.w3.org/TR/html401/interact/forms.html#successful-controls

Phillip Whelan
źródło
6
Formant NIE jest wyszarzony, a użytkownik MOŻE go edytować. Nie przeczytałeś całej sekcji i cytuję: „Następujące elementy obsługują atrybut tylko do odczytu: INPUT i TEXTAREA”.
Carlos Rendon
3
Wiem, że to stara odpowiedź, ale tak naprawdę działa. Nie znam powodu wielu negatywnych opinii.
Ze Luis,