I am currently trying to retrieve some data from book search sites and populate a personal database with that data. My idea is to inject the necessary jQuery on the page, so that when I see a title I think I'd like to return to in future, I can then just click a cheeckbox, make necessary additional comments, which I then hope to submit by AJAX to a PHP script which then populates my MySQL database for me with the appropriate title.
Do look at this example for a library catalogue:
// for every book entry, append checkboxes
$('.document-frame').append('<p>Choose:?<input type="checkbox" class="Jcustom_c" /></p><p>Serendepity?:<input type="checkbox" class="Jserep" /></p><p>Include snippet?:<input type="checkbox" class="Jsnippet" /></p>');
// append a Submit button at the bottom of the page, and a blank div for feedback upon success in POST-ing the necessary data
$('#resultPage').append('<input id="Justin" class="Jcustom" type="submit"/><div id="Jfeedback"></div>');
// whenever my checkbox is checked, retrieve / "scrape" the necessary book data
$('.Jcustom_c').change(function() {
if ($(this).is(':checked'))
{
var title = $(this).parent().parent().find('.title a').text();
var author = $(this).parent().parent().find('.authors a').text();
var publishd = $(this).parent().parent().find('.publisher').text();
var status = $(this).parent().parent().find('.metadata .summary').text();
var img_link = $(this).parent().parent().find('img.artwork').attr("src")
// create an XML string from that data. Escape "<" and ">", otherwise when we append the string to the browser for feedback, the browser will not render them correctly.
var appended = '<div class="Jappended"><item><title>' + title + '</title><author>' + author + '</author><publisher_n_edn>' + publishd + '</publisher_n_edn><status>' + status + '</status><image>' + img_link + '</image><serep>N</serep></item></div>';
// show the string just below the book title. Hence if I "pick" the book from the catalogue, the XML string will show up to confirm my the fact that I "picked" it.
$(this).parent().parent().append(appended);
}
// if I uncheck the box, I remove the XML string
else {
$(this).parent().nextAll(".Jappended").remove(appended);
$(this).parent().prevAll(".Jappended").remove(appended);
}
});
And then I have the AJAX:
$('#Justin').click(function(e) {
e.preventDefault;
var string = "<itemset>";
$(".Jappended").each(function() {
var placeh = $(this).text();
string = string + placeh;
$('.results_container').append(string);
})
// these come from <textarea> boxes I append to the end of the page just before the Submit button. (Above, I did not include the jQuery to append these boxes.)
var odp = $("#odp").val()
var mre = $("#motivation_revisit").val()
var mra = $("#motivation_rationale").val()
var stu = $(".hdr_block h5 span").text()
var string = string + "<odpath>" + odp + "</odpath><stused>" + stu + "</stused><motivation><revisit>" + mre + "</revisit><rationale>" + mra + "</rationale></motivation></itemset>"
var post_var = { xml_string : string, source : "NUS" };
$.post('http://localhost:8888/db-ajax.php', post_var , function(data) {
$('#Jfeedback').html(data);
});
My problem is that I can't seem to get the AJAX to work: When I click on my Submit button, I do not see the output I would expect when I used the exact same jQuery on an HTML file I called from localhost. This, which I called using http://localhost:8888/some_html.html worked:
<html>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" ></script>
<script>
$(document).ready( function() {
...
$('#Justin').click(function(e) {
e.preventDefault;
var string = "<itemset>";
/*
$(".Jappended").each(function() {
var post_var = { xml_string : "hello", source : "NUS" };
$.post('http://localhost:8888/db-ajax.php', post_var , function(data) {
// if (data == "Success") {
$('#Jfeedback').html(data);
// }
});
});
});
</script>
<body>
...
</body>
</html>
db-ajax.php is simply:
echo "Success";
I have read this post: jQuery cannot retrieve data from localhost, which mentions something about "JavaScript cannot currently make direct requests cross-domain due to the Same-origin Policy". Is this the reason why my code didn't work on the external page? If yes, what can I do to make the code work, or what other approaches can I adopt to achieve the same goal? I have mutliple book search sites that I am working on, and many of these do not have an API where I can extract data directly from.
Thank you in advance.
P.S.: I've also tried the suggestion by CG_DEV on How to use type: "POST" in jsonp ajax call, which says that $.post can be done with jsonp, which is the data type to use for cross-domain AJAX. Result: On Firebug I do see the POST request being made. But my function callback is not fired, and firebug doesn't register a Response body when at least "Success" should be returned.
you can set allow cross origin resource sharing
Follow two steps:
From server set this on response header
Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:*
//* if you want to allow it for all origin domain , or you can specify origin domains also to which you want to allow cors.
In client side add this on your page
$.support.cors = true;
Cons: It is not fully supported on ie < ie10.
Related
I'm trying to implement SEO friendly infinite scrolling in accordance with google's recommendations as seen here (http://scrollsample.appspot.com/items?page=7). I have a jquery function that sends a request to a php file, (which requests the data from the db) anytime someone scrolls to the bottom of the page, now everything is working fine except that when the user scrolls to the bottom of the page, the request function gets fired more than once. So duplicate entries of the data gets loaded into the page, now i know this isn't from my php file because i opened the page directly in my browser and everything was fine. Checkout the bug here http://devx.dx.am/haze/categor.php?artemis=foo&&page=1
I have already tried the solutions here (jQuery .load() callback function fires multiple times) and here ($(window).load() is executing 2 times?) and a few others as well.
$(window).bind('scroll', function() { //#cagorwrap is the div that should contain the data retrieved
if($(window).scrollTop() >= $('#cagorwrap').offset().top + $('#cagorwrap').outerHeight() - window.innerHeight) { //344.6
var queryParameters = {}, queryString = location.search.substring(1),
re = /([^&=]+)=([^&]*)/g, m;
while (m = re.exec(queryString)) {
queryParameters[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
}
var url2 = "modules/paginate.php?numpages=set";
// #rc is a hidden div too
$("#rc").load(url2, function() {
var rc = $(this).html();
if (queryParameters['page'] < rc) {
queryParameters['page']++;
console.log(rc);
var stateObj = queryParameters['page'];
let cagh = $('#cagorwrap').height() + 344.6 - 75;
$("#cagorwrap").height(cagh);
history.pushState(null, null, "categor.php?artemis=cat&&page="+stateObj);
var url = "modules/paginate.php?artemis=cats&&page="+stateObj;
$("#obtainer").load(url, function () {
$("#cagorwrap").append($(this).html());
}); //#obtainer is a hidden div that receives the data at first before it is appended to #cagorwrap
} else{
//unbind scroll here
}
});
}
});
well if all else fails and you absolutely need a solution, you can add a
counter=1; on the start
and only fire the request function in the case below
counter++;
if (counter%2==0){//fire request}
It's not clean, but if you're loosing too much time with this and want to return to the problem later on...
I am using Ajax to dynamically update a data table without refreshing. I have no problem so far. The user selects certain criteria from a Form . The issue is that , I no longer want to fetch content to this same page but I want to redirect and load content on a different template:
Users selection (Page1.html) -> Ajax -> redirect to Page2.html -> load data within Page2
Would someone please have a look at the code below and advise why it is not working ? I am able to redirect but there isn't any returned data.
Ajax
if (t && e ) {
dataArray = new Array;
dataArray[0] = e;
dataArray[1] = t;
$.ajax({
type: "POST",
url: "includes/filter.php",
data: {
Name: e,
Color: t,
},
success: function (e) {
window.location.href = 'Page2.html'; // Redirect to this page
$("#Wrapper").html(e); // Load content to this page in Div # Wrapper
// If I Uncomment the two lines above and just add $("#table").html(e); it will successfully load content within the table div on the same page
}
});
}
Where filter.php handles the server side query and outputs an html table with the data.
THanks
Pass e and t to your next page like
window.location.href = 'Page2.html?e=' + e + '&t=' + t;
Once page2 is loaded, get e and t and make your ajax call and replace html of wrapper. In your current solution page2 is loaded before wrapper html gets replaced.
for creating query string from array:
var array = [],
array["Name"] = "Car";
array["Color"] = "Red";
var queryStr = "";
for (var key in array){
if(queryStr != "") queryStr += "&";
queryStr += key + "=" + array[key];
}
var url = "Page2.html?" + queryStr;
Try this:
if (t && e ) {
dataArray = new Array;
dataArray[0] = e;
dataArray[1] = t;
$.ajax({
type: "POST",
url: "includes/filter.php",
data: {
Name: e,
Color: t,
},
success: function (data) {
window.location.href = 'Page2.html?data='+data ; // Redirect to this page
}
});
}
After send to the request to the page using POST. And add this line in
page2.html $("#Wrapper").html(e);
I would suggest to clearly choose your path :
Option 1 : drop the ajax request, and do open a new window
window.open('Page2.html?filter=yabayabayaba')
Option 2 : use an ajax request, and load the result in a dialog box (using bootstrap or jquery-ui)
success: function (e) { $(e).dialog(); }
There are a few things wrong here.
When window.location.href = 'Page2.html'; executes it stops the rest of the code from executing and redirects the browser.
The $("#Wrapper").html(e); is in your AJAX success function. So it
will only ever fire after the AJAX call. When the new page loads
this code isn't executed. (It will never fire anyway because of the redirect in front of it).
The whole point of AJAX is to not redirect the user. If you're redirecting them anyway then why not just have the correct content in Page2.html when it loads rather than inserting it with javascript?
Alternatively, you could drop the redirect and just load the entire Page2.html file into your current page in place of the original template using an AJAX request.
I don't know what your HTML looks like but if Page2.html has a div named #wrapper all you need to do is load everything from inside #wrapper of Page2.html into the #wrapper of Page1.html like this:
$('#wrapper').load('Page2.html #wrapper');
That code you should go in your AJAX success function in place of the redirect. You can see more about .load() here.
I'm working with jqueries address change event and am hitting a roadblock when a user copies and pastes a URL in the browser. I need to fist load a portion of the page that contains a form. I could do this after every pagination call but it seems really ineffecient.
Here is my current code block:
$.address.change(function(e) {
var urlAux = e.value.split('=');
var page = urlAux[0];
var start = urlAux[1];
if (page == "/visits") {
$.address.title("Profile Views");
if (start) {
$('#start').val(start);
// ***** If a user has copied and pasted this URL with a start value then I first need to load visits.php in the main div tag. Is it possible to see if this is loaded or not?
$.post("visits_results.php", $("#profile_form_id").serialize(),
function(data) {
$('#search_results').html(data);
location.href = "#visits=" + start;
});
}
else {
var args = localStorage.getItem("visits");
$('#main').load("visits.php?" + args, function () { });
}
}
My attempted work around was this:
var args = localStorage.getItem("visits");
$('#main').load("visits.php?" + args, function () {
$('#start').val(start);
$.post("visits_results.php", $("#profile_form_id").serialize(),
function(data) {
$('#search_results').html(data);
location.href = "#visits=" + start;
});
});
There must be a better way...this is realoading the same portion of the page (visits.php) with every pagination event. Is there a better way to load URLs and not have them trigger an address change?
Using paul's work around from his comments, but instead of Regex'ing html content in the visits.php form this solution will look for data() attached to #mainID.
Paul's work around notes:
After a bit more hacking I came up with this solution that seems to do
the trick. I'm not sure how good it is but it seems to do the trick. I
now get the main div id and do a regex match on a unique string in the
form. If I don't see it I load the form and then load the results. Not
sure if this is good practice or not but it seems to solve my issue.
Methodology to use .data() instead of a regex search of visits.php's html:
/*check if we're missing visits.php by looking for data() flag*/
if( !($("#main").data()["hasVisitsPhp"]) ){
var args = localStorage.getItem("visits");
$('#main').load("visits.php?" + args, function () {
$('#start').val(start);
$.post("visits_results.php", $("#profile_form_id").serialize(),
function(data) {
/* we've loaded visits.php, set the data flag on #main*/
$('#main').data("hasVisitsPhp","loaded");
$('#search_results').html(data);
location.href = "#visits=" + start;
});
});
}
try window.location.hash instead. Changing the whole href can/will trigger a whole-page reload, while changing just the hash by itself should at most cause the page to scroll.
Here is my situation. I have a webpage (not quite finished):
http://grapplingbasics.com/beta.php
I have the page slide to a specific div which puts a a url with a hash in the URL bar. If the user refers to this URL they can hit that specific part of the page.
However, I would like to allow them to hit that part of the page AND load a specific video with one address.
It doesn't seem that you can put a query string and hash dealy together like so: www.blah.com/index.php#BLAH?neat=one
originally i tried turning the hash into part of the querystring, and then using split in jquery to assign it into a hash on the fly. However, the problem with this, is that if I return false to the nav, it wont show the querystring on the URL bar, and if i don't return false, then it wants to navigate to something that isnt there!
What's a possible solution here?
I created a little example for you which should explain how you can get this fixed.
<script type="text/javascript">
function getParameterByName(name) {
name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
var regexS = "[\\?&]" + name + "=([^&#]*)";
var regex = new RegExp(regexS);
var results = regex.exec(window.location.href);
if (results == null)
return "";
else
return decodeURIComponent(results[1].replace(/\+/g, " "));
}
$(function () {
$('a').click(function (event) {
var thisHash = document.location.hash;
$('body').animate({ scrollTop: $(thisHash).offset().top }, function () {
if (getParameterByName('neat') != null) {
alert('I will play video ' + getParameterByName('neat'));
}
});
});
});
</script>
Html:
<a href='?neat=one#end'>Go</a>
<p id='end'>Imagine this is a panel you are going to in your example.</p>
The code above firstly has a getParameterByName function which looks into your URL to find your query string value pairs. and if its not null it returns its value.
in the section below that ...imagine that the anchor tag is your navigation and I clicked on it, then the page animates to the correct hash section. Once the animation is completed in the callback section is asks for the query string value. if it you have set a value for "neat" then your code for playing the video should sit where the alert is now.
You can put the querystring before the hash:
www.blah.com/index.php?neat=one#BLAH
Or for a more complex solution, look into the querying aspect of ben alman's jquery bbq plugin:
http://benalman.com/projects/jquery-bbq-plugin/
This is a general question, I have two pages, a main and a backgound function one (file.php)
Main page loads file.php passing variables:
$(document).ready(function() {
var page = $('#page').attr('value');
var user = $('#user').attr('value');
$('#DIV').load('file.php?user=' + user + '&page=' + page);
});
File.php queries database, inserts variables into more jquery stuff..
echos result...
The result on the main page is the desired one. If I fixe the variables in file.php (and load through browser) the script is fully functionnal and interactive.
My problem is as follows:
The file.php part of the main page is not interacive, i.e. when I click on it nothing happens, yet the 2 work fine idependently, together variables are passed, but the result is static.
My question, is this due to the .load() function? Should I be using $.ajax() type GET ...
Thanks in advance.
It sounds like you have jQuery behaviours attached to the DOM that are not being applied to the new content. This is because the new content is loaded after the DOM is ready (ie, after the load event fires).
This can be solved by using the .live jQuery function to attach events to a selector that will be applied to all elements, regardless of when they're added. E.g, instead of:
$('#button').click(function() { alert('hi'); });
Use:
$('#button').live('click', function() { alert('hi'); });
Is #DIV referring to:
<div id="DIV"></div>
Perhaps you should try this:
$(document).ready(function() {
var page = $('#page').attr('value');
var user = $('#user').attr('value');
// see the DIV below with the ID = "myId"
$("#myId").load("file.php?user=' + user + '&page=' + page", function(response, status, xhr) {
if (status == "error") {
var msg = "Sorry but there was an error: ";
$("#error").html(msg + xhr.status + " " + xhr.statusText);
}
});
});
<!-- empty containers with ID attributes -->
<div id="myId"></div>
<div id="error"></div>
If there is an error in the returned data, this will also tell you what the error is. Also, what does your debugger tell you?