jQuery-Mobile external Panel always open among pages - javascript

I've tried to search around but found no relatable topics I could understand.
I'm not very familiar with Javascript or coding in general.
I am using Jquery Mobile 1.4.5 and this is my issue:
I cannot get external panels to work properly. The panel displays just fine on my first page, but when I change page it won't show up as intended. My plan is to have the panels work in the same manner as they do on the Jquery mobile demo page.
Link: Jquery Mobile Demo
Here you can see the panel is always showing no matter what page they are on, I found out they don't use external panels on that site but it should still be possible.
How my site works at the moment:
Panel work just fine when loading first page (#page_home)
When entering new page (#page_kodi or #page_download) it does not show up automatically as intended.
When I enter #page_kodi or #page_download and manually bring it up it stays up as intended
This is the odd part: When I go from (with panel open) #page_download to #page_kodi to #page_home (main page) it works.
when I go from #page_home to another page it does not work.
Here is my JS code for panels, I'm sure there is a better way to write this, and maybe some of it is not needed.
Javascript:
<script>
<!-- Creates the panels & navbars/Tabs -->
$(document).on("pagecreate", function() {
$("body > [data-role='panel']").panel();
$("body > [data-role='panel'] [data-role='listview']").listview();
});
$(document).on("pageshow", function() {
$("body > [data-role='header']").toolbar();
$("body > [data-role='header'] [data-role='navbar']").navbar();
});
</script>
<script>
$(document).on("pagebeforeshow", function( event, data ) {
$('#leftpanel').panel("open");
})
</script>
<script>
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent) ) {
$(document).on("pagebeforecreate", "#page_home", function () {
$( "#leftpanel" ).panel({ dismissible: true });
$( "#leftpanel").panel("close");
});
}
</script>
<script>
$(document).on("pagecreate", "#page_home", function () {
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent) ) {
setTimeout(function(){
$('#leftpanel').panel("close");
}, 500);
}
});
</script>
<script>
$(document).on("pagebeforecreate", "#page_home", function () {
$( "#leftpanel" ).panel({ dismissible: false });
});
</script>
<script>
$(document).on("pagebeforecreate", "#page_download", function () {
$( ".leftpanel" ).panel( "option", "dismissible", false );
$('#leftpanel').panel("open");
});
</script>
<script>
$(document).on("pagebeforecreate", "#page_kodi", function () {
$( "#leftpanel" ).panel( "option", "dismissible", false );
$('#leftpanel').panel("open");
});
</script>
<script>
/* Left & Right swipe gestures to open panels*/
$(document).on("pagecreate", function() {
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent) ) {
$(document).on("swipeleft swiperight", function(e) {
if ($(".ui-page-active").jqmData("panel") !== "open") {
if (e.type === "swipeleft") {
$("#rightpanel").panel("open");
} else if (e.type === "swiperight") {
$("#leftpanel").panel("open");
}
}
});
}
});
</script>
I have placed all these in my HTML file.
HTML Panel:
<div style="margin-top: 0px; background-color: #212120;" class="customlist panel-open" data-role="panel" data-position="left" data-dismissible="" data-display="overlay" data-theme="none" id="leftpanel">
<ul data-role="listview" data-inset="false">
MY CONTENT HERE
</ul>
</div>
data-dismissible="" I have put it this way because that's what works when you set it manually with JS, or so i've read. It did not work if I set it to false or true.
Basically what I'm trying to do here is always have the panel OPEN on bigger screens and closed with option to open it with swipe on smaller screens. This works as of now. The trouble I am having is when changing pages the panel does not act as intended and closes when I am going from my front page to another, but not if I go from another to my front page.
PS: I've also put the panel between two of my pages like this:
page_home
-- panel
-- some popup
page_download
page_kodi
Thanks in advance for all the help you can give and sorry for the wall of text.

