9

In jQuery Mobile, lets say I have the following navigation bar:

<div data-role="navbar">
    <ul>
        <li><a id="item1">Item 1</a></li>
        <li><a id="item2">Item 2</a></li>
        <li><a id="item3">Item 3</a></li>
    </ul>
</div>

I can then just use jQuery to remove an item to make this look like:

<div data-role="navbar">
    <ul>
        <li><a id="item1">Item 1</a></li>
        <li><a id="item3">Item 3</a></li>
    </ul>
</div>

However, jQuery Mobile still renders it as if there are three tabs, and in the middle one, there is just nothing there. So instead of it being spaced out with each tab taking 1/2 of the width, each of the two remaining tabs just takes 1/3 of the width.

I looked closer and jQuery Mobile automatically adds a class to the <ul> element called "ui-grid-b" and if I change that manually to "ui-grid-a" it then looks fine and the two tabs take up the whole width. However, changing those classes manually seems too hackish and I'm guessing there is a better way to do it. Any ideas?

Spike
  • 5,040
  • 5
  • 32
  • 47

10 Answers10

4

I didn't figure out a great solution, but I at least figured out a less hacky one.

For my problem, I at least know all of the elements I want in my navbars ahead of time, so I can simply construct several sets of navbars and turn them on or off depending on certain situations. Thus, the HTML looks like phil's solution, but the JS for his solution would instead look like:

$('#navbar1').hide();
$('#navbar2').show();
$('#page1').page();
Spike
  • 5,040
  • 5
  • 32
  • 47
3

Try this:

<script type="text/javascript">
    function addItem() {
        // create the navbar element
        var li = $("<li></li>");
        var a = $("<a></a>");
        var navbar = $("#navbar1");

        a.attr("id", "item4").text("Item 4");
        li.append(a);
        // remove the JQM auto-init classes
        navbar.find("*").andSelf().each(function(){
            $(this).removeClass(function(i, cn){
                var matches = cn.match (/ui-[\w\-]+/g) || [];
                return (matches.join (' '));
            });
            if ($(this).attr("class") == "") {
                $(this).removeAttr("class");
            }
        });

        // destroy the navbar widget object
        navbar.navbar("destroy");

        // append the newly created element
        li.appendTo($("#page1 ul"));

        // re-init the navbar
        navbar.navbar();
        console.log(navbar.data());
    }
</script>

I guess you already know how to remove an element from navbar now.

Mihai Iorga
  • 39,330
  • 16
  • 106
  • 107
bean
  • 249
  • 2
  • 11
  • This is working with 1.4.3. Fiddle here : http://www.gajotres.net/jquery-mobile-and-how-to-enhance-the-markup-of-dynamically-added-content/ – Matthieu Jun 22 '16 at 14:34
  • Actually, it doesn't fully work in 1.4.3 : the newly created tabs keep the active state when you click on another tab – Matthieu Jun 24 '16 at 08:40
2

Not really a working example but: http://jsfiddle.net/ZsSHE/10/

<div data-role="page" id="page1"> 
    <div data-role="content"> 
        <div data-role="navbar" id="navbar1">
            <ul>
                <li><a id="item1">Item 1</a></li>
                <li><a id="item2">Item 2</a></li>
                <li><a id="item3">Item 3</a></li>
            </ul>
        </div>
        <br />
        <div data-role="navbar" id="navbar2">
            <ul>
                <li><a id="item4">Item 4</a></li>
                <li><a id="item5">Item 5</a></li>
            </ul>
        </div>
    </div><!-- /content --> 
</div><!-- /page --> 

JS

$('#item3').remove();
$('#page1').page();
Phill Pafford
  • 83,471
  • 91
  • 263
  • 383
  • .page() just doesn't seem to be refreshing the navbar... It refreshes rest of the page, but i just can't seem to get it to change the nav bar. – Spike Jun 09 '11 at 00:51
2

You can add buttons to a jQuery Mobile navbar by adding plain links (A), and then calling the navbar() method on the navbar element itself.

For example: in HTML you place an empty navbar like this:

  <div data-role="navbar" data-theme="a">
    <ul id="myNavbar"></ul>
  </div>

Than in JavaScript you do the following:

// creating new buttons
$("#myNavbar").append('<a href="#" class="ttxButton">button 1</a>');
$("#myNavbar").append('<a href="#" class="ttxButton">button 2</a>');
$("#myNavbar").append('<a href="#" class="ttxButton">button 3</a>');

// calling the navbar method
$("#myNavbar").navbar();
knee-cola
  • 736
  • 8
  • 17
  • Cool, I haven't tried this yet. I'm guessing it was added in one of the more recent releases, and I'll be sure to look into it next time I do this or if I just want to clean up existing code. – Spike Oct 17 '11 at 16:56
  • this didn't work for me in jquery mobile 1.1.0, however i came up with a variation that worked for me. im posting it here as an answer – Tejesh Alimilli Jun 08 '12 at 11:39
