it-swarm.com.de

HTML-Formular nur mit SELECT-Tag/Eingabe

Gemäß den HTML-Spezifikationen verfügt das select-Tag in HTML nicht über ein readonly-Attribut, sondern nur über ein disabled-Attribut. Wenn Sie also verhindern möchten, dass der Benutzer die Dropdown-Liste ändert, müssen Sie disabled verwenden.

Das einzige Problem ist, dass deaktivierte HTML-Formulareingaben nicht in den POST/GET-Daten enthalten sind.

Was ist der beste Weg, das readonly-Attribut für ein select-Tag zu emulieren und trotzdem die POST -Daten abzurufen?

482
Jrgns

Sie sollten das select-Element disabled beibehalten, aber auch eine weitere versteckte input mit demselben Namen und Wert hinzufügen.

Wenn Sie SELECT erneut aktivieren, sollten Sie dessen Wert in einem Onchange-Ereignis in die ausgeblendete Eingabe kopieren und die ausgeblendete Eingabe deaktivieren (oder entfernen).

Hier ist eine Demo:

$('#mainform').submit(function() {
    $('#formdata_container').show();
    $('#formdata').html($(this).serialize());
    return false;
});

$('#enableselect').click(function() {
    $('#mainform input[name=animal]')
        .attr("disabled", true);
    
    $('#animal-select')
        .attr('disabled', false)
    	.attr('name', 'animal');
    
    $('#enableselect').hide();
    return false;
});
#formdata_container {
    padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
    <form id="mainform">
        <select id="animal-select" disabled="true">
            <option value="cat" selected>Cat</option>
            <option value="dog">Dog</option>
            <option value="hamster">Hamster</option>
        </select>
        <input type="hidden" name="animal" value="cat"/>
        <button id="enableselect">Enable</button>
        
        <select name="color">
            <option value="blue" selected>Blue</option>
            <option value="green">Green</option>
            <option value="red">Red</option>
        </select>

        <input type="submit"/>
    </form>
</div>

<div id="formdata_container" style="display:none">
    <div>Submitted data:</div>
    <div id="formdata">
    </div>
</div>

405
bezmax

Wir könnten das auch gebrauchen 

Alle außer der ausgewählten Option deaktivieren:

<select>
    <option disabled>1</option>
    <option selected>2</option>
    <option disabled>3</option>
</select>

Auf diese Weise funktioniert das Dropdown-Menü weiterhin (und übermittelt seinen Wert), der Benutzer kann jedoch keinen anderen Wert auswählen.

Demo

142
vimal1083

Sie können das Auswahlobjekt beim Senden erneut aktivieren.

EDIT: d. h. Normalerweise wird das select-Tag (mit dem deaktivierten Attribut) normalerweise deaktiviert und dann automatisch wieder aktiviert, bevor das Formular gesendet wird:

Beispiel mit jQuery:

  • So deaktivieren Sie es:

    $('#yourSelect').prop('disabled', true);
    
  • Um es vor der Übermittlung erneut zu aktivieren, so dass GET/POST -Daten enthalten sind:

    $('#yourForm').on('submit', function() {
        $('#yourSelect').prop('disabled', false);
    });
    

Darüber hinaus können Sie jeden deaktivierten Eingang erneut aktivieren oder auswählen:

$('#yourForm').on('submit', function() {
    $('input, select').prop('disabled', false);
});
98
kemiller2002

eine andere Möglichkeit, ein readOnly-Attribut für ein select-Element auszuführen, ist die Verwendung von css.

du könntest gerne machen:

$('#selection').css('pointer-events','none');

DEMO

46
Yaje
<select id="countries" onfocus="this.defaultIndex=this.selectedIndex;" onchange="this.selectedIndex=this.defaultIndex;">
<option value="1">Country1</option>
<option value="2">Country2</option>
<option value="3">Country3</option>
<option value="4">Country4</option>
<option value="5">Country5</option>
<option value="6">Country6</option>
<option value="7" selected="selected">Country7</option>
<option value="8">Country8</option>
<option value="9">Country9</option>
</select>

