240

I have a jQuery dialog that requires the user to enter certain information. In this form, I have a "continue" button. I would like this "continue" button to only be enabled once all the fields have content in them, else it will remain disabled.

I wrote a function that is called everytime a field status has changed. However, I don't know how to enable and disable the dialog button from this function. What should I do?

Oops and I forgot to mention that these buttons were created as follows:

$(function() {
  $("#dialog").dialog({
    bgiframe: true,
    height: 'auto',
    width: 700,
    show: 'clip',
    hide: 'clip',
    modal: true,
    buttons: {
      'Add to request list': function() {
        $(this).dialog('close');
        $('form').submit();
      },
      'Cancel': function() {
        $(this).dialog('close');
      }
    }
  })
});
twernt
  • 20,271
  • 5
  • 32
  • 41
Draco
  • 16,156
  • 23
  • 77
  • 92
  • There is a good answer at: http://stackoverflow.com/questions/3646408/how-can-i-disable-a-button-on-a-jquery-ui-dialog – Amir Sep 08 '11 at 18:10
  • 3
    I researched this quite a bit and found that the cleanest solution by far is described in the following link: http://stackoverflow.com/a/4279852 –  Feb 23 '12 at 23:53

33 Answers33

261

You would want to set the disabled property

 $('#continueButton').attr("disabled", true);

