JS fails reading upcoming array elements - javascript

The goal is to create navigation out of a JSON-file in the #left div-box. There should be links to the previous/next page according to the file hierarchy in the #right div-box.
My implementation is running very weirdly. When you click on a link in the navigation, only the link to the previous page shows up. By clicking on said previous link, the one to the next page is updating as well. Navigating through those 2 previous/next links works. As soon as you switch back to navigating through the navigation on the left the next page link won't update anymore. The previous one still does.
Try it out yourself:
http://jsfiddle.net/cxdL3/6/
From what I found out the problem is reading an element ahead in the array ([subchap+1]) doesen't always work. Which confuses me as it should be loaded before the functions are getting called.
Do you have an explanation for that behavior? The two links are also basically created the same way.
var chap; //position in the array of the currently open chapter
var subchap; //position in the array of the currently open subchapter
function update_right() {
var path = data.chapter[chap].subchapter;
//Previous Page
if(subchap > 0) {
$("#prev").html("<b>Previous: </b><a href='"+path[subchap-1].url+"'>"+path[subchap-1].title+"</a><br/>");
$("#prev > a").click(back);
} else { //subchap == 0
$("#prev").html("");
};
//Next Page
if(subchap+1 < path.length) {
$("#next").html("<b>Next: </b><a href='"+path[subchap+1].url+"'>"+path[subchap+1].title+"</a><br/>");
$("#next > a").click(next);
} else {
$("#next").html("");
}
}
function back() {
subchap--;
update_right();
}
function next() {
subchap++;
update_right();
}
$(document).ready(function() // DOM needs to exist in order to be able to add stuff in there
{
//... Navigation created ...
//------ onClick Navigation
$('#left > ul > li > a').click(
function()
{
chap = $(this).attr("data-chap");
subchap = $(this).attr("data-subchap");
update_right();
}
);
});
The remaining files are pretty standard. In case they matter, they can be found here: http://fabitosh.bplaced.net/SkriptET_iFrame_v3/

When getting chap and subchap values in your click handlers, get them as integers, not strings:
chap = parseInt($(this).attr("data-chap"), 10);
subchap = parseInt($(this).attr("data-subchap"), 10);
so that things like chap + 1 become 1 when chap == 0, instead of "01" when chap == "0"
Updated example: http://jsfiddle.net/cxdL3/10/

If you use $(object).data('chap'), jQuery will handle the type conversion for you.

Related

jQuery: Add class to filter item containing active term, accounting for pagination

I'm working on an events page in a WordPress site that uses a set of filters to query posts; the markup for the filters is as follows:
<div class="event-filter">
All Events
Conferences
Webinars
Learning
Past Events
</div>
I'm using jQuery to add an active class to whichever filter is currently in use, the simple code for which is as follows:
$('.event-filter a').each(function() {
if (this.href == window.location.href) {
$(this).addClass("active");
}
});
This works perfectly fine except in the case that the resulting posts are paginated, as the url changes to reflect the current page, i.e. /events/page/2/?event-type=conference. How can I modify my JS to add the active class to the current filter if the URL contains the respective event-type term but also accounts for "All Events", and thus appends the class to "All Events" when the other filters are not in use? A couple notes: the "Past Events" option just links to an archive page that is a separate template from the main, filterable "Events" page; also, these filters are not using Ajax, they're just altering the WordPress query by URL parameter. Thanks for any insight here!
By the looks of it you will have to do a two part check, I would try something like:
$('.event-filter a').each(function() {
var currentHref = window.location.href.split('?'); // ['https://myexamplesite.com/events/page/2', 'event-type=conference']
var thisHref = this.href.split('?'); // ['https://myexamplesite.com/events', 'event-type=conference']
var currentHrefHasQuery = currentHref.length > 1 ? true : false; // true
var thisHrefHasQuery = thisHref.length > 1 ? true : false; //true
if (currentHrefHasQuery != thisHrefHasQuery) {
return; // they don't match
}
if (currentHrefHasQuery && currentHref[1] == thisHref[1]) { // if they have a query and the query is the same, it's a match!
$(this).addClass("active");
} else if (!currentHrefHasQuery && currentHref[0].indexOf(thisHref[0]) > -1) { //check to see if the current href contains this' href
$(this).addClass("active");
}
});
This could definitely be simplified, but hopefully this is fairly easy to read.
Fiddle: https://jsfiddle.net/m0hf3sfL/

