Quelle est la façon la plus simple de désactiver / activer les boutons et les liens (jQuery + Bootstrap)

360

Parfois, j'utilise des ancres conçues comme des boutons et parfois j'utilise simplement des boutons. Je veux désactiver des objets clicky spécifiques afin que:

  • Ils ont l'air handicapés
  • Ils cessent d'être cliqués

Comment puis-je faire ceci?

biofractal
la source
voir mon article en bas mais voici le bouton $ ("yourSelector"). ("enable") moins descriptif; // active le bouton ou $ ("yourSelector"). button ("disable"); // désactive le bouton si le widget bouton de jqueryUI est utilisé.
El Bayames
La documentation BS3 indique d'utiliser role="button"pour les liens, mais cela ne semble pas affecter ce problème. getbootstrap.com/css/#buttons
Jess
2
Le fait d'avoir l' a.btn[disabled]air désactivé tout en restant cliquable est un bogue dans Bootstrap IMO. L'attribut [disabled]doit uniquement apparaître désactivé pour buttonet input.
Jess

Réponses:

575

Boutons

Les boutons sont simples à désactiver, tout comme disabledune propriété de bouton 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/>
<button class="btn" disabled>My Button</button>

Pour les désactiver avec une fonction jQuery personnalisée, vous utiliseriez simplement fn.extend():

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

Bouton JSFiddle désactivé et démo d'entrée .

Sinon, vous utiliseriez la prop()méthode de jQuery :

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

Étiquettes d'ancrage

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

.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 [disabled]propriété est ciblée ainsi qu'une .disabledclasse. La .disabledclasse est ce qui 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 sûr, cela n'empêchera pas les liens de fonctionner lorsque vous cliquez dessus. Le lien ci-dessus nous amènera à http://example.com . Pour éviter cela, nous pouvons ajouter un simple morceau de code jQuery pour cibler les balises d'ancrage avec la disabledclasse à appeler event.preventDefault():

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

Nous pouvons basculer la disabledclasse en utilisant toggleClass():

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émo de liaison désactivée JSFiddle .


Combiné

Nous pouvons ensuite étendre la fonction de désactivation précédente effectuée ci-dessus pour vérifier le type d'élément que nous tentons de désactiver à l'aide is(). De cette façon , nous pouvons , toggleClass()si ce n'est pas un inputou buttonélément, ou bascule le disabledsi elle est la propriété:

// 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 JSFiddle combinée complète .

Il convient de noter en outre que la fonction ci-dessus fonctionnera également sur tous les types d'entrée.

James Donnelly
la source
Merci pour la réponse complète. S'il vous plaît voir mon Edit 1 pour une version de script de café. J'ai toujours du mal à obtenir les liens pour éviter de cliquer. Vouliez-vous que je conserve les return false if $(@).prop('disabled')gestionnaires de clics personnalisés? Sans cette ligne, ces gestionnaires sont exécutés malgré tout.
biofractal
1
@biofractal comme je l'ai mentionné disabledn'est pas une propriété de balise d'ancrage valide, donc cela ne devrait pas être utilisé. L'événement click j'ai donné est basé sur la .disabledclasse, mais ce que vous pouvez utiliser est hasClass('disabled')- si cela est vrai, preventDefault.
James Donnelly
Ah ok. Merci. Alors pourquoi ne devrais-je pas créer et utiliser la disabledpropriété sur l'ancre. C'est un objet dynamique, donc je peux simplement le définir et l'utiliser, comme si j'étais en train d'étendre le jeu de fonctionnalités de l'ancre? J'ai mis à jour ma réponse ci-dessous pour le montrer. Qu'est-ce que tu penses? Est-ce mal? De plus, devez-vous participer à .off()l' preventDefaultévénement click lorsque vous réactivez un lien?
biofractal
Cela va à l'encontre de la spécification et ne passerait pas les tests de validation. Si vous voulez une disabledpropriété personnalisée , vous pouvez utiliser des data-*attributs . Comme Bootstrap applique déjà les mêmes disabledstyles de propriété, class="disabled"vous pouvez également vous fier à la classe.
James Donnelly
J'ai compris - j'ai adapté ma réponse pour refléter vos commentaires. Je crains toujours que si je me connecte preventDefaultà tous les événements de clic d'ancrage, je devrai les détacher lorsque le lien sera réactivé. Ou est-ce que je comprends mal quelque chose?
biofractal
48

Je ne peux pas penser d'une manière plus simple / plus facile! ;-)


Utilisation de balises d'ancrage (liens):

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

Pour activer la balise d'ancrage:

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

entrez la description de l'image ici


Pour désactiver la balise d'ancrage:

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

entrez la description de l'image ici

oikonomopo
la source
27