Assuming you are using a single-page model, here is a simple stub for a JQM project with a Panel which can stay open among different pages. The default behavior is parametrized by overriding the _bindPageEvents function of the mobile.panel widget, so you can dinamcally set a flag for that.
You can set the stayAlwaysOpen flag as you like, by spoofing the useragent string or (maybe better) by checking the viewport width, up to you. You could also check a CSS breakpoint for that purpose.
To keep header navigation and make the panel somewhat more pleasant, i used also the function scalePanelToContent from: jQuery mobile panel between header and footer (credits: Omar).
var stayAlwaysOpen = true;
$.widget("mobile.panel", $.mobile.panel, {
_bindPageEvents: function() {
var self = this;
this.document
// Close the panel if another panel on the page opens
.on("panelbeforeopen", function(e) {
if (self._open && e.target !== self.element[0]) {
self.close();
}
})
// On escape, close? might need to have a target check too...
.on("keyup.panel", function(e) {
if (e.keyCode === 27 && self._open) {
self.close();
}
});
if (!this._parentPage && this.options.display !== "overlay") {
this._on(this.document, {
"pageshow": function() {
this._openedPage = null;
this._getWrapper();
}
});
}
// Clean up open panels after page hide
if(stayAlwaysOpen) return;
if (self._parentPage) {
this.document.on("pagehide", ":jqmData(role='page')", function() {
if (self._open) {
self.close( true );
}
});
} else {
this.document.on("pagebeforehide", function() {
if (self._open) {
self.close( true );
}
});
}
}
});
function scalePanelToContent() {
var screenH = $.mobile.getScreenHeight();
var headerH = $(".ui-header").outerHeight() - 1;
var footerH = $(".ui-footer").outerHeight() - 1;
var panelH = screenH - headerH - footerH;
$(".ui-panel").css({
"top": headerH,
"bottom": footerH,
"min-height": panelH
});
}
$(document).ready(function() {
$("[data-role='header'], [data-role='footer']").toolbar({
theme: "a",
position: "fixed",
tapToggle: false
});
$("#nav-panel").panel({
theme: "b",
display: "overlay",
position: "left",
positionFixed: true,
swipeClose: false,
dismissible: false
}).enhanceWithin();
$("#nav-panel").on("panelbeforeopen", function(event, ui) {
scalePanelToContent();
$(".ui-content").animate({
"margin-left": "17em"
}, 300, "swing");
});
$("#nav-panel").on("panelbeforeclose", function(event, ui) {
$(".ui-content").removeClass("panel-shrink").animate({
"margin-left": "0"
}, 300, "swing", function() {
$(this).removeAttr("style");
});
});
scalePanelToContent();
});
$(window).on("resize", function() {
scalePanelToContent();
});
$(document).on("pagecontainerbeforeshow", function(e, ui) {
var isPanelOpen = $("#nav-panel").hasClass("ui-panel-open");
$(".ui-content").toggleClass("panel-shrink", isPanelOpen);
});
.panel-shrink {
margin-left: 17em !important;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.css">
<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
<script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.js"></script>
</head>
<body>
<div data-role="header">
Menu
<h2>Header</h2>
</div>
<div data-role="footer">
<h2>Footer</h2>
</div>
<div data-role="page" id="page-1">
<div data-role="content">
<form>
<fieldset data-role="controlgroup">
<legend>Vertical:</legend>
<input name="checkbox-v-2a" id="checkbox-v-2a" type="checkbox">
<label for="checkbox-v-2a">One</label>
<input name="checkbox-v-2b" id="checkbox-v-2b" type="checkbox">
<label for="checkbox-v-2b">Two</label>
<input name="checkbox-v-2c" id="checkbox-v-2c" type="checkbox">
<label for="checkbox-v-2c">Three</label>
</fieldset>
</form>
</div>
</div>
<div data-role="page" id="page-2">
<div data-role="content">
<ul data-role="listview" data-inset="true">
<li>Acura</li>
<li>Audi</li>
<li>BMW</li>
<li>Cadillac</li>
<li>Ferrari</li>
</ul>
</div>
</div>
<div data-role="page" id="page-3">
<div data-role="content">
Page 3
</div>
</div>
<div data-role="panel" id="nav-panel">
<ul data-role="listview">
<li>Link #1
</li>
<li>Link #2
</li>
<li>Link #3
</li>
</ul>
</div>
</body>
</html>
Just a last hint:
You can use the same stayAlwaysOpen flag inside your swipe events so that the panel will keep the same behavior in mobile devices and in desktop browsers also for smaller window sizes.

Related

Based on internet connection change color of button to green or grey

I want the button itself to change its color when online(based on internet connection) to green otherwise gray.
I have a JS fiddle which gives a solution to click the button and we can see if we are online/offline by an alert.
Can someone please help
HTML:
<div data-role="page" id="index">
<div data-theme="a" data-role="header">
<h3>First Page</h3> Next </div>
<div data-role="content"> <a data-role="button" id="check-connection">Check internet connection</a> </div>
</div>
jQuery:
$(document).on('pagebeforeshow', '#index', function() {
$(document).on('click', '#check-connection', function() {
var status = navigator.onLine ? 'online' : 'offline';
(alert(status));
});
});
See JSFiddle.
Here is the working fiddle: http://jsfiddle.net/dn7zjm41/
I just added an if statement:
if(status==="online") {
$("#check-connection > span").css("background-color", "green");
} else if(status==="offline") {
$("#check-connection > span").css("background-color", "gray");
} else {
// the code for another scenario
}
And if you want an automatic run without click event - here it is: http://jsfiddle.net/f6paa9xy/
In this case your Javascript should look like this:
$(document).on('pagebeforeshow', '#index', function() {
var status = navigator.onLine ? 'online' : 'offline';
alert(status);
if(status==="online") {
$("#check-connection > span").css("background-color", "green");
} else if(status==="offline") {
$("#check-connection > span").css("background-color", "red");
}
});
Hope it helps
You could use a simple css class to do this:
$(document).on('click', '#check-connection', function(){
var status = navigator.onLine ? 'online' : 'offline';
this.className = 'status-'+status;
});
.status-online{ background-color: green; }
.status-offline{ background-color: grey; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div data-role="content">
<a data-role="button" id="check-connection">
Check internet connection
</a>
</div>
However, if you want a live determination, you can use an event listener provided by the browser, most support this (ie8+ for example):
window.addEventListener("offline", function() {
$("#check-connection")[0].className = "status-offline";
});
window.addEventListener("online", function() {
$("#check-connection")[0].className = "status-online";
});
More on this at MDN: https://developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/onLine

JQM specifying swipe page change

Trying to make a mobile webapp. Three of the pages namely article1,2,3 should transition from one another on swipe. Within each article page there should be links to other page that show up with a flip transition. I have managed to sort of make it work however the code I am using is causing the app to be able to swipe through all of my 'pages' while I wish to target only the 'article' pages for the swipe feature. I think mainly the JQ needs to be changed to go directly to specific pages, is this possible? The JQ i currently uses var nextpage = $.mobile.activePage.next('[data-role="page"]'); if i gave all article pages an id of 'article' how would i get it to target data-role="page" while also specifying pages with an ID of article only?
Article Page Example (to swipe to article 2 and 3):
<div data-role="page" id="article1">
<div data-role="content">
<div style="width:50px; height: 50px; background-color:blue;"></div>
<div style="width:50px; height: 50px; background-color:blue; float: right;"></div>
</div>
Example page (link lies within one of the article pages and flips):
<div data-role="page" id="pagethree">
<div data-role="header">
<h1>Welcome To pagethree</h1>
</div>
<div data-role="main" class="ui-content">
<p>Click on the link to go back. <b>Note</b>: fade is default.</p>
Go back to Page One
</div>
JQ:
<script>
$(document).on('swipeleft', '.ui-page', function(event){
if(event.handled !== true) // This will prevent event triggering more then once
{
var nextpage = $.mobile.activePage.next('[data-role="page"]');
// swipe using id of next page if exists
if (nextpage.length > 0) {
$.mobile.changePage(nextpage, {transition: "slide", reverse: false}, true, true);
}
event.handled = true;
}
return false;
});
$(document).on('swiperight', '.ui-page', function(event){
if(event.handled !== true) // This will prevent event triggering more then once
{
var prevpage = $(this).prev('[data-role="page"]');
if (prevpage.length > 0) {
$.mobile.changePage(prevpage, {transition: "slide", reverse: true}, true, true);
}
event.handled = true;
}
return false;
});
</script>
I am an idiot. I simply replaced var nextpage = $.mobile.activePage.next('[data-role="page"]'); with var nextpage = $.mobile.activePage.next('#article');

Jquery menu doesnt open on touch screen devices

I have a drop down menu where the user selects a location and it scrolls to the div to reveal the address (10 different locations).
This works well in a desktop browser. However on the ipad, iphone and nexus it doesnt work because of touch screen.
This is my code:-
<html>
<div class="location">
<ul>
<li>Select an Office
<ul class="officeselect">
<li><a data-emailaddress="" data-address='<span class="address">99 Walnut Tree Close</span>
<span class="address">Guildford</span>
<span class="address">Surrey</span>
<span class="address">GU1 4UQ</span><br>
<span class="address">T: +44 1483 881500</span>
<span class="address">info#petroplan.com</span>' href="">UK Head</a>
</li>
</ul>
</li>
</ul>
</div>
<div class="span4 alpha">
<div class="addresstitle">
<h3>Address</h3>
</div>
<div class="address">
</div>
</div>
</html>
<script>
// Scroll down to map and address function
$(".location ul li ul a").click(updateAddressDisplay);
function updateAddressDisplay(src) {
$('.office-sel-cont .chooser').text($(this).text());
var target = $(".address");
var source;
$('html,body').animate({
scrollTop: target.offset().top
}, 1000);
if (src === null)
source = $(".black-sectors li a.adr-src:eq(0)");
else
source = $(this);
target.fadeOut();
target.html(source.data("address") + source.data("emailaddress"));
target.fadeIn();
var chooser = $(this).parent().parent().parent().find('.chooser');
if (chooser.hasClass('open')) {
chooser.removeClass('open');
chooser.next($('.black-sectors')).animate({
'top': '60px',
'opacity': 0
}, 600, 'easeOutQuint', function() {
chooser.next($('.black-sectors')).toggle();
});
return false;
} else {
}
return false;
}
</script>
And I used this below from this website, but it's still dodgy.
<script>
$('.location ul li ul a').on('click touchend', function(e) {
e.preventDefault();
var el = $(this);
var link = el.attr('href');
window.location = link;
});
</script>
Thanks for your help.
this is the fiddle:-http://jsfiddle.net/ScVs9/
For your drop down list to work on a touch screen device you need to trigger the drop-down using a javascript click event rather than the css hover. Simple way would be create a class, called something like .active and then use a function like this:
$('.location a').on('click', function(){
$('.officeselect').toggleClass('active')
});
The active class would simply have visibility set to visible:
ul.officeselect.active {visibility:visible;}
The user should then be able to select the correct link and display the address as per usual.
I hope this helps

JS slidetoggle on UL Tree

When i click on second item with slideToggle, first item close.
$(function() {
$('.toggleSitemap').find('ul').css('display','none')
$('.toggleSitemap').click(function(){
$(this).parent().find('ul').slideToggle('slow');
});
});
http://jsfiddle.net/qHZsZ/2/
I dont know how much will this help you. I also needed to implement accordian(toggle) in my MVC project once, and I used something like this:
View.aspx:
<div class='toggle' style="float: left">
<div style="float: left;clear:both;">
<br />
<span class="ulGroup" jqattr="<%:Group.Key %>" style="font-weight: bold;font-color: black;cursor: pointer"><img src="<%: Url.Content("~/Images/imageplus.gif")%>"/>
<%:Group.Key%></span>
</div>
<div class="togglebox" style="clear:both;" >
<!-- Write contents as you wish -->
<!-- as
<ul> test
<li>Test1></li>
<li>Test2></li>
<li>Test3></li>
</ul>
.
.
.
-->
</div>
</div>
And called a design.js (javascript file) as :
$(document).ready(function () {
//Hide the tooglebox when page load
$(".togglebox").hide();
//slide up and down when click over span
$(".ulGroup").click(function () {
var valueText = $(this).attr('jqAttr');
// slide toggle effect set to slow you can set it to fast too.
var x = $(this).parent().next(".togglebox").css("display");
if (x == "block") {
$(this).text('');
$(this).append($('<img src="../../Images/imageplus.gif"/>'))
$(this).append(' ' + valueText);
}
else {
$(this).text('');
$(this).append($('<img src="../../Images/imageplus.gif"/>'))
$(this).append(' ' + valueText);
}
$(this).parent().next(".togglebox").slideToggle("fast");
return true;
});
});
You're pretty close. I think the key ingredient you're missing is to prevent propagation of the click event.
Also, to make it a little less quirky, you only want the click event to fire if the target's direct parent has the toggleSitemap class.
$(function() {
$('.toggleSitemap').click(function(e){
if ($(e.target).parent().hasClass('toggleSitemap')) {
e.stopPropagation();
$(this).children('ul').slideToggle('slow');
}
});
});
Here's an example: http://jsfiddle.net/DkbNA/2/

jQuery tab disable jQuery scroll

I use jqueryUI tabs and want to implement a smooth scroll bar inside each tab. I tried several scrollable plugins like jQuery custom content scroller, TinyScrollbar and now areaaperta NiceScroll, but each time I stack with the same problem - scrollbar works only inside one tab..
<script>
$(function() {
$( "#tabs" ).tabs();
});
</script>
<div id="tabs" style="width:900px; font-size:100%;">
<ul>
<li><a href="#tabs-1" >FIRST</a></li>
<li>SECOND</li>
<li>THIRD</li>
</ul>
<div id="tabs-1">
<div id="thisdiv">
<p><b>FIRST SCROLLABLE PARAGRAPH</b>...</p></div></div>
<div id="tabs-2"><div id="thisdiv2">
<p><b>SECOND SCROLLABLE PARAGRAPH</b>...</p>
</div></div>
<div id="tabs-3">
<p>THIRD TAB </p>
</div>
</div>
<script>
$(document).ready(
function() {
$("#thisdiv").niceScroll({cursorcolor:"#00F"});
$("#thisdiv2").niceScroll({cursorcolor:"#00F"}); }
);
</script>
Here is jsfiddle that shows that there is no conflicts between UItabs and two scrollbars of niceScroll plugin: http://jsfiddle.net/Fluc/EhcqX/4/
And here I tried to use same divs with scroll bars inside each tab: http://jsfiddle.net/Fluc/cJPT3/2/
As you can see, scrollable works only inside the first tab.. Same with other scrollable plugs..
I'm not jquery programmer but It feels like the problem is related to display property somewhere.
Any help would be very appreciated!
This one works perfect try and let me know.
<script>
$(document).ready(function() {
$("#tabs").tabs();
jQuery('#tabs').bind('tabsselect', function(event, ui) {
ui.tab
ui.panel
ui.index
if (ui.index==0) {
$("#tabs-1 > .scrollable").niceScroll({cursorcolor:"#00F"});
}else if (ui.index==1) {
$("#tabs-2 > .scrollable").niceScroll({cursorcolor:"#00F"});
}else if (ui.index==2) {
$("#tabs-3 > .scrollable").niceScroll({cursorcolor:"#00F"});
}
});
});
</script>
I have also updated your fiddle http://jsfiddle.net/cJPT3/9/

Categories

Resources