¿Cuál es la forma más fácil de deshabilitar / habilitar botones y enlaces (jQuery + Bootstrap)

360

A veces uso anclas con estilo como botones y otras solo uso botones. Quiero deshabilitar cosas específicas para que:

  • Se ven discapacitados
  • Dejan de ser cliqueados

¿Cómo puedo hacer esto?

biofractal
fuente
vea mi publicación al final pero aquí está el botón menos descriptivo $ ("yourSelector"). ("enable"); // habilite el botón o $ ("yourSelector"). button ("deshabilitar"); // deshabilita el botón si se usa el widget de botón de jqueryUI.
El Bayames
La documentación de BS3 dice que se use role="button"para enlaces, pero eso no parece afectar este problema. getbootstrap.com/css/#buttons
Jess
2
Haber a.btn[disabled]aparecido deshabilitado pero seguir haciendo clic es un error en Bootstrap IMO. El atributo [disabled]solo debe aparecer deshabilitado para buttony input.
Jess

Respuestas:

575

Botones

Los botones son fáciles de deshabilitar, ya que disabledes una propiedad del botón que maneja el 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 deshabilitarlos con una función jQuery personalizada, simplemente usaría 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);

Botón deshabilitado JSFiddle y demo de entrada .

De lo contrario, utilizaría el prop()método de jQuery :

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

Etiquetas de anclaje

Vale la pena señalar que disabledno es una propiedad válida para las etiquetas de anclaje. Por esta razón, Bootstrap usa el siguiente estilo en sus .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;
}

Tenga en cuenta cómo [disabled]se orienta la propiedad, así como una .disabledclase. La .disabledclase es lo que se necesita para que una etiqueta de anclaje parezca deshabilitada.

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

Por supuesto, esto no impedirá que los enlaces funcionen al hacer clic. El enlace anterior nos llevará a http://example.com . Para evitar esto, podemos agregar una pieza simple de código jQuery para dirigir las etiquetas de anclaje con la disabledclase a la que llamar event.preventDefault():

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

Podemos alternar la disabledclase 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);

JSFiddle deshabilitó la demostración del enlace .


Conjunto

Luego, podemos extender la función de deshabilitación anterior hecha anteriormente para verificar el tipo de elemento que estamos intentando deshabilitar is(). De esta manera podemos toggleClass()si no es una inputo buttonelemento, o alternar la disabledpropiedad si se trata de:

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

Demo combinada completa de JSFiddle .

Vale la pena señalar que la función anterior también funcionará en todos los tipos de entrada.

James Donnelly
fuente
Gracias por la respuesta integral. Consulte mi Edición 1 para obtener una versión de script de café. Todavía estoy luchando por obtener los enlaces para evitar hacer clic. ¿Querías mantener los return false if $(@).prop('disabled')controladores de clics personalizados? Sin esa línea, esos controladores se ejecutan independientemente.
biofractal
1
@biofractal como mencioné disabledno es una propiedad válida de etiqueta de anclaje, por lo que no debería usarse. El evento de clic que he dado se basa en la .disabledclase, pero lo que se puede utilizar es hasClass('disabled')- si eso es cierto, preventDefault.
James Donnelly
ah ok Gracias. Entonces, ¿por qué no debería crear y usar la disabledpropiedad en el ancla? Es un objeto dinámico, así que solo puedo configurarlo y usarlo, como si estuviera extendiendo el conjunto de características del ancla. He actualizado mi respuesta a continuación para mostrar esto. ¿Qué piensas? ¿Es malo? Además, usted tiene que .off()el preventDefaultevento de clic cuando se vuelva a habilitar un enlace?
biofractal
Va en contra de la especificación y no pasaría las pruebas de validación. Si desea una disabledpropiedad personalizada , puede utilizar los data-*atributos . Como Bootstrap ya aplica los mismos disabledestilos de propiedad, class="disabled"también puedes confiar en la clase.
James Donnelly
Entendido: he adaptado mi respuesta para reflejar sus comentarios. Todavía me preocupa que si conecto preventDefaulttodos los eventos de clic de anclaje, tendré que separarlos cuando se vuelva a habilitar el enlace. ¿O estoy malinterpretando algo?
biofractal
48

¡No puedo pensar de una manera más simple / fácil! ;-)


Uso de etiquetas de anclaje (enlaces):

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

Para habilitar la etiqueta de anclaje:

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

ingrese la descripción de la imagen aquí


Para deshabilitar la etiqueta de anclaje:

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

ingrese la descripción de la imagen aquí

oikonomopo
fuente
27

Supongamos que tiene un campo de texto y un botón de enviar,

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

Deshabilitante:

Para deshabilitar cualquier botón, por ejemplo, el botón enviar solo necesita agregar el atributo deshabilitado como

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

Después de ejecutar la línea anterior, su etiqueta html de botón de envío se vería así:

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

Observe que se ha agregado el atributo 'deshabilitado' .

Habilitación:

Para habilitar el botón, como cuando tiene texto en el campo de texto. Deberá eliminar el atributo de desactivación para habilitar el botón como,

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

Ahora el código anterior eliminará el atributo 'deshabilitado'.

Sohail xIN3N
fuente
22

Sé que llego tarde a la fiesta, pero específicamente para responder las dos preguntas:

"Solo quiero deshabilitar cosas específicas para que:

  • Dejan de hacer clic
  • Se ven discapacitados

¿Qué tan difícil puede ser esto?

Dejan de hacer clic

1. Para los botones gusta <button>o <input type="button">que añadir el atributo: disabled.

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

2. Para enlaces, CUALQUIER enlace ... en realidad, cualquier elemento HTML, puede usar eventos de puntero CSS3 .

.selector { pointer-events:none; }

