jump to named anchor with javascript - javascript

I have a php (codeigniter) program that displays all the finished projects of and engineering company. I can click the detail page and from there I can click a link to go back to the overview page. To avoid starting at the top of the list again I would like to jump to the project I cam from.
It seems easy but it gives me problems. I found this solution on the Internet that works with Chrome but not with Firefox and IE:
<script type="text/javascript" language="javascript">
function moveWindow (){window.location.hash="a13";}
</script>
<body onload="moveWindow()">
.
.
.
<a name="a13"></a>
The content of the anchor gets dynamically generated by PHP. As I said it works in Chrome only. IE says something like undefined function moveWindow when I go in debug mode.

You can attach a function to the details click that change the URL to currentURL#yourID and then change it to the final URL. This way, currentURL#yourID will be stored in the history of the browser and going back will get you to the right anchor.
Something like (assuming you use jQuery and your IDs are on the <a>):
$(document).ready( function() {
$('#yourlist a').click( function(e) {
e.preventDefault();
window.location = '#'+$(this).attr('id');
window.location = this.href; // intentionally not using jQuery ;-)
});
});
The HTML would look like:
<ul id="yourlist">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
Not tested...

Related

jquery-1.9.1.js:4421 Uncaught Error: Syntax error, unrecognized expression: /item/category/category_details/7

I am trying to implement bootstrap tabulation menu and each tab is a new page
This is my java script
<script type="text/javascript">
$(document).ready(function(){
$(".nav-tabs a").click(function(){
$(this).tab('show');
});
$('.nav-tabs a').on('shown.bs.tab', function(event){
var x = $(event.target).text(); // active tab
var y = $(event.relatedTarget).text(); // previous tab
$(".act span").text(x);
$(".prev span").text(y);
});
});
</script>
And this is my html for tabulation menu
<div class="container">
<h2>Material</h2>
<ul class="nav nav-tabs">
<li role="presentation" class="active">
BOM</li>
<li role="presentation">Manufacture</li>
<li role="presentation">Product</li>
<li role="presentation">UOM</li>
</ul>
And below the error I am getting each time I select a new tab and obviously my tab doesn't change to active. I assume I am trying to something that is not intended to work with direct links but should work only with divs on the same page. Is there is a way getting of tabulation effect in this way without having separate active tab menu for every page?
jquery-1.9.1.js:4421 Uncaught Error: Syntax error, unrecognized expression: /item/category/category_details/7
Bootstrap tabs expect the href to be a hash which is parsed as a selector, specifically an ID selector, by jQuery. That hash corresponds to the ID of the section to display. Your hrefs appear to be urls instead of hashes causing it to fail.
I want to add how I solved my problem at the end .
I was able to achieve active tabs with links using few templates in Django and by avoiding JS script altogether using this django snippet .
https://djangosnippets.org/snippets/2421/

Load js when visible

