Deep-Linking php queries to a data base - javascript

I have been having problems with deep-linking when I want to make a back or forward recall to some php script that involves a query to my data base.
I think that whats happening is that when a link requires a php script that is on a deeper level it doesn't makes the callback to the server. It just works when it uses the same php script that uses the link that was displayed right back or after it.
This is my JS function:
function loadload(loc) {
$("document").ready(function(){
function loadURL(url) {
console.log("loadURL: " + url);
$(loc).load(url);
}
// Event handlers
$.address.init(function(event) {
console.log("init: " + $('[rel=address:' + event.value + ']').attr('href'));
}).change(function(event) {
$(loc).load($('[rel=address:' + event.value + ']').attr('href'));
console.log("change");
})
$('a').click(function(){
loadURL($(this).attr('href'));
});
});
};
This is my php echo line:
echo "<li><a onclick='loadload("."&#34"."#txtHint"."&#34".")' href="."'php/getdaimler.php?q=".$row['Program']."'"."rel="."'address:/Daimler/".$row['Program']."'>". $row['Program']. "</a></li><br>";
Also it makes my page become slower when several links have been triggered.
If there are some better functions or methods to use it would be great.
I'll appreciate your answers.

The posted jQuery Code can't work like this. First you use an inline event handler (onclick) inside the html code.
echo "<li><a onclick='loadload("."&#34"."#txtHint"."&#34".")' href="."'php/getdaimler.php?q=".$row['Program']."'"."rel="."'address:/Daimler/".$row['Program']."'>". $row['Program']. "</a></li><br>";
The method you call is loadload, the parameter is &#34#txtHint&#34 which is used as a jQuery selector, but will never match any DOM Element. My best guess is, you want to load the server answer to an element with the id 'txtHint', in that case the selector would be: #txtHint.
Now to the jQuery/ javascript function itself:
function loadload(loc) {
// this is wrong, you can not use the event handler for dom ready here...
$("document").ready(function(){
function loadURL(url) {
console.log("loadURL: " + url);
$(loc).load(url);
}
// Where does $.address come from?....
// Event handlers
$.address.init(function(event) {
console.log("init: " + $('[rel=address:' + event.value + ']').attr('href'));
}).change(function(event) {
$(loc).load($('[rel=address:' + event.value + ']').attr('href'));
console.log("change");
})
// and here you'll define another click handler - inside the click handler
// will never be executed...
$('a').click(function(){
loadURL($(this).attr('href'));
});
});
};
Either you use the inline event handler, or a general bind logic, do not mix it.
Variant a: inline event handler
function loadload(loc,url) {
console.log("loadURL: " + url);
$(loc).load(url);
}
echo "<li><a onclick='loadload(\"#txtHint\",\"php/getdaimler.php?q=".$row['Program']."\")' href='php/getdaimler.php?q=".$row['Program']."' rel='address:/Daimler/".$row['Program']."'>". $row['Program']. "</a></li><br>";
Variant b: general binding:
$("document").ready(function(){
$('a.loadload',function() {
$('#txtHint').load($(this).attr('href'));
});
});
echo "<li><a class='loadload' href='php/getdaimler.php?q=".$row['Program']."' rel='address:/Daimler/".$row['Program']."'>". $row['Program']. "</a></li><br>";
So far for your javascript / html code. To be honest I have no idea if this fits your 'deep link' question, or the db-query you talked about, but it might be a starting point.

Related

Bind an event on a jquery generated element

