I'm doing a mobile App with jQuery mobile 1.4.3. I'm trying to build a navigation bar that changes dynamically, If the user has logged in the navigation bar will show 4 options, if not it will show 3 options. The problems:
Once I click the bar some times it turns all blue.
I'm sure I'm not using the correct code.
The navigation bar disappears for some time when I click in a button.
The blue click highlight is not persistent for the page click.
What I need is a fixed navigation bar that smoothly changes pages when clicked :)
http://jsfiddle.net/claire89/toxtcbhe/14/
var statusLogin = null;
$(document).on('pagecontainershow', function (e, ui) {
var myNavbar = null;
if (statusLogin == null) {
myNavbar = $('<div data-role="footer" data-id="footer" data-position="fixed"><div data-role="navbar"><ul><li>Menu</li><li>Sugestions</li><li>History</li><li>Settings</li></ul></div></div>');
$('.ui-content').append(myNavbar).trigger('create');
} else {
myNavbar = $('<div data-role="footer" data-id="footer" data-position="fixed"><div data-role="navbar"><ul><li>Menu</li><li>History</li><li>Settings</li></ul></div></div>').appendTo('.ui-content');
$('.content').append(myNavbar).trigger('create');
}
$("[data-role='navbar']").navbar();
$("[data-role='header'], [data-role='footer']").toolbar();
var activePage = $.mobile.pageContainer.pagecontainer("getActivePage");
var activePageId = activePage[0].id;
switch (activePageId) {
case 'listMenuPage':
alert("listMenuPage");
break;
case 'sugestionsPage':
alert("sugestionsPage");
break;
case 'settingsPage':
alert("settingsPage");
break;
case 'historyPage':
alert("historyPage");
break;
default:
}
});
footer div should be a direct child of page div, you should not place it inside content div. Moreover, you need to .remove() footer or navbar once you leave a page before you inject a new one. Otherwise, you will end up adding duplicating both footer and navbar in same page whenever the same page is shown.
Another note, when you inject toolbar dynamically, you need to reset the height of active page $.mobile.resetActivePageHeight() as toolbars adds padding to page, if height isn't reset, the page will scroll.
For better results, use pagecontainerbeforeshow to inject footer and navbar, and pagecontainerhide to remove them.
var statusLogin = null;
$(document).on('pagecontainerbeforeshow', function (e, ui) {
/* ui.toPage was introduced in 1.4.3
* can be used instead of "getActivePage"
* on pagecontainer events
*/
var activePage = $(ui.toPage),
activePageId = activePage[0].id,
myNavbar = "";
if (statusLogin == null) {
myNavbar = $('<tags></tags>');
activePage.append(myNavbar);
} else {
myNavbar = $('<tags></tags>');
activePage.append(myNavbar);
}
/* create footer and navbar
* add active class to button based on page's ID
*/
$("[data-role='footer']")
.toolbar()
.find("a[href=#" + activePageId + "]")
.addClass("ui-btn-active");
/* reset height of active page */
$.mobile.resetActivePageHeight();
}).on("pagecontainerhide", function (e, ui) {
/* remove footer once page is hidden */
$(".ui-footer", ui.prevPage).remove();
});
Demo
Related
I'm curently working on some extension to the gnome-shell. I added a new Popup menu into aggregate menu in status area, but can't move it to the desired position. Tried menu.moveMenuItem(item, position), but it moves only the "main" item, not the entire dropdown (How it looks - my PopupSubMenuMenuItem is named ThermalManagement, and submenu menu items starts from Optimized). What I need to do to move an entire submenu into specific position?
Code sample:
enable() {
this._item = new PopupMenu.PopupSubMenuMenuItem('Thermal Management', true);
this._item.icon.icon_name = 'applications-system-symbolic';
let position = this._findMenuItemPosition(Main.panel.statusArea.aggregateMenu._power.menu) + 1;
this._optimizedOption = this._createOptimizedOption();
this._item.menu.addMenuItem(this._optimizedOption);
this._quietOption = this._createQuietOption();
this._item.menu.addMenuItem(this._quietOption);
this._coolOption = this._createCoolOption();
this._item.menu.addMenuItem(this._coolOption);
this._ultraPerformanceOption = this._createUltraPerformanceOption();
this._item.menu.addMenuItem(this._ultraPerformanceOption);
Main.panel.statusArea.aggregateMenu.menu.addMenuItem(this._item);
Main.panel.statusArea.aggregateMenu.menu.moveMenuItem(this._item, position);
}
Context
I am working on a one-page website where the fixed navigation's class changes as it scrolls through the different sections in order to match the section's background color. To achieve this effect, I used and modified the 2nd solution listed here.
Issue
While it works great most of the time, the navigation code breaks when I resize the browser (or leave the page and click back). More specifically, the navigation's background color changes too early or too late and no longer matches the section's background.
I'm guessing that this happens because the section's height are calculated on page load. Ideally, they would be recalculated on every scroll - but I am a novice and that's just a guess. Any help to solve this issue would be appreciated.
JavaScript
FYI: there are four sections in the websites (Hero, Work, About, Contact). Navigation's bg color should be transparent in Hero, white in Work and Contact, and teal in About.
var afterhero = $('#hero-section').offset().top + $('#hero-section').height();
var afterwork = afterhero + $('#work-section').height();
var afterabout = afterwebsites + $('#about-section').height();
$(window).on('scroll', function() {
stop = Math.round($(window).scrollTop());
if (stop > afterabout) {
$('header').removeClass('teal');
$('header').addClass('white');
} else if (stop > afterwork) {
$('header').addClass('teal');
} else if (stop > afterhero) {
$('header').removeClass('teal');
$('header').addClass('white');
} else {
$('header').removeClass('teal');
$('header').removeClass('white');
}
});
Just try adding all your size variables into your scroll event handler:
$(window).on('scroll', function() {
var afterhero = $('#hero-section').offset().top + $('#hero-section').height();
var afterwork = afterhero + $('#work-section').height();
var afterabout = afterwebsites + $('#about-section').height();
stop = Math.round($(window).scrollTop());
if (stop > afterabout) {
$('header').removeClass('teal');
$('header').addClass('white');
} else if (stop > afterwork) {
$('header').addClass('teal');
} else if (stop > afterhero) {
$('header').removeClass('teal');
$('header').addClass('white');
} else {
$('header').removeClass('teal');
$('header').removeClass('white');
}
});
Now afterhero, afterwork and afterabout should all be recalculated on a page scroll.
I have the feeling I'm going around this totally the wrong way; here is the fiddle: http://jsfiddle.net/qhuprcLz/
What I'm trying to do is whenever I hover a main menu option, I want to grab the data-type set on that menu and set class on the main and then when I hover on the sub menu any of the menu items to get the data-background attr and set the background image on the container.
I loaded the site and menu into the jsfiddle so you can get a better understanding of what I mean.
JS:
// tablet and desktop only
if (window.matchMedia('(min-width: 960px)').matches) {
// menu background
$('.menu-menu ul li.cm-menu-item-responsive').on("mouseover", function () {
var menuType = $(this).attr("data-type");
var menuBackground = $(menuType + " .ty-menu__submenu-list li").attr("data-background");
console.log("menu type:"+menuType);
console.log("menu background:"+menuBackground);
$(this).find("div.ty-menu__submenu").addClass(menuType);
$(this).find("div.ty-menu__submenu").css('background-image', 'url(menu-' + menuBackground + '.png)');
});
}
Solution i came up with is as follows:
// menu background
$('.menu-menu ul li.cm-menu-item-responsive').on("mouseover", function () {
var menuType = $(this).attr("data-type");
$(this).find("div.ty-menu__submenu").addClass(menuType);
});
$('.ty-menu__submenu-list li').on("mouseover", function () {
var menuBackground = $(this).attr("data-background");
//console.log(menuBackground);
$("div.ty-menu__submenu.ty-menu__submenu-to-right").addClass(menuBackground);
});
I have applied a mega menu in one of my websites i.e. http://www.risenotes.com but when I try to convert it into a single and shortened menu for mobile view, it does not work. I succeeded initially for mobile view but only either of the two views work. Can anyone guide about any javascript code for displaying mega menu as regular mobile menu.
I tried using the below javascript but it succeeded me in my work on mobile version only while regular website version failed. Also, please that I have installed a mobile menu on http://www.risequotes.com which works perfect. That website is built in wordpress while my mega menu site is a php based website. Is there a way to apply my wordpress menu style to my php site? I mean some script.
I have tried below script which worked for conversion into mobile menu (including icons) but I need a bit more sophisticated version.
<script type="text/javascript">
function responsiveMobileMenu() {
$('.rmm').each(function() {
$(this).children('ul').addClass('rmm-main-list'); // mark main menu list
var $style = $(this).attr('data-menu-style'); // get menu style
if ( typeof $style == 'undefined' || $style == false )
{
$(this).addClass('graphite'); // set graphite style if style is not defined
}
else {
$(this).addClass($style);
}
/* width of menu list (non-toggled) */
var $width = 0;
$(this).find('ul li').each(function() {
$width += $(this).outerWidth();
});
// if modern browser
if ($.support.leadingWhitespace) {
$(this).css('max-width' , $width*1.05+'px');
}
//
else {
$(this).css('width' , $width*1.05+'px');
}
});
}
function getMobileMenu() {
/* build toggled dropdown menu list */
$('.rmm').each(function() {
var menutitle = $(this).attr("data-menu-title");
if ( menutitle == "" ) {
menutitle = "Menu";
}
else if ( menutitle == undefined ) {
menutitle = "Menu";
}
var $menulist = $(this).children('.rmm-main-list').html();
var $menucontrols ="<div class='rmm-toggled-controls'><div class='rmm-toggled-title'>" + menutitle + "</div><div class='rmm-button'><span> </span><span> </span><span> </span></div></div>";
$(this).prepend("<div class='rmm-toggled rmm-closed'>"+$menucontrols+"<ul>"+$menulist+"</ul></div>");
});
}
function adaptMenu() {
/* toggle menu on resize */
$('.rmm').each(function() {
var $width = $(this).css('max-width');
$width = $width.replace('px', '');
if ( $(this).parent().width() < $width*1.05 ) {
$(this).children('.rmm-main-list').hide(0);
$(this).children('.rmm-toggled').show(0);
}
else {
$(this).children('.rmm-main-list').show(0);
$(this).children('.rmm-toggled').hide(0);
}
});
}
$(function() {
responsiveMobileMenu();
getMobileMenu();
adaptMenu();
/* slide down mobile menu on click */
$('.rmm-toggled, .rmm-toggled .rmm-button').click(function(){
if ( $(this).is(".rmm-closed")) {
$(this).find('ul').stop().show(300);
$(this).removeClass("rmm-closed");
}
else {
$(this).find('ul').stop().hide(300);
$(this).addClass("rmm-closed");
}
});
});
/* hide mobile menu on resize */
$(window).resize(function() {
adaptMenu();
});
</script>
My current use of CSS hides the menu for mobile view and displays only parent Lists.
Instead of using JavaScript, can you use CSS media queries?
/* Mobile styling goes here */
#media screen and (min-width: 500px) {
/* Desktop styling overrides go here */
}
Here's an example (I'm not going to copy what you did, but you should get the gist of it) http://jsfiddle.net/1gw19yqg/
Hi i am opening the accordion panel of a page from external links. Its is working fine but the page is not coming to the top where the accordion panel is active . At some points it is offscreen(below the visible page area).
How can i move my active panel of accordion to the top of the page.It is working fine if i click on panel but not on paqge load with url something like this
http://22april/imagine2013.php?id=1$panel=10#accordion
This url gives me the active accordion panel but page doesnt comes to top as it comes on clicking the panel.
function getParam(name) {
var query = location.search.substring(1);
var myString = query.substr(query.indexOf("$") + 1)
if (myString.length) {
var parts = myString.split('&');
for (var i = 0; i < parts.length; i++) {
var pos = parts[i].indexOf('=');
if (parts[i].substring(0,pos) == name) {
return parts[i].substring(pos+1);
}
else{
return parts[i].substring(pos);
}
}
}
return 0;
}
$(function () {
var defaultPanel = parseInt(getParam('panel'));
$("#accordion").accordion({
heightStyle: "content",
collapsible:true,
active:defaultPanel,
navigation:true,
activate: function (event, ui) { //this particular code works when i click on accordion but not when page load and targeted accordion opens on that page.
var scrollTop = $(".accordion").scrollTop();
console.log(ui.newHeader);
if(!ui.newHeader.length) return;
var top = $(ui.newHeader).offset().top;
$("html,body").animate({
scrollTop: scrollTop + top - 5
}, "slow");
}
});
Here is the html part
<ul id="accordion" class="accordion">
<li>TEXT
<ul id="ac1" class="accordion1">
<li> Title of second accordion
<ul>Content of second accordion</ul>
</li>
</ul>
</li>
Please let me know if more information required.
Help me in this.