1

Going through a steep learning curve, i am currently experimenting various UX 'toys' that i will require to implement an app. One of these is to disable a button and enable it on the fly. Following the instructions of the good book , I wrote a little snippet of code to test it out. Clicking on "Soap" runs a series of chained promises, and toggles the "Soap1" button disabled prop.

My HTML/JS

<div data-role="content">
    <a href="#" id="btn_soap1" class="ui-input-btn ui-btn ui-mini ui-btn-inline ui-icon-back "
       onclick="getInitialNotifications();">Soap1</a>
    <button id="btn_soap" class="ui-btn ui-btn-inline ui-mini ui-icon-bullets "
            onclick="getInitialNotifications();">
        Soap
    </button>

    <script>

        $("#btn_soap1").button({            // required initialization
            disabled:false
        });

        $("#btn_soap").on("click", function () {

            // bubbled from the onClick thingie in the markup

            var isDis = $("#btn_soap1").button("option","disabled");
            $("#btn_soap1").button("option","disabled",!isDis);

//                var but = $("#btn_soap1");
//                var className = "ui-state-disabled";
//                if(but.hasClass(className)) {
//                    but.removeClass(className);
//                } else {
//                    but.addClass(className);
//                }


        });
    </script>
</div>

Intended rendering

enter image description here

Broken rendering (all browsers and device sims and devices)

enter image description here

Question : can you see any noob error in the JS that would cause this side-effect. I added (in comments) my work-around, which works as specified, but is seems counter-intuitive.

EDIT: (from Mr. Duc Nguyen's answer). What breaks the rendering is adding the initialization. If it is not there, i get an exception whining that i am calling a function prior to initialization when changing the disabled state.

EDIT AGAIN : discovered JSfiddle, ... a fiddle that reproduces this

YvesLeBorg
  • 9,070
  • 8
  • 35
  • 48

1 Answers1

1

Edited: new answer basing on jsFiddle

You have gotten yourself in a very interesting situation, some points below:

  • jQM has an auto-initaliasation merchanism, if you want to leverage that, you have to follow the rules, or totally disable it and do the initialisation yourself. jQM global config
  • You have 2 "buttons", but they are actually 1 <a> and 1 <button>, disabling the <a> was never an easy one, have a look here disabling html link
  • jQM might confuse you that the <a> tag is a button widget, but it is not! It just has the same styling as a button, not a button widget. Button widget is only applying to <button> and appropriate <input> type (it was clearly mentioned in the documents back in 1.2.0's days, I couldn't find it in the 1.4.5 docs)

So, here is how I would do to leverage the jQM auto-initialisation:

    <a href="#" id="btn_soap1" class="ui-disabled" data-role="button" data-inline="true" data-icon="back">Soap1</a>
    <button id="btn_soap" data-inline="true">Soap</button>

Notice on the <a>:

  • The attribute data-role="button" was to tell jQM to mark it up as a button
  • This classclass="ui-disabled" was to disable it initially.

And how to disable the link <a> on-the-fly. Notice that by just adding a class, it won't work on some specific infamous browsers, referring to the above stackoverflow answer for more information.

    var isDis = $("#btn_soap1").hasClass("ui-disabled");
    if (!isDis) {
        $("#btn_soap1").addClass("ui-disabled");
    } else {
        $("#btn_soap1").removeClass("ui-disabled");
    }

Again, you can only call .button([method]) on a real button!

Have a look on this updated jsFiddle, I have cleaned things up a bit.

Community
  • 1
  • 1
Mr. Duc Nguyen
  • 1,049
  • 7
  • 16
  • That is what i am struggling with. If i do as you suggest, i get an exception `Uncaught Error: cannot call methods on button prior to initialization; attempted to call method 'disable'` ... suggesting it is not initialized. So i added the 'initialization' stuff, which breaks the rendering. – YvesLeBorg Jul 01 '15 at 23:50
  • Same result (predictably). It is not initialized, thus the initialization code executes ... and breaks rendering. The real issue is `why is it not initialized at that stage in the document's life cycle`. Thanks anyways. +1 for the valiant effort. – YvesLeBorg Jul 02 '15 at 00:09
  • Well, actually, checking for widget initialsed or not is quite tricky with jQM. I've tried the code with 1.4.5 (latest release now) and it worked. I modified the code a little bit to follow http://api.jqueryui.com/jquery.widget/ – Mr. Duc Nguyen Jul 02 '15 at 00:18
  • If you still have issue then the problem must be somewhere else. If you can provide a jsfiddle link, I can help more :) – Mr. Duc Nguyen Jul 02 '15 at 00:23
  • thks again for making me discover JSfiddle :) ... if i could i would upvote your answer twice. Fiddle link in the body of the question. – YvesLeBorg Jul 02 '15 at 00:48
  • thanks a million ! lots of good 'up the learning curve' leads in your answer. – YvesLeBorg Jul 02 '15 at 02:02