JQuery/Javascript works on & off - javascript

I am using JQuery 1.3.2-min in a project to handle JavaScript animations, ajax, etc. I have stored the file on the same server as the site instead of using Google. When I run the site locally on my development machine, everything works fine in FF, IE, Opera, and Safari (all the latest versions - I work from home and I only have 1 machine for personal use and development use) except for some CSS differences between them and when I go to the live site on my machine it works fine also. I have cleared my caches and hard refreshed the page, and it still works.
This is where it gets interesting however. When I send the site to my boss to test in various OS/Browser configurations, one page doesn't work correctly, some of it works, some doesn't. Also, the client (who uses IE 8) has also confirmed that it is not completely working - in fact he has told me that the page will work fine for a hour, and then just "turn off" for a while. I have never heard of this sort of thing before, and google isn't turning too much up. I have a hunch it may partly be with JQuery's .data(), but I'm not sure.
The page is basically nested unordered lists, and three basic actions happen on the list.
The top most unordered list is set to visible (all list via css are set to display: none to keep them hidden on a fresh page request); all list items divs are given a hover action of full opacity on mouseon, and faded back to 50% opacity on mouseoff; and then whenver a paragraph is clicked, the top most unordered list in that list item is displayed.
Here is my Javascript file for the page:
$(function() {
// Set first level ul visible
$('div#pageListing ul:first').css('display', 'block');
// Disable all the hyperlinks in the list
$('div#pageListing li a').click(function() {
var obj;
obj = $(this).parent(0).parent('div:first');
highlight(obj);
return false;
});
// List Item mouse hovering
$('#pageListing li').hover(
// Mouse On
function() {
if ($(this).children('div').attr('id') !== 'activePage') {
$(this).children('div').css('opacity', 1).css('filter',
'alpha(opacity=100)');
}
}, // Mouse off
function() {
if ($(this).children('div').attr('id') !== 'activePage') {
$(this).children('div').css('opacity', 0.4).css('filter',
'alpha(opacity=40)');
}
});
// Active list item highlighting
$('#pageListing li div').click(function() {
highlight($(this));
});
// Sub-list expanding/collapsing
$('#pageListing p.subpageslink').click(function() {
// Get next list
var subTree = $(this).parent('div').next('ul');
// If list is currently active, close it, else open it.
if (subTree.data('active') != true) {
subTree.data('active', true);
subTree.show(400);
} else {
subTree.data('active', false);
subTree.hide(400);
}
});
// Double clicking of list item - edit a page
$('#pageListing li div').dblclick(function() {
var classes = $(this).attr('class');
var classArray = classes.split(' ');
var pageID = classArray[1];
editPage(pageID);
});
// Handle button clicking
$('button#addPage').click(function() {
addPage();
});
$('button#editPage').click(function() {
var div = $('div#activePage');
var classes = div.attr('class');
var classArray = classes.split(' ');
var pageID = classArray[1];
editPage(pageID);
});
$('button#delPage').click(function() {
var div = $('div#activePage')
var classes = div.attr('class');
var classArray = classes.split(' ');
var pageID = classArray[1];
delPage(pageID);
});
});
// Highlighting of page when clicked
function highlight(obj) {
// Get previous hightlighted element
// and un-highlight
var oldElement = $('div#activePage');
oldElement.css('background', 'white');
oldElement.css('opacity', 0.4).css('filter', 'alpha(opacity=40)');
oldElement.removeAttr('id');
// highlight current selection
obj.attr('id', 'activePage');
obj.css('opacity', 1).css('filter', 'alpha(opacity=100)');
obj.css('background', '#9dc0f4');
// add appropiate action buttons
$('button.pageButton').css('display', 'inline');
}
function addPage() {
window.location = "index.php?rt=cms/editPage";
}
function delPage(page) {
var confirm = window.confirm("Are you sure? Any sub-pages WILL BE deleted also.");
if (confirm) {
var url = './components/cms/controller/forms/deletePage.php';
$.ajax( {
url : url,
type : 'GET',
data : 'id=' + page,
success : function(result) {
if (!result) {
document.location = "index.php?rt=cms";
} else {
window.alert('There was a problem deleting the page');
}
}
});
}
}
function editPage(page) {
var url = "index.php?rt=cms/editPage/" + page;
window.location = url;
}