Triggering a function on multiple events

I've written some code to collapse 2 columns if the text on the left is longer than the image on the right:
var collapsed = null;
var banner = function() {
var txt = $('.banner .text').outerHeight();
var image = $('.banner .main-image').outerHeight();
if (txt > image) {
// Collapse columns
$('.banner').addClass('single-line');
// Set the breakpoint the column collapsed at
if (collapsed == null) {
collapsed = $(window).width();
}
}
// Restore the 2 columns when the browser hits the breakpoint
if ($(window).width() >= collapsed) {
$('.banner').removeClass('single-line')
}
}
My problem is getting this function to trigger at the right times. This works:
$(window).resize(banner);
But neither of these work...
$(window).onload(banner); // When the page first loads
$(window).on('orientationchange', banner); // When device is rotated
I could be completely on the wrong tracks here, so please feel free to point me in the right direction.
Thanks in advance!
Acording to the documentation of JQuery,there is no "onload" method for the jquery object, instead you should use "ready":
$(window).ready(banner);
About this line not getting fired, probably because you"re using the wrong synthax. The reference for "on" method :
.on( events [, selector ] [, data ], handler )
so you should try this :
$(window).on('orientationchange','window', banner)
Cheers
To run when the page first load, you can use:
$(document).ready(function() {
banner();
});
Regarding the orientationchange event, make sure you are using the jquery.mobile.js (https://api.jquerymobile.com/orientationchange/)

Expand only one row in javascript code

hey guys having trouble figuring out how to make it so that i can make it only open one table at once, once you open another the other should close any help here?
function showRow(cctab){
if (document.getElementById(cctab)) {
document.getElementById(cctab).style.display = '';
}
}
function hideRow(row1){
if (document.getElementById(cctab)) {
document.getElementById(cctab).style.display = 'none';
}
}
function toggleRow(cctab){
if (document.getElementById(cctab)) {
if (document.getElementById(cctab).style.display == 'none') {
showRow(cctab)
} else {
hideRow(cctab)
}
}
}
Now I want to make it so that only one table "cctab" opens after I suggest the onClick="javascript:toggleRow(cctab);" anyhelp?
Well you could save a reference to the previously shown item and hide it when another is shown:
var currentTab;
function showRow(cctab){
if (document.getElementById(cctab))
document.getElementById(cctab).style.display = '';
if (currentTab && currentTab != cctab)
hideRow(currentTab);
currentTab = cctab;
}
Note that doing inline event handler attributes is so 1999, but assuming you're sticking with it for whatever reason you don't need the javascript: in onClick="javascript:toggleRow(cctab);". (Just say onClick="toggleRow(cctab);")
First you need to store the old row somewhere.
What you've got is a system where you're using <element onclick="..."> to pass the id of the current element into the controller that shows or hides the row.
But if you look at that, what you're missing is a way of telling what the last open row was.
So what your code will need is a central object, or variables which store the old element and the new element.
How you do this is up to you, but if you did something like this:
var table_rows = { current : null /* or set a default */, previous : null };
function rowController (cctab) {
var newRow = document.getElementById(cctab);
if (newRow === table_rows.current) { toggleRow(newRow); }
else {
table_rows.previous = table_rows.current;
table_rows.current = newRow;
showRow(table_rows.current);
hideRow(table_rows.previous);
}
}
Note:
This deals with elements directly, so you don't have to do getById in your functions;
that's handled one time, and then that element is passed around and saved and checked against.
It assumes that the click is happening on the row itself, and not on anything inside of the row;
that's a separate issue that your code has.
Unless it's obvious and easy to click on the row, and not the cells inside of the row, it's difficult to tell how you want users to be able to open and close rows.
What I mean is if only the table-row has an onclick, and somebody clicks on a table-column, then then onclick isn't going to fire.

menu is not active after clicking the link..(after page loads)

finally i did this by following javascript..
function extractPageName(hrefString)
{
var arr = hrefString.split('/');
return (arr.length<2) ? hrefString : arr[arr.length-2].toLowerCase() + arr[arr.length-1].toLowerCase();
}
function setActiveMenu(arr, crtPage)
{
for (var i=0; i<arr.length; i++)
{
if(extractPageName(arr[i].href) == crtPage)
{
if (arr[i].parentNode.tagName != "DIV")
{
arr[i].className = "selected";
arr[i].parentNode.className = "selected";
}
}
}
}
function setPage()
{
hrefString = document.location.href ? document.location.href : document.location;
if (document.getElementById("but_a")!=null)
setActiveMenu(document.getElementById("but_a").getElementsByTagName("a"), extractPageName(hrefString));
}
if i click the ul without clicking the link.. its working.. when i click the link. it works until the page loads. after the page load, the ul back groud going default class not "selected" class..am new to tis.. am struggling so hard.. need help..??
I've added a jdFiddle with an example here:
http://jsfiddle.net/Suren/u4szQ/1/
$(document).ready(function() {
$("a.button").click(function () {
$(this).toggleClass("selected");
});
});
You've got too much javascript there.
After your posted fiddle. Here is a working fiddle.
Note you have a great deal of malformed HTML. You can't place divs in between list items. You can't have multiple objects on a page with the same ID (use a class instead).
After clicking on anchor the page is going to navigate to the url set on anchor's href attribute so whatever javascript operation you do is going to be lost after the page is loaded.
If you want to highlight the selected link the you can probably send the link id or some identifier along with the url and then check for it on page load and set the appropriate link selected.
By the way toggleClass adds or removes one or more classes from each element in the set of matched elements, depending on either the class's presence or the value of the switch argument.

With JS, how to create an access key to jump to the "next section" on a page?

I have a page with several sections, and each section begins with a H2 tag. Each section has a different length from each other. I'd like to have two access keys: P and N, for "previous" and "next".
Let's say a user is viewing this page and scrolls to the middle of the page, and is viewing Section 5. If they hit the P access key to go to the previous section, then the browser should jump them to the H2 heading of Section 4. If they hit N to go to the next section, then they should jump to the H2 heading of Section 6.
Is it possible to do this, without needing to create a separate access key for every section? (E.g. "1" for Section 1, "2" for Section 2, etc.)
No you don't have to make separate keys - you only need a pointer to where the user got to and an array of all your sections... Assuming each section starts with H2 here is the code that will do what you want:
<script>
var sections = new Array();
$(document).ready(function(){
//get an array of all your sections
sections = $("h2");
//your pointer to a current section
index= 0;
$(document).keydown(function(event) {
//previous 'p'
if (event.keyCode == '80') {
if (index!=0) {
index--;
} else {
//wrap navigation (go tot the last item if on first item)
index = sections.length-1;
}
jump(sections[index]);
event.preventDefault();
}
//next 'n'
if (event.keyCode == '78') {
if (index<sections.length-1) {
index++;
} else {
//wrap navigation (go the the first item if on last item)
index = 0;
}
jump(sections[index]);
event.preventDefault();
}
})
})
function jump(obj){
var new_position = $(obj).offset();
window.scrollTo(new_position.left,new_position.top);
}
</script>
You'll need to build an array of the offsetTop for each matching h2.
When the user presses 'P' or 'N' you'll need to check the current scrollTop position in the window, and find where this sits on the sections.
From here grab the prev/next position and change the window's scrollTop via scrollTo()...
It would honestly take more time to write this out, and if you're using a library (jquery, dojo, etc) would make it easier.

Categories