145

How do I go about disabling a button on the jQuery UI dialog. I can't seem to find this in any of the documentation in the link above.

I have 2 buttons on the modal confirmation ("Confirm" and "Cancel"). In certain cases, I want to disable the "Confirm" button.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
leora
  • 188,729
  • 360
  • 878
  • 1,366
  • See the answers in this thread: http://stackoverflow.com/questions/577548/how-can-i-disable-a-button-in-a-jquery-dialog-from-a-function – Erik Sep 05 '10 at 14:42
  • 5
    @Erik - The situation has changed a bit since those answers, namely because of the `.button()` plugin, so they're not necessarily the best/cleanest solutions anymore. – Nick Craver Sep 05 '10 at 14:55

14 Answers14

220

Looks like anyone, even in this linked question, have proposed this solution, similar to the first part of the answer given by 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");
            }
        }
    ]
});

Then, elsewhere, you should be able to use the API for the jquery UI button:

$("#button-ok").button("disable");
Community
  • 1
  • 1
Nicola Tuveri
  • 2,209
  • 1
  • 13
  • 5
  • 15
    +1. I am not sure why this answer has not received more votes. It's the cleanest I have come across and works nicely. – Doug Wilson Jan 19 '12 at 18:43
  • 39
    This needs to be in the docs... it doesn't even show that you can assign an id to buttons. – Jay K Feb 06 '12 at 17:30
  • 1
    This is without a doubt the best answer. There are other solutions out there that do it by searching for the button using selectors that are wrong. Good job Nicola! – jnoreiga Sep 24 '12 at 18:15
  • 4
    Agree : it's THE solution I was thinking the UI team should implement... :+) You can do even quicker : `{text:"ok",disabled:true,click: function(){}}` – Matthieu Nov 15 '12 at 09:32
  • 10
    This is great! You can also use "class" instead of "id" if you are worried about the id being unique. Though you will have to type a bit more in order to search for the button: `$("#dialog").dialog("widget").find(".button-ok-class").button("enable")` – desm Jul 30 '13 at 09:28
  • **Hint:** Enabling works similar, see this [linked answer.](http://stackoverflow.com/a/17331742/1016343) – Matt May 19 '14 at 14:38
  • Does this syntax work with JQ 1.4.2? I just get two buttons labled 0 and 1. – SomeRandomDeveloper Jun 03 '14 at 21:57
  • 1
    *Be careful with this solution*: don't forget that ids are to be unique per document. You can do more than assign `id` to a button. You can invoke any jQuery function by passing it as a property of the button object. For example, html: `[ html: 'Some Text!' ]`. The magic is in line 10529 of the jquery-ui source: `$( "", props )` where props is the object that defines your button. – crush Dec 03 '14 at 22:20
  • If you're using a class, then you can also do something like this jQuery(".selector", jQuery("#dialogID").parent("div")).button("disable"); Replace the #dialogID with "this" (unquoted) if you want to do this from inside a function/event such as create, close etc – Phil Hawthorne Mar 05 '15 at 06:29
159

If you're including the .button() plugin/widget that jQuery UI contains (if you have the full library and are on 1.8+, you have it), you can use it to disable the button and update the state visually, like this:

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

You can give it a try here...or if you're on an older version or not using the button widget, you can disable it like this:

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

If you want it inside a specific dialog, say by ID, then do this:

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

In other cases where :contains() might give false positives then you can use .filter() like this, but it's overkill here since you know your two buttons. If that is the case in other situations, it'd look like this:

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

This would prevent :contains() from matching a substring of something else.

Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
  • next() won't work for me, as there is all the "resizable" div between the dialog and the buttonpan. So I used nextAll(), and separate the buttonPan from the button : `$("#dialogID").nextAll(".ui-dialog-buttonpane").find("button:contains('Confirm')").attr("disabled", true).addClass("ui-state-disabled");` – Matthieu Nov 15 '12 at 09:21
  • Note that due to the button pane not being a child of the dialog container you may have issues if your page defines multiple dialogs. – Brett Ryan May 31 '13 at 07:48
  • Excellent solution with `$(".ui-dialog-buttonpane button:contains('Confirm')").button("disable");` although if you want to disable the button from a function you have for it, you have to _widgetize_ that dialog and disable the button after that; like this `$(this).dialog("widget").find(".ui-dialog-buttonpane button:contains('Confirm')").button("disable");` – meridius Sep 25 '13 at 08:23
  • 3
    Note that if you don't want to query the desired button by its text, you can also give a class to the button; jQuery UI's dialog supports an array with objects for the button option, each object containing information about the buttons attributes. – Dennis Aug 26 '14 at 12:21
  • This worked for me: $(this).closest(".ui-dialog").find("button:contains('Save')").prop("disabled", true).addClass("ui-state-disabled"); – Adrian P. Mar 10 '15 at 15:00
  • Can I ask how to disable button on load of dialog(on open of dialog) and then enable when one of the radio button inside dialog is selected? – Java_User Jul 15 '15 at 03:01
  • Probably should use `prop`' rather than `attr`. – Joe Mabel Dec 22 '15 at 18:10
51

You can also use the not now documented disabled attribute:

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

    }]
});

