How can I disable a button on a jQuery UI dialog?
Asked Answered
C

14

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.

Conde answered 5/9, 2010 at 14:32 Comment(2)
See the answers in this thread: #578048Ermines
@Ermines - 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.Mckim
M
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.

Mckim answered 5/9, 2010 at 14:43 Comment(7)
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");Ruyter
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.Lecia
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");Anthocyanin
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.Annabell
This worked for me: $(this).closest(".ui-dialog").find("button:contains('Save')").prop("disabled", true).addClass("ui-state-disabled");Choroiditis
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?Hy
Probably should use prop' rather than attr.Guenzi
V
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");
Ventral answered 25/11, 2010 at 18:13 Comment(9)
+1. I am not sure why this answer has not received more votes. It's the cleanest I have come across and works nicely.Bathyscaphe
This needs to be in the docs... it doesn't even show that you can assign an id to buttons.Jemison
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!Dragonet
Agree : it's THE solution I was thinking the UI team should implement... :+) You can do even quicker : {text:"ok",disabled:true,click: function(){}}Ruyter
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")Instate
Hint: Enabling works similar, see this linked answer.Vikiviking
Does this syntax work with JQ 1.4.2? I just get two buttons labled 0 and 1.Orose
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: '<span class="my-class">Some Text!</span>' ]. The magic is in line 10529 of the jquery-ui source: $( "<button></button>", props ) where props is the object that defines your button.Sahara
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 etcPuett
M
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.

Mckim answered 5/9, 2010 at 14:43 Comment(7)
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");Ruyter
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.Lecia
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");Anthocyanin
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.Annabell
This worked for me: $(this).closest(".ui-dialog").find("button:contains('Save')").prop("disabled", true).addClass("ui-state-disabled");Choroiditis
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?Hy
Probably should use prop' rather than attr.Guenzi
H
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/

Honey answered 16/10, 2012 at 13:12 Comment(6)
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.Sahara
Not undocumented anymore. It is official.Clerc
This solution is much more elegant than the more popular version. This allows you all the flexibility without the problem of vagely defined selectors.Laurettalaurette
Note that the disabled attribute must be assigned when creating the buttons.Plausible
Tried to downvote, but I upvoted 4 hours ago and can't do so. This solution does not appear to work properly anymore.Plausible
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.Parsimony
L
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');
            }
        }
    });
}
Larcenous answered 23/4, 2011 at 15:54 Comment(1)
but then you have to click before it is greyed out.Vikiviking
D
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");
Depreciation answered 30/3, 2015 at 7:34 Comment(0)
H
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.

Hyperdulia answered 5/9, 2010 at 14:42 Comment(0)
R
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 :)

Rhyton answered 14/10, 2010 at 19:26 Comment(0)
C
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' );
    }
}
Courtroom answered 29/5, 2011 at 9:3 Comment(0)
M
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"); }
}] );
Moneychanger answered 15/7, 2011 at 22:38 Comment(0)
Y
0

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

$('.ui-dialog-buttonpane button:first').attr('disabled', 'disabled');
Yaker answered 5/9, 2010 at 14:43 Comment(0)
C
0

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

This is the shortest and easiest way I found.

Conch answered 14/1, 2014 at 19:33 Comment(0)
S
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...

Sahara answered 3/12, 2014 at 23:15 Comment(0)
C
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>
Clerc answered 6/5, 2015 at 11:32 Comment(0)
C
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" );
                                    }
                                }
                        });
                    }
                });
        }
    }
}); 
Crossindex answered 27/10, 2017 at 12:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.