¿Cómo puedo desactivar un botón en un diálogo de jQuery UI?

143

¿Cómo hago para deshabilitar un botón? en el cuadro de diálogo jQuery UI ? Parece que no puedo encontrar esto en ninguna de la documentación en el enlace de arriba.

Tengo 2 botones en la confirmación modal ("Confirmar" y "Cancelar"). En ciertos casos, quiero deshabilitar el botón "Confirmar".

leora
fuente
Vea las respuestas en este hilo: stackoverflow.com/questions/577548/…
Erik
55
@Erik: la situación ha cambiado un poco desde esas respuestas, es decir, debido al .button()complemento, por lo que ya no son necesariamente las mejores / más limpias soluciones.
Nick Craver

Respuestas:

158

Si incluye el .button()complemento / widget que contiene jQuery UI (si tiene la biblioteca completa y está en 1.8+, la tiene), puede usarla para deshabilitar el botón y actualizar el estado visualmente, así:

$(".ui-dialog-buttonpane button:contains('Confirm')").button("disable");

Puede probarlo aquí ... o si tiene una versión anterior o no usa el widget de botón, puede deshabilitarlo así:

$(".ui-dialog-buttonpane button:contains('Confirm')").attr("disabled", true)
                                              .addClass("ui-state-disabled");

Si lo desea dentro de un cuadro de diálogo específico, digamos por ID, haga esto:

$("#dialogID").next(".ui-dialog-buttonpane button:contains('Confirm')")
              .attr("disabled", true);

En otros casos en los que :contains()podría dar falsos positivos, puede usarlo .filter()así, pero es excesivo aquí ya que conoce sus dos botones. Si ese es el caso en otras situaciones, se vería así:

$("#dialogID").next(".ui-dialog-buttonpane button").filter(function() {
  return $(this).text() == "Confirm";
}).attr("disabled", true);

Esto evitaría que :contains()coincida una subcadena de otra cosa.

Nick Craver
fuente
next () no funcionará para mí, ya que existe todo el div "redimensionable" entre el diálogo y el buttonpan. Así que usé nextAll (), y separé el buttonPan del botón:$("#dialogID").nextAll(".ui-dialog-buttonpane").find("button:contains('Confirm')").attr("disabled", true).addClass("ui-state-disabled");
Matthieu
Tenga en cuenta que debido a que el panel de botones no es un elemento secundario del contenedor de diálogo, puede tener problemas si su página define varios diálogos.
Brett Ryan
Excelente solución, $(".ui-dialog-buttonpane button:contains('Confirm')").button("disable");aunque si desea deshabilitar el botón de una función que tiene para ello, debe widgetizar ese diálogo y deshabilitar el botón después de eso; como este$(this).dialog("widget").find(".ui-dialog-buttonpane button:contains('Confirm')").button("disable");
meridius
3
Tenga en cuenta que si no desea consultar el botón deseado por su texto, también puede asignarle una clase al botón; El cuadro de diálogo de jQuery UI admite una matriz con objetos para la opción de botón, cada objeto contiene información sobre los atributos de los botones.
Dennis
Esto funcionó para mí: $ (this) .closest (". Ui-dialog"). Find ("button: contiene ('Guardar')"). Prop ("disabled", true) .addClass ("ui-state- discapacitado");
Adrian P.
217

Parece que cualquiera, incluso en esta pregunta vinculada , ha propuesto esta solución, similar a la primera parte de la respuesta dada por Nick Craver:

$("#dialog").dialog({
    width: 480,
    height: "auto",
    buttons: [
        {
            id: "button-cancel",
            text: "Cancel",
            click: function() {
                $(this).dialog("close");
            }
        },
        {
            id: "button-ok",
            text: "Ok",
            click: function() {
                $(this).dialog("close");
            }
        }
    ]
});

Luego, en otro lugar, debería poder usar la API para el botón jquery UI:

$("#button-ok").button("disable");
Nicola Tuveri
fuente
15
+1. No estoy seguro de por qué esta respuesta no ha recibido más votos. Es el más limpio que he encontrado y funciona muy bien.
Doug Wilson el
38
Esto debe estar en los documentos ... ni siquiera muestra que puede asignar una identificación a los botones.
Jay K
1
Esta es sin duda la mejor respuesta. Existen otras soluciones que lo hacen buscando el botón utilizando selectores que están mal. Buen trabajo Nicola!
jnoreiga
44
De acuerdo: es LA solución que estaba pensando que el equipo de UI debería implementar ...: +) Puedes hacerlo aún más rápido:{text:"ok",disabled:true,click: function(){}}
Matthieu
10
¡Esto es genial! También puede usar "clase" en lugar de "id" si le preocupa que el id sea único. Aunque tendrá que escribir un poco más para buscar el botón:$("#dialog").dialog("widget").find(".button-ok-class").button("enable")
desm
49