1

Refreshes the NavBar without recreating the component

function refreshNavbar(el) {
    var ul = el.children("ul"),
        childCount = 0, cls, visibleEl,
        children = ul.children("li"),
        clsList = ["ui-grid-solo","ui-grid-a","ui-grid-b","ui-grid-c","ui-grid-d","ui-grid-duo"],
        clsArr = ["ui-grid-solo","ui-grid-a","ui-grid-b","ui-grid-c","ui-grid-d","ui-grid-duo ui-grid-a"];

    for (var i = 0, j = children.length; i < j; i++) {
        child = $(children[i]);
        if (child.is(":visible")) {
            childCount++;
        }
    }

    cls = clsArr[childCount-1];
    if (childCount == 1) {
        visibleEl = ul.children("li:visible");
        if (!visibleEl.hasClass("ui-block-a")) {
            visibleEl.addClass("ui-block-a");
        }
     } else {
        ul.children("li").removeClass("ui-block-a");
        ul.children("li:first").addClass("ui-block-a");
     }

    //remove existing grid class
    var rx = new RegExp(clsList.join("|"), "gi");
    var oldCls = ul.attr("class").replace(rx, function (matched) {
        return "";
   });

    //set new grid class, preserving existing custom clases
    ul.attr("class", oldCls + " "+ cls);
}

Fiddle

http://jsfiddle.net/tM3KR/

Richard A
  • 2,100
  • 15
  • 13
  • Out of a thousand answers on this question which has been asked a thousand times, this is the only one that works. Thanks! I've modified your code a bit to turn it into a Knockout plugin and know Knockout and jQuery Mobile finally work together. – Josh Mouch Dec 12 '14 at 16:51
  • Thats awesome to hear! glad to help :) – Richard A Dec 12 '14 at 23:47
1

You should simply use $('#navbar').navbar('refresh'). #navbar could be any id or element reference.

SuperNova
  • 2,792
  • 2
  • 25
  • 34
1

The .navbar method by itself, does not seem to work on jquery mobile 1.4.2. I had to perform a destroy first and it seems the styles get reapplied.

FYI, this will work as long as the buttons added do not wrap. If you add enough buttons for the navbar to wrap them, the style applied is not totally correct.

The code would look like

$('#yournavbarDIV').navbar("destroy");
$('#yournavbarDIV').navbar();

after you append your li elements.

dcapelo
  • 79
  • 3
0

the html

<div id="def"></div>

the javascript

$("#def").append("<ul id='abc'></ul>");
$("#abc").append('<li><a href="#">111</a></li>');
$("#abc").append('<li><a href="#">222</a></li>');
$("#abc").append('<li><a href="#">333</a></li>');
$("#def").navbar();
Tejesh Alimilli
  • 1,782
  • 1
  • 21
  • 31
0

I had the same problem and this is what I did.

In HTML

<div data-theme="b" data-role="footer" data-position="fixed">
  <div class="maintenance_tabs">
  </div>
</div>

And then in the JS function, I did this

var mynavbar = '<div data-role="navbar" data-iconpos="top" class="maintenance_tabs">'
                +'  <ul>'
                +'    <li>'
                +'      <a href="log.html" data-transition="fade" data-theme="b" data-icon="bars">'
                +'        View Log'
                +'      </a>'
                +'    </li>'
                +'    <li>'
                +'      <a href="'+ data.page +'" data-transition="fade" data-theme="b" data-icon="plus">'
                +'        New Entry'
                +'      </a>'
                +'   </li>'
                +'    <li>'
                +'      <a href="" data-transition="fade" data-theme="b" data-icon="back" onclick="return logoutAction();">'
                +'        Logout'
                +'      </a>'
                +'   </li>'
                +'  </ul>'
                +'</div>';
  $(".ui-page-active .maintenance_tabs").empty();
  $(".ui-page-active .maintenance_tabs").append(mynavbar).trigger('create');

I called the .empty() everytime so that it doesn't repeat the navbar again and again. Hope this helps someone.

Thanks.

0

I have a lot of problems changing a navbar content. This because the new content/buttons do not acting as normal

Actually, it doesn't fully work in 1.4.3 : the newly created tabs keep the active state when you click on another tab – Matthieu

Searching deep in source I found that navbar is doing this:

$navbar.delegate( "a", "vclick", function( /* event */ ) {

So, even if you destroy the navbar and recreate it, this event will be fired twice and this will break the normal behaviour. This will work:

navbar = $("#my-navbar");
navbar.navbar("destroy");
navbar.undelegate();

navbar.html("<ul><li><a href=\"#area1\">First  option</a></li><li><a href=\"#area2\">Second option</a></li></ul>");
navbar.navbar();
$('#my-tabs').tabs('refresh');

This has drive me crazy many days in a row... I hope it will help you.

Junior
  • 507
  • 5
  • 19