Qual é a maneira mais fácil de desativar / ativar botões e links (jQuery + Bootstrap)

360

Às vezes, uso âncoras denominadas botões e, às vezes, apenas uso botões. Desejo desativar cliques específicos para que:

  • Eles parecem desativados
  • Eles param de ser clicados

Como posso fazer isso?

biofractal
fonte
veja minha postagem na parte inferior, mas aqui está o menos descritivo $ ("yourSelector"). button ("enable"); // habilita o botão ou $ ("yourSelector"). button ("disable"); // desabilite o botão se o widget de botão do jqueryUI for usado.
El Bayames
A documentação do BS3 diz para usar role="button"em links, mas isso não parece afetar esse problema. getbootstrap.com/css/#buttons
Jess
2
Tendo a.btn[disabled]aparecer desativado ainda permanecem clicável é um bug no Bootstrap IMO. O atributo [disabled]deve aparecer apenas desativado para buttone input.
Jess

Respostas:

575

Botões

Os botões são simples de desativar, pois disabledé uma propriedade de botão que é manipulada pelo navegador:

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

Para desabilitá-los com uma função jQuery personalizada, basta usar 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);

JSFiddle botão desativado e demonstração de entrada .

Caso contrário, você faria uso do jQuery prop() método :

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

Tags de âncora

Vale ressaltar que disablednão é uma propriedade válida para tags de âncora. Por esse motivo, o Bootstrap usa o seguinte estilo em seus .btnelementos:

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

Observe como a [disabled]propriedade é segmentada, bem como um.disabled classe. A .disabledclasse é o que é necessário para fazer uma marca de âncora parecer desativada.

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

Obviamente, isso não impedirá que os links funcionem quando clicados. O link acima nos levará a http://example.com . Para evitar isso, podemos adicionar um pedaço simples de código jQuery para direcionar tags âncora com a disabledclasse a ser chamada event.preventDefault():

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

Podemos alternar a disabledclasse usando 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);

Demonstração do link desativado do JSFiddle .


Combinado

Podemos então estender a função de desativação anterior feita acima para verificar o tipo de elemento que estamos tentando desativar usando is(). Desta forma, podemos toggleClass(), se não é um inputou buttonelemento, ou alternar a disabledpropriedade se ela é:

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

Demonstração JSFiddle combinada completa .

Vale a pena notar ainda que a função acima também funcionará em todos os tipos de entrada.

James Donnelly
fonte
Obrigado pela resposta abrangente. Por favor, veja meu Edit 1 para uma versão do script de café. Ainda estou lutando para obter os links para impedir o clique. Você queria que eu mantivesse os return false if $(@).prop('disabled')manipuladores de cliques personalizados? Sem essa linha, esses manipuladores são executados independentemente.
biofractal 28/05
11
O @biofractal, como mencionei, disablednão é uma propriedade válida da marca âncora, portanto não deve ser usada. O evento de clique que eu dei é baseado na .disabledclasse, mas o que você pode usar é hasClass('disabled')- se isso for verdade preventDefault,.
James Donnelly
Ah ok. Obrigado. Então, por que não devo criar e usar a disabledpropriedade na âncora? É um objeto dinâmico para que eu possa defini-lo e usá-lo, como se estivesse estendendo o conjunto de recursos da âncora? Atualizei minha resposta abaixo para mostrar isso. O que você acha? Isso é mau? Além disso, você precisa .off()do preventDefaultevento click ao reativar um link?
biofractal 28/05
Isso vai contra a especificação e não passa nos testes de validação. Se você deseja uma disabledpropriedade customizada, pode usar data-*atributos . Como o Bootstrap já aplica os mesmos disabledestilos de propriedade, class="disabled"você também pode confiar na classe.
James Donnelly 28/05
Entendi - adaptei minha resposta para refletir seus comentários. Ainda estou preocupado que, se eu conectar preventDefaulttodos os eventos de clique de âncora, precisarei desanexá-los quando o link for reativado. Ou estou entendendo mal alguma coisa?
Biofractal 28/05
48

Não consigo pensar em uma maneira mais simples / fácil! ;-)


Usando tags Anchor (Links):

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

Para habilitar a tag Anchor:

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

insira a descrição da imagem aqui


Para desativar a marca Anchor:

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

insira a descrição da imagem aqui

oikonomopo
fonte
27

Suponha que você tenha o campo de texto e o botão enviar,

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

Desativando:

Para desativar qualquer botão, por exemplo, enviar botão, basta adicionar o atributo desativado como,

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

Depois de executar a linha acima, a tag html do botão enviar ficaria assim:

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

Observe que o atributo 'disabled' foi adicionado .

Possibilitando:

Para ativar o botão, como quando você tem algum texto no campo de texto. Você precisará remover o atributo desativar para ativar o botão como,

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

Agora, o código acima removerá o atributo 'disabled'.

Sohail xIN3N
fonte
22

Sei que estou atrasado para a festa, mas para responder especificamente às duas perguntas:

"Eu só quero desativar cliques específicos para que:

  • Eles param de clicar
  • Eles parecem desativados

Quão difícil isso pode ser? "

Eles param de clicar

1. Para os botões gosta <button>ou <input type="button">você adicionar o atributo: disabled.

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

2. Para links, QUALQUER link ... na verdade, qualquer elemento HTML, você pode usar eventos de ponteiro CSS3 .

.selector { pointer-events:none; }