Supposons que vous ayez un champ de texte et un bouton d'envoi,

<input type="text" id="text-field" />
<input type="submit" class="btn" value="Submit"/>

Désactivation:

Pour désactiver un bouton, par exemple, soumettre un bouton, il vous suffit d'ajouter un attribut désactivé comme,

$('input[type="submit"]').attr('disabled','disabled');

Après avoir exécuté la ligne ci-dessus, la balise html de votre bouton de soumission ressemblerait à ceci:

<input type="submit" class="btn" value="Submit" disabled/>

Notez que l'attribut «désactivé» a été ajouté .

Activation:

Pour activer le bouton, par exemple lorsque vous avez du texte dans le champ de texte. Vous devrez supprimer l' attribut disable pour activer le bouton comme,

 if ($('#text-field').val() != '') {
     $('input[type="submit"]').removeAttr('disabled');
 }

Maintenant, le code ci-dessus supprimera l'attribut «désactivé».

Sohail xIN3N
la source
22

Je sais que je suis en retard à la fête, mais pour répondre spécifiquement aux deux questions:

"Je veux juste désactiver les clicky-choses spécifiques pour que:

  • Ils arrêtent de cliquer
  • Ils ont l'air handicapés

Cela peut-il être difficile? "

Ils arrêtent de cliquer

1. Pour les boutons aiment <button>ou <input type="button">vous ajoutez l'attribut: disabled.

<button type="submit" disabled>Register</button>
<input type="button" value="Register" disabled>

2. Pour les liens, TOUT lien ... en fait, tout élément HTML, vous pouvez utiliser des événements de pointeur CSS3 .

.selector { pointer-events:none; }

La prise en charge du navigateur pour les événements de pointeur est impressionnante par l'état de l'art d'aujourd'hui (5/12/14). Mais nous devons généralement prendre en charge les navigateurs hérités dans le domaine IE, donc IE10 et les versions antérieures NE prennent PAS en charge les événements de pointeur: http://caniuse.com/pointer-events . Donc, utiliser l'une des solutions JavaScript mentionnées par d'autres ici peut être la voie à suivre pour les navigateurs hérités.

Plus d'informations sur les événements de pointeur:

Ils ont l'air handicapés

Évidemment, c'est une réponse CSS, donc:

1. Pour les boutons comme <button>ou <input type="button">utilisez le [attribute]sélecteur:

button[disabled] { ... }

input[type=button][disabled] { ... }

-

Voici une démo de base avec les éléments que j'ai mentionnés ici: http://jsfiddle.net/bXm5B/4/

J'espère que cela t'aides.

Ricardo Zea
la source
17

Si, comme moi, vous voulez juste désactiver un bouton, ne manquez pas la réponse simple subtilement cachée dans ce long fil:

 $("#button").prop('disabled', true);
Graham Laight
la source
le vrai héros, c'est tout ce dont j'avais besoin.
ricks
7

@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, donc je vais adapter son code pour qu'il fonctionne comme j'en ai besoin.

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)

Usage

$('.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 prennent en charge la disabledpropriété et, s'ils sont définis surtrue , ils auront l'air désactivés (grâce au bootstrap) et ne se déclencheront pas lorsque vous cliquez dessus.

Les ancres ne prennent pas en charge la propriété désactivé, nous allons donc compter sur la .disabledclasse pour les rendre désactivées (grâce au bootstrap à nouveau) et connecter un événement de clic par défaut qui empêche le clic en renvoyant false (pas besoin de preventDefaultvoir ici ) .

Remarque : vous n'avez pas besoin de décrocher cet événement lors de la réactivation des ancres. Il suffit de supprimer la .disabledclasse.

Bien sûr, cela n'aide pas si vous avez attaché un gestionnaire de clics personnalisé au lien, ce qui est très courant lors de l'utilisation de bootstrap et de jQuery. Donc, pour faire face à cela, nous allons utiliser l' isDisabled()extension pour tester la .disabledclasse, comme ceci:

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

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

12 tours
la source
7

Notez qu'il y a un problème étrange si vous utilisez les boutons JS de Bootstrap et l'état de «chargement». Je ne sais pas pourquoi cela se produit, mais voici comment y remédier.

Disons que vous avez un bouton et que vous le placez dans l'état de chargement:

var myButton = $('#myBootstrapButton');
myButton.button('loading');

Vous voulez maintenant le retirer de l'état de chargement, mais également le désactiver (par exemple, le bouton était un bouton Enregistrer, l'état de chargement indiquait une validation en cours et la validation a échoué). Cela ressemble à Bootstrap JS raisonnable:

myButton.button('reset').prop('disabled', true); // DOES NOT WORK

