Como posso desativar um botão em uma caixa de diálogo jQuery UI?

143

Como desabilito um botão na caixa de diálogo jQuery UI . Não consigo encontrar isso em nenhuma documentação no link acima.

Eu tenho 2 botões na confirmação modal ("Confirmar" e "Cancelar"). Em certos casos, desejo desativar o botão "Confirmar".

leora
fonte
Veja as respostas neste tópico: stackoverflow.com/questions/577548/…
Erik
5
@Erik - A situação mudou um pouco desde essas respostas, principalmente por causa do .button()plug - in, então elas não são mais as melhores / mais limpas soluções.
Nick Craver

Respostas:

158

Se você estiver incluindo o .button()plug - in / widget que a jQuery UI contém (se você possui a biblioteca completa e está no 1.8+, você o possui), você pode usá-lo para desativar o botão e atualizar o estado visualmente, assim:

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

Você pode experimentá-lo aqui ... ou, se você estiver em uma versão mais antiga ou não estiver usando o widget de botão, poderá desativá-lo assim:

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

Se você quiser dentro de uma caixa de diálogo específica, diga por ID e faça o seguinte:

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

Em outros casos em que :contains()pode dar falsos positivos, você pode usar .filter()assim, mas é um exagero aqui, pois você conhece seus dois botões. Se esse for o caso em outras situações, seria assim:

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

Isso impediria a :contains()correspondência de uma substring de outra coisa.

Nick Craver
fonte
next () não funcionará para mim, pois há toda a divisão "redimensionável" entre a caixa de diálogo e a abotoadura. Então eu usei nextAll (), e separar a buttonPan a partir do botão:$("#dialogID").nextAll(".ui-dialog-buttonpane").find("button:contains('Confirm')").attr("disabled", true).addClass("ui-state-disabled");
Matthieu
Observe que, devido ao painel de botões não ser filho do contêiner de diálogo, você poderá ter problemas se sua página definir várias caixas de diálogo.
Brett Ryan
Excelente solução, $(".ui-dialog-buttonpane button:contains('Confirm')").button("disable");embora, se você deseja desativar o botão de uma função que você possui, é necessário widgetizar esse diálogo e desativar o botão depois; assim$(this).dialog("widget").find(".ui-dialog-buttonpane button:contains('Confirm')").button("disable");
meridius 25/09
3
Observe que, se você não deseja consultar o botão desejado pelo texto, também pode dar uma classe ao botão; O diálogo da interface do usuário do jQuery suporta uma matriz com objetos para a opção de botão, cada objeto contendo informações sobre os atributos dos botões.
Dennis
Isso funcionou para mim: $ (this) .closest (". Ui-dialog"). Find ("button: contains ('Save')"). Prop ("disabled", true) .addClass ("ui-state- Desativado");
Adrian P.
217

Parece que qualquer pessoa, mesmo nesta pergunta vinculada , propôs esta solução, semelhante à primeira parte da resposta 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");
            }
        }
    ]
});

Em outros lugares, você poderá usar a API para o botão da interface do usuário do jquery:

$("#button-ok").button("disable");
Nicola Tuveri
fonte
15
+1. Não sei por que essa resposta não recebeu mais votos. É o mais limpo que já encontrei e funciona muito bem.
Doug Wilson
38
Isso precisa constar nos documentos ... nem mostra que você pode atribuir um ID aos botões.
Jay K
1
Esta é sem dúvida a melhor resposta. Existem outras soluções por aí pesquisando o botão usando seletores que estão errados. Bom trabalho Nicola!
Jnoreiga # 24/12
4
Concordam: é a solução que eu estava pensando a equipe UI deve implementar ...: +) Você pode fazer ainda mais rápido:{text:"ok",disabled:true,click: function(){}}
Matthieu
10
Isso é ótimo! Você também pode usar "classe" em vez de "id" se estiver preocupado com o ID ser exclusivo. Embora você precise digitar um pouco mais para procurar o botão:$("#dialog").dialog("widget").find(".button-ok-class").button("enable")
desm 30/07/2013
49

Você também pode usar o atributo não documentado agora disabled:

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

    }]
});

Para ativar após a abertura da caixa de diálogo, use:

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

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

Jérôme
fonte
Não é que não esteja documentado. É que, quando os botões são processados, todas as propriedades do objeto são executadas em relação à sua propriedade jQuery equivalente. Por exemplo, você pode adicionar attr: { 'data-value' : 'some value here' }se quiser adicionar o atributo data-valueao botão.
esmagar
2
Não está mais documentado. É oficial.
Salman A
Esta solução é muito mais elegante que a versão mais popular. Isso permite toda a flexibilidade sem o problema de seletores vagamente definidos.
KimvdLinde
Observe que o disabledatributo deve ser atribuído ao criar os botões.
user1032531
Tentei diminuir o voto, mas votei há 4 horas e não posso fazê-lo. Esta solução não parece mais funcionar corretamente.
user1032531
7

Os seguintes trabalhos de dentro dos botões clicam na função:

$(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
fonte
mas você precisa clicar antes de ficar acinzentado.
Matt
1

Um botão é identificado pela classe ui-button. Para desativar um botão:

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

A menos que esteja criando dinamicamente a caixa de diálogo (o que é possível), você saberá a posição do botão. Portanto, para desativar o primeiro botão:

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

A ui-state-disabledclasse é o que dá a um botão esse belo estilo esmaecido.

Chris Laplante
fonte
1

Eu criei uma função jQuery para facilitar essa tarefa. Provavelmente agora existe uma solução melhor ... de qualquer maneira, aqui estão meus 2 centavos. :)

Basta adicionar isso ao seu arquivo 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;}
});};

Desative o botão 'Ok' na caixa de diálogo com a classe 'dialog':

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

Ative todos os botões:

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

Ative o botão 'Fechar' e altere a cor:

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

Texto em todos os botões em vermelho:

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

Espero que isto ajude :)

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

Você pode substituir a matriz de botões e deixar apenas as necessárias.

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

esse código desabilita o botão com 'YOUR_BUTTON_LABEL'. você pode substituir o nome em contains (). desabilitar

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

substitua 'YOUR_BUTTON_LABEL' pela etiqueta do seu botão. para habilitar

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

Você pode fazer isso para desativar o primeiro botão, por exemplo:

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

O jeito que eu faço é Cancel: function(e) { $(e.target).attr( "disabled","disabled" ); }

Esta é a maneira mais curta e fácil de encontrar.

Bhavin
fonte
0

Se você estiver usando o nocaute, isso é ainda mais limpo. Imagine que você tem o seguinte:

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>

A mágica vem da fonte da interface do usuário do jQuery :

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

Basicamente, você pode chamar QUALQUER função de instância jQuery passando-a pelo objeto button.

Por exemplo, se você deseja usar HTML:

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

Ou, se você quiser adicionar uma classe ao botão (você pode fazer isso de várias maneiras):

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

Talvez você seja louco e queira remover o botão do dom quando estiver pairando:

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

Estou realmente surpreso que ninguém parece ter mencionado isso no número incontável de threads como este ...

A paixão súbita
fonte
0

Isso funcionou para mim -

$("#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
fonte
0

Você pode desativar um botão ao criar a caixa de 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>

Ou você pode desativá-lo a qualquer momento após a criação da caixa de 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
fonte