O suporte do navegador para eventos de ponteiro é impressionante pelo estado da arte de hoje (5/12/14). Mas geralmente precisamos oferecer suporte a navegadores herdados no domínio do IE, portanto o IE10 e abaixo NÃO suportam eventos de ponteiro: http://caniuse.com/pointer-events . Portanto, o uso de uma das soluções JavaScript mencionadas por outras pessoas aqui pode ser o caminho a percorrer para navegadores herdados.

Mais informações sobre eventos do ponteiro:

Eles parecem desativados

Obviamente, esta é uma resposta CSS, então:

1. Para botões como <button>ou <input type="button">use o [attribute]seletor:

button[disabled] { ... }

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

-

Aqui está uma demonstração básica com as coisas que mencionei aqui: http://jsfiddle.net/bXm5B/4/

Espero que isto ajude.

Ricardo Zea
fonte
17

Se, como eu, você apenas deseja desativar um botão, não perca a resposta simples sutilmente oculta neste longo tópico:

 $("#button").prop('disabled', true);
Graham Laight
fonte
o verdadeiro herói, isso é tudo que eu precisava.
Ricks
7

@ James Donnelly forneceu uma resposta abrangente que se baseia na extensão do jQuery com uma nova função. Essa é uma ótima idéia, então eu vou adaptar o código dele para que funcione da maneira que eu preciso.

Estendendo o 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)

Uso

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

O código processará um único elemento ou uma lista de elementos.

Botões e entradas suportam a disabledpropriedade e, se definido comotrue , parecerão desativados (graças à inicialização) e não serão acionados quando clicados.

As âncoras não suportam a propriedade desativada; portanto, confiaremos no .disabled classe para fazê-la parecer desabilitada (graças ao bootstrap novamente) e conectamos um evento de clique padrão que impede o clique retornando false (não há necessidade de preventDefaultver aqui ) .

Nota : Você não precisa soltar esse evento ao reativar âncoras. Simplesmente remover a .disabledturma faz o truque.

Obviamente, isso não ajuda se você anexou um manipulador de cliques personalizado ao link, algo que é muito comum ao usar o bootstrap e o jQuery. Então, para lidar com isso, vamos usar a isDisabled()extensão para testar a.disabled classe, assim:

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

Espero que ajude a simplificar um pouco as coisas.

biofractal
fonte
7

Observe que há um problema estranho se você estiver usando os botões JS do Bootstrap e o estado 'loading'. Não sei por que isso acontece, mas aqui está como corrigi-lo.

Digamos que você tenha um botão e defina-o no estado de carregamento:

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

Agora você deseja retirá-lo do estado de carregamento, mas também desativá-lo (por exemplo, o botão era um botão Salvar, o estado de carregamento indicava uma validação em andamento e a validação falhou). Parece JS de Bootstrap razoável:

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

Infelizmente, isso redefinirá o botão, mas não o desativará. Aparentemente, button()executa alguma tarefa atrasada. Portanto, você também precisará adiar sua desativação:

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

Um pouco chato, mas é um padrão que estou usando bastante.

Henrik Heimbuerger
fonte
6

Ótima resposta e contribuições de todos! Eu tive que estender essa função ligeiramente para incluir a desativação de elementos selecionados:

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

Parece estar trabalhando para mim. Obrigado a todos!

Brandon Johnson
fonte
5

Para esse tipo de comportamento, eu sempre uso o buttonwidget jQueryUI , para links e botões.

Defina a tag no HTML:

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

Use jQuery para inicializar os botões:

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

Use os buttonmétodos do widget para desativá-los / ativá-los:

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

Isso cuidará do comportamento do botão e do cursor, mas se você precisar se aprofundar e alterar o estilo do botão quando desativado, substitua as seguintes classes CSS no arquivo de estilo CSS da página.

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

Mas lembre-se: essas classes CSS (se alteradas) também mudarão o estilo para outros widgets.

El Bayames
fonte
11
Certamente, essa resposta é para os botões da interface do usuário do jQuery e não para os botões do Bootstrap usados ​​com o jQuery comum, o último sendo o que o OP está usando. Aliás, colocar uma resposta em um comentário sobre a questão não é o método preferido de divulgação. ; ^)
ruffin
3

O seguinte funcionou muito bem para mim:

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

Esta é uma resposta bastante tardia, no entanto, me deparei com essa pergunta enquanto procurava uma maneira de desativar os botões do boostrap após clicar neles e talvez adicionar um efeito interessante (por exemplo, um girador). Eu encontrei uma ótima biblioteca que faz exatamente isso:

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

Você acabou de incluir os css e js necessários, adicionar algumas propriedades aos botões e ativar o lada com javascript ... Presto! Seus botões têm uma nova vida (verifique a demonstração para ver como é bonito)!

Serafeim
fonte
2

Isso acima não funciona porque às vezes

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

ajuste seu código com

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

Sei que minha resposta está atrasada, mas na OMI é a maneira mais fácil de alternar entre os botões 'ativar' e 'desativar'

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

Suponha que você tenha esses botões na página como:

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

O código js:

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

Digamos que você tenha essa aparência ativada no momento.

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

Apenas adicione isto:

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

e você vai conseguir isso que irá desativar o botão

<button id="btnSave" class="btn btn-primary" disabled>Save</button>
Apollo
fonte
2
A pergunta feita sobre botões e âncoras. A disabledpropriedade não é uma propriedade válida para tags de âncora.
biofractal
0

Se você deseja desativar o clicável, também pode adicioná-lo em linha em html

style="cursor: not-allowed;"
Ken Xu
fonte