NavBar Item in Footer - javascript

I have one problem need help.
My jquery mobile page, if I put the Navbar content static into the page:
<div data-role="footer">
<div id='footerButton' data-role="navbar">
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
</div><!-- /navbar -->
</div><!-- /footer -->
The navbar button display Horizontally button nicely and automatically equal the width of each button.
But if I leave the Navbar DIV empty and dynamically insert the UL and LI:
$('#userMainPage').on('pagebeforecreate', function() {
$('#footerButton').html('<ul><li>One</li><li>Two</li><li>Three</li></ul>');
});
With the above code, the Item will not listed as Horizontal. It will became Vertical li without button styling.
May I know what is wrong with my code to insert the content dynamically? Please advice, thank you.

The pagebeforecreate event doesn't emit on page, it emits on document. Thus, you can't bind it to a specific page.
/* has no effect on #pageID */
$("#pageID").on("pagebeforecreate", function (event)
$(document).on("pagebeforecreate", "#pageID", function (event)
/* to know which page is going to be created */
$(document).on("pagebeforecreate", function (event) {
console.log(event.target);
});
/* this works, but you'll need to enhance dynamically added elements manually */
$(document).on("pagecreate", "#pageID", function (event) {
/* do something */
$("footer").append( $("<div data-role='navbar'></div>").navbar() );
});
In light of the above, if you want to perform something on pagebeforecreate event based on page that is being created:
$(document).on("pagebeforecreate", function (event) {
var page = event.target.id;
if(page == "pageID") {
/* do something */
}
});
Demo
However, since pagecreate and pagebeforecreate fires ONCE per page, if you want to change Navbar every time a specific page is shown, you need to utilize pageContainer events, e.g. pagecontainershow. Those events don't emit on a specific page as well, so you need to retrieve ActivePage's id.
Note that you will also need to inject "fresh/new" Navbar since this widget has no refresh methods.
$(document).on('pagecontainershow', function (event) {
/* retrieve ID of active page */
var page = $.mobile.pageContainer.pagecontainer("getActivePage")[0].id;
if (page == "page1") {
$('[data-role=footer]').html($("<div id='footerButton' data-role='navbar'><ul><li><a href='#'>One</a></li><li><a href='#'>Two</a></li><li><a href='#'>Three</a></li></ul></div>").navbar());
} else {
$('[data-role=footer]').html($("<div id='footerButton' data-role='navbar'><ul><li><a href='#'>Four</a></li><li><a href='#'>Five</a></li><li><a href='#'>Six</a></li></ul></div>").navbar());
}
});
Demo
Enhancement / manual initialization of Widget:
.navbar() is enhancement method of data-role="navbar" when it is injected dynamically. Static elements, e.g. Navbar, are auto-initialized when jQM framework is first initialized, or when they are retrieved via Ajax. However, when elements are dynamically injected, they need to be initialized manually, .navbar() is used for Navbar widget.

Related

Executing infinite scroll on dynamically created content

I have a page that load content using a MySQL database. And users can filter content using few buttons and then this content get replaced with dynamically pulled data using jQuery. Also the link I use in infinite scroll also change. But infinite scroll plugin seems to only take the same old link and not the newly loaded link to trigger scroll.
jQuery infinity scroll plugin that i use
https://cdnjs.cloudflare.com/ajax/libs/jquery-infinitescroll/2.1.0/jquery.infinitescroll.js
This is my code
<div class="container" id="myposts">
<div class=”post”>
<p>my content</p>
</div>
</div>
<nav id="page-nav"></nav>
//jQuery code
$('#myposts').infinitescroll({
navSelector : '#page-nav', // selector for the paged navigation
nextSelector : '#page-nav a', // selector for the NEXT link (to page 2)
itemSelector : '. post ', //
loading: {
finishedMsg: 'End of the page',
img: 'images/loader.gif'
}
}, function(newElements, data, url){
});
I’m changing the scroll trigger link from
<nav id="page-nav"></nav>
To
<nav id="page-nav"></nav>
But plugin still take the old link to trigger scroll. Is there any solution for this? Appreciate your time.
You could listen for the append.infiniteScroll event and then update the link from your page.
https://infinite-scroll.com/events.html#append
https://infinite-scroll.com/api.html#option
Something like this:
$container.on( 'append.infiniteScroll', function( event, response, path, items ) {
$container.infiniteScroll( 'nextSelector', '#page-nav a' )
});

trigger a CSS :hover with javascript by scrolling

I am working on a Website with fixed menu at the top of the Site. If you hover over the navigationbar it moves down to reveal the links.
The hover is realised with css classes.
The navigation should be shown completely, when you enter the site or scroll to the top.
I am trying to realise it using a javascript method which uses with the scroll progress.
$(window).scroll(function() {
var wS = $(this).scrollTop();
if (wS > 200){
alert('you have scrolled to the h1!');
$document.getElementById('awning').addClass('awning:hover');
$document.getElementById('nav').addClass('awning:hover #nav');
}
});
Does it make sense or is there a better way to do it?
The alert doesn't even show up
You cannot assign pseudo-classes like this. A pseudo-class is used to define a style of element when special state occurs (for example hovering over element, link being already visited) or element is somehow special( first of kind, even etc.).
You will have to create additional class in css like this:
#awning.revealed{ /* notice there is no space between selectors */
/*your css code goes here (same as in :hover)*/
}
And then just add class to element like this:
$document.getElementById('awning').addClass('revealed');
Please use the code below and click on the 2nd value (200)
$('.wi').on( "click", function() {
console.log('clicked');
var temp = $('.wi');
if (temp.hasClass('wi-celsius')) {
alert("Current is 'Celsius'... updating it to 'Fahrenheit!'");
var convertedTemp = parseInt(temp.text()) * 9 / 5 + 32;
temp.text(convertedTemp);
temp.removeClass('wi-celsius');
temp.addClass('wi-fahrenheit');
}else {
alert("Current is 'Fahrenheit'... updating it to 'Celsius!'");
var convertedTemp = (parseInt(temp.text()) -32)/ (9/5);
temp.text(convertedTemp);
temp.removeClass('wi-fahrenheit');
temp.addClass('wi-celsius');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<ul id="list">
<li>100</li>
<li> <i class="wi wi-celsius">200</i></li>
<li>300</li>
</ul>
Is that what you need?

How can I close the Foundation topbar menu when a link is clicked?

I am using Zurb Foundation's fixed topbar on my single page site, and it contains anchor links to places within the page. I would like it so that whenever a link inside the expanded mobile menu is clicked, the menu closes.
Currently, when a link is clicked, the page scrolls, but the menu is left open at the top of the page out of view.
In a previous version of Foundation, I was able to reverse engineer the code and find a simple solution. Since updating to 4.3.1 to fix another issue with the topbar, I am unable to find a solution due to my limited knowledge of javascript.
topbar
It seems to me that if I could fire the event or function for menu closing when a link in the menu is clicked, it would be fixed. Previously, I put my code that happened on a link click on line 261.
When the mobile menu closes, .fixed is added to the div surrounding the topbar, while .expanded and .fixed are removed from the .topbar div.
You can try adding some jQuery to collapse the menu when you click on a link.
You can add the code wrapped inside a script element. Place it after all your html elements (inside body element). You can also put it in a separate javascript file that you can source like you would any other javascript file. Make sure you put that link after jquery link.
The code itself can be pretty simple since it looks like foundation adds a class called "expanded" to the nav bar when you toggle the menu icon on and off. So you can just remove the "expanded" class when someone clicks on your buttons.
This is what it should look like:
jQuery(document).ready(function($) {
$('.top-bar ul.right(or .left depending how you arranged your buttons) li').click(function() {
$('.top-bar').removeClass('expanded');
});
}(jQuery));
The selector '.top-bar ul.right(or .left depending how you arranged your buttons) li' can be called with an id also if you give your menu (the ul element) a unique id. In this case it would be:
jQuery(document).ready(function($) {
$('#myMenuId li').click(function() {
$('.top-bar').removeClass('expanded');
});
}(jQuery));
Hope that helps.
Try:
$('#main-menu li').click(function() {
$('.toggle-topbar').trigger('click');
});
I'm working with Foundation 6 for the first time, and I ran across this post while trying to figure out a way to close the new top-bar menu on mobile when a link had been clicked. I wanted to comment with my solution in case anyone else working on Foundation 6 runs across this post, since it was a good starting place for me.
Here's what I did:
Navigation setup - horizontal nav on medium and large breakpoints, responsive toggle vertical nav on small breakpoint
<!-- Mobile responsive toggle (hamburger menu) -->
<div class="title-bar" data-responsive-toggle="siteNav" data-hide-for="medium">
<button class="menu-icon" type="button" data-toggle></button>
<div class="title-bar-title">Menu</div>
</div>
<!-- Nav items -->
<div id="siteNav" class="top-bar">
<p><ul class="vertical medium-horizontal menu text-center">
<li >HOME</li>
<li >SERVICES</li>
<li >CONTACT</li>
</ul></p>
</div>
Then I added a modified version of the jquery based on the previous solutions in this post (thanks to amazingBastard and Cerbrus):
$(document).ready(function($) {
$('#siteNav li').click(function() {
if(Foundation.MediaQuery.current == 'small'){
$('#siteNav').css('display', 'none');
}
});
});
In Foundation 6 the css selector "display" is added to an expanded menu and set to either "display:none" for hidden or "display:block" for expanded. This jquery snippet checks the current breakpoint against small(mobile device) on click of a nav item in the default menu class I am using, and if true changes the css selector to "display:none", effectively closing the menu toggle.
A cleaner way (instead of trigger click or remove class) :
$(document).on("click", ".top-bar li", function () {
Foundation.libs.topbar.toggle($('.top-bar'));
});
I copied some of the code in the code of the Foundation 6 dropdown's close function.
To make it work I also had to set the option data-disable-hover="true on the menu element otherwise the menu wouldn't close the first time the user clicked an element in it.
I wrote my code in AngularJS and made it work. I'm guessing it would look like this for jQuery. In other word, the code is not tested.
$('#main-menu li').click(function closeDropdown() {
var $toClose = $('#main-menu');
if(!$toClose){
return;
}
var somethingToClose = $toClose.hasClass('is-active') || $toClose.find('.is-active').length > 0;
if (somethingToClose) {
$toClose.find('li.is-active').add($toClose).attr({
'aria-expanded': false,
'data-is-click': false
}).removeClass('is-active');
$toClose.find('ul.js-dropdown-active').attr({
'aria-hidden': true
}).removeClass('js-dropdown-active');
}
});
This is what works for me:
setTimeout(function() {$(document).foundation('topbar', 'reflow')}, 500);
Let me know if this works for you too. (Maybe reduce "500" to a time shorter than half a second too).
Here's an expanded version:
<script type="text/javascript">
function hideDropDown() {
setTimeout(function() {$(document).foundation('topbar', 'reflow')}, 500);
}
</script>
<nav class="top-bar" data-topbar role="navigation">
<section class="top-bar-section">
<!-- Right Nav Section -->
<ul class="right">
<li class="has-dropdown">
My menu
<ul class="dropdown">
<li><a onclick="hideDropDown()" target="another_page" href="/some/where">Menu item</a></li>
</ul>
</li>
</ul>
</section>
</nav>

Might I have the wrong idea of hoverIntent

I have a div containing a collection of li to build up a menu.
Outside of the containing ul I have a div that should be displayed only when an item in the original menu is hovered.
Now, I understand the whole mouseout, mouseover effect but what I'm stuck with is to keep the content div active if the mouse is moved over it, but hide (cleared) and then displayed if any of the li elements are selected.
Code (trimmed for legibility)
<div id="menu-ext" class="ext-menu wrapper">
<div class="navigation">
<ul>
<li>
Menu Item 1
</li>
<li>
Menu Item 2
</li>
<li>
Menu Item 3
</li>
<li>
Menu Item 4
</li>
</ul>
</div>
<div class="clear"></div>
<div class="content window" style="display:none;">
this contains text to be displayed, based on a what is hoverd in the navigation above (template driven)
</div>
</div>
The important thing here is not the data that will be displayed in div.content.window but rather how to keep it open if the mouse is moved down after visibility has been set, and then how to hide it if the mouse is moved either outside of div.content.window or over any of the navigational items.
I figured hoverIntent would be able to do this, but the intent (I have) is not initialized.
My code for that:
<script type="text/javascript">
jQuery(document).ready(function ($) {
'use strict';
var config = {
interval: 100,
sensitivity: 1,
out: onHoverOut,
over: onHoverOver
};
$("li", $(".navigation")).hoverIntent(config);
});
function onHoverOver(parent) {
'use strict';
var $currentTarget = $(parent.currentTarget),
$hasTemplate = ($("selector", $currentTarget).length >= 1);
if ($hasTemplate) {
onPopulateMenu(parent);
// show menu
}
}
function onHoverOut(parent) {
'use strict'
onClearMenu();
// TODO: hide the menu
// I think the problem is here?
}
function onClearMenu() {
'use strict';
// TODO: clear the menu of all HTML
}
function onPopulateMenu(parent) {
'use strict';
// TODO: populate the content menu
}
</script>
I'm sure I would be able to keep the one div active, but I cannot seem to identify the solution to this problem. Is this possible?
Update
Apologies for not being very clear.
Basically, when user hovers over menu item, a mega-menu-type navigation should pop-up with additional links that users can click on. My current problem is that the "mega-menu" window is outside of each of the li elements in the original navigation, which is what hoverIntent is looking for.
My question here is, am I missing something? Because as soon as the mouse cursor is moved away from the li towards the menu pop-up, it disappears, which is not the functionality I'm looking for.
Should the menu window be embedded in each li? This does not make sense to me so I thought if I put it outside, it would work.
my fiddling
As stated, I need the window to stay active if the cursor is moved away from the li but I need it to disappear if the state is outside of the window.
I can write some intense JS to figure out the position of the cursor, see if the coordinates correspond with accepted locations and then toggle, but this seems a bit excessive as well?
If I understand you correctly you want something similar to this: Making the content-window appear and show some specific content based on which menu item is being hovered over and disappearing when you stop hovering over a menu item?
jQuery(document).ready(function () {
timeoutId = false;
$('.navigation li').on('mouseover', function () {
//If there is a timeoutId set by a previous mouseout event cancel it so the content-window is not hidden
if (timeoutId != false) {
clearTimeout(timeoutId);
}
$('.content-window').css('display', 'block');
$('.content-window .demo-content').html($(this).html());
});
$('.navigation li, .content-window').on('mouseout', function () {
//start a countdown of 3000 milliseconds before removing the content-window
timeoutId = setTimeout(function () {
$('.content-window').css('display', 'none');
}, 3000);
});
//if cursor moves over to the content-window, stop the timeout from occuring
$('.content-window').on('mouseover', function () {
if (timeoutId != false) {
clearTimeout(timeoutId);
}
});
});
http://jsfiddle.net/UHTAk/
Hope that helps,
R.
Update:
Due to your more specific question update I have amended the code above and updated a jsfiddle as below. What it does now is sets a timeout() timer to remove the content-window after a pre-determined time on a mouseout. This removal is halted if there is another mouseover over an li or the .content-window itself.
http://jsfiddle.net/UHTAk/1/

How do I get Waypoints (Jquery plugin) to work for infinite scroll in the following case?

I am using the Waypoints Jquery plugin: http://imakewebthings.github.com/jquery-waypoints/#documentation
My issue is that I want to load content dynamically when the waypoint is reached. Initially, content is loaded dynamically, then I want the waypoint at the end... when the waypoint is reached, I want to load more content in front of it, etc.
Structure:
<div class="viewport">
<div class="viewport-content">
<div id="messages">
/* {messages loaded here} */
</div>
/* #waypoint added after messages loaded via appendTo('.viewport-content') */
<div id="waypoint"></div>
</div>
</div>
The viewport/viewport-content form the scrollable region via css. I was using the appendTo to append the waypoint after the initial messages had loaded, otherwise the waypoint was at the top and was hit. However, when I use the appendTo after loading the initial messages, when I scroll down, I can't get it to work properly.
Here is my current JS in regards to the waypoint:
var opts = {
offset: 'bottom-in-view',
context: '#central-pane .viewport-content',
};
$('#waypoint').waypoint(function(event, direction) {
alert("You've hit my waypoint! ow!");
$('#messages').append($loading);
messagesLoad(); /* loads more messages via appendTo('#messages') */
$('#waypoint').waypoint(opts);
}, opts);
Any ideas on how I can get this to work?
That's what I did on my page:
var opts = {
offset: '110%',
context: '#central-pane .viewport-content'
};
$('#waypoint').waypoint(function(event, direction) {
alert("You've hit my waypoint! ow!");
$('#messages').append($loading);
if(direction === 'down') {
messagesLoad(); /* loads more messages via appendTo('#messages') */
}
$.waypoints('refresh');
}, opts);
I used 110% to trigger loading before the bottom is reached and checked if the direction is down.
Why don't you just attach the waypoint to the ".viewport-content" and keep the "bottom-in-view" option. That way when the content gets loaded it pushes the bottom out of view and when you scroll down more it will fire the event again when the bottom is back in view.

Categories