Quel est le moyen le plus simple d'activer/désactiver des boutons et des liens (jQuery + Bootstrap) ?

Parfois, j'utilise des ancres stylisées comme des boutons et parfois j'utilise simplement des boutons. Je veux désactiver des éléments cliquables spécifiques afin que :

  • Ils aient l'air désactivés
  • Ils ne soient plus cliqués

Comment faire ?

Solution

Boutons

Les boutons sont simples à désactiver car disabled est une propriété du bouton qui est gérée par le navigateur :

<input type="submit" class="btn" value="My Input Submit" disabled/>
<input type="button" class="btn" value="My Input Button" disabled/>
My Button

Pour les désactiver avec une fonction jQuery personnalisée, il suffit d'utiliser [fn.extend()][1] :

// Disable function
jQuery.fn.extend({
    disable: function(state) {
        return this.each(function() {
            this.disabled = state;
        });
    }
});

// Disabled with:
$('input[type="submit"], input[type="button"], button').disable(true);

// Enabled with:
$('input[type="submit"], input[type="button"], button').disable(false);

[Démo du bouton et de l'entrée désactivés de JSFiddle][2].

Sinon, vous devez utiliser la méthode [prop()][3] de jQuery :

$('button').prop('disabled', true);
$('button').prop('disabled', false);

Balises d'ancrage

Il convient de noter que disabled n'est pas une [propriété valide][4] pour les balises d'ancrage. Pour cette raison, Bootstrap utilise le style suivant sur ses éléments .btn :

.btn.disabled, .btn[disabled] {
    cursor: default;
    background-image: none;
    opacity: 0.65;
    filter: alpha(opacity=65);
    -webkit-box-shadow: none;
    -moz-box-shadow: none;
    box-shadow: none;
    color: #333;
    background-color: #E6E6E6;
}

Notez comment la propriété [disabled] est ciblée ainsi qu'une classe .disabled. La classe .disabled est nécessaire pour faire apparaître une balise d'ancrage désactivée.

<a href="http://example.com" class="btn">My Link</a>

Bien entendu, cela n'empêchera pas les liens de fonctionner lorsqu'on clique dessus. Le lien ci-dessus nous mènera à http://example.com. Pour éviter cela, nous pouvons ajouter un simple morceau de code jQuery pour cibler les balises d'ancrage avec la classe disabled et appeler [event.preventDefault()][5] :

$('body').on('click', 'a.disabled', function(event) {
    event.preventDefault();
});

Nous pouvons faire basculer la classe disabled en utilisant [toggleClass()][6] :

jQuery.fn.extend({
    disable: function(state) {
        return this.each(function() {
            var $this = $(this);
            $this.toggleClass('disabled', state);
        });
    }
});

// Disabled with:
$('a').disable(true);

// Enabled with:
$('a').disable(false);

[Démonstration du lien désactivé par JSFiddle][8].


Combiné

Nous pouvons ensuite étendre la fonction disable précédente pour vérifier le type d'élément que nous essayons de désactiver en utilisant [is()][9]. De cette façon, nous pouvons toggleClass() si ce n'est pas un élément input ou button, ou basculer la propriété disabled si c'est le cas :

// Extended disable function
jQuery.fn.extend({
    disable: function(state) {
        return this.each(function() {
            var $this = $(this);
            if($this.is('input, button, textarea, select'))
              this.disabled = state;
            else
              $this.toggleClass('disabled', state);
        });
    }
});

// Disabled on all:
$('input, button, a').disable(true);

// Enabled on all:
$('input, button, a').disable(false);

[Démo complète et combinée de JSFiddle][10].

Il convient de noter que la fonction ci-dessus fonctionne également avec tous les types d'entrée.

[1] : http://api.jquery.com/jQuery.fn.extend/ [2] : http://jsfiddle.net/JamesD/TFTvn/1/ [3] : http://api.jquery.com/prop/ [4] : http://www.w3.org/TR/html5/text-level-semantics.html#the-a-element [5] : http://api.jquery.com/event.preventDefault/ [6] : http://api.jquery.com/toggleClass/ [8] : http://jsfiddle.net/JamesD/TFTvn/15/ [9] : http://api.jquery.com/is/ [10] : http://jsfiddle.net/JamesD/TFTvn/14/

Commentaires (17)

Je ne peux pas imaginer un moyen plus simple/plus facile ! ;-)


Utilisation des balises d'ancrage (liens) :

<a href="#delete-modal" class="btn btn-danger" id="delete">Delete</a>

Pour activer la balise Anchor :

 $('#delete').removeClass('disabled');
 $('#delete').attr("data-toggle", "modal");

![entrez la description de l'image ici][1]


Pour désactiver la balise Anchor :

 $('#delete').addClass('disabled');
 $('#delete').removeAttr('data-toggle');

![entrez la description de l'image ici][2]

[1] : http://i.stack.imgur.com/Ud9Xu.png [2] : http://i.stack.imgur.com/zERjo.png

Commentaires (0)

@James Donnelly a fourni une réponse complète qui repose sur l'extension de jQuery avec une nouvelle fonction. C'est une excellente idée, je vais donc adapter son code pour qu'il fonctionne comme je le souhaite.

Extension de jQuery

$.fn.disable=-> setState $(@), true
$.fn.enable =-> setState $(@), false
$.fn.isDisabled =-> $(@).hasClass 'disabled'

setState=($el, state) ->
    $el.each ->
        $(@).prop('disabled', state) if $(@).is 'button, input'
        if state then $(@).addClass('disabled') else $(@).removeClass('disabled')

    $('body').on('click', 'a.disabled', -> false)

Utilisation

$('.btn-stateful').disable()
$('#my-anchor').enable()

Le code traitera un seul élément ou une liste d'éléments.

Les boutons et les entrées supportent la propriété disabled et, si elle est définie à true, ils auront l'air désactivés (grâce au bootstrap) et ne se déclencheront pas lorsqu'ils seront cliqués.

Les ancres ne supportent pas la propriété disabled, nous allons donc nous appuyer sur la classe .disabled pour qu'elles aient l'air désactivées (encore merci à bootstrap) et connecter un événement de clic par défaut qui empêche le clic en retournant false (pas besoin de preventDefault, voir [ici][1]).

Note : Vous n'avez pas besoin de décrocher cet événement lorsque vous réactivez les ancres. Il suffit de supprimer la classe .disabled.

Bien sûr, cela ne sert à rien si vous avez attaché un gestionnaire de clics personnalisé au lien, ce qui est très courant lorsque vous utilisez bootstrap et jQuery. Pour résoudre ce problème, nous allons utiliser l'extension isDisabled() pour tester la classe .disabled, comme ceci :

$('#my-anchor').click -> 
    return false if $(@).isDisabled()
    # do something useful

J'espère que cela vous aidera à simplifier un peu les choses.

[1] : http://css-tricks.com/return-false-and-prevent-default/

Commentaires (0)