Formulaire HTML en lecture seule SELECT / entrée

589

Selon les spécifications HTML, la selectbalise HTML n'a pas d' readonlyattribut, seulement un disabledattribut. Donc, si vous voulez empêcher l'utilisateur de modifier la liste déroulante, vous devez utiliser disabled.

Le seul problème est que les entrées de formulaire HTML désactivées ne sont pas incluses dans les données POST / GET.

Quelle est la meilleure façon d'émuler l' readonlyattribut d'une selectbalise et d'obtenir toujours les données POST?

Jrgns
la source
5
Ne vous fiez pas à cela pour le côté serveur. N'importe qui peut créer sa propre page HTML et en faire une RW.
Brendan Byrd
11
Mais ce n'est pas une question spécifique à PHP.
Kaleb Brasee
4
Je suggérerais de ne pas utiliser du tout d'élément select dans ce cas. Y a-t-il une raison pour laquelle vous ne pouvez pas simplement afficher la valeur en texte brut?
Big McLargeHuge
2
@ppumkin votre commentaire n'a aucun sens. Je ne dis pas qu'il n'y a jamais de bon cas d'utilisation pour les champs de formulaire sélectionnés ou masqués. L'OP avait du mal à afficher du texte sur la page, et je me demandais simplement quel était le but d'utiliser un élément select dans ce cas.
Big McLargeHuge
2
Je dois lire la mauvaise question. Il dit qu'il veut désactiver la sélection afin que l'utilisateur ne la modifie pas. Peut-être qu'il a besoin de rendre la page avec des sélections et d'utiliser jquery pour empêcher les changements. Mais quand il le soumet, il n'y a pas de données pour cela. Je faisais la même chose. Je dois afficher les sélections qui sont filtrées par d'autres sélections et la dernière liste déroulante est enregistrée dans DB via ajax, donc toutes les précédentes doivent être verrouillées. Lorsque je rend la page, oui, OK - je pouvais afficher des étiquettes au lieu de sélectionner. Mais ce n'est pas le problème :)
Piotr Kula

Réponses:

461

Vous devez conserver l' selectélément disabledmais également en ajouter un autre caché inputavec le même nom et la même valeur.

Si vous réactivez votre SELECT, vous devez copier sa valeur dans l'entrée masquée dans un événement onchange et désactiver (ou supprimer) l'entrée masquée.

Voici une démo:

$('#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>

bezmax
la source
5
Si vous réactivez la sélection, vous devez également désactiver ou supprimer l'entrée cachée (après avoir copié sa valeur comme décrit) bien sûr. Sinon, vous obtiendrez la valeur soumise double
Adam
1
@max Ah !. Ok, ça marche aussi. J'avais supposé depuis que vous avez dit que l'entrée cachée devrait avoir le "même nom" que la sélection avait un nom.
Adam
2
Et si j'utilise une sélection multiple?
Anyul Rivas
2
Avoir deux éléments avec les mêmes noms ne fera que renvoyer la dernière entrée activée / sélectionnée, pas le double. De plus, seule la selectedvaleur est publiée et non la liste entière. Ainsi, votre hiddensiège devant votre selectet détient la valeur sélectionnée. Si la sélection est désactivée pour "lecture seule", la publication ne contiendra que la valeur de l'entrée masquée. Si la sélection est activée, l'option sélectionnée visible "écrasera / remplacera" la valeur cachée, et c'est la valeur qui sera publiée en retour.
Piotr Kula
30
Bien que ce soit la solution évidente, cela craint comme solution, car vous devez ajouter un autre champ de saisie.
Donato
190

On pourrait aussi utiliser ça

Désactivez tout sauf l'option sélectionnée:

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

De cette façon, la liste déroulante fonctionne toujours (et soumet sa valeur) mais l'utilisateur ne peut pas sélectionner une autre valeur.

Démo

vimal1083
la source
3
Nice one for dynamic option's
Diego Favero
11
Parfait pour une balise SELECT à valeur unique! Mais ne fonctionnera pas pour un <select multiple>, ce qui permettra toujours aux utilisateurs de désélectionner certaines des options sélectionnées, modifiant ainsi la valeur.
Mikhail Bunkin
2
Prise en charge du navigateur pour l' attribut de la optionbalisedisabled
Jo.
4
C'est une excellente solution. J'ajouterai que vous pouvez y parvenir facilement avec jQuery comme ceci: $("#yourSelectId option:not(:selected)).attr("disabled", "disabled")
Onkel-j
105

Vous pouvez réactiver l'objet sélectionné lors de la soumission.

EDIT : c'est-à-dire, désactivant normalement la balise de sélection (avec l'attribut désactivé), puis la réactivant automatiquement juste avant de soumettre le formulaire:

Exemple avec jQuery:

  • Pour le désactiver:

    $('#yourSelect').prop('disabled', true);
  • Pour le réactiver avant la soumission afin que les données GET / POST soient incluses:

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

De plus, vous pouvez réactiver chaque entrée désactivée ou sélectionner:

$('#yourForm').on('submit', function() {
    $('input, select').prop('disabled', false);
});
kemiller2002
la source
4
utilisez .prop ('désactivé', vrai / faux) pour définir la propriété désactivée. L'attribut ne changera pas l'état réel.
Paris Char
Je pense que cette solution est plus intelligente que la solution @bezmax . Parce que si nous ajoutions une entrée cachée, nous devions considérer qu'une seule de chaque entrée (même nom) était activée à tout moment. Dans le cas contraire, si les deux entrées ont été activées, côté serveur, le programme prendra un tableau d'entrées qui peut provoquer une exception (par exemple, si nous n'avons pas géré cette situation, nous attendons une chaîne et utilisons 'Request.Form [FieldName] 'commande)
MiT
@Kevin, fonctionne> 90% des cas. De plus, vous devez avoir jquery dans votre ceinture ... Eh.
sitilge
C'est beaucoup plus propre la réponse acceptée. Plus facile de défaire la logique si vous ne voulez plus que l'élément soit désactivé et sans balises d'entrée supplémentaires.
Haohmaru
51

une autre façon de faire un readOnlyattribut à un selectélément consiste à utilisercss

vous pourriez faire comme:

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

DEMO

Yaje
la source
8
Belle solution. Mais vous pouvez toujours changer la valeur avec le clavier.
Mario Werner
1
Oui, c'est assez génial. Pour modifier la valeur avec le clavier, vous devez TAB sur l'élément et il devient alors sélectionné. Si vous rendez la couleur d'arrière-plan grise ou désactivée, vous informez visuellement l'utilisateur qu'elle est "désactivée" lorsqu'elle n'est pas désactivée. Personne ne supporte plus IE donc peu importe. Vous pouvez également mettre un keydown empêche la valeur par défaut si vous voulez empêcher.
Piotr Kula
Assez peu orthodoxe !! Si la sélection doit être bloquée du rendu de page,... .on('mouseover', function(){ ... });
Fr0zenFyr
pointer-events: noneempêche la mise au point du curseur de la souris. Pour également empêcher la mise au point du clavier, vous pouvez la compléter en floutant immédiatement tous les événements de mise au point:$('select').css('pointer-events', 'none').on('focus', function () {$(this).blur();});
Quinn Comendant
39
<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>

Testé et fonctionne sous IE 6, 7 et 8b2, Firefox 2 et 3, Opera 9.62, Safari 3.2.1 pour Windows et Google Chrome.

Grant Wagner
la source
15
Le problème avec cela est que la liste déroulante est rendue comme si elle n'était pas en lecture seule. L'utilisateur pensera que la chose ne fonctionne pas ...
Lukas Eder
8
Cela est déroutant pour l'utilisateur car il peut toujours sélectionner une option, mais lorsqu'il la sélectionne, la liste revient à la valeur précédemment sélectionnée. Il est beaucoup plus intuitif de désactiver la liste pour empêcher l'utilisateur de sélectionner quoi que ce soit.
dana
11
J'ai eu un problème similaire et je l'ai résolu en affichant uniquement l'option sélectionnée. Aucun JS requis, moins de confusion pour l'utilisateur ... <select id="countries"> <option value="7" selected="selected">Country7</option> </select>
Potherca
1
@ppumkin @dana @LukasEder Non .. pas si vous pouvez corriger cette UX. Par exemple, vous pourriez faire quelque chose comme onchange = 'this.selectedIndex=this.defaultIndex; alert("You should not change this..");'au lieu de simplement changer l'index sélectionné en silence ..
Fr0zenFyr
1
@LukasEder Pour quiconque se méfie de l'expérience du répondant, il peut ajouter du CSS pour vraiment souligner que le menu déroulant ne doit pas être modifié. Positionnez le curseur sur not-allowedet la couleur d'arrière-plan sur #CCC.
Alexander Dixon
36

Solution jQuery simple

Utilisez-le si vos sélections ont la readonlyclasse

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

Ou ceci si vos sélections ont l' readonly="readonly"attribut

$('select[readonly="readonly"] option:not(:selected)').attr('disabled',true);
Logiciel Black Brick
la source
7
Veuillez expliquer un peu votre code. Doit-on ajouter une classe «en lecture seule» aux éléments sélectionnés? Quand devons-nous appeler ce code: uniquement dans document.ready ou à chaque fois qu'une sélection est activée / désactivée? Votre code noscript est-il sûr?
anar khalilov
$(document).ready(function(){$('select option:not(:selected)').attr('disabled',true);});fonctionne très bien sur une seule sélection. Aucune classe "en lecture seule" n'est requise. La sélection multiple est problématique en ce sens que s'il y a plus d'une option déjà sélectionnée et donc non désactivée et qu'un utilisateur sélectionne l'une des options non désactivées, les autres options précédemment sélectionnées deviennent non sélectionnées.
gordon
je ne comprends rien de tout cela.
Piotr Kula
Il désactive les options autres que celles sélectionnées pour les cases de sélection avec la classe "en lecture seule". Si vous avez l'élément de sélection en main, vous pouvez écrire:$select.find('option').not(':selected').attr('disabled', 'disabled');
Semra
1
J'aime cette solution. Je changerais le sélecteur pour select[readonly]que vous ajoutiez simplement l'attribut readonly à l'élément - de cette façon, vous n'avez pas à traiter les sélections différemment de tout autre type. Le javascript améliore ensuite progressivement l'effet. Gardez à l'esprit que cette solution (et la plupart des autres) n'aide que l'agent utilisateur à fournir la meilleure expérience utilisateur - elle n'applique rien (cela doit être fait côté serveur si nécessaire).
jgivoni
21

Solution CSS simple:

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

select[readonly] option{
    display:none;
}

Cela se traduit par Sélectionner pour être gris avec un joli curseur "désactiver" au survol
et sur sélectionner la liste des options est "vide" afin que vous ne puissiez pas changer sa valeur.

d.raev
la source
1
Si vous avez une validation CSRF (comme dans symfony et beaucoup d'autres frameworks), cela ne fonctionnera pas.
ThEBiShOp
11

C'est la meilleure solution que j'ai trouvée:

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

Le code ci-dessus désactive toutes les autres options non sélectionnées tout en conservant l'option sélectionnée activée. Ce faisant, l'option sélectionnée sera intégrée dans les données post-back.

Leniel Maccaferri
la source
11

Je sais qu'il est beaucoup trop tard, mais cela peut être fait avec du CSS simple:

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

Le style masque toutes les options et les groupes lorsque la sélection est en readonlyétat, de sorte que l'utilisateur ne peut pas modifier sa sélection.

Aucun piratage JavaScript n'est nécessaire.

nrofis
la source
Agréable et simple. Je l'aime.
Jonathan Parent Lévesque
C'est une très bonne solution au problème. Je vous remercie!
OderWat
10

Plus simple encore: ajoutez l'attribut style à votre balise de sélection :

style="pointer-events: none;"
mainak chakraborty
la source
Cela fonctionne pour moi, mais les événements de pointeur permettront aux navigateurs croisés de prendre en charge?
Abhijit Jagtap
3
Ça ne marchera pas. L'utilisateur peut modifier l'entrée à l'aide du clavier.
Sandhu
6

C'est la solution la plus simple et la meilleure. Vous définissez un attr readolny sur votre sélection, ou tout autre attr comme data-readonly, et procédez comme suit

$("select[readonly]").live("focus mousedown mouseup click",function(e){
    e.preventDefault();
    e.stopPropagation();
});
Guilherme Ferreira
la source
1
vous devez ajouter ici une touche clé et une liste déroulante. La liste déroulante est toujours disponible en la "tabulant" et en utilisant les touches fléchées pour modifier la valeur.
apfz
5

Définissez la sélection désactivée lorsque vous prévoyez qu'elle soit en lecture seule, puis supprimez l'attribut désactivé juste avant de soumettre le formulaire.

// 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
Craig Ambrose
la source
Cela ressemble à une condition de course qui attend de se produire.
Brendan Byrd
5

En plus de désactiver les options qui ne devraient pas être sélectionnables, je voulais en fait les faire disparaître de la liste, mais toujours pouvoir les activer en cas de besoin:

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

Cela recherche tous les éléments de sélection avec un attribut en lecture seule, puis recherche toutes les options à l'intérieur des sélections qui ne sont pas sélectionnées, puis les masque et les désactive.

Il est important de séparer la requête jquery en 2 pour des raisons de performances, car jquery les lit de droite à gauche, le code:

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

trouvera d'abord toutes les options non sélectionnées dans le document, puis filtrera celles qui se trouvent à l'intérieur des sélections avec un attribut en lecture seule.

cernunnos
la source
Peut-être à la .prop("disabled", true)place
sam
4

Une approche simple côté serveur consiste à supprimer toutes les options sauf celle que vous souhaitez sélectionner. Ainsi, dans Zend Framework 1.12, si $ element est un Zend_Form_Element_Select:

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

Si vous désactivez un champ de formulaire, celui-ci ne sera pas envoyé lors de l'envoi du formulaire. Donc, si vous avez besoin d'un readonlyqui fonctionne comme si vous disabledenvoyiez des valeurs, procédez comme suit:

Après toute modification des propriétés en lecture seule d'un élément.

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

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

Solution avec tabindex. Fonctionne avec des entrées de sélection mais aussi de texte.

Utilisez simplement une classe .disabled.

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" />

Edit: Avec Internet Explorer, vous avez également besoin de ce JS:

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

À la suite de la suggestion de Grant Wagners; voici un extrait jQuery qui le fait avec des fonctions de gestionnaire au lieu d'attributs onXXX directs:

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);
        }
    });

};
thetoolman
la source
2

