In this second part of the tutorial about the navigation system in a Cordova mobile application we’ll se how to create a fixed top bar which will allow our users an alternative way to navigate between main views.
First of all we have to install material icons by Google. They are great icons to use in a mobile app and we’ll use them to build our top bar. Open your CLI in your project directory and type the following command:
npm install material-design-icons
You can find some alternative ways to install material icons here. |
This command will create a new directory called material-desiogn-icons in swipingPages/node-modules directory: use your file manager and look for the iconfont folder, then copy it in your project css folder. Finally, put a link to the file material-icons.css in your index.html:
<link rel="stylesheet" type="text/css" href="css/iconfont/material-icons.css">
Now that we have material icons in place we can start with the markup of our top navigation.
The navigation top bar
Tha basic structure
Since we want to make our top bar fixed, we put its markup directly in the body, jus above the Bootstrap carousel. Let’s take a look at the markup:
<div id="cfx-topbar"> <ul id="cfx-topbar-menu"> <li class="active"><a href="#" data-index="0"><i class="material-icons">dashboard</i></a></li> <li><a href="#" data-index="1"><i class="material-icons">group_work</i></a></li> <li><a href="#" data-index="2"><i class="material-icons">search</i></a></li> <li><a href="#" data-index="3"><i class="material-icons">share</i></a></li> <li><a href="#" id="sidemenu-open"><i class="material-icons">menu</i></a></li> </ul> </div> <!-- cfx-topbar -->
Now let’s go with the CSS.
We want our navigation top bar be always visible so we set its position property to fixed:
#cfx-topbar{ background: #689F38; top : 0; left : 0; position : fixed; width : 100%; height : 50px; z-index : 3; }
In addition, we set our material icons to a bigger size than the default one of 24px.
#cfx-topbar .material-icons{ font-size: 32px; }
Now we have to manage the <ul> element which actually manages our navigation bar:
#cfx-topbar-menu{ list-style: none; position: relative; padding: 0; width: 100%; } #cfx-topbar-menu li{ width: 19% !important; display: inline-block; text-align: center; vertical-align: middle; } #cfx-topbar-menu li a{ display: block; background: transparent !important; text-decoration: none; margin-top: .3em; color: white; } #cfx-topbar-menu li a:hover{ color: #fff; } #cfx-topbar-menu li a .material-icons{ color: #fff; }
This way our top bar is ready. We’ve just to slightly change our views’ markup adding a page-wrapper and some content to make our app jst a bit more realistic. For these new elements, we’ll also have to do some more change in our index.css.
Modifying our views
Open your index.html file and look for the markup of the carousel which holds our views: it should look like this:
<div id="myCarousel" class="carousel slide" data-ride="carousel" data-interval="false"> <div class="carousel-inner" role="listbox"> <div id="page1" class="item active"><h2>Page 1</h2></div> <div id="page2" class="item"><h2>Page 2</h2></div> <div id="page3" class="item"><h2>Page 3</h2></div> <div id="page4" class="item"><h2>Page 4</h2></div> </div> </div>
We have now to add an element which will wrap our views’ content. So change the carousel markup in order to make it look like this:
<div id="myCarousel" class="carousel slide" data-ride="carousel" data-interval="false"> <div class="carousel-inner" role="listbox"> <div id="page1" class="item view active"> <div class="page-wrapper"> <h2>Page 1</h2> </div> </div> <div id="page2" class="item view"> <div class="page-wrapper"> <h2>Page 2</h2> </div> </div> <div id="page3" class="item view"> <div class="page-wrapper"> <h2>Page 3</h2> </div> </div> <div id="page4" class="item view"> <div class="page-wrapper"> <h2>Page 4</h2> </div> </div> </div> </div>
The page-wrapper will ensure our content will be scrollable. To give some content to our views, just add to them following fake text:
<p>Lorem ipsum dolor sit amet, vix clita vitae debitis ne. Ut eros porro facete has, sed an recusabo delicatissimi, nam ei elit graeco dissentiet. Ex cum homero copiosae, id sed utamur consectetuer. Zril utamur in his, et dico movet munere sit, ea usu prima cetero tractatos. His no cibo illud, ei vidisse volutpat pro, erroribus repudiare ut per.</p> <p>No insolens euripidis moderatius duo, mea quando dignissim an. Cetero inermis ut vis, vim iracundia rationibus an. Ut qui malis quaestio, sea at brute mandamus. Eam cu bonorum delicata, vim sonet percipitur sadipscing no. Quot habeo erroribus vel ex.</p> <p>Eu cum menandri incorrupte, vis et doming legimus utroque. Mei at solum putant, sea ut omittam omittantur, amet saperet sit in. Nibh eloquentiam ea mel. Eum ad tollit impetus euripidis, corpora ponderum accommodare ut mel. Exerci constituam ex sit, elit dissentias pri eu, et has unum error habemus.</p> <p>Dicat labore dignissim mea ei, an similique reformidans adversarium usu. Cu inani possim everti pro, ea noster denique elaboraret nec, vituperata dissentiunt et nec. Sit ut ludus audire facilisis. Duo illud molestie oportere ei. Cum ad errem laoreet. Pri an amet etiam splendide, eam ex falli similique.</p> <p>Ea ipsum laudem dissentiunt has. Sumo causae ei nam, eruditi molestiae dissentiet mei te. Mazim alterum cu per, munere civibus et ius. Eripuit apeirian at eum, est et nisl erat patrioque, labores omnesque salutandi ius id. Cu prodesset disputationi cum.</p>
The final carousel element markup should look like this:
<div id="myCarousel" class="carousel slide" data-ride="carousel" data-interval="false"> <div class="carousel-inner" role="listbox"> <div id="page1" class="item view active"> <div class="page-wrapper"> <h2>Page 1</h2> <p>Lorem ipsum dolor sit amet, vix clita vitae debitis ne. Ut eros porro facete has, sed an recusabo delicatissimi, nam ei elit graeco dissentiet. Ex cum homero copiosae, id sed utamur consectetuer. Zril utamur in his, et dico movet munere sit, ea usu prima cetero tractatos. His no cibo illud, ei vidisse volutpat pro, erroribus repudiare ut per.</p> <p>No insolens euripidis moderatius duo, mea quando dignissim an. Cetero inermis ut vis, vim iracundia rationibus an. Ut qui malis quaestio, sea at brute mandamus. Eam cu bonorum delicata, vim sonet percipitur sadipscing no. Quot habeo erroribus vel ex.</p> <p>Eu cum menandri incorrupte, vis et doming legimus utroque. Mei at solum putant, sea ut omittam omittantur, amet saperet sit in. Nibh eloquentiam ea mel. Eum ad tollit impetus euripidis, corpora ponderum accommodare ut mel. Exerci constituam ex sit, elit dissentias pri eu, et has unum error habemus.</p> <p>Dicat labore dignissim mea ei, an similique reformidans adversarium usu. Cu inani possim everti pro, ea noster denique elaboraret nec, vituperata dissentiunt et nec. Sit ut ludus audire facilisis. Duo illud molestie oportere ei. Cum ad errem laoreet. Pri an amet etiam splendide, eam ex falli similique.</p> <p>Ea ipsum laudem dissentiunt has. Sumo causae ei nam, eruditi molestiae dissentiet mei te. Mazim alterum cu per, munere civibus et ius. Eripuit apeirian at eum, est et nisl erat patrioque, labores omnesque salutandi ius id. Cu prodesset disputationi cum.</p> </div> </div> <div id="page2" class="item view"> <div class="page-wrapper"> <h2>Page 2</h2> <p>Lorem ipsum dolor sit amet, vix clita vitae debitis ne. Ut eros porro facete has, sed an recusabo delicatissimi, nam ei elit graeco dissentiet. Ex cum homero copiosae, id sed utamur consectetuer. Zril utamur in his, et dico movet munere sit, ea usu prima cetero tractatos. His no cibo illud, ei vidisse volutpat pro, erroribus repudiare ut per.</p> <p>No insolens euripidis moderatius duo, mea quando dignissim an. Cetero inermis ut vis, vim iracundia rationibus an. Ut qui malis quaestio, sea at brute mandamus. Eam cu bonorum delicata, vim sonet percipitur sadipscing no. Quot habeo erroribus vel ex.</p> <p>Eu cum menandri incorrupte, vis et doming legimus utroque. Mei at solum putant, sea ut omittam omittantur, amet saperet sit in. Nibh eloquentiam ea mel. Eum ad tollit impetus euripidis, corpora ponderum accommodare ut mel. Exerci constituam ex sit, elit dissentias pri eu, et has unum error habemus.</p> <p>Dicat labore dignissim mea ei, an similique reformidans adversarium usu. Cu inani possim everti pro, ea noster denique elaboraret nec, vituperata dissentiunt et nec. Sit ut ludus audire facilisis. Duo illud molestie oportere ei. Cum ad errem laoreet. Pri an amet etiam splendide, eam ex falli similique.</p> <p>Ea ipsum laudem dissentiunt has. Sumo causae ei nam, eruditi molestiae dissentiet mei te. Mazim alterum cu per, munere civibus et ius. Eripuit apeirian at eum, est et nisl erat patrioque, labores omnesque salutandi ius id. Cu prodesset disputationi cum.</p> </div> </div> <div id="page3" class="item view"> <div class="page-wrapper"> <h2>Page 3</h2> <p>Lorem ipsum dolor sit amet, vix clita vitae debitis ne. Ut eros porro facete has, sed an recusabo delicatissimi, nam ei elit graeco dissentiet. Ex cum homero copiosae, id sed utamur consectetuer. Zril utamur in his, et dico movet munere sit, ea usu prima cetero tractatos. His no cibo illud, ei vidisse volutpat pro, erroribus repudiare ut per.</p> <p>No insolens euripidis moderatius duo, mea quando dignissim an. Cetero inermis ut vis, vim iracundia rationibus an. Ut qui malis quaestio, sea at brute mandamus. Eam cu bonorum delicata, vim sonet percipitur sadipscing no. Quot habeo erroribus vel ex.</p> <p>Eu cum menandri incorrupte, vis et doming legimus utroque. Mei at solum putant, sea ut omittam omittantur, amet saperet sit in. Nibh eloquentiam ea mel. Eum ad tollit impetus euripidis, corpora ponderum accommodare ut mel. Exerci constituam ex sit, elit dissentias pri eu, et has unum error habemus.</p> <p>Dicat labore dignissim mea ei, an similique reformidans adversarium usu. Cu inani possim everti pro, ea noster denique elaboraret nec, vituperata dissentiunt et nec. Sit ut ludus audire facilisis. Duo illud molestie oportere ei. Cum ad errem laoreet. Pri an amet etiam splendide, eam ex falli similique.</p> <p>Ea ipsum laudem dissentiunt has. Sumo causae ei nam, eruditi molestiae dissentiet mei te. Mazim alterum cu per, munere civibus et ius. Eripuit apeirian at eum, est et nisl erat patrioque, labores omnesque salutandi ius id. Cu prodesset disputationi cum.</p> </div> </div> <div id="page4" class="item view"> <div class="page-wrapper"> <h2>Page 4</h2> <p>Lorem ipsum dolor sit amet, vix clita vitae debitis ne. Ut eros porro facete has, sed an recusabo delicatissimi, nam ei elit graeco dissentiet. Ex cum homero copiosae, id sed utamur consectetuer. Zril utamur in his, et dico movet munere sit, ea usu prima cetero tractatos. His no cibo illud, ei vidisse volutpat pro, erroribus repudiare ut per.</p> <p>No insolens euripidis moderatius duo, mea quando dignissim an. Cetero inermis ut vis, vim iracundia rationibus an. Ut qui malis quaestio, sea at brute mandamus. Eam cu bonorum delicata, vim sonet percipitur sadipscing no. Quot habeo erroribus vel ex.</p> <p>Eu cum menandri incorrupte, vis et doming legimus utroque. Mei at solum putant, sea ut omittam omittantur, amet saperet sit in. Nibh eloquentiam ea mel. Eum ad tollit impetus euripidis, corpora ponderum accommodare ut mel. Exerci constituam ex sit, elit dissentias pri eu, et has unum error habemus.</p> <p>Dicat labore dignissim mea ei, an similique reformidans adversarium usu. Cu inani possim everti pro, ea noster denique elaboraret nec, vituperata dissentiunt et nec. Sit ut ludus audire facilisis. Duo illud molestie oportere ei. Cum ad errem laoreet. Pri an amet etiam splendide, eam ex falli similique.</p> <p>Ea ipsum laudem dissentiunt has. Sumo causae ei nam, eruditi molestiae dissentiet mei te. Mazim alterum cu per, munere civibus et ius. Eripuit apeirian at eum, est et nisl erat patrioque, labores omnesque salutandi ius id. Cu prodesset disputationi cum.</p> </div> </div> </div> </div>
In the index.css we replace the carousel rules we had set in the first part of this tutorial:
.carousel,.item,.active{ height:100%; } .carousel-inner{ height:100%; }
whit these new rules:
.carousel { height: 100%; } .carousel-inner { height: 100%; } .carousel-inner>.item { height: 100%; padding: 10px 0; overflow: auto; } .carousel-inner .page-wrapper{ padding: 50px 10px 0 10px !important; margin-bottom: 60px; }
These rules ensure we’ll be able to vertically scroll our views to see all their content.
That’s all: try to run the application to see how the navigation bar looks. Now we’re going to give it life with a bit of javascript.
Bring navigation bar to life!
We can finally write a piece of javascript to bring our top navigation bar to life. It’s quite simple: using jQuery we’ve just to bind the click event for the anchor links in our list items and execute a simple command. Start looking at the code:
$(document).on('click', '#cfx-topbar #cfx-topbar-menu', function () { var target = $(this).data('index'); $('.carousel').carousel(target); switch (target) { case 0: //do here stuff specific to the view such as loading data...; break; case 1: //do here stuff specific to the view such as loading data...; break; case 2: //do here stuff specific to the view such as loading data...; break; case 3: //do here stuff specific to the view such as loading data...; break; } });
Thank you so much to Paul who noticed a typo in this code snippet where I had used “cfx-topbar-menu” as a class instead of as an id.
You had probably noticed that in our top bar markup I had inserted a data attribute without telling anything about: now it’s time to reveal the goal of the data-index attribute, but you have already guessed it, didn’t you? Since the carousel() method of the carousel object accepts as parameter a numeric index, we have to provide us with an easy and quick way to get the index of the page (view) we want to go to. We have just hard coded this index using the data-index attribute (keep in mind the index starts from 0) and then, from jQuery, we get the index of the view our link points to and we use it to invoke the carousel() method.
I have also added a switch statement because in the real world we could expect any page performs some specific task and loads some specific data: the best place where we can perform these basic actions for each specific view is right here, in the event handler whcih loads the view itself.
If you run the application now, you’ll see that you can navigate through its views both swiping your finger to the left and to the right or just tapping the top bar buttons.
Wait a moment, things aren’t quite adding up…
In our app we have only four views but in navigation top bar we have five buttons where we can tap on! What the fifth button does? Well, you see that button has the classical side-menu icon widely used in so many apps: in fact that button opens a side-menu, but before we can see it in action we have to introduce a new view’s type. This new view is external to the carousel flow: we can’t go to it just swiping our fingers and it doesn’t belong to a set of views like the carousel views do. We could call this view type single-view or secondary-view (in opposition to the main-view held in our carousel) and it’s going to be the argument of the third part of this article.
Part 1 – Part 2 – Part 3 – Part 4
Excellent website you have here but I was wondering if you knew of any user discussion forums that cover the same topics talked about in this
article? I’d really like to be a part of community where I can get feedback from other experienced individuals that share the same
interest. If you have any recommendations, please let me know.
Thanks a lot!
Hi download! Unfortunately I don’t know such a community specific to Cordova. But for sure you know StackOverflow and Experts-Exchange. Especially Experts-Exchange is a really comfortable community you partecipate to 🙂
Hello,
Thank you for taking the time to write this tutorial. It’s now over 3 years since this was published, and I’m sure you’ll get a warm glow knowing that it’s still finding an audience!
I have a question about the final Jquery code. I cannot seem to get the “click” event to fire unless I change “.cfx-topbar-menu” to “#cfx-topbar-menu”. Is this a typo?
Also, the next line…
var target = $(this).data(‘index’);
…returns “undefined” (and upon investigation, “this” is a HTMLUListElement object) and not the value of the “data-index” attribute.
I’m now stuck trying to figure out if the code is somehow wrong. Do you have the finished code so I can at least check the code samples published here against a working code-set.
BTW: I am using jQuery 3.4.1
Many thanks.
Hello,
OK. Worked it out. Simple really.
The selector:
‘#cfx-topbar .cfx-topbar-menu’
Should read:
‘#cfx-topbar #cfx-topbar-menu a’
As ‘cfx-topbar-menu’ is an identifier in the HTML, and not a class, and the ‘data-index’ is on the and not the element.
I hope this helps any future readers of this tutorial.
Hi Paul. Thank you so much for your comment and for your fix: it was actually a typo: “cfx-topbar-menu” was not a class but an id. I’ll update the code in the article.