10

I have a jQuery Mobile site with some buttons. I want to show some text on the right side of the button if and when the viewport is 640 pixels or wider and hide the text otherwise.

I know about the iconpos option/data-attribute that is meant for that purpose, and that it can be set to left to show the text when I want it and notext when I don't. I can probably come up with some Javascript to change the attribute and refresh the button on page load, orientation change, and window resize events, but that may become cumbersome, and I am not sure if I am forgetting some event that can cause the viewport width to change.

EDIT 2: I tested my site on several browsers and devices and it seems like changing the orientation, resizing the window, and showing and hiding the on-screen keyboard (in situations where those things are possible) always caused the resize event to be triggered on the window object. Of course, I don't know for sure that this will always happen in all browsers.

I thought about using some sort of media query to set the display CSS property on the text as inline or none depending on the viewport width but after I looked at the code for jQuery Mobile, it seems like the iconpos option affects more than just the visibility of the text: it affects the dimensions, title attribute, icon position, and some other stuff, so this may not be possible using only CSS.

EDIT: I forgot to mention that the button is in a header so it is one of the inline buttons. Simply hiding the text via CSS is going to make it look funny.

Does anyone here know a simple and practical way to show or hide the text based on the viewport width? Or as a more general question, does anyone here know how to alter a data-attribute based on the viewport width and make jQuery Mobile acknowledge the change whenever the viewport width changes? I found a similar question about changing a data-attribute and it does not have any reasonable answers.

Community
  • 1
  • 1
Elias Zamaria
  • 96,623
  • 33
  • 114
  • 148

5 Answers5

6

This is a pure css solution, it requires a HTML5 browser but then again jQuery Mobile also requires one:

/* Less then 620 px -------------------*/ 
@media all and (max-width: 620px){  
    #custom-button span span { visibility:hidden;} 
}       

/* More then 640 px -------------------*/ 
@media only screen and (min-width: 640px) {
    #custom-button span span { visibility:visible;} 
}  

Visibility is a better solution then Display because button height will remain the same.

This is a working jsFiddle example: http://jsfiddle.net/Gajotres/adGTK/, just stretch a Result area to see a difference.

EDIT :

This should do it, example is the same: http://jsfiddle.net/Gajotres/adGTK/

/* Less then 639 px -------------------*/ 
@media all and (max-width: 639px){  
    #custom-button span span.ui-btn-text 
    { 
        left: -9999px !important;
        position: absolute !important;
    } 

    #custom-button span span.ui-icon 
    { 
        float: left !important;
        margin: 2px 1px 2px 3px !important;
        display: block !important;
        z-index: 0 !important;   
        position: relative;
        left: 0 !important;
    } 

    #custom-button span.ui-btn-inner
    { 
        padding: 0 !important;
    } 

    #custom-button
    { 
        height: 24px !important;
        width: 24px !important;
        margin-top: 5px;
    }     
}       

This example will work only with buttons created with an <a> tag.

Tony Shih
  • 430
  • 5
  • 6
Gajotres
  • 57,309
  • 16
  • 102
  • 130
  • I forgot to mention that I am using an inline button. That kind of button is supposed to be much smaller without the text than with. In any case, I tried your idea and it just kept the button the same size but hid the icon and the text. – Elias Zamaria Feb 22 '13 at 18:17
  • In addition, I don't know whether `span span` is a reliable selector for targeting the text on the button, or if the structure inside the button may change in future jQuery Mobile versions. – Elias Zamaria Feb 22 '13 at 18:21
  • You can see an example of what happens when I try your idea on an inline button at http://jsfiddle.net/7mvdc/. – Elias Zamaria Feb 22 '13 at 18:22
  • This solution will work no matter which button kind you use. If button structure changes so will your code, no matter if you use javascript or css solution in this case. jQuery Mobile dont have a button text change function (like icon change one) so down the level javascript/jQuery solution is needed if you don want to use pure CSS. CSS solution is better because you are not going to do any more unnecessary javascript processing plus good luck finding real screen width among 100+ different devices with viewport calculations changing all the time (here pointing a finger to iOS platform). – Gajotres Feb 22 '13 at 19:12
  • Apparently I didn't read your question comprehensively, what do you mean by: "I want to show some text on the right side of the button"? – Gajotres Feb 22 '13 at 19:17
  • I want to show the text in the button on the right side of the icon. Go to http://api.jquerymobile.com/button/, scroll down to where it says "Mini & Inline". I am trying to make the button look like the first one in viewports greater than 640 pixels and like the last one in narrower viewports. – Elias Zamaria Feb 22 '13 at 21:33
  • By "pixels", I mean CSS pixels. I can easily get the viewport width in css pixels using `window.innerWidth`. – Elias Zamaria Feb 22 '13 at 21:34
  • BTW, I don't see how the CSS solution is "better". Look at the fiddle I linked to above and try resizing the window. I don't want to only hide the text. I want to make the button smaller. – Elias Zamaria Feb 22 '13 at 21:35
  • I think I linked to the wrong fiddle above. Sorry about that. You can see what I was trying to do at http://jsfiddle.net/pUfjK/3/. I tried your CSS with an inline button in the header and the latest stable version of jQuery Mobile (1.3.0). Your CSS doesn't seem to do anything at all. I don't see how it can work because the button doesn't have any spans in it. – Elias Zamaria Feb 22 '13 at 21:41
  • Take a look at my new example, I think this is what you have wanted. Of course it will work only with a button created with a tag. – Gajotres Feb 22 '13 at 21:59
  • Thank you. That appears to do what I want. It looks somewhat fragile and cumbersome, and I haven't tested it yet in jQuery Mobile 1.3.0, so I think I will wait and see if someone comes up with a better solution before accepting this one. – Elias Zamaria Feb 23 '13 at 00:14