Je l'ai résolu avec jquery:

      $("select.myselect").bind("focus", function(){
        if($(this).hasClass('readonly'))
        {
          $(this).blur();   
          return;
        }
      });
propriétaire
la source
Cela a très bien fonctionné, bien que l'animation de survol affiche toujours une flèche déroulante qui semble cliquable.
Johncl
Cela ne fonctionne pas pour moi dans Chrome 26: la sélection est toujours entièrement fonctionnelle.
Andy
Mais il affiche toujours la liste lorsque vous double-cliquez dessus sur IE. Quoi qu'il en soit pour empêcher cela?
user1995781
2

Si vous utilisez jquery validate, vous pouvez faire ce qui suit ci-dessous, j'ai utilisé l'attribut désactivé sans problème:

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

Ce que j'ai trouvé fonctionne très bien, avec du javascript simple (c'est-à-dire: aucune bibliothèque JQuery requise), c'est de changer le innerHTML de la <select>balise en la valeur restante unique souhaitée.

Avant:

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

Exemple de Javascript:

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

Après:

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

De cette façon, aucun changement d'effet visuel, et cela POST / GET dans le <FORM>.

Syd
la source
1

Plutôt que la sélection elle-même, vous pouvez désactiver toutes les options à l'exception de l'option actuellement sélectionnée. Cela donne l'apparence d'une liste déroulante de travail, mais seule l'option que vous souhaitez transmettre est une sélection valide.

