Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling button("refresh") on a jQuery mobile button breaks the button style

I'm trying to dynamically update the text on a jQuery mobile button. The button is actually a link which is styled as a button.

According to the jQuery mobile documentation, you should call button("refresh") if you manipulate the button via javascript. However, when I do this, the button's style goes a but crazy - it gets shrunk to half-height and the button looks crap.

Here's a JS Fiddle which demonstrates the problem.

The code is essentially as follows:

$(function() {
    // Buttonize
    var $button = $("#myCrapButton");
    $button.button();

    // Change text on click
    $button.click(function() {
        $button.text("Awesome Button");
        $button.button("refresh");
    });
});

What's more, calling button("refresh") causes the javascript error: Cannot call method 'removeClass' of undefined.

I know that I can work around this problem by manipulating the .ui-btn-text span that's nested inside the button; however, this seems like the wrong approach as it requires explicit knowledge of the internal workings of jquery Mobile.

Can anyone tell me how to get the refresh call to work?

Using versions:

  • jQuery 1.9.1
  • jQuery Mobile 1.3.0 (in the JSFiddle it's 1.3.0 beta but the final has the same behavior).

Thanks!

like image 817
gerrod Avatar asked Mar 06 '13 23:03

gerrod


2 Answers

EDIT:

Sorry read to fast and didn't see that you were looking specifically for the refresh functionality. As you hav noticed jQM doesn;t offer that on the anchor tag buttons.

Well an alternative is just to replace the button with a new one and let jQM add the markup as before

  • http://jsfiddle.net/rfdQC/4/

JS

$(function() {
    // Buttonize
    var $button = $("#myCrapButton");
    var $clone = $button.clone();
    $button.button();

    // Change text on click
    $button.click(function() {
        $clone.text("Awesome Button");
        $clone.button();
        $button.replaceWith($clone);
    });
});

Hope this helps!

Original:

You just need to drill down into the added markup that jQM adds.

<a id="myCrapButton" href="#" class="ui-btn ui-shadow ui-btn-corner-all ui-btn-up-c" data-corners="true" data-shadow="true" data-iconshadow="true" data-wrapperels="span" data-theme="c">
    <span class="ui-btn-inner">
        <span class="ui-btn-text">
            Click me!
        </span>
    </span>
</a>

You're changing the button text:

<a id="myCrapButton" href="#" class="ui-btn ui-shadow ui-btn-corner-all ui-btn-up-c" data-corners="true" data-shadow="true" data-iconshadow="true" data-wrapperels="span" data-theme="c">
    Awesome Button
</a>

Doing this you loose the added markup jQM needs to display the button. You need to change the nested span text.

$(function() {
    // Buttonize
    var $button = $("#myCrapButton");
    $button.button();

    // Change text on click
    $button.click(function() {
        $button.children().children().text("Awesome Button");
    });
});

no refresh needed:

<a id="myCrapButton" href="#" class="ui-btn ui-shadow ui-btn-corner-all ui-btn-up-c" data-corners="true" data-shadow="true" data-iconshadow="true" data-wrapperels="span" data-theme="c">
    <span class="ui-btn-inner">
        <span class="ui-btn-text">
            Awesome Button
        </span>
    </span>
</a>

Live Example:

  • http://jsfiddle.net/rfdQC/3/
like image 62
Phill Pafford Avatar answered Sep 30 '22 01:09

Phill Pafford


Never mind; just found this at the top of the documentation:

Note: Links styled like buttons have all the same visual options as true form-based buttons below, but there are a few important differences. Link-based buttons aren't part of the button plugin and only just use the underlying buttonMarkup plugin to generate the button styles so the form button methods (enable, disable, refresh) aren't supported. If you need to disable a link-based button (or any element), it's possible to apply the disabled class ui-disabled yourself with JavaScript to achieve the same effect.

Although this doesn't actually solve my problem (of how to update the button text) - at least it answers why the "refresh" method isn't supported.

Edit:

I am aware that I can directly update the text on the button; I said as much in the original question:

I know that I can work around this problem by manipulating the .ui-btn-text span that's nested inside the button; however, this seems like the wrong approach as it requires explicit knowledge of the internal workings of jquery Mobile.

I was hoping to avoid this solution by somehow getting the "refresh" method to work. However, based on the snippet of documentation that I later found (and have quoted above), I realised that using the "refresh" method was not an option.

Given that; I was still hoping there was another way to update the text on the button without explicitly addressing the generated DOM elements (i.e. by using the jQM API) - but so far as I can see, there's no API method to do so. Updating the DOM elements seems like the only way to achieve the desired result.

Both of the selectors provided by @Phil Pafford ($(this).find('span span')) and @OmarNew2PHP ($button.children().children()) are (in my opinion) incorrect. Yes, they work perfectly in the example given above, however, if you add an icon to the button:

<a id="myCrapButton" href="#" data-icon="delete">Click me!</a>

Then jQM adds in an additional span to display that icon (anchor tag attributes trimmed for brevity):

<a href="#">
    <span class="ui-btn-inner">
        <span class="ui-btn-text">Delete</span>
        <span class="ui-icon ui-icon-delete ui-icon-shadow">&nbsp;</span>
    </span>
</a>

Using the selectors above will add the text to both of the inner span tags. This is another example of why I was hoping to avoid updating the DOM directly - because you can't (and shouldn't have to) predict what jQM is going to generate.

But, at the end of the day, it looks like the best way of updating the text inside the button is using the method I was hoping to avoid:

$button.click(function() {
    $(".ui-btn-text", this).text("Awesome Button");
});

Thanks for your answers.

like image 27
gerrod Avatar answered Sep 30 '22 01:09

gerrod