Getestet und getestet in IE 6, 7 & 8b2, Firefox 2 & 3, Opera 9.62, Safari 3.2.1 für Windows und Google Chrome.

38
Grant Wagner

Einfache jQuery-Lösung

Verwenden Sie dies, wenn Ihre Auswahl die readonly-Klasse hat

jQuery('select.readonly option:not(:selected)').attr('disabled',true);

Oder dies, wenn Ihre Auswahl das readonly="readonly"-Attribut hat

$('select[readonly="readonly"] option:not(:selected)').attr('disabled',true);
31

Einfache CSS-Lösung:

select[readonly]{
    background: #eee;
    cursor:no-drop;
}

select[readonly] option{
    display:none;
}

Dies führt dazu, dass Select mit grauem "Deaktivieren" des Cursors im Hover angezeigt wird
und bei Auswahl ist die Liste der Optionen "leer", sodass Sie ihren Wert nicht ändern können.

19
d.raev

Eine weitere zeitgemäßere Option (kein Wortspiel beabsichtigt) ist das Deaktivieren aller anderen Optionen des Auswahlelements als des ausgewählten Elements. 

beachten Sie jedoch, dass dies eine HTML 4.0-Funktion ist .__ und 6,7,8 Beta 1 scheint dies nicht zu beachten.

http://www.gtalbot.org/BrowserBugsSection/MSIE7Bugs/OptionDisabledSupport.html

12
epeleg

Dies ist die beste Lösung, die ich gefunden habe:

$("#YourSELECTIdHere option:not(:selected)").prop("disabled", true);

Der Code überdeaktiviertalle anderen Optionen nicht ausgewählt, während die ausgewählte Option aktiviert bleibt. Dadurch wird die ausgewählte Option zu den Post-Back-Daten.

9

Noch einfacher: Füge das style-Attribut zu deinem select tag hinzu:

style="pointer-events: none;"
7

Ich weiß, dass es viel zu spät ist, aber es kann mit einfachem CSS ausgeführt werden:

select[readonly] option, select[readonly] optgroup {
    display: none;
}

Der Stil blendet alle Optionen und Gruppen aus, wenn sich select im Status readonly befindet, sodass der Benutzer seine Auswahl nicht ändern kann.

Es werden keine JavaScript-Hacks benötigt.

6
nrofis

Legen Sie die Auswahl deaktiviert fest, wenn Sie planen, schreibgeschützt zu sein, und entfernen Sie dann das deaktivierte Attribut, bevor Sie das Formular absenden.

// global variable to store original event/handler for save button
var form_save_button_func = null;

// function to get jQuery object for save button
function get_form_button_by_id(button_id) {
    return jQuery("input[type=button]#"+button_id);
}

// alter value of disabled element
function set_disabled_elem_value(elem_id, value)  {
    jQuery("#"+elem_id).removeAttr("disabled");
    jQuery("#"+elem_id).val(value);
    jQuery("#"+elem_id).attr('disabled','disabled');
}

function set_form_bottom_button_save_custom_code_generic(msg) {
    // save original event/handler that was either declared
    // through javascript or html onclick attribute
    // in a global variable
    form_save_button_func = get_form_button_by_id('BtnSave').prop('onclick'); // jQuery 1.6
    //form_save_button_func = get_form_button_by_id('BtnSave').prop('onclick'); // jQuery 1.7

    // unbind original event/handler (can use any of following statements below)
    get_form_button_by_value('BtnSave').unbind('click');
    get_form_button_by_value('BtnSave').removeAttr('onclick');

    // alternate save code which also calls original event/handler stored in global variable
    get_form_button_by_value('BtnSave').click(function(event){
        event.preventDefault();
        var confirm_result = confirm(msg);
        if (confirm_result) {
            if (jQuery("form.anyForm").find('input[type=text], textarea, select').filter(".disabled-form-elem").length > 0) {
                jQuery("form.anyForm").find('input[type=text], textarea, select').filter(".disabled-form-elem").removeAttr("disabled");
            }

            // disallow further editing of fields once save operation is underway
            // by making them readonly
            // you can also disallow form editing by showing a large transparent
            // div over form such as loading animation with "Saving" message text
            jQuery("form.anyForm").find('input[type=text], textarea, select').attr('ReadOnly','True');

            // now execute original event/handler
            form_save_button_func();
        }
    });
}