Adam Bellaire
la source
3
En théorie, c'est une excellente idée - mais il n'y a PAS de support pour les options désactivées dans IE avant IE8. tinyurl.com/yle4bto
scunliffe
1

solution html:

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

celles en javascript:

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

ôter:

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

modifier: ajout de méthodes de suppression

Kadmillos
la source
@ButtleButkus les javascript fonctionnent-ils? je suppose que cela peut être un problème lié au navigateur. avez-vous essayé d'ajouter un tabindex à l'élément
Kadmillos
1

Supprimez simplement l'attribut désactivé avant d'envoyer le formulaire.

    $('form').submit(function () {
        $("#Id_Unidade").attr("disabled", false);
    });
Wendell Carvalho
la source
1
<select id="case_reason" name="case_reason" disabled="disabled">

disabled="disabled" ->obtiendra votre valeur de la base de données et le montrera dans le formulaire. readonly="readonly" ->vous pouvez modifier votre valeur dans selectbox, mais votre valeur n'a pas pu être enregistrée dans votre base de données.

Afwan Zikri
la source
mal, c'est enregistré. Il semble que la propriété "en lecture seule" ne soit pas traitée par tous les navigateurs et ne soit donc pas fiable.
richey
0

Si la liste déroulante de sélection est en lecture seule depuis la naissance et n'a pas besoin de changer du tout, peut-être devriez-vous utiliser un autre contrôle à la place? Comme un simple <div>(plus un champ de formulaire caché) ou un <input type="text">?

