web-dev-qa-db-fra.com

Evénement sur une entrée désactivée

Apparemment, un <input> désactivé n'est traité par aucun événement

Existe-t-il un moyen de résoudre ce problème?

<input type="text" disabled="disabled" name="test" value="test" />
$(':input').click(function () {
    $(this).removeAttr('disabled');
})

Ici, je dois cliquer sur l'entrée pour l'activer. Mais si je ne l’active pas, l’entrée ne doit pas être publiée.

203
Pierre de LESPINAY

Les éléments désactivés ne déclenchent pas les événements de souris. La plupart des navigateurs propagent un événement provenant de l'élément désactivé dans l'arborescence DOM, de sorte que les gestionnaires d'événements peuvent être placés sur des éléments conteneur. Cependant, Firefox ne présente pas ce comportement, il ne fait rien du tout lorsque vous cliquez sur un élément désactivé.

Je ne peux pas penser à une meilleure solution, mais pour une compatibilité totale entre navigateurs, vous pouvez placer un élément devant l'entrée désactivée et intercepter le clic sur cet élément. Voici un exemple de ce que je veux dire:

<div style="display:inline-block; position:relative;">
  <input type="text" disabled />
  <div style="position:absolute; left:0; right:0; top:0; bottom:0;"></div>
</div>​

jq:

$("div > div").click(function (evt) {
    $(this).hide().prev("input[disabled]").prop("disabled", false).focus();
});​

Exemple: http://jsfiddle.net/RXqAm/170/ (mis à jour pour utiliser jQuery 1.7 avec prop au lieu de attr).

234
Andy E

Peut-être pourriez-vous rendre le champ en lecture seule et, lors de la soumission, désactiver tous les champs en lecture seule

$(".myform").submit(function(e) {
    $("input[readonly]", this).attr("disabled", true);
});

et l'entrée (+ script) devrait être

<input type="text" readonly="readonly" name="test" value="test" />

$('input[readonly]').click(function () {
    $(this).removeAttr('readonly');
})
62
Tokimon

Les éléments désactivés "mangent" les clics dans certains navigateurs - ils ne leur répondent pas et ne leur permettent pas non plus d'être capturés par les gestionnaires d'événements, que ce soit sur l'élément ou sur l'un de ses conteneurs.

IMHO le moyen le plus simple et le plus propre de "réparer" ceci (si vous avez réellement besoin de capturer des clics sur des éléments désactivés comme le fait l'OP) consiste simplement à ajouter le CSS suivant à votre page:

input[disabled] {pointer-events:none}

Cela fera que tous les clics sur une entrée désactivée tomberont sur l'élément parent, où vous pourrez les capturer normalement. (Si vous avez plusieurs entrées désactivées, vous pouvez placer chacune dans un conteneur individuel, si elles ne sont pas déjà présentées de cette façon - un <span> supplémentaire ou un <div>, par exemple - simplement pour faciliter la distinction des l’entrée désactivée a été cliquée).


L'inconvénient est que cette astuce ne fonctionnera malheureusement pas pour les navigateurs plus anciens qui ne prennent pas en charge la propriété CSS pointer-events. Cela devrait fonctionner à partir de IE 11, FF v3.6, Chrome v4): caniuse.com/#search=pointer-events

Si vous devez prendre en charge des navigateurs plus anciens, vous devrez utiliser l'une des autres réponses!

41
Doin

Je suggérerais une alternative - utiliser CSS:

input.disabled {
    user-select : none;
    -moz-user-select : none;
    -webkit-user-select : none;
    color: gray;
    cursor: pointer;
}

au lieu de l'attribut désactivé. Ensuite, vous pouvez ajouter vos propres attributs CSS pour simuler une entrée désactivée, mais avec davantage de contrôle.

13
Ron Reiter

$(function() {

  $("input:disabled").closest("div").click(function() {
    $(this).find("input:disabled").attr("disabled", false).focus();
  });

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>

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

7
Rejeesh Prarath

Au lieu de disabled, vous pouvez envisager d'utiliser readonly. Avec quelques CSS supplémentaires, vous pouvez attribuer un style à l’entrée afin qu’elle ressemble à un champ disabled.

Il y a en réalité un autre problème. L'événement change ne se déclenche que lorsque l'élément perd le focus, ce qui n'est pas logique considérant un champ disabled. Vous envoyez probablement des données dans ce champ à partir d'un autre appel. Pour que cela fonctionne, vous pouvez utiliser l'événement 'bind'.

$('form').bind('change', 'input', function () {
    console.log('Do your thing.');
});
4
Nykac

OU faites ceci avec jQuery et CSS!

$('input.disabled').attr('ignore','true').css({
    'pointer-events':'none',
     'color': 'gray'
});

De cette façon, vous donnez l’impression que l’élément est désactivé et aucun événement de pointeur ne se déclenche. Toutefois, il permet la propagation. Si vous le soumettez, vous pouvez utiliser l’attribut 'ignore' pour l’ignorer.

4
sidonaldson

Nous avons eu aujourd'hui un problème comme celui-ci, mais nous ne voulions pas changer le code HTML. Nous avons donc utilisé mouseenter event pour y parvenir

var doThingsOnClick = function() {
    // your click function here
};

$(document).on({
    'mouseenter': function () {
        $(this).removeAttr('disabled').bind('click', doThingsOnClick);
    },
    'mouseleave': function () {
        $(this).unbind('click', doThingsOnClick).attr('disabled', 'disabled');
    },
}, 'input.disabled');
0
Raul Sanchez