$(document).ready(function() {
    // if you want to define save button code in javascript then define it now

    // code below for record update
    set_form_bottom_button_save_custom_code_generic("Do you really want to update this record?");
    // code below for new record
    //set_form_bottom_button_save_custom_code_generic("Do you really want to create this new record?");

    // start disabling elements on form load by also adding a class to identify disabled elements
    jQuery("input[type=text]#phone").addClass('disabled-form-elem').attr('disabled','disabled');
    jQuery("input[type=text]#fax").addClass('disabled-form-elem').attr('disabled','disabled');
    jQuery("select#country").addClass('disabled-form-elem').attr('disabled','disabled');
    jQuery("textarea#address").addClass('disabled-form-elem').attr('disabled','disabled');

    set_disabled_elem_value('phone', '123121231');
    set_disabled_elem_value('fax', '123123123');
    set_disabled_elem_value('country', 'Pakistan');
    set_disabled_elem_value('address', 'address');

}); // end of $(document).ready function
5
Craig Ambrose

Dies ist die einfachste und beste Lösung. Sie legen ein readolny-Attribut in Ihrem select oder ein anderes attr wie data-readonly fest und führen Folgendes aus

$("select[readonly]").live("focus mousedown mouseup click",function(e){
    e.preventDefault();
    e.stopPropagation();
});
5

Zusätzlich zum Deaktivieren der Optionen, die nicht auswählbar sein sollten, wollte ich sie tatsächlich von der Liste verschwinden lassen, aber immer noch in der Lage sein, sie zu aktivieren, sollte ich später etwas anderes benötigen:

$("select[readonly]").find("option:not(:selected)").hide().attr("disabled",true);

Dadurch werden alle Select-Elemente mit einem Readonly-Attribut gefunden. Anschließend werden alle Optionen in den nicht ausgewählten Selects gefunden. Anschließend werden sie ausgeblendet und deaktiviert.

Es ist wichtig, die Jquery-Abfrage aus Leistungsgründen in 2 zu trennen, da Jquery sie von rechts nach links liest, den Code: 

$("select[readonly] option:not(:selected)")

sucht zuerst alle nicht ausgewählten Optionen im Dokument und filtert dann die in selects enthaltenen Optionen mit einem Readonly-Attribut.

5
cernunnos

Wenn Sie ein Formularfeld deaktivieren, wird dieses nicht gesendet, wenn das Formular gesendet wird. Wenn Sie eine readonly benötigen, die wie disabled funktioniert, aber Werte sendet, tun Sie dies

Nach jeder Änderung der Readonly-Eigenschaften eines Elements.

$('select.readonly option:not(:selected)').attr('disabled',true);

$('select:not([readonly]) option').removeAttr('disabled');
4
Joaquim Perez

Ein einfacher serverseitiger Ansatz besteht darin, alle Optionen mit Ausnahme derjenigen zu entfernen, die Sie auswählen möchten. Wenn also in Zend Framework 1.12 $ element ein Zend_Form_Element_Select ist:

 $value =  $element->getValue();
 $options = $element->getAttrib('options');
 $sole_option = array($value => $options[$value]);
 $element->setAttrib('options', $sole_option);
4
David

Lösung mit tabindex. Funktioniert mit Auswahl- aber auch Texteingaben. 

Verwenden Sie einfach eine .disabled-Klasse.

CSS:

.disabled {
    pointer-events:none; /* No cursor */
    background-color: #eee; /* Gray background */
}

JS:

$(".disabled").attr("tabindex", "-1");

HTML:

<select class="disabled">
    <option value="0">0</option>
</select>

<input type="text" class="disabled" />

Bearbeiten: Mit Internet Explorer benötigen Sie auch diese JS:

$(document).on("mousedown", ".disabled", function (e) {
    e.preventDefault();
});
3
jBelanger

Wenn Sie jquery validate verwenden, können Sie Folgendes tun: Ich habe das disabled-Attribut ohne Probleme verwendet:

$(function(){
    $('#myform').validate({
        submitHandler:function(form){
            $('select').removeAttr('disabled');
            form.submit();
        }
    });
});
2
Rafael Moni

Was ich gefunden habe, funktioniert mit einfachem Javascript (dh, es ist keine JQuery-Bibliothek erforderlich), darin, die innerHTML des <select>-Tags auf den gewünschten verbleibenden Einzelwert zu ändern.

Vor:

<select name='day' id='day'>
  <option>Sun</option>
  <option>MON</option>
  <option>TUE</option>
  <option>WED</option>
  <option>THU</option>
  <option>FRI</option>
  <option>SAT</option>
</select>

Beispiel Javascript:

document.getElementById('day').innerHTML = '<option>FRI</option>';

Nach dem:

<select name='day' id='day'>
  <option>FRI</option>
</select>

Auf diese Weise ändert sich kein visueller Effekt, und dies wird POST/GET innerhalb des <FORM>.

2
Syd

Im Anschluss an Grant Wagners Vorschlag; Hier ist ein jQuery-Snippet, das mit Handler-Funktionen anstelle von direkten onXXX-Attributen funktioniert:

var readonlySelect = function(selector, makeReadonly) {

    $(selector).filter("select").each(function(i){
        var select = $(this);

        //remove any existing readonly handler
        if(this.readonlyFn) select.unbind("change", this.readonlyFn);
        if(this.readonlyIndex) this.readonlyIndex = null;

        if(makeReadonly) {
            this.readonlyIndex = this.selectedIndex;
            this.readonlyFn = function(){
                this.selectedIndex = this.readonlyIndex;
            };
            select.bind("change", this.readonlyFn);
        }
    });

};
2
thetoolman

Ich habe es mit jquery gelöst:

      $("select.myselect").bind("focus", function(){
        if($(this).hasClass('readonly'))
        {
          $(this).blur();   
          return;
        }
      });
2
ownking
<select id="case_reason" name="case_reason" disabled="disabled">

disabled="disabled" -> wird Ihren Wert aus der Datenbank abrufen und in der Form anzeigen .readonly="readonly" ->Sie können Ihren Wert in der selectbox ändern, der Wert kann jedoch nicht in Ihrer Datenbank gespeichert werden.

1
Afwan Zikri

hTML-Lösung:

<select onfocus="this.blur();">

javascript diejenigen:

selectElement.addEventListener("focus", selectElement.blur, true);selectElement.attachEvent("focus", selectElement.blur); //thanks, IE

zu entfernen:

selectElement.removeEventListener("focus", selectElement.blur, true);selectElement.detachEvent("focus", selectElement.blur); //thanks, IE

bearbeiten: Entfernungsmethoden hinzugefügt

1
Kadmillos

Anstelle der Auswahl können Sie alle Optionen außer der aktuell ausgewählten Option deaktivieren. Dies zeigt den Eindruck einer funktionierenden Dropdown-Liste, aber nur die Option, die Sie übergeben möchten, ist eine gültige Auswahl.

1
Adam Bellaire

Entfernen Sie einfach das deaktivierte Attribut, bevor Sie das Formular absenden.

    $('form').submit(function () {
        $("#Id_Unidade").attr("disabled", false);
    });
1

Unten arbeitete für mich:

$('select[name=country]').attr("disabled", "disabled"); 
0
john

Ich weiß, dass dies nicht jedem helfen wird (wenn Sie nur Client-Seite sind), aber es wird einigen helfen, die volles Stack haben und sowohl das Backend als auch die Front kontrollieren können.

Wenn ein Benutzer nicht über ein Recht zum Bearbeiten eines Felds verfügt, gebe ich nur die aktuelle Auswahl für das Dropdown-Menü zurück.

Hier sind einige meiner Backend-Controller:

        #region Prepare Action Priviledges
        editAuditVM.ExtAuditEditRoleMatrixVM = new ExtAuditEditRoleMatrixVM
        {
            CanEditAcn = _extAuditEditRoleMatrixHelper.CanEditAcn(user, audit),
            CanEditSensitiveDesignation = _extAuditEditRoleMatrixHelper.CanEditSensitiveDesignation(user, audit),
            CanEditTitle = _extAuditEditRoleMatrixHelper.CanEditTitle(),
            CanEditAuditScope = _extAuditEditRoleMatrixHelper.CanEditAuditScope(user, audit)
        };
        #endregion


        #region Prepare SelectLists for Drop Downs
        #region AuditScope List
        IQueryable<SelectListItem> auditScopes = _auditTypesRepo.AuditTypes
            .Where(at => at.AuditTypeClassCode.ToLower() == "e")
            .Select(at => new SelectListItem
            { Text = at.AuditTypeText, Value = at.AuditTypeID.ToString() });
        // Cannot make a select readonly on client side.
        //  So only return currently selected option.
        if (!editAuditVM.ExtAuditEditRoleMatrixVM.CanEditAuditScope)
        {
            auditScopes = auditScopes
                .Where(ascopeId => ascopeId.Value == editAuditVM.ExternalAudit.AuditTypeID.ToString());
        }
        #endregion
        #endregion
0
Sam

sehr einfach. Erster Wert in Variable speichern. Dann bei Änderung des Ereignissatzes auf gespeicherte Variable, die den Anfangswert von enthält 

Ich habe einen, dessen Name Mapping ist. Dann lautet mein Code wie folgt;

$("document").ready(function(){ 
    var mapping=$("select[name=mapping]").val();
    $("select[name=mapping]").change(function(){
        $("select[name=mapping]").val(mapping);
    });
});
0
ramesh shinde

In IE konnte ich den onfocus => onblur-Ansatz durch einen Doppelklick auf ..__ besiegen. Wenn ich mich jedoch an den Wert erinnere und ihn dann im onchange-Event wieder herstelle, scheint dieses Problem gelöst zu werden.

<select onfocus="this.oldvalue=this.value;this.blur();" onchange="this.value=this.oldvalue;">
....
</select>

Sie können ähnliche Eigenschaften ohne Expando-Eigenschaften verwenden, indem Sie eine Javascript-Variable verwenden.

0
Sojourneer

Ich habe es geschafft, indem ich das Auswahlfeld verdeckte und an seiner Stelle eine span mit nur informativem Wert zeigte. Bei Deaktivierung der .readonly-Klasse müssen auch die .toVanish-Elemente entfernt und die .toShow-Elemente angezeigt werden.

 $( '.readonly' ).live( 'focus', function(e) {
                $( this ).attr( 'readonly', 'readonly' )
                if( $( this ).get(0).tagName == 'SELECT' ) {
                    $( this ).before( '<span class="toVanish readonly" style="border:1px solid; padding:5px">' 
                            + $( this ).find( 'option:selected' ).html() + '</span>' )
                    $( this ).addClass( 'toShow' )
                    $( this ).hide()
            }
    });