Update: Ahha, I see the complexity now. The jQuery Dialog had a single line that will be of use (under the "buttons" section.

 var buttons = $('.selector').dialog('option', 'buttons');

You'll need to get the buttons collection from the dialog, loop through that to find which one you need, and then set the disabled attribute as I showed above.

Shiva Saurabh
  • 1,281
  • 2
  • 25
  • 47
Tom Ritter
  • 99,986
  • 30
  • 138
  • 174
  • Unfortunetly the JQuery dialog doesn't make it too easy to do, so you'll have to work at it a little. – Tom Ritter Feb 23 '09 at 14:18
  • Yes, but the buttons option doesn't return DOM elements but functions - iterating through them is fine, but disabling one isn't so straightforward. Am I missing something here? – Remi Despres-Smyth Jul 23 '10 at 13:52
  • 1
    You need to work around this method to disable the buttons. Use jQuery-foo to get the resultant dom elements off the page. – Stefan Kendall Jul 23 '10 at 14:12
  • 37
    Agreed - so why is this the selected answer? -1 for incomplete. – Remi Despres-Smyth Jul 27 '10 at 16:26
  • @Remi Agreed, this is incomplete and basically a regurgitation of the documentation at http://jqueryui.com/demos/dialog/#option-buttons. It shouldn't have been marked as an answer but that's the OP's prerogative. Also giving a -1 for incompleteness and for teasing me with a possible answer after doing a google search. – SRM May 20 '11 at 16:37
  • does not work for me at all. i did alert out the "getter" with alert(buttons.toSource) and clicked ok. it THEN changed but it does not change automatically with the code from the manual – smugford Feb 15 '12 at 23:33
  • 22
    I believe `.prop('disabled', true)` is preferred in jQuery 1.6+ – Molomby May 25 '12 at 13:21
195

It's very simple:

$(":button:contains('Authenticate')").prop("disabled", true).addClass("ui-state-disabled");
Ry-
  • 218,210
  • 55
  • 464
  • 476
Raman
  • 1,967
  • 1
  • 11
  • 2
  • 4
    I like this solution, but it really should read: $(":button:contains('Authenticate')").attr("disabled","disabled").addClass( 'ui-state-disabled' ); (the addClass was missing) – Eric Asberry Dec 28 '10 at 19:03
  • I also like this solution and the comment by Eric to add addClass('ui-state-disabled'). The only thing I would add would be totweak the selector to only look within the jQuery dialog DOM element (just in case you had another button somewhere else with the same button text). – hydrogen Feb 17 '11 at 04:53
  • 4
    If there are several dialogs you have to define what dialog you need to change: $("#dialogId").parent().$(":button:contains('Authenticate')").attr("disabled","disabled").addClass( 'ui-state-disabled' ); – podeig May 25 '11 at 13:19
  • 5
    +1: This is the best answer by far... The accepted answer does not answer anything, just suggests an imperative approach - which is cumbersome btw: we don't need to loop through anything, jquery can do that for us. – rsenna Jan 02 '12 at 15:25
  • 1
    I found this works as well since the buttons within the jQueryUI Dialog are jQueryUI buttons: $("#dialogID").parent().find(":button:contains('Authenticate')").button("disable"); – writes_on Feb 03 '12 at 17:37
  • 12
    I believe `.prop('disabled', true)` is preferred in jQuery 1.6+ – Molomby May 25 '12 at 13:21
  • 1
    And .toggleClass("ui-state-disabled", true) instead of addClass becomes useful if you want to enable the button too. – Colin Jun 26 '13 at 10:18
38

You are all over complicating a simple task; the jQueryUI dialog has two ways to set buttons for a reason.

If you only need to set the click handler for each button, use the option that takes an Object argument. For disabling buttons and provide other attributes, use the option that takes an Array argument.

The following example will disable a button, and update its state correctly by applying all of the jQueryUI CSS classes and attributes.

Step 1 - Create your dialog with an Array of buttons:

// Create a dialog with two buttons; "Done" and "Cancel".
$(".selector").dialog({ buttons: [
    {
        id: "done"
        text: "Done",
        click: function() { ... }
    },
    {
        id: "cancel"
        text: "Cancel",
        click: function() { ... }
    }
] });

Step 2 - Enable/disable the Done button after the dialog is created:

// Get the dialog buttons.
var dialogButtons = $( ".selector" ).dialog("option", "buttons");

// Find and disable the "Done" button.
$.each(buttons, function (buttonIndex, button) {
    if (button.id === "done") {
        button.disabled = true;
    }
})

// Update the dialog buttons.
$(".selector").dialog("option", "buttons", dialogButtons);
Ido Sela
  • 1,396
  • 1
  • 12
  • 5
  • 2
    Right idea, but the `each` loop is unnecessary. Specify a `class` attribute in the `buttons` array and you can use that to find the right element. – cdmckay Feb 11 '11 at 03:21
  • as cdmackay said, you dont need to looping. In your example above you can just go ahead and use a jQuery selector: var $doneButton = $("#done"); – Rob May 23 '11 at 00:46
  • When I try to create the buttons using the above method (the array way), the buttons are being displayed as '1' and '0' and not as 'Done' and 'Cancel'. Why is this happening? The text is not being shown in the button and neither the click function is being fired. – Harke Oct 12 '11 at 14:09
  • 1
    This works for me and you don't need the loop. Set the id then access the element:this.myDialog.dialog( "option", "buttons", [{ id : "addAdapterFormOkButton", text: "OK",click: function() {} } ] ) Then you just need to access it with the selector as they all say above: var okButt = $("#addAdapterFormOkButton"); okButt.addClass('ui-state-disabled'); okButt.attr('disabled', true); – Gurnard Nov 10 '11 at 09:32
34

If you create a dialog providing id's for the buttons,

$("#dialog").dialog({ buttons: [ {
 id: "dialogSave",
 text: "Save",
 click: function() { $(this).dialog("close"); }
},
{
 id: "dialogCancel",
 text: "Cancel",
 click: function() { $(this).dialog("close"); 
}
}]});       

we can disable button with the following code:

$("#dialogSave").button("option", "disabled", true);
vitalnik
  • 568
  • 6
  • 10
29

I wanted to be able to find the button by name (since I have several buttons in my jQuery UI dialog). I also have several dialogs on the page so I need a way to get the buttons of a specific dialog. Here is my function:

function getDialogButton( dialog_selector, button_name )
{
  var buttons = $( dialog_selector + ' .ui-dialog-buttonpane button' );
  for ( var i = 0; i < buttons.length; ++i )
  {
     var jButton = $( buttons[i] );
     if ( jButton.text() == button_name )
     {
         return jButton;
     }
  }

  return null;
}

// create the dialog
$('#my_dialog').dialog( dialogClass : 'dialog1',
                        buttons: {
                                   Cancel: function() { $(this).dialog('close'); },
                                   Submit: function() { ... } 
                             } );

// now programmatically get the submit button and disable it
var button = getDialogButton( '.dialog1', 'Submit' );
if ( button )
{
  button.attr('disabled', 'disabled' ).addClass( 'ui-state-disabled' );
}
Nick B
  • 7,639
  • 2
  • 32
  • 28
  • Nice solution. I'd mention in the solution, though, that the button pane is *not* a child of the dialog - the key is setting a unique dialogClass, and using it for the selector. This got me when I was looking at it. – Remi Despres-Smyth Jul 23 '10 at 16:08
  • Interesting that the text of the button is set by the key of the buttons object. Seems to be limited to when you don't need to set the attribute. Otherwise the array version is better, where text is set explicitly per button. – Gerard ONeill May 08 '18 at 22:35
19

This disables a button:

var firstButton=$('.ui-dialog-buttonpane button:first');
firstButton.addClass('ui-state-disabled');

You have to add the dialog id if you have several dialogs on a page.

Rainer Blessing
  • 1,131
  • 2
  • 11
  • 22
12

Here's the sample from the question modified to disable the button once clicked:

$(function() {
    $("#dialog").dialog({
        bgiframe: true,
        height: 'auto',
        width: 700,
        show: 'clip',
        hide: 'clip',
        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');
            }
        }
    });
}