Malheureusement, cela réinitialisera le bouton, mais ne le désactivera pas. Apparemment, button()effectue une tâche retardée. Vous devrez donc également reporter votre désactivation:

myButton.button('reset');
setTimeout(function() { myButton.prop('disabled', true); }, 0);

Un peu ennuyeux, mais c'est un modèle que j'utilise beaucoup.

Henrik Heimbuerger
la source
6

Excellente réponse et contributions de tous! J'ai dû étendre légèrement cette fonction pour inclure la désactivation des éléments sélectionnés:

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

Je semble travailler pour moi. Merci a tous!

Brandon Johnson
la source
5

Pour ce genre de comportement, j'utilise toujours le buttonwidget jQueryUI , je l'utilise pour les liens et les boutons.

Définissez la balise dans HTML:

<button id="sampleButton">Sample Button</button>
<a id="linkButton" href="yourHttpReferenceHere">Link Button</a>

Utilisez jQuery pour initialiser les boutons:

$("#sampleButton").button();
$("#linkButton").button();

Utilisez les buttonméthodes du widget pour les désactiver / les activer:

$("#sampleButton").button("enable"); //enable the button
$("#linkButton").button("disable"); //disable the button

Cela prendra en charge le comportement du bouton et du curseur, mais si vous devez approfondir et modifier le style du bouton lorsqu'il est désactivé, remplacez les classes CSS suivantes dans votre fichier de style CSS de page.

.ui-state-disabled,
.ui-widget-content .ui-state-disabled,
.ui-widget-header .ui-state-disabled {
      background-color:aqua;
      color:black;
 }

Mais rappelez-vous: ces classes CSS (si elles sont modifiées) changeront également le style des autres widgets.

El Bayames
la source
1
Je suis sûr que cette réponse est pour les boutons jQuery UI et non pour les boutons Bootstrap utilisés avec jQuery vanilla ordinaire, ce dernier étant ce que l'OP utilise. D'ailleurs, mettre une réponse dans un commentaire sur la question n'est pas la méthode de diffusion préférée. ; ^)
ruffin
3

Ce qui suit a très bien fonctionné pour moi:

$("#button").attr('disabled', 'disabled');
Raptor
la source
2

C'est une réponse assez tardive, mais je suis tombé sur cette question en cherchant un moyen de désactiver les boutons boostrap après avoir cliqué dessus et peut-être ajouter un bel effet (par exemple un spinner). J'ai trouvé une excellente bibliothèque qui fait exactement cela:

http://msurguy.github.io/ladda-bootstrap/

Vous venez d'inclure les css et js requis, ajoutez des propriétés à vos boutons et activez lada avec javascript ... Presto! Vos boutons ont une nouvelle vie (veuillez vérifier la démo pour voir à quel point c'est beau)!

Serafeim
la source
2

Cela ne fonctionne pas parce que parfois

$(this).attr('checked') == undefined

ajustez votre code avec

if(!$(this).attr('checked') || $(this).attr('checked') == false){
Kiko Seijo
la source
2

Je sais que ma réponse est en retard, mais OMI, c'est le moyen le plus simple de basculer un bouton «activer» et un bouton «désactiver»

function toggleButtonState(button){

  //If button is enabled, -> Disable
  if (button.disabled === false) {
    button.disabled = true;

  //If button is disabled, -> Enable
  } else if (button.disabled === true) {
    button.disabled = false;
  }
}
jward01
la source
1

Supposons que vous ayez ces boutons sur la page comme:

<input type="submit" class="byBtn" disabled="disabled" value="Change"/>
<input type="submit" class="byBtn" disabled="disabled" value="Change"/>
<input type="submit" class="byBtn" disabled="disabled" value="Change"/>
<input type="submit" class="byBtn" disabled="disabled" value="Change"/>
<input type="submit" class="byBtn" disabled="disabled" value="Change"/>
<input type="submit"value="Enable All" onclick="change()"/>

Le code js:

function change(){
   var toenable = document.querySelectorAll(".byBtn");        
    for (var k in toenable){
         toenable[k].removeAttribute("disabled");
    }
}
Samit
la source
1

Supposons que vous en ayez un qui soit actuellement activé.

<button id="btnSave" class="btn btn-info">Save</button>

Ajoutez simplement ceci:

$("#btnSave").prop('disabled', true);

et vous obtiendrez ce qui désactivera le bouton

<button id="btnSave" class="btn btn-primary" disabled>Save</button>
Apollon
la source
2
La question portait sur les boutons et les ancres. La disabledpropriété n'est pas une propriété valide pour les balises d'ancrage.
biofractal
0

Si vous souhaitez désactiver le cliquable, vous pouvez également l'ajouter en ligne en html

style="cursor: not-allowed;"
Ken Xu
la source