My code is like this:
$('.flag-icon-dz').click(function() {
var lang = 'Arab';
var $frame = $('.goog-te-menu-frame:first');
if (!$frame.size()) {
console.log("Error: Could not find Google translate frame.");
return false;
}
$frame.contents().find('.goog-te-menu2-item span.text:contains(' + lang + ')').get(0).click();
$("li.ql-item.linkid188546").after("<li class='ql-item linkid18854777 closegoogle'><a href='#' class='btn-primary' target='_self'><i class='icon closegoogle ls-lang-frr' aria-hidden='true'></i></a></li>").fadeIn(500);
$('li.ql-item.linkid188546').fadeOut(500);
return false;
});
$('.closegoogle').click(function() {
$('.skiptranslate').contents().find('.goog-close-link > img').click();
$('li.ql-item.linkid18854777').fadeOut('fast').remove();
$('li.ql-item.linkid188546').fadeIn(500);
});
The first function works great, but the second doesn't. I realize that if I copy/paste the second function in the console after the first one, it works too.
I tried a few solutions (callback / setTimeout / jquery deferred / jquery .when method...) I didn't try promise but I don't think I have to in my context. Maybe I didn't write these solutions good enough.
I finally try to put my event (click) directly the .before() which create my new element like this :
$('.flag-icon-dz').click(function() {
var lang = 'Arab';
var $frame = $('.goog-te-menu-frame:first');
if (!$frame.size()) {
console.log("Error: Could not find Google translate frame.");
return false;
}
$frame.contents().find('.goog-te-menu2-item span.text:contains(' + lang + ')').get(0).click();
$("li.ql-item.linkid188546").after("<li class='ql-item linkid18854777 closegoogle'><a href='#' class='btn-primary' target='_self'><i class='icon closegoogle ls-lang-frr' aria-hidden='true'></i></a></li>").fadeIn(500).click(function() {
$('.skiptranslate').contents().find('.goog-close-link > img').click();
$('li.ql-item.linkid18854777').fadeOut('fast').remove();
$('li.ql-item.linkid188546').fadeIn(500);
});
$('li.ql-item.linkid188546').fadeOut(500);
return false;
});
But it doesn't work either.
Thanks for the help.
EDIT :
I finally found a kind of solution for my second click event (which isn't the best solution but i works) :
window.setInterval(function(){$('.closegoogle').on("click",function(){
$('.skiptranslate').contents().find('.goog-close-link > img').click();
$('li.ql-item.linkid18854777').fadeOut('fast').remove();
$('li.ql-item.linkid188546').fadeIn(500);
}); }, 1000);
Thanks.
You need to use a delegated bind as the element does not exist before you try your binding:
$('#parent-element-of-closegoogle').on('click', '.closegoogle', function() {
$('.skiptranslate').contents().find('.goog-close-link > img').click();
$('li.ql-item.linkid18854777').fadeOut('fast').remove();
$('li.ql-item.linkid188546').fadeIn(500);
});
Please note that the #parent-element-of-closegoogle needs to be an element that already exists when you do the binding - this can be $(document) if you hjave no other element to bind to

jQuery event fires once, then never again

I've been wrestling with a simple JQuery event handler for hours.
My event handler fires exactly once, when the page loads, and never again no matter the event or the interaction with the select box.
When deferred, the alert (when I have one) shows the first select option. When not, the alert is blank.
All I want is for the select box to load from AJAX and for a user choice to trigger another AJAX call.
HTML:
<select id="connection" name="Connection"></select>
<div id="testme" style="background: #CCC; width:100%; height:50px;position:relative;color:red">testing</div>
Javascript:
$(document).ready(function () {
// Event handler. Tried as a separate function and as a parameter to $.on(...)
function connectionSelected() {
var str = $('#connection option:selected').text();
alert(str);
$("#testme").text(str);
}
var $connectionSelect = $('#connection');
//$connectionSelect.selectmenu(); // Tried enabling/disabling
// Tried this and all JS code inside and outside of $(document).ready(...)
$.when(
$.ajax({
dataType: "JSON",
url: '#Url.Content("~/API/ConnectionHint")', // The AJAX call (using ASP Razor) works fine
success: function(data) {
// This function is always called and works
var items = [];
$.each(data, function(key, val) {
items.push("<option value='" + key + "'>" + val + "</option>");
});
$connectionSelect.append(items.join(""));
// Tried setting up the event handler here
},
error: function() {
$connectionSelect.html('<option id="-1">none available</option>');
}
})
).then(function() {
//$("#connection option").blur(connectionSelected()).change();
$("#connection").on("change", connectionSelected());
});
});
Tried dozens of variations of the event handler, several events, inside and outside of a deferred.done and deferred.then, etc.. E.g.:
$connectionSelect.selectmenu({
change: function (event, data) {
$('#connection').change(function () {
var str = "";
$('#connection').each(function () {
str += $(this).text() + "<br>";
});
$("#testme").text(str);
});
}
});
I usually write back-end code and am familiar only with portions of JQuery, and this is driving me crazy. I've looked more than 30 related question on SO and elsewhere, e.g.
Jquery event fires once
Jquery .change() function not working with dynamically populated SELECT list
http://jqueryui.com/selectmenu/#product-selection
Any ideas are appreciated.
Instead of
$("#connection").on("change", connectionSelected());
try
$("#connection").on("change", connectionSelected);
Note that in the second one I'm passing your function handler by reference, instead of invoking it.

Defined function is not found

I have this function which is called in a for loop.
function printResult(name, i) {
$('#list').append("<a href='#' onClick='goto(" + i + ");' class='item'><H1>" + name + "</H1> </a>");
}
The a href-tags are appended as they should, but when I call the goto function firebug says: 'goto is not defined'
But it is!!
This is the function:
function goto(myPoint){
map.setCenter(new google.maps.LatLng(marker[myPoint-1].position.lat(), marker[myPoint-
1].position.lng()));
markerArr[myPoint-1]['infowindow'].open(map, markerArr[myPoint-1]);
}
I'm clueless as to why the function is not found. Does it have something to do with it being called in the appended a href-tag?
goto() is a terrible name for a function, because it's commonly used as a keyword in a lot of programming languages.
In Javascript, it is not a keyword. However, it is a reserved word, on the grounds that it may be used in future versions of the language. This alone may be causing JS to reject your function or fail to call it.
But even if it weren't a reserved, is could be seen as a potential ambiguity, and so would not be recommended for use.
Therefore, my suggestion would be to change the function name. With luck, it might magically start working.
Using jQuery click events like this:
Html:
function printResult(name, i) {
$('#list').append("<a href='#' rel='" + i + "' class='item'><H1>" + name + "</H1></a>");
}
Js:
$(document).on('click', 'a.item', function (e) {
goto($(this).attr("rel"));
});
But I recommend to rename the function goto to something else or do:
$(document).on('click', 'a.item', function (e) {
var myPoint = $(this).attr("rel");
map.setCenter(new google.maps.LatLng(marker[myPoint-1].position.lat(), marker[myPoint-
1].position.lng()));
markerArr[myPoint-1]['infowindow'].open(map, markerArr[myPoint-1]);
});
When you define event handlers by using onclick attributes, the definition of goto() must be global, i.e. window.goto must exist.
More importantly, this is not the jQuery way; event handlers should be defined in JavaScript code rather than HTML.
function printResult(name, i)
{
var $title = $('<h1 />', { text: name }),
$anchor = $('<a href="#" class="item" />')
.append($title)
.on('click', {
index: i
}, moveToIndex)
.appendTo('#list');
}
// this is the click handler
function moveToIndex(evt)
{
// evt.data.index = the value of i
}
I have renamed your goto() function into moveToIndex() which is somewhat more descriptive. This should not have the same scope issues as your current code.
You are using onClick='goto(" + i + ");'. Use onclick ='goto("+i+")' instead, don't use a semicolon

Hover effect not working from the second time in Safari

I'm facing a weird problem with safari
I'm now developing a website that loads its contents with Ajax I'm applying this by using Hashchange methodology and when hashchange
I'm getting the url and then load the content for the page
jQuery(window).bind('hashchange', function () {
url = window.location.hash.substring(1);
if (!url) {
return;
}
var tsTimeStamp= new Date().getTime();
jQuery.get(url, { action: "get", time: tsTimeStamp,"ajaxed": "true"} , function (data, status, xmlHttp) {
var container = jQuery("#hidden");
container.html(xmlHttp.responseText);
var content = jQuery(".inner", container).html();}
and then after loading the content I'm applying some jquery stuff like
var ids = " ";
var ids_2 = " ";
for (var i = 0; i <= jQuery(".cats").length; i++) {
ids += "#c" + i + ",";
ids_2 += "#l" + i + ",";
}
ids = ids.substr(0, (ids.length) - 1);
ids_2 = ids_2.substr(0, (ids_2.length) - 1);
jQuery(ids).hover(function () {
href = jQuery(this).attr("href");
id = jQuery('a[href="' + href + '"]').attr("id");
jQuery("img").not(jQuery("img."+id)).addClass("op");
}, function () {
time = setTimeout(remove, 200);
});
jQuery(ids_2).hover(function () {
clearTimeout(time);
jQuery("img.op").removeClass("op");
href = jQuery(this).attr("href");
id = jQuery('a[href="' + href + '"]').attr("id");
jQuery("img").not(jQuery("img." + id)).addClass("op");
}, function () {
jQuery("img.op").delay(200).removeClass("op");
});
function remove() {
jQuery("img.op").removeClass("op");
}
The above code is applying hover over effect on map areas for images
(this code is applicable to 4 pages).
All the above code is working fine with all the browser except Safari
The problem is when the first page that contains the maps loaded the code is working fine but when you load another page contains the same areas it will stop working until the whole page being refreshed.
seems like it caches the handler for the first time and then does not apply it to the new selectors
Keep in mind that when Alert ids & ids_2 it gives the correct values but when using alert inside the .hover it does not fire in the second time.
I know its complicated but really I'm stuck with this issue.
Well, it would be better to have small code snippets, but from what I can see you're having problem on binding jQuery handlers on newly created elements. To solve this problem you have to use the jQuery .live().
From jQuery documentation:
This method is a variation on the
basic .bind() method for attaching
event handlers to elements. When
.bind() is called, the elements that
the jQuery object refers to get the
handler attached; elements that get
introduced later do not, so they would
require another .bind() call.
The .live() method provides an
alternative to this behavior. To bind
a click handler to the target element
using this method:
$('.hoverme').live('hover', function(){
// Live handler called.
});
And then later add a new element:
$('body').append('<div class="hoverme">Another target</div>');
Then clicks on the new element will
also trigger the handler.

Javascript scope question: Can't change element via 'this' obj passed to function, but I can using longhand approach

REVISED QUESTION (SEE BELOW FOR ORIGINAL):
Here is an example of a simple ajax load with an event binding on an element within the loaded content:
soTest.htm
<!DOCTYPE html>
<html>
<head>
<script language="JavaScript" type="text/javascript" src="http://code.jquery.com/jquery-1.6.min.js"></script>
<script>
function changeBG(obj)
{
alert('Color 1: Should Turn Red');
jQuery(obj).css('background-color','red');
alert('Color 2: Should Turn Green');
jQuery('#' + jQuery(obj).attr('id')).css('background-color','green');
}
jQuery(document).ready(
function() {
jQuery('.loadedContent').load('soTest2.htm');
jQuery('body').delegate("#theElem","click",
function(){
var obj = this;
jQuery('.loadedContent').load('soTest2.htm',
function(){
changeBG(obj);
}
);
});
}
);
</script>
</head>
<body>
<div class="loadedContent">
</div>
</body>
</html>
Ajax loaded content, soTest2.htm:
<div id="theElem" >
Hello
</div>
So why is it that this doesn't work:
jQuery(obj).css('background-color','red');
But this does:
jQuery('#' + jQuery(obj).attr('id')).css('background-color','red');
++++++++++ORIGINAL QUESTION:++++++++++
I have a table that I want to sort when specific table headings are clicked (those with the class "sort").
For instance:
Location
To do that I have this code:
jQuery('body').delegate("click", ".sort", function(event) {
event.preventDefault();
jQuery('.searchResults').html('<div align="center" style="margin-top:35px;"><img src="/common/images/ajax-loader_big.gif" /></div>');
var TimeStamp = new Date().getTime();
var sortItem = this;
jQuery('.searchResults').load('modules/configSearchResultsOutput.cfm?' + TimeStamp + '&sortby=' + jQuery(this).attr('sortby') + '&direction=' + jQuery(this).attr('direction'), {
data: jQuery('#results').val()
}, function() {
sortCallback(sortItem);
});
});
So on the click event for one of these sortable column headings I'm storing the entire 'this' scope in a var to pass through to this function.
To simplify the question I'll just say that we're trying to change the background color of the clicked element based on the custom attr 'direction' I'm using:
function sortCallback(obj) {
//Returns correct attribute value
alert('In Callback: ' + jQuery(obj).attr('direction'));
//Does not return correct attribute value -- almost like it's cached or something
alert('Long hand reference: ' + jQuery('.sort[sortby="' + jQuery(obj).attr('sortby') + '"]').attr('direction'));
//Must reference value via (obj) to get correct updated value
if (jQuery(obj).attr('direction') == 'asc') {
//Changing a value within the element via this longhand approach works
jQuery('.sort[sortby="' + jQuery(obj).attr('sortby') + '"]').css('background-color', 'red');
//Changing a value within the element via this shorter approach does not work
jQuery(obj).css('background-color', 'red');
}
else {
//Works
jQuery('.sort[sortby="' + jQuery(obj).attr('sortby') + '"]').css('background-color', 'green');
//Doesn't work
jQuery(obj).css('background-color', 'green');
}
}
I'm assuming I'm not understanding some aspect of javascript scoping (understanding 'this' has been very elusive to me).
Question summarized:
If I'm passing a var'd 'this' scope to a function why can't I change the aspects of the 'this' element, why must I drill down using the long way to change them?
A tricky question for me to articulate, hopefully I did a good enough job.
Thanks!
This is happening because your ajax call replaces the DOM element. obj refers to a DOM element that was in the DOM before you called .load, but was replaced. Another element with the same ID does exist, though! That's the one you're referring to with your 'longhand' method.
I think your problem is because that load call is asynchronous, causing jQuery to get confused. Put your code inside a callback for load and it should work:
jQuery(document).ready(function() {
jQuery('.loadedContent').load('soTest2.htm',
function(resp, status, xhr){
jQuery("#theElem").bind('click',
function(){
changeBG(this);
});
});
});

Categories