开发者

More than 5 items per line in jQuery Mobile navbar

开发者 https://www.devze.com 2023-03-08 19:00 出处:网络
I have unsuccessfully looked for a variable to change the maximum number of items in a single line in a navbar.

I have unsuccessfully looked for a variable to change the maximum number of items in a single line in a navbar.

I am just starting with jQuery Mobile, trying to create a navbar with around 7 single-letter items. The navbar wraps automatically when more than 5 items are present, which is undesirable for my project.

Can anyone point me to a piece in the code or css that regulates this behavior开发者_如何学运维?


You're right jQM limits the columns to 5. Looking over the code this seems to be the function:

/*
* jQuery Mobile Framework : plugin for creating CSS grids
* Copyright (c) jQuery Project
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*/ 
(function($, undefined ) {
$.fn.grid = function(options){
    return this.each(function(){
        var o = $.extend({
            grid: null
        },options);


        var $kids = $(this).children(),
            gridCols = {solo:1, a:2, b:3, c:4, d:5},
            grid = o.grid,
            iterator;

            if( !grid ){
                if( $kids.length <= 5 ){
                    for(var letter in gridCols){
                        if(gridCols[letter] == $kids.length){ grid = letter; }
                    }
                }
                else{
                    grid = 'a';
                }
            }
            iterator = gridCols[grid];

        $(this).addClass('ui-grid-' + grid);

        $kids.filter(':nth-child(' + iterator + 'n+1)').addClass('ui-block-a');
        if(iterator > 1){   
            $kids.filter(':nth-child(' + iterator + 'n+2)').addClass('ui-block-b');
        }   
        if(iterator > 2){   
            $kids.filter(':nth-child(3n+3)').addClass('ui-block-c');
        }   
        if(iterator > 3){   
            $kids.filter(':nth-child(4n+4)').addClass('ui-block-d');
        }   
        if(iterator > 4){   
            $kids.filter(':nth-child(5n+5)').addClass('ui-block-e');
        }

    }); 
};

It will take some work but you can extend this to the desired 7 column layout. You will also need to add the custom CSS as well to handle the new columns, so you new function would look something like this

/*
* jQuery Mobile Framework : plugin for creating CSS grids
* Copyright (c) jQuery Project
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*/ 
(function($, undefined ) {
$.fn.grid = function(options){
    return this.each(function(){
        var o = $.extend({
            grid: null
        },options);


        var $kids = $(this).children(),
            gridCols = {solo:1, a:2, b:3, c:4, d:5, e:6, f:7},
            grid = o.grid,
            iterator;

            if( !grid ){
                if( $kids.length <= 7 ){
                    for(var letter in gridCols){
                        if(gridCols[letter] == $kids.length){ grid = letter; }
                    }
                }
                else{
                    grid = 'a';
                }
            }
            iterator = gridCols[grid];

        $(this).addClass('ui-grid-' + grid);

        $kids.filter(':nth-child(' + iterator + 'n+1)').addClass('ui-block-a');
        if(iterator > 1){   
            $kids.filter(':nth-child(' + iterator + 'n+2)').addClass('ui-block-b');
        }   
        if(iterator > 2){   
            $kids.filter(':nth-child(3n+3)').addClass('ui-block-c');
        }   
        if(iterator > 3){   
            $kids.filter(':nth-child(4n+4)').addClass('ui-block-d');
        }   
        if(iterator > 4){   
            $kids.filter(':nth-child(5n+5)').addClass('ui-block-e');
        }
            if(iterator > 5){   
            $kids.filter(':nth-child(6n+6)').addClass('ui-block-f');
        }
            if(iterator > 6){   
            $kids.filter(':nth-child(7n+7)').addClass('ui-block-g');
        }

        }); 
    };
}); // end

In the CSS:

change this:

.ui-block-a, .ui-block-b, .ui-block-c, .ui-block-d, .ui-block-e { margin: 0; padding: 0; border: 0; float: left; min-height:1px;}

to this:

.ui-block-a, .ui-block-b, .ui-block-c, .ui-block-d, .ui-block-e, .ui-block-f, .ui-block-g { margin: 0; padding: 0; border: 0; float: left; min-height:1px;}

and add these:

/* grid e: 16/16/16/16/16/16 */
.ui-grid-d .ui-block-a, .ui-grid-d .ui-block-b, .ui-grid-d .ui-block-c, .ui-grid-d .ui-block-d, .ui-grid-d .ui-block-e .ui-block-f { width: 16%; }
.ui-grid-d .ui-block-a { clear: left; }

/* grid f: 14/14/14/14/14/14/14 */
.ui-grid-d .ui-block-a, .ui-grid-d .ui-block-b, .ui-grid-d .ui-block-c, .ui-grid-d .ui-block-d, .ui-grid-d .ui-block-e .ui-block-f .ui-block-g { width: 14%; }
.ui-grid-d .ui-block-a { clear: left; }

There might be other changes as well but these are the ones that stand out as of now.

  • Link to JS
  • Link to CSS

Failed Attempt to use buttons for the navbar but they stack on one another as well: Live Link


Using jQuery mobile 1.4.0, all I had to do is to create my own CSS class:

.mytab {
    width: 12.5% !important;  /* 12.5% for 8 tabs wide */
    clear: none !important;  /* Prevent line break caused by ui-block-a */
}

..and include it in my list:

<ul id='tabsList'>
  <li class="mytab"><a href="#tab1" data-ajax="false">One</a></li>
  <li class="mytab"><a href="#tab2" data-ajax="false">Two</a></li>
  <li class="mytab"><a href="#tab3" data-ajax="false">Three</a></li>
  <li class="mytab"><a href="#tab4" data-ajax="false">Four</a></li>
  <li class="mytab"><a href="#tab5" data-ajax="false">Five</a></li>
  <li class="mytab"><a href="#tab6" data-ajax="false">Six</a></li>
  <li class="mytab"><a href="#tab7" data-ajax="false">Seven</a></li>
  <li class="mytab"><a href="#tab8" data-ajax="false">Eight</a></li>
</ul>

(original answer had jQuery mobile version wrong)


From Phill Pafford

"and add these: .... " { css code }

please change to .... (NOTE: Width changed to 16.65%. This note added because StackOverflow doesn't allow one-letter edits.)

/* grid e: 16/16/16/16/16/16 */
.ui-grid-e .ui-block-a, .ui-grid-e .ui-block-b, .ui-grid-e .ui-block-c, .ui-grid-e .ui-block-d, .ui-grid-e .ui-block-e, .ui-grid-e .ui-block-f { width: 16.65%; }
.ui-grid-e .ui-block-a { clear: left; }

/* grid f: 14/14/14/14/14/14/14 */
.ui-grid-f .ui-block-a, .ui-grid-f .ui-block-b, .ui-grid-f .ui-block-c, .ui-grid-f .ui-block-d, .ui-grid-f .ui-block-e, .ui-grid-f .ui-block-f, .ui-grid-f .ui-block-g { width: 14.2857%; }
.ui-grid-f .ui-block-a { clear: left; }


You can try another way to add items in navbar as many as you required. Let me explain.

HTML of navbar is as fallows.

<div data-role="navbar" id="my-navbar">
<ul>
    <li><a href="a.html">One</a></li>
    <li><a href="b.html">Two</a></li>
    <li><a href="a.html">Three</a></li>
    <li><a href="b.html">Four</a></li>
    <li><a href="a.html">Five</a></li>
    <li><a href="b.html">Seven</a></li>
</ul>

Add this Jquery function to remove class ui-grid-a from <ul> that limits the number of items on navbar.

$(document).ready(function() {

    $("#my-navbar > ul").removeClass("ui-grid-a");

});

Now you will have to calculate the width of each navbar item OR you can set it manually. In this example we have 7 items to display on navbar and we want to divide the space equally to each item.

For a PHP page we will do this.

<?php

/// calculating width of each navbar ///

$width = 100/7; /// dividing 100% space among 7 items. If data is coming form DB then use mysql_num_rows($resource) instead of static number "7"
?>

<style>

.ui-block-a {
width:<?php echo $width;?>% !important;
}
.ui-block-b {
width:<?php echo $width;?>% !important;
}

</style>

<?php

/// end calculating ///
?>

For static HTML pages you can set the width of each item manually

<style>

.ui-block-a {
width:14.28% !important;
}
.ui-block-b {
width:14.28% !important;
}

</style>

Thats it :)

I have used it for me and it works fine.


After:

/* grid d: 20/20/20/20/20 */ .ui-grid-d .ui-block-a, .ui-grid-d .ui-block-b, .ui-grid-d .ui-block-c, .ui-grid-d .ui-block-d, .ui-grid-d .ui-block-e { width: 19.925%; } .ui-grid-d > :nth-child(n) { width: 20%; } .ui-grid-d .ui-block-a { clear: left; }

in CSS, ADD

/* grid e: 16/16/16/16/16/16 */ .ui-grid-e .ui-block-a, .ui-grid-e .ui-block-b, .ui-grid-e .ui-block-c, .ui-grid-e .ui-block-d, .ui-grid-e .ui-block-e, .ui-grid-e .ui-block-f { width: 16.66%; } .ui-grid-e > :nth-child(n) { width: 16.6%; } .ui-grid-e .ui-block-a { clear: left; }

/* grid f: 14/14/14/14/14/14/14 */ .ui-grid-f .ui-block-a, .ui-grid-f .ui-block-b, .ui-grid-f .ui-block-c, .ui-grid-f .ui-block-d, .ui-grid-f .ui-block-e, .ui-grid-f .ui-block-f, .ui-grid-f .ui-block-g { width: 14.28%; } .ui-grid-f > :nth-child(n) { width: 14.28%; } .ui-grid-f .ui-block-a { clear: left; }

And do a little modification in js:

(function( $, undefined ) {
$.fn.grid = function( options ) {
    return this.each(function() {

        var $this = $( this ),
            o = $.extend({
                grid: null
            }, options ),
            $kids = $this.children(),
            gridCols = { solo:1, a:2, b:3, c:4, d:5, e:6, f:7 },
            grid = o.grid,
            iterator;

            if ( !grid ) {
                if ( $kids.length <= 7 ) {
                    for ( var letter in gridCols ) {
                        if ( gridCols[ letter ] === $kids.length ) {
                            grid = letter;
                        }
                    }
                } else {
                    grid = "a";
                    $this.addClass( "ui-grid-duo" );
                }
            }
            iterator = gridCols[grid];
            //alert(iterator);

        $this.addClass( "ui-grid-" + grid );

        $kids.filter( ":nth-child(" + iterator + "n+1)" ).addClass( "ui-block-a" );

        if ( iterator > 1 ) {
            $kids.filter( ":nth-child(" + iterator + "n+2)" ).addClass( "ui-block-b" );
        }
        if ( iterator > 2 ) {
            $kids.filter( ":nth-child(" + iterator + "n+3)" ).addClass( "ui-block-c" );
        }
        if ( iterator > 3 ) {
            $kids.filter( ":nth-child(" + iterator + "n+4)" ).addClass( "ui-block-d" );
        }
        if ( iterator > 4 ) {
            $kids.filter( ":nth-child(" + iterator + "n+5)" ).addClass( "ui-block-e" );
        }
        if ( iterator > 5 ) {
            $kids.filter( ":nth-child(" + iterator + "n+6)" ).addClass( "ui-block-f" );
        }
        if ( iterator > 6 ) {
            $kids.filter( ":nth-child(" + iterator + "n+7)" ).addClass( "ui-block-g" );
        }
    });
};
})( jQuery );

You can use up to 7 grid by this. In html code use data-grid="e" for 6 grid, data-grid="f" for 7 grid.


The OP was not explicit about having an odd number of items above 5. For even numbers we can use jQuery's responsive grids in conjunction with navbar.

e.g.

<div data-role="navbar">
    <div class="ui-grid-a center">
        <div class="ui-block-a">
            <ul>
                <li><a href="#" data-icon="camera">camera</a></li>
                <li><a href="#" data-icon="edit">edit</a></li>
                <li><a href="#" data-icon="gear">settings</a></li>
            </ul>
        </div>
        <div class="ui-block-b">
            <ul>
                <li><a href="#" data-icon="grid">grid</a></li>
                <li><a href="#" data-icon="info">about</a></li>
                <li><a href="#" data-icon="mail">mail</a></li>
            </ul>
        </div>
    </div>
</div>


The white-space property specifies how white-space inside an element is handled.

nowrap: Sequences of whitespace will collapse into a single whitespace. Text will never wrap to the next line. The text continues on the same line until a <br /> tag is encountered

Also CSS word wrap property

break-word: Content will wrap to the next line when necessary, and a word-break will also occur if needed.

Source for this answer: W3C

I looked at the jQuery mobile code also and found this section:

.ui-grid-d .ui-block-a, .ui-grid-d .ui-block-b, .ui-grid-d .ui-block-c, .ui-grid-d .ui-block-d, .ui-grid-d .ui-block-e { width:20%; }

So perhaps by reducing this amount you should be able to squeeze more items in the list. (By the looks of it you also would need to define f and g as this one has only got up to e)


I would look at a different ui pattern. This is going to be a really tricky navbar on a small iphone 4, or even on iphone 5 device. Just because you can do this doesn't mean you should.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号