I have constructed an app with push state. Everything is working fine. However in some instances my jquery function are fireing multiple times. That is because when I call push state I bind the particular js file for each page I call. Which means that the same js functions are binded many times to the html while I surf in my page.
Tip: I am using documen.on in my jquery funciton because I need my function to get bound to the dynamical printed HTML through Ajax.
I tried to use off in the push state before printing with no success!
Here is my code:
var requests = [];
function replacePage(url) {
var loading = '<div class="push-load"></div>'
$('.content').fadeOut(200);
$('.container').append(loading);
$.each( requests, function( i, v ){
v.abort();
});
requests.push( $.ajax({
type: "GET",
url: url,
dataType: "html",
success: function(data){
var dom = $(data);
//var title = dom.filter('title').text();
var html = dom.find('.content').html();
//alert(html);
//alert("OK");
//$('title').text(title);
$('a').off();
$('.push-load').remove();
$('.content').html(html).fadeIn(200);
//console.log(data);
$('.page-loader').hide();
$('.load-a').fadeIn(300);
}
})
);
}
$(window).bind('popstate', function(){
replacePage(location.pathname);
});
Thanks in advance!
simple bind new function with blank code
$( "#id" ).bind( "click", function() {
//blank
});
or
used
$('#id').unbind();
Try this,
var requests = [];
function replacePage(url) {
var obj = $(this);
obj.unbind("click", replacePage); //unbind to prevent ajax multiple request
var loading = '<div class="push-load"></div>';
$('.content').fadeOut(200);
$('.container').append(loading);
$.each(requests, function (i, v) {
v.abort();
});
requests.push(
$.ajax({
type: "GET",
url: url,
dataType: "html",
success: function (data) {
var dom = $(data);
//var title = dom.filter('title').text();
var html = dom.find('.content').html();
//alert(html);
//alert("OK");
//$('title').text(title);
obj.bind("click", replacePage); // binding after successfulurl ajax request
$('.push-load').remove();
$('.content').html(html).fadeIn(200);
//console.log(data);
$('.page-loader').hide();
$('.load-a').fadeIn(300);
}
}));
}
Hope this helps,Thank you
Related
Actually i want to transfer the value of my variable to another function in javascript. I tried many methods. In fact I search on stackoverflow but i didn't get correct output.
When i click on button show() function runs and form open
function show(){
var target = event.target || event.srcElement;
var id = target.id;
var x = document.getElementById(id).parentElement.id; // I am getting the value of 'x' when i alert it shows correct output
//alert(x);
$.ajax({
url: 'php/retrieve_characters.php',
type: 'post',
data: {},
success: function(response) {
var data = $.parseJSON(response);
if(data!='') {
$.each(data, function(i, item) {
$('#0').attr('src',data[0].charac);
$('#1').attr('src', data[1].charac);
});
}
}
})
}
Now when form opens i click a button which is in form and new function runs
function setimage(){
var target = event.target || event.srcElement;
var id = target.id;
$.ajax({
url: 'php/retrieve_characters.php',
type: 'post',
data: {},
success: function(response) {
var data = $.parseJSON(response);
if(data!='') {
$.each(data, function(i, item) {
var parent=document.getElementById("par1");
var child = parent.lastElementChild;
while (child) {
parent.removeChild(child);
child = parent.lastElementChild;
}
var li = document.createElement("img");
li.setAttribute("id", "char"+id);
li.setAttribute("src", data[id].charac);
li.setAttribute("onclick", "show()");
li.setAttribute("class", "imgs-thumbnail");
parent.appendChild(li);
});
}
}
})
}
In function setimage() i want the value of x which is in first function.
Remember one thing I don't want to call one function into another because in both functions i m retrieving data from database which will be messed up if both functions will be concatenated.
I have the following js/jquery code:
var trigger = $('#loadTableData');
var wrapperClass = 'tableAccordionWrapper';
var url = 'data/tableData.json';
var template = 'includes/tableInput.html';
var parentWrapper = $('#selectedTables .sub-content .input-controls');
var href;
var intID;
var items;
var i;
// retrieve node data send from exteral source
addExternalTableInput = function(){
$('.tableAccordionWrapper').remove();
$.ajax({
type: 'GET',
url: url,
dataType: 'json',
success:function(data){
items = data.items
for(i in items){ // this loops 3 times
addExternalTemplate();
}
},
error:function(status){
console.log(status, "Something went wrong");
},
complete:function(){
}
});
}
// append table input to document
addExternalTemplate = function(){
var wrapper;
$.ajax({
type: 'GET',
url: template,
dataType: 'html',
success:function(data){
intID = i;
wrapper = $('<li/>');
wrapper.addClass(wrapperClass);
wrapper.attr('data-id','table-' +intID);
href = $('<a href="#"/>');
wrapper.append(href);
wrapper.append(data).insertBefore(parentWrapper);
var anchor = wrapper.find('> a');
anchor.html(items[intID].tableName); // this returns 'DB_SOURCE_3' for all 3 templates added to the DOM
},
error:function(status){
console.log(status, "Something went wrong");
},
complete:function(){
}
});
}
The concept is that I am using a small json file to run another ajax request. The length of the data in the json file determines how many times the consecutive function should be fired.
The json contains very basic data, but as I loop through it I want the second ajax function to append a template of html to the document (at which point I want to be able to run other functions). One part of data from the json file needs to be injected into the template as it is iterating through the loop.
It appears that the loop works in that in this example the html template gets appended to the dom 3 times, but it passes the last table name in the json to each template that is added to the dom. The second function appears to run after the loop has finished.
Example JSON:
{
"items":[
{
"tableName": "DB_SOURCE_1",
"tableID" : "14739",
"tableDescription" : "Main customer table"
},
{
"tableName": "DB_SOURCE_2",
"tableID" : "184889",
"tableDescription" : "Partitions table"
},
{
"tableName": "DB_SOURCE_3",
"tableID" : "9441093",
"tableDescription" : "Loans Table"
}
]
}
I have tried passing the function in the ajax complete function.
I have also tried to trigger the second ajax function inside the first ajax success function like so:
addExternalTableInput = function(){
$('.tableAccordionWrapper').remove();
$.ajax({
type: 'GET',
url: url,
dataType: 'json',
success:function(data){
items = data.items
for(i in items){
$.ajax({
type: 'GET',
url: template,
dataType: 'html',
success:function(data){
intID = i;
wrapper = $('<li/>');
wrapper.addClass(wrapperClass);
wrapper.attr('data-id','table-' +intID);
href = $('<a href="#"/>');
wrapper.append(href);
wrapper.append(data).insertBefore(parentWrapper);
var anchor = wrapper.find('> a');
anchor.html(items[intID].tableName);
},
error:function(status){
console.log(status, "Something went wrong");
},
complete:function(){
}
});
}
},
But everything I have tried seems to return the same results.
The code has been rewritten somewhat, but here is what I am doing.
var templateData;
addExternalTableInput = function(){
$('.tableAccordionWrapper').remove();
$.ajax({
type: 'GET',
url: url,
dataType: 'json',
success:function(data){
var items = data.items;
for(var i in items){
addExternalTemplate(items[i], i); // pass parameters to this function
}
},
error:function(status){
// etc.
}
});
}
addExternalTemplate = function(item, intID){ // add parameters to our function so we can access the same data
var wrapper;
// load template data once
if(!templateData){ // only run this function if !templateData (should only run once).
$.ajax({
type: 'GET',
url: template,
dataType: 'html',
async: false, // wait until we have a response before progressing
success:function(data){
templateData = data;
},
error:function(status){
console.log(status, "Something went wrong");
}
});
}
// append templateData to the dom
if(templateData){
var href = $('<a href="#"/>');
var tableNameInput = wrapper.find('[name="tables"]');
tableNameInput.val(item.tableName);
// etc
}
// update for, id and name attributes etc.
updateInputAttributes = function(){
// do other stuff to each instance of the template
}();
}
I have moved alot of the global variables out and instead I am using function parameters.
I am only calling the html template once, but for each iteration of the loop I can run functions to update certain atrributes in that instance of the template as well as match items in the json to items in the template.
I have to pass some result string to the view after sucessful ajax post. At the moment my js is placed in the view and the callback function creates a resultstring and then posts it to the results div. Since I have some blade syntax in the string that is being generated by the callback function it works until I leave the js in the blade.php view file, if I put the javascript in public/js/some.js blade doesn't parse that syntax and the result is the view is rendered with the syntax instead of data. So I was thinking: Can I put the sting in a separate view/js/result.blade.php and in the jquery function do somtehing like:
var resultStr = (content of view/js/result.blade.php)
for(var i=0; i<obj.length; i++){
resultStr
};
$("#results").html(resultStr);
If so, how do I load the external file into partialstring?
My guess is that as it's a blade file it will be parsed.
#c-smile tried this code but is not working, the file is opened but then the view doesn't get the data
jQuery(function ($) {
$(document).ready(function () {
var form = $('form');
form.submit(function (e) {
e.preventDefault();
$.get("js/blade/filler.blade.php", function (data) {
var resultStr = data;
$.ajax({
url: form.prop('action'),
type: 'post',
dataType: 'json',
data: form.serialize(),
success: function (data) {
var obj = (data);
for (var i = 0; i < obj.length; i++) {
resultStr;
}
$("#results").html(resultStr);
}
});
});
});
});
});
That's subject of AJAX functionality.
With jQuery you would do it as:
$.get( "view/js/result.blade.php", function( data ) {
var resultStr = data;
...
});
I have an AJAX function triggerd by a click which basically copies one table row into another table.
The problem I am having is that I get the required variables from the original table row before the AJAX request however these variables don't seem to be passed to the success function and they come out as undefined.
Is there anyway to pass the variables to the function ?
$('.addfile_popup').on('click', '.add2_fl', function(){
var file_id1=$(this).data('file');
var id=$('.useri').val();
var file_name1=$(this).closest('tr').children('td:first').text();
var upload_date1=$(this).closest('tr').children('td').eq(1).text();
var upload_desc=$(this).closest('tr').children('td').eq(2).text();
var job_idx=$(this).data('jid');
//write to appointment database
var data="job_id="+job_idx+"&file_id="+file_id1+"&user_id="+id;
$.ajax({
type:"POST",
url:"admin_includes/prepend_files.php",
data:data,
success:function(html){
var ups='';
ups+='<tr data-file='+file_id1+'><td width="40%">'+file_name1+'</td><td>'+upload_date1+'</td><td>'+upload_desc+'</td><td>VIEW FILE | DELETE</td></tr>';
$(ups).prependTo('.app_table');
}
});
});
$('.addfile_popup').on('click', '.add2_fl', function(){
var file_id1=$(this).data('file');
var id=$('.useri').val();
var file_name1=$(this).closest('tr').children('td:first').text();
var upload_date1=$(this).closest('tr').children('td').eq(1).text();
var upload_desc=$(this).closest('tr').children('td').eq(2).text();
var job_idx=$(this).data('jid');
//write to appointment database
var data="job_id="+job_idx+"&file_id="+file_id1+"&user_id="+id;
// closure function that wrap your variables
function success(file_id1, file_name1, upload_date1 ... ) {
return function(html) {
var ups='';
ups+='<tr data-file='+file_id1+'><td width="40%">'+file_name1+'</td><td>'+upload_date1+'</td><td>'+upload_desc+'</td><td>VIEW FILE | DELETE</td></tr>';
$(ups).prependTo('.app_table');
}
$.ajax({
type:"POST",
url:"admin_includes/prepend_files.php",
data:data,
success: success(file_id1, file_name1, upload_date1 ...)
});
});
You need to use a closure. You can read about them here: How do JavaScript closures work?
This should work:
$('.addfile_popup').on('click', '.add2_fl', function(){
var me = this;
(function() {
var file_id1=$(me).data('file');
var id=$('.useri').val();
var file_name1=$(me).closest('tr').children('td:first').text();
var upload_date1=$(me).closest('tr').children('td').eq(1).text();
var upload_desc=$(me).closest('tr').children('td').eq(2).text();
var job_idx=$(me).data('jid');
//write to appointment database
var data="job_id="+job_idx+"&file_id="+file_id1+"&user_id="+id;
$.ajax({
type:"POST",
url:"admin_includes/prepend_files.php",
data: {
job_id: job_idx,
file_id: file_id1,
user_id: id
},
success:function(html){
var ups='';
ups+='<tr data-file='+file_id1+'><td width="40%">'+file_name1+'</td><td>'+upload_date1+'</td><td>'+upload_desc+'</td><td>VIEW FILE | DELETE</td></tr>';
$(ups).prependTo('.app_table');
}
});//end ajax
})();
});
Note also I've changed how you pass data to the AJAX call.
I've looked over a lot of 'similar' q&a threads on SO but to be honest, as I don't have too much of a grip on js programming, I'm finding it difficult to make sense of a lot of the answers (as far as they may apply to my own situation).
The context is this, I have two php scripts one returning a list of customer_ids (json encoded) for a set period and the other returning their preferences for news feeds (json encoded).
I wrote the following, having googled a bit to get a basic understanding of how to setup an ajax function in jQuery:
$('document').ready(function() {
$.ajax({
type:'GET', url: 'cust_selection.php', data: '',
succes:function(cstmrid) {
var clistlen = cstmrid.length;
var i=0;
var cstmr;
for( ;cstmr=cstmrid[i++]; ) {
$('#adminPanel>ul>li').append("<a href='' onclick='alert("+cstmr+")' class='lst_admin basic'>"+cstmr+"</a>"); //alert to be replaced with a function call which passes customerid to the function below.
}
},
dataType:'json'
});
var cstmrid = "483972258"; //hardcoded for testing purposes
$.ajax({
type:'GET', url:'newsfpref.php?', data:'cref='+cstmrid,
success:function(npfdata) {
var item;
var n=0;
for( ;item=npfdata[n++]; ) {
var news = npfdata[n].nsource;
$('#adminMain>table>tbody').append("<tr><td>"+item+"</td></tr>");
}
},
dataType:'json'
});
});
Now from the first ajax function, I get a list of links which I want to be able to click to launch the second ajax function and pass it the customer id so that it can grab a list of the news sources that they've configured for their pages.
The alert and the hard-coded customer id both suggest that the functions are 'working', but when I try and adjust the first function so that:
...
$('#adminPanel>ul>li').append("<a href='' onclick='getCustomerNP("+cstmr+")' class='lst_admin basic'>"+cstmr+"</a>");
... is calling a modified version of the second function, as below:
...
function getCustomerNP(cstmrid) {
$.ajax({
type:'GET', url:'newsfpref.php?', data:'cref='+cstmrid,
success:function(nprfdata) {
var item;
var n=0;
for( ;item=npfdata[n++]; ) {
var news = npfdata[n].nsource;
$('#adminMain>table>tbody').append("<tr><td>"+item+"</td></tr>");
}
},
dataType:'json'
});
}
Everything seems to just fail at this point. The second function doesn't seem to 'receive' the variable and I'm not sure if it's something elementary that I've overlooked (like some muddled up " and ' placements) or if what I am trying to accomplish is actually not the way jQuery ajax functions interact with each other.
As you can see, I've cannibalised bits of code and ideas from many SO q&a threads, but copying without much of an understanding makes for a frustratingly dependent life.
I would appreciate as much - expansive - comment as you can provide, as well as a solution or two (naturally).
EDIT: Not to confuse anyone further, I've been modifying the above and correcting my (many) errors and typos along the way. At present, the code looks like below:
$('document').ready(function () {
$.ajax({
type: 'GET', url: 'cust_selection.php', data: '',
succes: function (cstmrid) {
var clistlen = cstmrid.length;
var i = 0;
var cstmr;
for (; cstmr = cstmrid[i++]; ) {
var a = $("<a href='' class='lst_admin basic'>" + cstmr + "</a>").click(function () {
getCustomerNP(cstmr)
})
$('#adminPanel>ul>li').append(a); //alert to be replaced with a function call which passes customerid to the function below.
}
},
dataType: 'json'
});
function getCustomerNP(cstmr) {
alert(cstmr);
}
});
You've got a typo in the $.ajax() success function within getCustomerNP(). The function declaration:
success:function(nprfdata) {
... has a parameter nprfdata, but then within the function you use npfdata (missing the r).
Also this code:
var item;
var n=0;
for( ;item=npfdata[n++]; ) {
var news = npfdata[n].nsource;
$('#adminMain>table>tbody').append("<tr><td>"+item+"</td></tr>");
}
...declares and sets variable news that you never use. And it doesn't seem right to increment n in the for test expression but then use n within the loop. You never set item to anything but you use it in your .append().
(Note also that JS doesn't have block scope, only function scope, so declaring variables inside an if or for loop doesn't limit them to that if or for block.)
I would not create inline onclick handlers like that. I'd probably do something more like this:
$('#adminPanel>ul>li').append("<a href='' data-cstmr='"+cstmr+"' class='lst_admin basic'>"+cstmr+"</a>");
...and then within the document ready setup a delegated event handler to catch the clicks on those anchors:
$('#adminPanel>ul>li').on('click', 'a.lst_admin', function() {
$.ajax({
type:'GET', url:'newsfpref.php?', data:'cref='+ $(this).attr('data-cstmr'),
success:function(npfdata) {
var item,
n=0,
// cache the jQuery object rather than reselecting on every iteration
$table = $('#adminMain>table>tbody');
// increment n only after the current iteration of the loop
for( ;item=npfdata[n]; n++) {
// change to use item
$table.append("<tr><td>"+item.nsource+"</td></tr>");
}
},
dataType:'json'
});
});
As you append your like with <a href='' onclick='getCustomerNP("+cstmr+")', Make sure you can access the function getCustomerNP.
Try to define getCustomerNP as
window.getCustomerNP = function(cstmrid) {
...
If you defined it in the $(document).ready(function(){ ... }) block, try this
$('document').ready(function () {
$.ajax({
type: 'GET', url: 'cust_selection.php', data: '',
succes: function (cstmrid) {
var clistlen = cstmrid.length;
var i = 0;
var cstmr;
for (; cstmr = cstmrid[i++]; ) {
var a = $("<a href='' class='lst_admin basic'>" + cstmr + "</a>").click(function () {
getCustomerNP(cstmr)
})
$('#adminPanel>ul>li').append(a); //alert to be replaced with a function call which passes customerid to the function below.
}
},
dataType: 'json'
});
function getCustomerNP(cstmrid) {
$.ajax({
type: 'GET', url: 'newsfpref.php?', data: 'cref=' + cstmrid,
success: function (nprfdata) {
var item;
var n = 0;
for (; item = npfdata[n++]; ) {
var news = npfdata[n].nsource;
$('#adminMain>table>tbody').append("<tr><td>" + item + "</td></tr>");
}
},
dataType: 'json'
});
}
});