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

A veces utilizo anclas con estilo de botones y a veces sólo utilizo botones. Quiero desactivar las cosas clicks específicas para que:

  • Se vean deshabilitados
  • Dejen de ser pulsados

¿Cómo puedo hacerlo?

Solución

Botones

Los botones son sencillos de desactivar ya que disabled es una propiedad del botón que es manejada por el navegador:

idioma: html -->

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

Para desactivarlas con una función personalizada de jQuery, basta con hacer uso de fn.extend():

lenguaje: javascript -->

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

[Demostración de botones y entradas desactivadas de JSFiddle][2].

De lo contrario, usted's hacer uso de jQuery's prop() método:

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

Anchor Tags

Cabe destacar que disabled no es una propiedad válida para las etiquetas de anclaje. Por esta razón, Bootstrap utiliza el siguiente estilo en sus elementos .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;
}

Observe cómo la propiedad [disabled] está orientada así como una clase .disabled. La clase .disabled es lo que se necesita para que una etiqueta de anclaje aparezca desactivada.

Idioma: html -->

<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 añadir un simple trozo de código jQuery para apuntar a las etiquetas de anclaje con la clase disabled para llamar a event.preventDefault():

-- Lenguaje: javascript -->

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

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

[Demostración de enlace deshabilitado de JSFiddle][8].


Combinado

Podemos entonces extender la función disable anterior para comprobar el tipo de elemento que estamos intentando deshabilitar usando is(). De esta manera podemos toggleClass() si no es un elemento input o button, o alternar la propiedad disabled si lo es:

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

[Demostración completa de JSFiddle][10].

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

Comentarios (17)

No se me ocurre una forma más sencilla/fácil ;-)


Uso de etiquetas de anclaje (enlaces) :

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

Para activar la etiqueta Anchor:

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


Para desactivar la etiqueta Anchor:

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

introduzca aquí la descripción de la imagen

Comentarios (0)

@James Donnelly ha proporcionado una respuesta completa que se basa en la ampliación de jQuery con una nueva función. Es una gran idea, así que voy a adaptar su código para que funcione como yo lo necesito.

Extender 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 propiedad disabled y, si se establece como true, se verán deshabilitados (gracias a bootstrap) y no se dispararán al hacer clic.

Los anclajes no soportan la propiedad "disabled", por lo que vamos a confiar en la clase "disabled" para hacer que se vean deshabilitados (gracias a bootstrap de nuevo) y enganchar un evento de clic por defecto que impida el clic devolviendo false (no es necesario el preventDefault ver aquí).

Nota: No es necesario desenganchar este evento cuando se vuelvan a habilitar los anclajes. Basta con eliminar la clase .disabled para que funcione.

Por supuesto, esto no ayuda si has adjuntado un manejador de clic personalizado al enlace, algo que es muy común cuando se usa bootstrap y jQuery. Así que para lidiar con esto vamos a usar la extensión isDisabled() para probar la clase .disabled, así:

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

Espero que esto ayude a simplificar un poco las cosas.

Comentarios (0)