Also, the following question will also be helpful with this: How can I disable a button on a jQuery UI dialog?

Community
  • 1
  • 1
Chris Pietschmann
  • 29,502
  • 35
  • 121
  • 166
9

I found an easy way to disable (or perform any other action) on a dialog button.

    var dialog_selector = "#myDialogId";

    $(dialog_selector).parent().find("button").each(function() {
        if( $(this).text() == 'Bin Comment' ) {
            $(this).attr('disabled', true);
        }
    });

You simply select the parent of your dialog and find all buttons. Then checking the Text of your button, you can identify your buttons.

Hugh Turner
  • 91
  • 1
  • 1
9

I got this working with the method .dialog("widget") which returns the dialog DIV itself. If you're in the dialog methods:

$(this)
.dialog("widget")
.find("button")
.addClass("ui-state-disabled") // for the style
.attr("disabled", true);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
8

From a usability perspective, it's usually better to leave the button enabled but show an error message if someone tries to submit an incomplete form. It drives me nuts when the button I want to click is disabled and there is no clue to why.

erikkallen
  • 33,800
  • 13
  • 85
  • 120
6

Try this:

$('button:eq(0)',$('#dialog_id').dialog.buttons).button('disable');
Pablo Santa Cruz
  • 176,835
  • 32
  • 241
  • 292
jrey
  • 2,163
  • 1
  • 32
  • 48
5

haha, just found an interesting method to access the bottons

$("#dialog").dialog({

      buttons: {
        'Ok': function(e) { $(e.currentTarget).button('disable'); }

      }
 });

It seems you all don't know there is an event object in the arguments...

by the way, it just accesses the button from within the callback, in general cases, it is good to add an id for access

haohaolee
  • 677
  • 1
  • 9
  • 16
5

Here is my enableOk function for a jQuery dialog:

function enableOk(enable)
{
    var dlgFirstButton = $('.ui-dialog-buttonpane').find('button:first');

    if (enable) {
        dlgFirstButton.attr('disabled', '');
        dlgFirstButton.removeClass('ui-state-disabled');
    } else {
        dlgFirstButton.attr('disabled', 'disabled');
        dlgFirstButton.addClass('ui-state-disabled');
    }
}