I have a phtml page that has separate tabs
<div id="maintabs">
<ul id='mainTabNav'>
<li>Tab 1</li>
<li>Tab 2</li>
</ul>
<div id="maintabs-1">
<p><?php require_once VIEW_DIR."somewhere/tab1.phtml"; ?></p>
</div>
<div id="maintabs-2">
<p><?php require_once VIEW_DIR."somewhere/tab2.phtml"; ?></p>
</div>
</div>
Each tab/page has a header with a js source specific to the page like this
<script src="js/tab<num>.js"></script>
On the page load though each javascript file is loading. Is there a way to only load the js for the tab currently open? When a new tab opens then the js reloads with just the js for the current tab?
You could keep click events on each of the main tabs that would dynamically load the appropriate javascript using something like jQuery.getScript().
$('div[id^="#maintabs"]').click(function(e){
var tabno = $( this ).index();
$.getScript("js/tab"+tabno);
});
The pitfall I'd imagine with this is that you seem to want to have all the previous javascript to be washed away once the latest JS file was loaded. I'm not sure if that's doable or if you'll have side effects from it.
Also this could totally be done with vanilla JS but well, time savings.
Is there a way to only load the js for the tab currently open?
Since you are using PHP you could manage to pass the number of the current page to view. Pseudo-code
View::factory('templateView')
->set('page_number', $page_number)
The $page_number variable now holds the page number that can be used in your scripts with ease
<script src="js/tab<?php echo $page_number; ?>.js"></script>
...
<div id="maintabs">
<ul id='mainTabNav'>
<li>Tab 1</li>
<li>Tab 2</li>
</ul>
<div id="maintabs-".<?php echo $page_number; ?>>
<p><?php require_once VIEW_DIR."somewhere/tab".<?php echo $page_number; ?>.".phtml"; ?></p>
</div>
</div>
Can't you just put this:
<script src="js/tab<num>.js"></script>
into your somewhere/tab*.phtml?
Using pure Javascript, I believe it is possible if you are loading the page using AJAX.
This tutorial, http://code.tutsplus.com/tutorials/how-to-load-in-and-animate-content-with-jquery--net-26, demonstrates a way of loading another page (I call them child pages) into the main page (which I call the index page). As far as I can tell, if you include associated script tags in the child pages rather than the index page, then they are dynamic in that they load when the child page loads, and unloads when he child page unloads.
I have used a modified version of this tutorial in my own projects before, where I don't create the child pages with the same content as the index page as the tutorial shows, and instead use the whole child html file solely for only the child page's content.
Here’s an example based off your code:
indexScript.js :
/* When index.html is loaded and ready */
$(document).ready(function() {
/* Handels on-click of menu buttons */
$('#mainTabNav a').click(function(){
/* Getting the linked page */
var toLoad = $(this).attr('href');
/* Hiding content and calling loadContent function - creates animation*/
$('#contentDiv').hide('slow', loadContent);
/* Injects content to contentDiv div tag */
function loadContent(){
$('#contentDiv').load(toLoad, '', showNewContent);
}
/* Shows contentDiv div */
function showNewContent() {
$('#contentDiv').show('normal');
}
demonstratePageChange(); //For testing - you can remove this
/* In order to stop the browser actually navigating to the page */
return false;
});
/* Initial Load - load first child page by simulation of clicking on it*/
$('#maintabs_1').click();
});
/* To demonstrate the respective JS script is loaded as needed */
function demonstratePageChange() {
setTimeout(function(){
alert(testMsg); //Alerts the message from resepctive child page script
}, 3000);
}
index.html :
<!DOCTYPE html>
<html>
<head></head>
<body>
<div id='maintabs'>
<ul id='mainTabNav'>
<a id='maintabs_1' href='childA.html'><li>Tab 1</li></a>
<a id='maintabs_2' href='childB.html'><li>Tab 2</li></a>
</ul>
</div>
<div id='contentWrapper'>
<div id='contentDiv'></div>
</div>
</body>
<script type='text/javascript' src='jquery-2.1.1.min.js'></script>
<script type='text/javascript' src='indexScript.js'></script>
</html>
childA.html :
<div id='maintabs-1' class='contentBody'>
<script type='text/javascript' src='childAScript.js'></script>
Child A - Page
</div>
childAScript.js :
console.log("childAScript has been loaded");
var testMsg = "This is Child A";
childB.html :
<div id='maintabs-2' class='contentBody'>
<script type='text/javascript' src='childBScript.js'></script>
Child B - Page
</div>
childBScript.js :
console.log("childBScript has been loaded");
var testMsg = "This is Child B!!!!";
However, there are few things to consider using this method:
This particular method requires jQuery
This method doesn't support reload, you'd have to code that in. i.e. if you're on tab 2, you need store that fact and on refresh, point back to tab 2.
Local testing - as far as I can tell, only FF supports this when testing it locally. If you want to test this on Chrome for example, you'd need to upload this onto a server and only then will this work. This is due to the "XMLHttpRequest cannot load" error, if you try this locally.
I hope this helps and resolves your problem.
The use of AMD requirejs can do this also. It is possible to use pure js although I prefer AMD modules [i.e. define()]. For my apps depending on user actions, code is downloaded on the fly reducing load. An onclick event fires on the tab control calling requirejs and the script get downloaded and you call it. PsuedoExample:
<script type="text/javascript" src="require.js"></script>
$(document).ready(function() {
//Assuming using jQuery, use document.getElementById and what not otherwise
$('#maintabs-1').click(function(e) {
require(['/js/tabnum1.js'], function (tab1) {
tab1(doStuff);
});
});
}
Use a for loop for multiple tabs. Also, I try and put as much processing [sans data storage and server validation (obviously)] into the client side.

Jquery ajax clear before reload

I know this is a topic discussed here many times, but none of the solution of the site have helped me....
I'm having two nav items and both of them load two different PHP files by using jquery ajax. I'm using jquery mobile.
My problem is that whenever i click on the other nav item the other one doesn't clear itself, so basically i get div on top of div.
I've tried .html(""); but hasn't worked for me so far.
HTML:
<div id="tabs">
<ul>
<li><a class="classloader1">Upcoming</a></li>
<li><a class="classloader2">History</a></li>
</ul>
</div>
<div id="content"></div>
JS:
$(".classloader1").click(function(){
$("#content").load("get.php");
})
$(".classloader2").click(function(){
$("#content").load("history.php");
})
I would try a different tab structure like
<div id="tabs">
<ul>
<li><a class="classloader one">Upcoming</a></li>
<li><a class="classloader two">History</a></li>
</ul>
</div>
where both elements share the classloader class name. Then I would use jQuery .html() to load the content but returning the specific file depending on the clicked tab like :
$(".classloader").on("click", function (event) {
var file = $(event.target).hasClass("one") ? "get.php" : "history.php";
$("#content").html(function () {
return $(this).load(file);
});
});
If you have more than two tabs, you could use a switch statement to set the value of the file var.
See DEMO
UPDATE : see DEMO using jQuery mobile.

Add class to active page does not work for pages in sub folders

I have the following script that add a class .active to the current page:
//Main menu .active classes handler
$("#mainMenu a").filter(function () {
var href = location.href.replace(/#*/, "");
if (location.pathname === "/") {href += "index";}
return href === this.href;
}).addClass("active");
Everything works fine for the pages in the main directory but it does not work for the pages in sub folders, for example:
It works for Home but it won't work for: Home Why is that? Do I need to add something like "last of index"?
Full HMTL:
<li>Home</li>
<li>About</li>
<li class="subMenu">Gallery
<ul>
<li>Page in a sub folder</li>
</ul>
</li>
<li>Contact</li>
The error isn't in your code, but rather the fact that you're including the site javascript using relative paths:
When you visit /testing/test the javascript files return as 404 because they're relative.
assets/js/main.js becomes /testing/test/assets/js/main.js
Just use absolute paths or you can look into setting the base href
You should use a developer console like Firebug or Chrome dev tools to watch for any errors. I immediately saw 404 errors and noticed it was your js file.
I solved the problem by adding <base href="/"> in my head. It works like magic!

jQuery Mobile Navigation Tabs

I want to have a tab-navigation in my jQuery Mobile project. I know I can use the data-role 'navbar' but I only want to change the content below that navbar without swiping to a new page. So far I could only have several different pages with the same navbar linking to each other but that's not what I want.
Can anyone help me?
Thank you in advance
You can use the jQuery Mobile navbar styling but use your own click-handler so instead of changing pages the click will just hide/show the proper content on the same page.
HTML
<div data-role="navbar">
<ul>
<li>One</li>
<li>Two</li>
</ul>
</div><!-- /navbar -->
<div class="content_div">onLoad Content</div>
<div id="a" class="content_div">Some 'A' Content</div>
<div id="b" class="content_div">Some 'B' Content</div>
JAVASCRIPT
$(document).delegate('[data-role="navbar"] a', 'click', function () {
$(this).addClass('ui-btn-active');
$('.content_div').hide();
$('#' + $(this).attr('data-href')).show();
return false;//stop default behavior of link
});
CSS
.content_div {
display: none;
}
.content_div:first-child {
display: block;
}
Here is a jsfiddle of the above code: http://jsfiddle.net/3RJuX/
NOTE:
Each of the links in the navbar have a "data-href" attribute set to the id of the div (or whatever container you want to use) that will be displayed.
Update
After 1 year I came back to this answer and noticed that the delegated event handler selector can be optimized a bit to utilize a class rather than an attribute (which is a lot faster of a lookup):
$(document).delegate('.ui-navbar a', 'click', function () {
$(this).addClass('ui-btn-active');
$('.content_div').hide();
$('#' + $(this).attr('data-href')).show();
});
Update
This code can be made to be more modular by using relative selectors rather than absolute ones (like $('.content_div'), as this will select all matching elements in the DOM rather than just ones relative to the button clicked).
//same selector here
$(document).delegate('.ui-navbar ul li > a', 'click', function () {
//un-highlight and highlight only the buttons in the same navbar widget
$(this).closest('.ui-navbar').find('a').removeClass('ui-navbar-btn-active');
//this bit is the same, you could chain it off of the last call by using two `.end()`s
$(this).addClass('ui-navbar-btn-active');
//this starts the same but then only selects the sibling `.content_div` elements to hide rather than all in the DOM
$('#' + $(this).attr('data-href')).show().siblings('.content_div').hide();
});​
This allows you to nest tabs and/or have multiple sets of tabs on a pages or pseudo-pages.
Some documentation for the "relative selectors" used:
.closest() : http://api.jquery.com/closest
.siblings() : http://api.jquery.com/siblings
Here was an example: http://jsfiddle.net/Cfbjv/25/ (It's offline now)
UPDATE: Check out my jsfiddle at http://jsfiddle.net/ryanhaney/eLENj/
I just spent some time figuring this out, so I thought I would answer this. Note I am using multi-page single file, YMMV.
<div data-role="footer" data-position="fixed">
<div data-role="navbar">
<ul>
<li>Page 1</li>
<li>Page 2</li>
<li>Page 3</li>
</ul>
</div>
</div>
$("div[data-role=page]").bind("pagebeforeshow", function () {
// prevents a jumping "fixed" navbar
$.mobile.silentScroll(0);
});
$("a[data-role=tab]").each(function () {
// bind to click of each anchor
var anchor = $(this);
anchor.bind("click", function () {
// change the page, optionally with transitions
// but DON'T navigate...
$.mobile.changePage(anchor.attr("href"), {
transition: "none",
changeHash: false
});
// cancel the click event
return false;
});
});
#Mike Bartlett
I struggled with this myself but after breaking Jasper's code down it looks like there is a slight nuance from his posted code and that on the jsfiddle page.
Where he has posted
$(document).delegate('[data-role="navbar"] a', 'click', function () {
$(this).addClass('ui-btn-active');
$('.content_div').hide();
$('#' + $(this).attr('data-href')).show(); });
I found it useful to change the last line to simply call whatever content you set the "data-href" value to be in your navbar.
$('div[data-role="navbar"] a').live('click', function () {
$(this).addClass('ui-btn-active');
$('div.content_div').hide();
$($(this).attr('data-href')).show();
});
my navbar html then reads
<div data-role="navbar">
<ul>
<li>One</li>
<li>Two</li>
</ul>
Which is pretty much the same as his but for some reason I got no "error loading page" message. Hope that helps...
Please refers this below link for all kind of nav bar in jquery
http://jquerymobile.com/demos/1.0rc2/docs/toolbars/docs-navbar.html
<div data-role="navbar">
<ul>
<li>One</li>
<li>Two</li>
</ul>
</div>
thanks
I noticed that the question was asked four years ago, so i'm not sure whether the Tab widget were available with JQ Mobile at that time. anyway i'm a guy from 2015
the awesome solution that i use as below with Jquery Mobile 1.4.5
<div data-role="tabs" id="tabs">
  <div data-role="navbar">
    <ul>
      <li>one</li>
      <li>two</li>
      <li>three</li>
    </ul>
  </div>
  <div id="one" class="ui-body-d ui-content">
    <h1>First tab contents</h1>
  </div>
  <div id="two">
    <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>
I liked #Ryan-Haney's answer, but thought I'd add my own rough draft in, if anyone can find a more efficient way of doing this, then please add a comment.. thanks
I did it this way because I have a bunch of "include" files that get loaded into the DOM at runtime, so I couldn't hard-code that the n-th tab is highlighted/active for each page like Ryan could. I also do have the luxury of having only a single tabbar in my app.
$(document).delegate('.ui-navbar a', 'tap', function ()
{
$('.ui-navbar').find('li').find('a').removeClass('ui-btn-active');
$('.ui-navbar').find('li:nth-child(' + ($(this).parent().index() + 1) + ')').find('a').addClass('ui-btn-active');
});

Categories

Resources