También puede usar el atributo no documentado ahora disabled:

$("#element").dialog({
    buttons: [
    {
        text: "Confirm",
        disabled: true,
        id: "my-button-1"
    }, 
    {
        text: "Cancel",
        id: "my-button-2",
        click: function(){            
               $(this).dialog("close");
        }  

    }]
});

Para habilitar después de que se haya abierto el diálogo, use:

$("#my-button-1").attr('disabled', false);

JsFiddle: http://jsfiddle.net/xvt96e1p/4/

Jérôme
fuente
No es que sea indocumentado. Es que cuando se procesan los botones, todas las propiedades del objeto se ejecutan contra su equivalente de propiedad jQuery. Por ejemplo, puede agregar attr: { 'data-value' : 'some value here' }si desea agregar el atributo data-valueal botón.
aplastar
2
Ya no está documentado. Es oficial.
Salman A
Esta solución es mucho más elegante que la versión más popular. Esto le permite toda la flexibilidad sin el problema de selectores vagamente definidos.
KimvdLinde
Tenga en cuenta que el disabledatributo debe asignarse al crear los botones.
user1032531
Intenté votar en contra, pero voté hace 4 horas y no puedo hacerlo. Esta solución ya no parece funcionar correctamente.
user1032531
7

Lo siguiente funciona desde la función de clic de botones:

$(function() {
    $("#dialog").dialog({
        height: 'auto', width: 700, modal: true,
        buttons: {
            'Add to request list': function(evt) {

                // get DOM element for button
                var buttonDomElement = evt.target;
                // Disable the button
                $(buttonDomElement).attr('disabled', true);

                $('form').submit();
            },
            'Cancel': function() {
                $(this).dialog('close');
            }
        }
    });
}
Chris Pietschmann
fuente
pero luego tienes que hacer clic antes de que esté atenuado.
Matt
1

La clase identifica un botón ui-button. Para deshabilitar un botón:

$("#myButton").addClass("ui-state-disabled").attr("disabled", true);

A menos que esté creando dinámicamente el diálogo (que es posible), sabrá la posición del botón. Entonces, para deshabilitar el primer botón:

$("#myButton:eq(0)").addClass("ui-state-disabled").attr("disabled", true);

La ui-state-disabledclase es lo que le da a un botón ese bonito estilo atenuado.

Chris Laplante
fuente
1

Creé una función jQuery para hacer esta tarea un poco más fácil. Probablemente ahora hay una mejor solución ... de cualquier manera, aquí están mis 2 centavos. :)

Simplemente agregue esto a su archivo JS:

$.fn.dialogButtons = function(name, state){
var buttons = $(this).next('div').find('button');
if(!name)return buttons;
return buttons.each(function(){
    var text = $(this).text();
    if(text==name && state=='disabled') {$(this).attr('disabled',true).addClass('ui-state-disabled');return this;}
    if(text==name && state=='enabled') {$(this).attr('disabled',false).removeClass('ui-state-disabled');return this;}
    if(text==name){return this;}
    if(name=='disabled'){$(this).attr('disabled',true).addClass('ui-state-disabled');return buttons;}
    if(name=='enabled'){$(this).attr('disabled',false).removeClass('ui-state-disabled');return buttons;}
});};

Deshabilitar el botón 'Aceptar' en el diálogo con la clase 'diálogo'

$('.dialog').dialogButtons('Ok', 'disabled');

Habilitar todos los botones:

$('.dialog').dialogButtons('enabled');

Habilite el botón 'Cerrar' y cambie el color:

$('.dialog').dialogButtons('Close', 'enabled').css('color','red');

Texto en todos los botones rojos:

$('.dialog').dialogButtons().css('color','red');

Espero que esto ayude :)

sergiodlopes
fuente
1
function getDialogButton( jqUIdialog, button_names )
{
    if (typeof button_names == 'string')
        button_names = [button_names];
    var buttons = jqUIdialog.parent().find('.ui-dialog-buttonpane button');
    for (var i = 0; i < buttons.length; i++)
    {
        var jButton = $( buttons[i] );
        for (var j = 0; j < button_names.length; j++)
            if ( jButton.text() == button_names[j] )
                return jButton;
    }

    return null;
}

function enableDialogButton( jqUIdialog, button_names, enable )
{
    var button = getDialogButton( jqUIdialog, button_names );
    if (button == null)
        alert('button not found: '+button_names);
    else
    {
        if (enable)
            button.removeAttr('disabled').removeClass( 'ui-state-disabled' );
        else
            button.attr('disabled', 'disabled').addClass( 'ui-state-disabled' );
    }
}
Ronny Sherer
fuente
1

Puede sobrescribir la matriz de botones y dejar solo los que necesita.

$( ".selector" ).dialog( "option", "buttons", [{
    text: "Close",
    click: function() { $(this).dialog("close"); }
}] );
jfredys
fuente
1