The "first" button is the one furthest to the right. You both disable the button and set the dialog's disabled class, for the proper visual effect.

Remi Despres-Smyth
  • 4,173
  • 3
  • 36
  • 46
  • Note, this assumes you've only got one dialog on the page. I've since written a function to fetch any button by name from any dialog on the page to deal with this. – Remi Despres-Smyth Nov 01 '10 at 11:49
5

In the legacy jQuery UI (version 1.7.3) I was able to simply use

$('.ui-dialog-buttonpane button')[0].disabled=true;

to just disable the button on the DOM element itself. Now that we've upgraded to the newer jQuery UI (version 1.8.7) that method no longer works in Firefox, but I can simply call the jquery UI button specific disable and enable functions on the button jquery objects:

$('.ui-dialog-buttonpane button').eq(0).button('disable');
Matt Palmerlee
  • 2,668
  • 2
  • 27
  • 28
4

If you really want to disable a button, I found that you also need to call the .unbind() method on it. Otherwise the button may still be active, and a double-click could lead to multiple form submissions. The following code works for me:

button = $(this).parent().find("button:contains('OK')");
button.unbind();
button.addClass('ui-state-disabled');
postrational
  • 6,306
  • 3
  • 22
  • 27
4

I created a jQuery function in order to make this task a bit easier. Just add this to your JavaScript 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');

I hope this helps.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
4

I found a workaround that may apply to people trying to do something similar. Instead of disabling the button I put a simple if statement in the function to check if the checkbox was checked.

If it wasn't, it displayed a simple message saying the box had to be checked before submission.

For example:

$("#confirmation-dialog").dialog({
    modal: true,
    autoOpen: false,
    width: 600,
    overlay: {
        backgroundColor: '#000',
        opacity: 0.5
    },
    close: function() {
        $('input[type="submit"]')
      .val('Record Reading')
      .attr('disabled', false);
    },
    buttons: {
        'Confirm Reading': function() {
            if($('#check-box').attr("checked")){
                $(this).dialog('close')
                $('form')
                .addClass('confirmed')
                .submit();
            }
            else {
                $('#please-check').show("slide");
            }
        }
    }
});

Anyway, I hope that helps someone.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
3

Just for the record, this post helped me to solve my problem. In short words, you have to set the disabled attribute to disabled, not to false:

_send_button.attr('disabled','disabled');

This is how all the code looks, I also added some styles to make it look disabled:

var _send_button = $('.ui-dialog-buttonpane button:contains(Send)');
var original_text = _send_button.text();
_send_button.text('Please wait...');
_send_button.addClass('ui-state-disabled');
_send_button.attr('disabled','disabled');
_send_button.fadeTo(500,0.2);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
3

I think it should work with all,

<script type="text/javascript">
    $(document).ready(function() {
        $('#dialog').dialog('open');
        $(function(){
            $('#dialog').dialog({
                autoOpen: true,
                width: 400,
                modal: true,
                overlay: {
                    opacity: 0.8,
                    background: "black"
                },
                resizable: false,
                show: 'slow',
                buttons: {
                    //"OK":function() {
                    //    window.location="index.php?view=list";
                    //},
                    "Cancel": function() {
                        $(this).dialog("close");
                        $(this).attr("class", "button");
                    }
                }
            });

            var dlgFirstButton = $('.ui-dialog-buttonpane').find('button:first');
            dlgFirstButton.addClass('button');
        });
    });
</script>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
3

According to the documentation:

https://api.jqueryui.com/dialog/#option-buttons

// Setter
$( ".selector" ).button( "option", "disabled", true );

To be able to simply select the button, you could add an own CSS class to the button, that should be enabled / disabled.