Is it possible that you are linking to (some of) the script files using a src that points to a file on your local disk/HDD? If so, that would explain why it works only on your machine, as then only your machine has access to the script file.

Thank you one and all for your suggestions. The end problem was miscommunication. I work from home, and upload my projects to a SVN server, which the boss then uses to update the live server. Somehow, the correct files were not getting updated - a communication error on my part. Another possible reason was that the page, while being declared XHTML 1.0 Strict, had something like 50 validation errors (mosting incorrectly nested UL), and I cleaned that up to 5 errors. So thank you all, but again a sad example of the importance of team work communication.

Related

Use Cookies to prevent user clicking link twice

I am trying to prevent the class .activeAdv being added if the link within has it's URL stored in cookie, this cooke is added if user clicks links so basically I am trying to stop returning users clicking same link twice.
The link is by default hidden underneath a div which animates on addition of .activeAdv class, revealing link.
Current code is below along with codepen example of project. I'm guessing I need to wrap the activeAdv addClass in an IF conditional which:
Gets value of child link's href
Check to see if a matching cookie exists
Only add .activeAdv if condition returns false
I think I have the right idea and have got as far as setting cookie on click of link, I am struggling with the IF statement though, could anyone lend a hand?
http://codepen.io/Jambob/pen/wKyoRr
<article>
<div id="on-1" class="box">
<h2>1 dec</h2>
</div>
<div class="present">
content
www.google.com
</div>
</article>
// Checks for content within .present, if TRUE adds .activeAdv animation class
$(".present").filter(function(){
return $(this).html().trim().length > 0;
}).parent().addClass('activeAdv');
// When link clicked, store its URL in cookie
$( ".present a" ).click(function() {
$.cookie($(this).attr('href'), true);
});
if ( '(".present").html().trim().length > 0;' ) {
if ( '(".present a").attr("href")' === "http://www.google.com") {
$(this).parent().addClass('activeAdv');
}
}
After a bit of thinking I have come up with a different IF statement which may be along the right lines
// Checks if content exists
if ( '(".present").html().trim().length > 0;' ) {
// Checks if HREF of child link matches existing cookie (using a string for testing)
if ( '(".present a").attr("href")' === "http://www.google.com") {
$(this).parent().addClass('activeAdv');
}
}
So if :visited CSS pseudoclass isn't sufficient (it matches visited links), you can make use of localStorage, which is much more dedicated to this purpose. I created script which can be run out the Firebug console and colors non-visited links:
(function(links) {
// Load visited links from local storage
var visited = JSON.parse(localStorage["visited"]||"[]");
// Safety check
if(!visited instanceof Array) {
visited = [];
localStorage["visited"] = [];
}
function setClassToLinks() {
links.each(function(){
// Remember state - asume not visited
var linkVisited = false;
// Check for inner HTML
if(this.innerHTML.trim().length > 0) {
// Check if in list of visited links
if(visited.indexOf(this.href)==-1)
linkVisited = true;
else
console.log("Already visited: "+this.href);
}
else
// Skip empty links
return console.log("No inner HTML.");
// Reset color
this.style.color = !linkVisited?"":"red";
// And remove class
if(linkVisited)
$(this).removeClass("activeAdv");
else
$(this).addClass("activeAdv");
})
}
setClassToLinks();
// When link clicked, store its URL in LocalStorage
links.click(function() {
// Prevent duplicities
if(visited.indexOf(this.href)==-1) {
visited.push(this.href);
localStorage["visited"] = JSON.stringify(visited);
}
});
// [OPTIONAL] Update links realtime - triggers when local storage changes
window.addEventListener('storage', function (event) {
if(event.key=="visited") {
visited = JSON.parse(localStorage["visited"]||"[]");
// Change CSS
setClassToLinks();
}
});
})($("a"));
Neat aspect of my solution is, that the links automatically update when you browse in different tab (provided this tab has run the script).
The visited array may quickly grow, which is why I think cookie is such a bad idea.