este código deshabilita el botón con 'YOUR_BUTTON_LABEL'. puede reemplazar el nombre en contiene (). deshabilitar

$(".ui-dialog-buttonpane button:contains('YOUR_BUTTON_LABEL')").button("disable");

reemplace 'YOUR_BUTTON_LABEL' con la etiqueta de su botón. para permitir

$(".ui-dialog-buttonpane button:contains('YOUR_BUTTON_LABEL')").button("enable");
Sumeet_Pol
fuente
0

Puede hacer esto para deshabilitar el primer botón, por ejemplo:

$('.ui-dialog-buttonpane button:first').attr('disabled', 'disabled');
Darin Dimitrov
fuente
0

La forma en que lo hago es Cancel: function(e) { $(e.target).attr( "disabled","disabled" ); }

Esta es la forma más corta y fácil que encontré.

Bhavin
fuente
0

Si está utilizando knockout, entonces esto es aún más limpio. Imagina que tienes lo siguiente:

var dialog = $('#my-dialog').dialog({
    width: '100%',
    buttons: [
        { text: 'Submit', click: $.noop, 'data-bind': 'enable: items() && items().length > 0, click: onSubmitClicked' },
        { text: 'Enable Submit', click: $.noop, 'data-bind': 'click: onEnableSubmitClicked' }
    ]
});

function ViewModel(dialog) {
    var self = this;

    this.items = ko.observableArray([]);

    this.onSubmitClicked = function () {
        dialog.dialog('option', 'title', 'On Submit Clicked!');
    };

    this.onEnableSubmitClicked = function () {
        dialog.dialog('option', 'title', 'Submit Button Enabled!');
        self.items.push('TEST ITEM');
        dialog.text('Submit button is enabled.');
    };
}

var vm = new ViewModel(dialog);
ko.applyBindings(vm, dialog.parent()[0]); //Don't forget to bind to the dialog parent, or the buttons won't get bound.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/themes/smoothness/jquery-ui.css" />
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<div id="my-dialog">
  Submit button is disabled at initialization.
</div>

La magia proviene de la fuente jQuery UI :

$( "<button></button>", props )

Básicamente, puede llamar a CUALQUIER función de instancia de jQuery pasándola a través del objeto de botón.

Por ejemplo, si quieres usar HTML:

{ html: '<span class="fa fa-user"></span>User' }

O, si desea agregar una clase al botón (puede hacerlo de varias maneras):

{ addClass: 'my-custom-button-class' }

Tal vez estés loco, y quieras eliminar el botón del dom cuando está suspendido:

{ mouseover: function () { $(this).remove(); } }

Estoy realmente sorprendido de que nadie parezca haber mencionado esto en la infinidad de hilos como este ...

Persona especial
fuente
0

Esto funcionó para mí

$("#dialog-confirm").html('Do you want to permanently delete this?');
$( "#dialog-confirm" ).dialog({
    resizable: false,
    title:'Confirm',
    modal: true,
    buttons: {
        Cancel: function() {
            $( this ).dialog( "close" );
        },
        OK:function(){
            $('#loading').show();
            $.ajax({
                    type:'post',
                    url:'ajax.php',
                    cache:false,
                    data:{action:'do_something'},
                    async:true,
                    success:function(data){
                        var resp = JSON.parse(data);
                        $("#loading").hide();
                        $("#dialog-confirm").html(resp.msg);
                        $( "#dialog-confirm" ).dialog({
                                resizable: false,
                                title:'Confirm',
                                modal: true,
                                buttons: {
                                    Close: function() {
                                        $( this ).dialog( "close" );
                                    }
                                }
                        });
                    }
                });
        }
    }
}); 
Pramod Kumar
fuente
0

Puede deshabilitar un botón cuando construye el diálogo:

$(function() {
  $("#dialog").dialog({
    modal: true,
    buttons: [
      { text: "Confirm", click: function() { $(this).dialog("close"); }, disabled: true },
      { text: "Cancel", click: function() { $(this).dialog("close"); } }
    ]
  });
});
@import url("https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.min.css");
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>

<div id="dialog" title="Confirmation">
  <p>Proceed?</p>
</div>

O puede deshabilitarlo en cualquier momento después de crear el diálogo:

$(function() {
  $("#dialog").dialog({
    modal: true,
    buttons: [
      { text: "Confirm", click: function() { $(this).dialog("close"); }, "class": "confirm" },
      { text: "Cancel", click: function() { $(this).dialog("close"); } }
    ]
  });
  setTimeout(function() {
    $("#dialog").dialog("widget").find("button.confirm").button("disable");
  }, 2000);
});
@import url("https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.min.css");
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>

<div id="dialog" title="Confirmation">
  <p>Button will disable after two seconds.</p>
</div>

Salman A
fuente