// while initializing
$("#dialog").dialog({
...
buttons: [{
    disabled: true,
    text: "Add to request list",
    click: function (e: JQueryEventObject) {
        // Some logic
    },
    "class": "myDialogButton"
}]
...
});

Then the enabling / disabling would look like this:

$(".myDialogButton" ).button( "option", "disabled", (SOME_CONDITION) ? true : false);
theSpyCry
  • 12,073
  • 28
  • 96
  • 152
3

Unfortunately no solutions from given here worked for several dialogs on the page.

Also the problem was that original dialog doesn't contain button pane in itself, but is a sibling of it.

So I came up with selecting by dialog ID like that:

        var getFirstDialogButton = function (dialogSelector) {
            return $('.ui-dialog-buttonpane button:first',
                    $(dialogSelector).parent()[0]);
        };

...

        $('#my_dialog').dialog({
            open: function(event, ui) {
                getFirstDialogButton("#my_dialog")
                 .addClass("ui-state-disabled").attr('disabled', 'disabled' );
            },

...

and then the same getFirstDialogButton() function could be later used to enable button, e.g. after successful validation.

Hope it can help someone.

3

Here's an example that I just implemented using the Array method of assigning buttons, which then allows me to use id selectors later on - just as the accepted answer stated originally - to enable/disable buttons and even show/hide them completely as I'm doing.

$( "#dialog-form" ).dialog({
autoOpen: true,
height: 500,
width: 450,
modal: true,
buttons: [
{
    id: "submit_btn",
    text: "Make Apointment",
    click: function() { 
        //do ajax       
    }       
},
{
    id: "cancel_btn",
    text: "Cancel",
    click: function() {
       $( this ).dialog( "close" );
    }
},
{
    id: "ok_btn",
    text: "OK",
    click: function() {
       $( this).dialog('close');
    },
    disabled: "disabled"
}],
close: function() {
    allFields.val( "" ).removeClass( "ui-state-error" );
}
});

After successfully submitting, I disable and hide two of the buttons and enable the OK button that was disabled by default.

$('#submit_btn, #cancel_btn').attr('disabled','disabled').addClass('ui-state-disabled').hide();
$('#ok_btn').attr('disabled','').removeClass('ui-state-disabled').show();

Hope this helps.

3

I created a function similar to what Nick did, but my method would not require setting the dialogClass and you will be able to get the buttons of a specific dialog via the id (if more than one exists in your application)

function getDialogButton( dialog_id, button_name) {
    var target = '#'+dialog_id;
    var buttons = $(target).parent().find('button');
    for ( var i=0; i<buttons.length; ++i ) {
        var jButton = $( buttons[i] );
        if ( jButton.text() == button_name ) {
              return jButton;
        }
    }
    return null;
} 

So if you created the dialog like so:

$(function() {
    $("#myDialogBox").dialog({

      bgiframe: true, height: 'auto', width: 700, modal: true,
      buttons: {
        'Add to request list': function() {
                                     $(this).dialog('close');
                                     $('form').submit();
                               },
        'Cancel': function() {
                       $(this).dialog('close');
                  }
      }
});

You can get the buttons by doing the following:

var addToRequestListBtn = getDialogButton('myDialogBox','Add to request list');
var cancelBtn           = getDialogButton('myDialogBox','Cancel');

To disable:

addToRequestListBtn.attr('disabled', true).addClass( 'ui-state-disabled');
          cancelBtn.attr('disabled', true).addClass( 'ui-state-disabled');

To enable:

addToRequestListBtn.attr('disabled', false).removeClass( 'ui-state-disabled');
          cancelBtn.attr('disabled', false).removeClass( 'ui-state-disabled');
Shao
  • 41
  • 4
2

To Disable the Save button in my Dialog box use following line in your function.

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

To change a text in a button use following line( this change the cancel button text to Close Me)

 $(".ui-dialog-buttonpane button:contains('Cancel') span").text("Close Me");
Chanaka
  • 59
  • 1
  • 4
1

In the jQuery world, if you want to select an object from a set of DOM elements, you should use eq().

Examples:

var button = $('button').eq(1);

or

var button = $('button:eq(1)');

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
diewland
  • 1,865
  • 5
  • 30
  • 41
1

@Chris You can use following lines of code to enable/disable dialog buttons until your check box check/unchecked

<div id="dialog-confirm" title="test">
    <label>Enable Confirm?<input type="checkbox" checked /></label>
</div>

    $("#dialog-confirm").dialog({
    resizable: false,
    height:240,
    modal: true,
    buttons: {
        Cancel: function() {
            $(this).dialog('close');
        },
        'Confirm': function() {
            $(this).dialog('close');
        }
    }
});

    $("#dialog-confirm :checkbox").change(function() {
        $(".ui-dialog-buttonpane button:contains('Confirm')")
           .button(this.checked ? "enable" : "disable");
    });

Original source: http://jsfiddle.net/nick_craver/rxZPv/1/

Chanaka
  • 59
  • 1
  • 4
1

Calling .attr("disabled", true) of course works, but using jQuery you'd like do it in more 'sugar' way, so I've written simple extension:

(function( $ ) {
  $.fn.disable = function(isDisabled) {
    var val = isDisabled;
    if (isDisabled === undefined)
        val = true;
    this.attr("disabled", val);
  };
  $.fn.enable = function(isEnabled) {
    var val = !isEnabled;
    if (isEnabled === undefined)
        val = false;
    this.attr("disabled", val); 
  }
})( jQuery );

Now you have functions enable() and disable(), so you can do your job that way:

$('#continueButton').disable();

Which is same as

$('#continueButton').disable(true);

and

$('#continueButton').enable(false);
Danubian Sailor
  • 1
  • 38
  • 145
  • 223
1

This did the job for me:

$find("<%= btnPrint.ClientID %>").set_enabled(true);
coder
  • 11
  • 1
0

If anybody is looking to replace a button with something like a loading animation when clicked (for example when a "Submit" button submits the form in the dialog) - you can replace the button with your image like this:

...
buttons: {
    "Submit": function(evt) {
        $(evt.target).closest('button').replaceWith('<img src="loading.gif">');
    }
}

jQuery replaceWith docs

scrowler
  • 24,273
  • 9
  • 60
  • 92
0

To disable one button, at dialog open:

$("#InspectionExistingFacility").dialog({
    autoOpen: false, modal: true, width: 700, height: 550,
    open: function (event, ui) {
        $("#InspectionExistingFacility").parent().find(":button:contains('Next')").prop("disabled", true).addClass("ui-state-disabled");
    },
    show: { effect: "fade", duration: 600 }, hide: { effect: "slide", duration: 1000 },
    buttons: { 'Next step': function () { }, Close: function () { $(this).dialog("close"); } }
});
BernieSF
  • 1,722
  • 1
  • 28
  • 42
0

I had one button I didn't want displayed till a trigger point.

At first I tried this which works: -

$(":button:contains('OK')").hide();

but leaves a line (because they have all gone!), so added this instead in my CSS: -

.ui-dialog .ui-dialog-buttonpane {
display: none;
}

This hides ALL the buttons.

I can re-enable when needed by : -

$('.ui-dialog .ui-dialog-buttonpane').css({"display":"block"}); //show button
Mikeys4u
  • 1,494
  • 18
  • 26
0

jQuery Solution works for me.

$('.ui-button').addClass("ui-state-disabled");$('.ui-button').attr("aria-disabled",'true');$('.ui-button').prop('disabled', true);
jalalBK
  • 31
  • 2
0

you can simply add id to the button, it is not in the document, but it works.

$().dialog(buttons:[{id:'your button id'....}]);

then in your function just use the

$('#your button id') 

to disable it.

Lemon Kazi
  • 3,308
  • 2
  • 37
  • 67
Jacky
  • 7
  • 3