3

This is the best thing I have come up with so far:

$(window).resize(function() {
    $(".ui-btn-left, .ui-btn-right, .ui-btn-inline").filter("[data-icon]")
        .buttonMarkup({iconpos: window.innerWidth >= 640 ? "left" : "notext"})
        .buttonMarkup("refresh");
});

$(document).delegate("[data-role=page]", "pageinit", function() {
    $(window).resize();
});
Elias Zamaria
  • 96,623
  • 33
  • 114
  • 148
  • Media Queries are much better to tackle such problems compared to using JS. And that's because mobile browser always supports MQ. – George Katsanos Mar 03 '13 at 17:29
  • What rules am I supposed to put in the media queries? I looked at Gajotres's answer and it looked kind of fragile. – Elias Zamaria Mar 03 '13 at 20:39
  • how are we supposed to know the code required if you don't post a use-case!? – George Katsanos Mar 04 '13 at 07:34
  • What do you mean "mobile browser always supports MQ"? I am sure that there are a few that don't, although they may be getting less and less common. Anyway, I would think that any browser that supports Javascript supports `window.innerWidth`, or if it doesn't, I can probably get the width using jQuery's `width` function. – Elias Zamaria Mar 04 '13 at 18:15
  • I think I described my use-case well enough in the question. Is there anything you are having trouble understanding? – Elias Zamaria Mar 04 '13 at 18:16
  • Thanks for this. While using CSS only is all fine-and-dandy, if you are using JQM, then you are using JS/JQ and this solution works great! – Red2678 May 13 '13 at 18:12
1

This is working for me pretty solidly in jQuery Mobile 1.4 beta 1 after moving over to the class-only button declaration.

$(window).on("throttledresize", function() {
  var smallButtons = $(window).width() <= 480;
  $('#article_nav a').toggleClass('ui-btn-icon-notext', smallButtons);
  $('#article_nav a').toggleClass('ui-btn-icon-left', !smallButtons);
});
Benjamin H
  • 5,164
  • 6
  • 34
  • 42
0

Work for a and button tags of type data-icon, by default set data-iconpos="notext" in html, then bind pagebeforecreate orientationchange event to add or remove attribute according to screen width:

$(document).on('pagebeforecreate orientationchange', updateIcons);

function updateIcons () {
    if ($(window).width() > 480) {
        $('a[data-icon], button[data-icon]').removeAttr('data-iconpos');
    } else {
        $('a[data-icon], button[data-icon]').attr('data-iconpos', 'notext');
    }
}

EDIT: Looks like it only works on page creation and not on orientation change.

Credit: Aurelio@buildmobile.com

WispyCloud
  • 4,140
  • 1
  • 28
  • 31
  • Does this work on non-mobile devices when the user resizes the window? I think this needs to be bound to the `resize` event also. – Elias Zamaria Mar 03 '13 at 20:45
  • I am at work where I am able to test this and it doesn't seem to work at all. Simply changing the `data-iconpos` attribute doesn't make the text appear or disappear. The button needs to be refreshed. See my answer. – Elias Zamaria Mar 04 '13 at 17:33
  • It works on page creation but does not seem to work on orientation change (I've tested it, you can do the same by downloading [this app[(https://www.dropbox.com/s/95qmzdyvms924gg/WhereIparkedmycar-debug.apk?m) for example). Maybe to make it work on orientation change or resize, some additional code would be required to trigger the jquery-mobile page creation event, but I don't have to look into this at the moment. – WispyCloud Mar 05 '13 at 00:52
0

Here is a pure css solution that will work on IE8+ and all other browsers. Note that the code is from Twitter-Bootstrap, just modified a little.

DEMO

<button type="submit" class="btn btn-primary" value="Submit">
    <i id="versturen" class="fa fa-check"></i>
    <span class="sr-only-xs"> Versturen</span>
</button>

@media (max-width: 767px) {
  .sr-only-xs {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0,0,0,0);
    border: 0;
  }
}
Schmalzy
  • 17,044
  • 7
  • 46
  • 47