0
fiatjaf
 var selectedOpt; // initialisiert var 
 var newIdForHidden; // initialisiert var 
 $ ('. disabledOnEdit'). focusin (function () {
 selectedOpt = $ (this) .find (": selected"). val (); 
 newIdForHidden = $ (this) .attr ('id ') +' Hidden '; 
 //Alert(selectedOpt+','+newIdForHidden) ;
 $ (This) .append (''); 
 $ (This) .find ('input.hiddenSelectedOpt ') .attr (' id ', newIdForHidden) .val (selectedOpt); 
}); 
 $ ('. disabledOnEdit'). focusout (function () {
 var oldSelectedValue = $ (this) .find ('input.hiddenSelectedOpt'). val (); 
 $ (this) .val (oldSelectedValue) ; 
}); 
0
Robin

Wenn Sie ein select-Tag haben, das nur gelesen werden kann, müssen Sie das Auswahlfeld logisch in ein einzelnes "Text" -Feld transformieren.

Ich sage logisch, weil es so ist: "Ich muss dem Benutzer einen Wert anzeigen"

Unabhängig davon, ob der Wert von einem select-Tag stammt, ist immer noch ein einzelner Wert und kann nicht geändert werden (readonly).

Logischerweise verwenden Sie ein select-Tag nur, wenn Sie den Wert zum ersten Mal einfügen.

Wenn Sie diesen Wert dann anzeigen müssen, müssen Sie ihn auf "Textfeld lesen" stellen.

Dasselbe gilt für eine Mehrfachauswahl, die zu einer Liste von Werten (dem ausgewählten Wert) wird, wenn nur gelesen

Ich verwende "Text", weil ein readonly-Tag kein Attribut "type" . Cheers benötigt

0
Mindexperiment

Wenn die Auswahl-Dropdownliste seit der Geburt schreibgeschützt ist und nicht geändert werden muss, sollten Sie stattdessen ein anderes Steuerelement verwenden. Wie ein einfacher <div> (plus ausgeblendetes Formularfeld) oder ein <input type="text">?

Hinzugefügt: Wenn das Dropdown-Menü nicht immer schreibgeschützt ist und JavaScript zum Aktivieren/Deaktivieren verwendet wird, ist dies immer noch eine Lösung. Ändern Sie einfach das DOM im laufenden Betrieb.

0
Vilx-

Hier ist ein Versuch, eine benutzerdefinierte jQuery-Funktion zu verwenden, um die Funktionalität zu erreichen (wie hier erwähnt):

$(function(){

 $.prototype.toggleDisable = function(flag) {
    // prepare some values
    var selectId = $(this).attr('id');
    var hiddenId = selectId + 'hidden';
    if (flag) {
      // disable the select - however this will not submit the value of the select
      // a new hidden form element will be created below to compensate for the 
      // non-submitted select value 
      $(this).attr('disabled', true);

      // gather attributes
      var selectVal = $(this).val();
      var selectName = $(this).attr('name');

      // creates a hidden form element to submit the value of the disabled select
      $(this).parents('form').append($('<input></input>').
        attr('type', 'hidden').
        attr('id', hiddenId).
        attr('name', selectName).
        val(selectVal) );
    } else {
      // remove the newly-created hidden form element
      $(this).parents('form').remove(hiddenId);
      // enable back the element
      $(this).removeAttr('disabled');
    }
  }

  // Usage
  // $('#some_select_element').toggleDisable(true);
  // $('#some_select_element').toggleDisable(false);

});
0
tamersalama

select multiple reagiert auf die obigen Codevorschläge nicht annähernd so gut. Mit VIEL Sledgehammering und Klatsch endete ich damit:

var thisId="";
var thisVal="";
function selectAll(){
    $("#"+thisId+" option").each(function(){
        if(!$(this).prop("disabled"))$(this).prop("selected",true);
    });
    $("#"+thisId).prop("disabled",false);
}
$(document).ready(function(){
    $("select option:not(:selected)").attr('disabled',true);
    $("select[multiple]").focus(function(){
        thisId=$(this).prop("id");
        thisVal=$(this).val();
        $(this).prop("disabled",true).blur();
        setTimeout("selectAll();",200);
    });
});
0
gordon