Transfer data from one page to another jQuery Mobile

I using PhoneGap to create a Geolocation App following this excellent tutorial (link). Unfortunatelly, I'm having an issue that I can't figure out. The relevant parts that are giving me a headache are these:
//Section 1
$('#history').on('pageshow', function () {
tracks_recorded = window.localStorage.length;
$("#tracks_recorded").html("<strong>" + tracks_recorded + "</strong> workout(s) recorded");
$("#history_tracklist").empty();
for (i = 0; i < tracks_recorded; i++) {
$("#history_tracklist").append("<li><a href='#track_info' data-ajax='false'>" + window.localStorage.key(i) + "</a></li>");
}
$("#history_tracklist").listview('refresh');
});
//Section 2
$("#history_tracklist li a").on('click', function () {
$("#track_info").attr("track_id", $(this).text());
});
//Section 3
$('#track_info').on('pageshow', function () {
var key = $(this).attr("track_id");
$("#track_info div[data-role=header] h1").text(key);
var data = window.localStorage.getItem(key);
data = JSON.parse(data);
});
Section 1 works just fine, the data is stored, and the list is created without any issues. But then in Section 2 is when everything goes to hell. By clicking on the element, a new attribute (track_id) is supposed to be created, but it doesn't. Therefore, in Section 3, the "var key" won't get a value, and as a consequence, "var data" will be null also. As you can imagine, nothing works from there. What am I doing wrong here? I only included what I considered the relevant code, but if more is needed I'll do so. Thansk!
In section 2, I think you just need to delegate click handling to the "#history_tracklist" container, as follows :
$("#history_tracklist").on('click', "li a", function () {
$("#track_info").attr("track_id", $(this).text());
});
Without delegation you have a rule saying :
when any existing li a element within #history_tracklist is clicked execute my function
With delegation, you have a rule saying :
when any existing or future li a element within #history_tracklist is clicked execute my function

Applying .click event only to links in a certain div-container

The code already creates a navigation based on a JSON-file. The url are accessible by writing data.chapter[].subchapter[].url, the according title through data.chapter[].subchapter[].title
In case you are interested in that part or want the complete code, I uploaded it there: http://fabitosh.bplaced.net/SkriptET_iFrame_v2/
The goal now is to create a right sidebar which shows the links to the next and previous files in the structure. My approach is below.
What confuses me, is that back() is called until subchap is zero, when a link in #left is being clicked on. It should only be called when the previous-link is being clicked on. What do I have to change in order to achieve that?
Thanks a lot already!
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("");
};
}
function back() {
subchap--;
update_right();
}
$(document).ready(function() // DOM needs to exist in order to be able to add stuff in there
{
...Navigation being built up...
//------ onClick Navigation
$('#left > ul > li > a').click(
function(e)
{
chap = $(this).attr("data-chap");
subchap = $(this).attr("data-subchap");
update_right();
}
);
});

Making editable table work cross-browser