To enable after dialog has opened, use:

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

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

KimvdLinde
  • 587
  • 8
  • 19
Jérôme
  • 616
  • 5
  • 15
  • It's not that it's undocumented. It's that when the buttons are processed, all the properties from the object are executed against their jQuery property equivalent. For example, you can add `attr: { 'data-value' : 'some value here' }` if you wanted to add the attribute `data-value` to the button. – crush Dec 03 '14 at 22:16
  • 2
    Not undocumented anymore. It is official. – Salman A May 06 '15 at 11:06
  • This solution is much more elegant than the more popular version. This allows you all the flexibility without the problem of vagely defined selectors. – KimvdLinde Oct 06 '15 at 15:27
  • Note that the `disabled` attribute must be assigned when creating the buttons. – user1032531 Oct 20 '15 at 13:19
  • Tried to downvote, but I upvoted 4 hours ago and can't do so. This solution does not appear to work properly anymore. – user1032531 Oct 20 '15 at 17:24
  • I just tried it in version 1.11.4 and this answer worked the best for me. Even if the dialog was already created it still worked. I used: disabled: function() { return aaa == bbb; }, and it did the evaluation correctly on the open. – adg Nov 24 '16 at 05:36
7

The following works from within the buttons click function:

$(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
  • 29,502
  • 35
  • 121
  • 166
2

this code disable the button with 'YOUR_BUTTON_LABEL'. you can replace name in contains(). to disable

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

replace 'YOUR_BUTTON_LABEL' with your button's label. to enable

$(".ui-dialog-buttonpane button:contains('YOUR_BUTTON_LABEL')").button("enable");
Sumeet_Pol
  • 929
  • 8
  • 13
1

A button is identified by the class ui-button. To disable a button:

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

Unless you are dynamically creating the dialog (which is possible), you will know the position of the button. So, to disable the first button:

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

The ui-state-disabled class is what gives a button that nice dimmed style.

Chris Laplante
  • 29,338
  • 17
  • 103
  • 134
1

I created a jQuery function in order to make this task a bit easier. Probably now there is a better solution... either way, here's my 2cents. :)

Just add this to your JS file:

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

Disable button 'Ok' on dialog with class 'dialog':

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

Enable all buttons:

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

Enable 'Close' button and change color:

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

Text on all buttons red:

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

Hope this helps :)

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
  • 8,349
  • 1
  • 22
  • 9
1

You can overwrite the buttons array and left only the ones you need.

$( ".selector" ).dialog( "option", "buttons", [{
    text: "Close",
    click: function() { $(this).dialog("close"); }
}] );
jfredys
  • 472
  • 3
  • 7
0

The way I do it is Cancel: function(e) { $(e.target).attr( "disabled","disabled" ); }

This is the shortest and easiest way I found.

Bhavin
  • 427
  • 3
  • 15
0

If you're using knockout, then this even cleaner. Imagine you have the following:

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>

The magic comes from the jQuery UI source:

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

You can basically call ANY jQuery instance function by passing it through the button object.

For example, if you want to use HTML:

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

Or, if you want to add a class to the button (you can do this multiple ways):

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

Maybe you're nuts, and you want to remove the button from the dom when it's hovered:

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

I'm really surprised that no one seems to have mentioned this in the countless number of threads like this...

crush
  • 16,713
  • 9
  • 59
  • 100
0

You can disable a button when you construct the dialog:

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

Or you can disable it anytime after the dialog is created:

$(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
  • 262,204
  • 82
  • 430
  • 521
0

You could do this to disable the first button for example:

$('.ui-dialog-buttonpane button:first').attr('disabled', 'disabled');
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
0

This worked for me --

$("#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" );
                                    }
                                }
                        });
                    }
                });
        }
    }
});