El soporte del navegador para eventos de puntero es impresionante por el estado actual de la técnica (5/12/14). Pero generalmente tenemos que admitir navegadores heredados en el ámbito de IE, por lo que IE10 y versiones inferiores NO admiten eventos de puntero: http://caniuse.com/pointer-events . Por lo tanto, usar una de las soluciones de JavaScript mencionadas por otros aquí puede ser el camino a seguir para los navegadores heredados.

Más información sobre eventos de puntero:

Se ven discapacitados

Obviamente esta es una respuesta CSS, entonces:

1. Para botones como <button>o <input type="button">use el [attribute]selector:

button[disabled] { ... }

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

-

Aquí hay una demostración básica con las cosas que mencioné aquí: http://jsfiddle.net/bXm5B/4/

Espero que esto ayude.

Ricardo Zea
fuente
17

Si, como yo, solo desea deshabilitar un botón, no se pierda la respuesta simple sutilmente oculta en este largo hilo:

 $("#button").prop('disabled', true);
Graham Laight
fuente
El verdadero héroe, esto es todo lo que necesitaba.
ricks
7

@James Donnelly ha proporcionado una respuesta integral que se basa en extender jQuery con una nueva función. Esa es una gran idea, así que voy a adaptar su código para que funcione como lo necesito.

Extendiendo 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()

El código procesará un solo elemento o una lista de elementos.

Los botones y las entradas admiten la disabledpropiedad y, si se configuran true, se verán deshabilitados (gracias a bootstrap) y no se activarán al hacer clic.

Los anclajes no admiten la propiedad deshabilitada, por lo que confiaremos en la .disabledclase para que se vean deshabilitados (gracias a bootstrap nuevamente) y conectemos un evento de clic predeterminado que evite que el clic regrese falso (no es necesario preventDefaultverlo aquí ) .

Nota : No es necesario desenganchar este evento al volver a habilitar los anclajes. Simplemente eliminar la .disabledclase hace el truco.

Por supuesto, esto no ayuda si ha adjuntado un controlador de clic personalizado al enlace, algo que es muy común al usar bootstrap y jQuery. Entonces, para lidiar con esto, vamos a usar la isDisabled()extensión para probar la .disabledclase, así:

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

Espero que eso ayude a simplificar un poco las cosas.

revs biofractal
fuente
7

Tenga en cuenta que hay un problema extraño si está utilizando los botones JS de Bootstrap y el estado de "carga". No sé por qué sucede esto, pero he aquí cómo solucionarlo.

Digamos que tiene un botón y lo configura en el estado de carga:

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

Ahora desea sacarlo del estado de carga, pero también deshabilitarlo (por ejemplo, el botón era un botón Guardar, el estado de carga indicaba una validación continua y la validación falló). Esto parece razonable Bootstrap JS:

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

Desafortunadamente, eso restablecerá el botón, pero no lo deshabilitará. Al parecer, button()realiza alguna tarea retrasada. Entonces también tendrás que posponer tu inhabilitación:

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

Un poco molesto, pero es un patrón que estoy usando mucho.

Henrik Heimbuerger
fuente
6

Gran respuesta y contribuciones de todos! Tuve que extender esta función ligeramente para incluir la desactivación de elementos seleccionados:

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 trabajando para mí. ¡Gracias a todos!

Brandon Johnson
fuente
5

Para ese tipo de comportamiento, siempre uso el buttonwidget jQueryUI , lo uso para enlaces y botones.

Defina la etiqueta en HTML:

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

Use jQuery para inicializar los botones:

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

Use los buttonmétodos del widget para deshabilitarlos / habilitarlos:

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

Eso se encargará del comportamiento del botón y el cursor, pero si necesita profundizar y cambiar el estilo del botón cuando está deshabilitado, sobrescriba las siguientes clases CSS dentro del archivo de estilo CSS de su página.

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

Pero recuerde: esas clases CSS (si se cambian) también cambiarán el estilo de otros widgets.

El Bayames
fuente
1
Estoy bastante seguro de que esta respuesta es para los botones jQuery UI y no para los botones Bootstrap utilizados con jQuery simple, ya que este último es el que está utilizando el OP. Por cierto, poner una respuesta en un comentario sobre la pregunta no es el método preferido de difusión. ; ^)
ruffin
3

Lo siguiente me ha funcionado muy bien:

$("#button").attr('disabled', 'disabled');
Rapaz
fuente
2

Esta es una respuesta bastante tardía, sin embargo, me topé con esta pregunta mientras buscaba una forma de deshabilitar los botones de arranque después de hacer clic en ellos y tal vez agregar un buen efecto (por ejemplo, un spinner). He encontrado una gran biblioteca que hace exactamente eso:

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

Solo incluye los css y js requeridos, agrega algunas propiedades a tus botones y habilita lada con javascript ... ¡Presto! ¡Sus botones tienen una nueva vida (por favor revise la demostración para ver qué hermoso es)!

Serafeim
fuente
2

Lo anterior no funciona porque a veces

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

ajusta tu código con

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

Sé que mi respuesta llega tarde, pero en mi opinión, esta es la forma más fácil de alternar un botón 'habilitar' y un botón 'deshabilitar'

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

Supongamos que tiene estos botones en la 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()"/>

El código js:

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

Digamos que tiene ese aspecto que está habilitado actualmente.

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

Solo agrega esto:

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

y obtendrás esto que deshabilitará el botón

<button id="btnSave" class="btn btn-primary" disabled>Save</button>
Apolo
fuente
2
La pregunta se refería a botones y anclas. La disabledpropiedad no es una propiedad válida para etiquetas de anclaje.
biofractal
0

Si desea deshabilitar los clics, también puede agregar esto en línea en html

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