I've been working on an ASP.NET page containing a ListView. When the user clicks a row, the content of the last (visible) column of this (once parsed) HTML table is replaced with a textbox (by means of jQuery), making the value editable.
So far, this works like a charm in Chrome but no joy in IE10.
In this jsfiddle, the value becomes editable but then the Save button doesn't work as expected.
In IE the textbox doesn't appear. Funny detail: if I comment out the four vars (invNr, newInvNr, oldHtml and spanWidth), the input element DOES appear in IE10 but of course I have no data to work with. Really REALLY weird.
The jQuery:
$(document).ready(function () {
$('tr[id*="itemRow"]').click(function () {
$clickedRow = $(this);
//this makes sure the input field isn't emptied when clicked again
if ($clickedRow.find('input[id$="editInvNr"]').length > 0) {
return;
}
var invNr = $clickedRow.find('span[id$="InvoiceNumber"]').text(),
newInvNr = '',
oldHtml = $clickedRow.find('span[id$="InvoiceNumber"]').html(),
spanWidth = $clickedRow.find('span[id$="InvoiceNumber"]').width();
$clickedRow.find('span[id$="InvoiceNumber"]').parent('td').html('<input type="text" ID="editInvNr"></input>');
$clickedRow.find('input[id="editInvNr"]').val(invNr).focus().on('input propertychange', function () {
$clickedRow.find('span[id$="SaveResultMsg"]').hide();
$clickedRow.find('td[id$="SaveOption"]').show();
$clickedRow.find('input[id*="btnSaveInvNrFormat"]').show();
newInvNr = $(this).val();
if (newInvNr == $clickedRow.find('span[id$="InvoiceNumber"]').text()) {
$clickedRow.find('td[id$="SaveOption"]').hide();
}
});
});
$('tr[id*="itemRow"]').focusout(function () {
$rowLosingFocus = $(this);
var previousValue = $rowLosingFocus.find('input[id$="editInvNr"]').val();
$rowLosingFocus.find('input[id$="editInvNr"]').closest('td').html('<asp:Label ID="lblInvoiceNumber" runat="server" />');
$rowLosingFocus.find('span[id$="InvoiceNumber"]').text(previousValue);
});
});
function UpdateInvoiceNrFormat(leButton) {
$buttonClicked = $(leButton);
$buttonClicked.focus();
var companyName = $buttonClicked.closest('tr').find('span[id$="lblCompanyName"]').text(),
invoiceType = $buttonClicked.closest('tr').find('span[id$="lblInvoiceType"]').text(),
invNrFormat = $buttonClicked.closest('tr').find('span[id$="lblInvoiceNumber"]').text();
PageMethods.UpdateInvoiceNumberFormat(companyName, invoiceType, invNrFormat, onSuccess, onError);
function onSuccess(result) {
$buttonClicked.hide();
$buttonClicked.siblings('span[id$="SaveResultMsg"]').text(result).show();
}
function onError(result) {
$buttonClicked.hide();
$buttonClicked.siblings('span[id$="SaveResultMsg"]').text('Error:' + result).show();
}
}
I've tried various combinations of jQuery statements, chaining and avoiding chaining, placing it at the bottom of the page as someone suggested, commenting out various parts of the code out of sheer desperation. Still nada.
There was no way to make the html() method replace the html correctly in IE10, although I never did find out exactly why. I ended up writing both elements into the table cell, set style="display:none" for one of them and use show() / hide() and that's good enough for me (and apparently for IE10 as well).
For anyone encountering the same issue: this is a workaround, not a solution in the strictest sense.

jQuery conditionally change events depending on .html( 'string' ) values