Ajouté: Si le menu déroulant n'est pas en lecture seule tout le temps et que JavaScript est utilisé pour l'activer / le désactiver, alors c'est toujours une solution - il suffit de modifier le DOM à la volée.

Vilx-
la source
Ce n'est pas en lecture seule depuis le début. J'utilise JavaScript pour changer et mettre à jour. Si une liste déroulante précédente a une certaine valeur, celle-ci devient en lecture seule.
Jrgns
Alors peut-être pouvez-vous remplacer cette liste déroulante par une zone de texte à la volée?
Vilx
Oui, mais l'entrée toujours cachée est plus élégante à mon avis
Jrgns
0

Ci-dessous a fonctionné pour moi:

$('select[name=country]').attr("disabled", "disabled"); 
John
la source
11
Pour info: le champ de formulaire désactivé ne sera pas inclus dans une soumission.
mz_01
0

Je l'ai réussi en cachant la case de sélection et en montrant un spanà sa place avec seulement une valeur informative. En cas de désactivation de la .readonlyclasse, nous devons également supprimer les .toVanishéléments et afficher .toShowceux-ci.

 $( '.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()
            }
    });
fiatjaf
la source
0

Dans IE, j'ai pu vaincre l'approche onfocus => onblur en double-cliquant. Mais se souvenir de la valeur puis la restaurer dans l'événement onchange semble gérer ce problème.

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

Vous pouvez faire de même sans propriétés expando en utilisant une variable javascript.

Sojourneer
la source
0

Voici une tentative d'utiliser une fonction jQuery personnalisée pour obtenir la fonctionnalité (comme mentionné ici):

$(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);

});
tamersalama
la source