http://jsfiddle.net/motocomdigital/Qh8fL/4/
Please feel free to change the heading if you think I've worded it wrong.
General
I'm running a wordpress site with multilingual control. And my menu/navigation is dynamic, controlled via the wordpress admin. The multilingual language plugin also changes the dynamic menu/navigation content, as well as page content.
My Contact button, which is in the dynamic navigation, opens a sliding menu using jQuery. Very simple animation using top css. The contact button is on the page twice, hence why I'm not using the .toggle for iterations. See jsFiddle.
Script
var $button = $(".contact-button"),
// var for button which controls sliding div
$slide = $("#content-slide");
// var for the div which slides up and down
$button.on('click', function () {
// function for when button is clicked
if ($button.html() == 'Close') {
// run this if button says 'Close'
$slide.stop().animate({ top: "-269px" }, 300);
// close slide animation
$button.html('Contact');
// change text back to 'Contact'
} else {
// else if button says Contact or anything else
$slide.stop().animate({ top: "0" }, 300);
// open slide animation
$button.html('Close');
// change text to 'Close'
}
});
Problem
Because I'm running multilingual on the site. The navigation spelling changes. See jsFiddle flag buttons for example. This is fine, the animation still runs OK, because it's using the button class 'contact-button'.
But because I'm using the .html to replace the text of the button to "Close" and then on the second iteration, back to "Contact" - obviously this is a problem for other languages, as it always changes to English 'close' and back to English 'Contact'
But my three languages and words that I need the iterations to run through are...
Contact - Close
Contatto - Cerca
Contacto - Chiudere
Can anyone help me expand my script to accommodate three languages, all my attempts have failed. The jsFiddle has the script.
The language functionality in the fiddle is only for demo purposes, so the iteration sequence can be tested from the beginning. I understand if you change the language whilst the menu is open (in the fiddle), it will confused it. But when the language is changed on my site, the whole page refreshes, which closes the slide and resets the sequence. So it does not matter.
Any pro help would be awesome thanks!!!
MY POOR ATTEMPT, BUT YOU CAN SEE WHAT I'M TRYING TO ACHIEVE
var $button = $(".contact-button"),
// Var for button which controls sliding div
$slide = $("#content-slide");
// Var for the div which slides up and down
$button.on('click', function () {
// function for when button is clicked
if ($button.html() == 'Close' || 'Cerca'|| 'Chiudere' ) {
// run this if button says Close or Cerca or Chiudere
$slide.stop().animate({ top: "-269px" }, 300);
// Close slide animation
$(function () {
if ($button.html(== 'Close') {
$button.html('Contact'); }
else if ($button.html(== 'Cerca') {
$button.html('Contatto'); }
else ($button.html(== 'Chiudere') {
$button.html('Contacto'); }
});
// Change text back to Contact in correct language
} else {
// else if button says Contact or anything else
$slide.stop().animate({ top: "0" }, 300);
// Open slide animation
$(function () {
if ($button.html(== 'Contact') {
$button.html('Close'); }
else if ($button.html(== 'Contatto') {
$button.html('Cerca'); }
else ($button.html(== 'Contacto') {
$button.html('Chiudere'); }
});
// Change text back to Close in the correct language
}
});
See my attempt script above which is not working on this jsFiddle.
Here's a working example: http://jsfiddle.net/Qh8fL/2/
When one of the language buttons gets clicked, it stores the strings for Contact and Close using jQuery's .data() method. Then, when the contact/close button gets clicked, it refers to those strings rather than having it hard-coded.
Here are the relevant lines of code:
$("#english").click(function() {
$(".contact-button").html('Contact').data('langTxt',{contact:'Contact',close:'Close'});
});
$("#spanish").click(function() {
$(".contact-button").html('Contatto').data('langTxt',{contact:'Contatto',close:'Close'});
});
$("#italian").click(function() {
$(".contact-button").html('Contacto').data('langTxt',{contact:'Contacto',close:'Close'});
});
if ($button.html() == 'Close') {
//...
$button.html($button.data('langTxt').contact);
} else {
//...
$button.html($button.data('langTxt').close);
}
All you need to do to modify the "close" text appropriately is by editing the close property inside the calls to data() that occur in each of the click events.
You should never depend on label strings ... especially in a multilingual environment. Instead you should use placeholders that you store in an attribute (maybe using .data()). Then you write your own setters for the labels depending on the value of the attribute.
var myLabels = {'close': ['Close', 'Cerca', 'Chiudere'], 'contact' : ['Contact', 'Contatto', 'Contacto']};
var currLang = 2; // to select italian
....
// to set the label
$button.data('mylabel', 'close');
$button.html(myLabels['close'][currLang]);
....
if($button.data('mylabel') == 'close') {
$button.data('mylabel', 'contact');
$button.html(myLabels['contact'][currLang]);
} else {
$button.data('mylabel', 'close');
$button.html(myLabels['close'][currLang]);
}

Categories

Resources