basically I am trying to load some PHP into a DIV using JS.
Using this code:
$('#preview').load("includes/event_image_crop.php?img=" + fname);
However, its not just putting the fname string in there its adding a random string too like this &_=1369168657782
Any ideas?
Thanks
This is a feature designed to prevent caching. It should have no effect on the page (unless you need to use the _ GET variable), but if you need to disable it you should set cache: true using ajaxSetup:
$.ajaxSetup ({
cache: true
});
Of course, as Ian mentions, this will affect every Ajax call on the page, so be aware of that if you have other Ajax calls. It might be better to refactor your code and use a more configurable function than .load().
See a similar (opposite) question here: Stop jQuery .load response from being cached
Related
Mid development I decided to switch to server-side rendering for a better control amongst other benefits. My web application is completely AJAX based, no url redirecting, so the idea here is a website that builds itself up
I just couldn't figure out the proper way to send javascript events/functions along with the html string, or should all the necessary javascript always be preloaded in the static files?
Let's say client clicks a pre-rendered button 'open table'
The server will make a query, build the html table and send it back, but this table also needs javascript triggers and functions to work properly, how are these sent, received and executed?
There are a couple of articles that mention to not use eval() in Javascript, is there any way around this? I don't want to have to preload unnecessary events for elements that don't yet exist
The server is Python and the Client is Javascript/JQuery
Theoretical example :
Client Base Javascript :
$("body").on("click", "#open_table", function() {
$.getJSON('/get_table', function(response){
$("#table_div").append(response.html);
eval(response.javascript()); //??
}
});
Python Server(views.py) :
def get_table(request):
data = {}
#String containing rendered html
data['html'] = get_render_table()
#String containing Javascript code?
data['javascript'] = TABLE_EVENTS_JAVASCRIPT
return HttpResponse(json.dumps(data),content_type='json')
Worth noting my question comes from an experimental/learning perspective
Update:
You can use jQuery.getScript() to lazy load JS. I think this solution is as close as you can get to run JS without using eval().
See this example:
jQuery.getScript("/path/to/script.js", function(data, textStatus, jqxhr) {
/* Code has been loaded and executed. */
console.log( data ); // Data returned
console.log( textStatus ); // Success
console.log( jqxhr.status ); // 200
console.log( "Load was performed." );
});
and "/path/to/script.js" could be a string returned from $.getJOSN response.
Also, the documentation for getScrippt() has examples on how to handle errors and cache files.
Old Answer:
Using .on() attaches events to current and future DOM elements.
You can either attache events prior to DOM insertion or attache event after DOM insertion.
So in your example you can do something like:
$("body").on("click", "#open_table", function() {
$.getJSON('/get_table', function(response){
var code = $(response.html);
code.find(".elementToFind").on("click", function (){
// Code to be executed on click event
});
$("#table_div").append(code);
}
});
I did not test the code but I think it should work.
Assuming you can't just set up an event-binding function and then call it from the main script (the JavaScript you need can't be guessed ahead of time, for example) then one really easy way is just to append the JavaScript to the bottom of the returned HTML content within script tags. When it's appended along with the HTML, the script should simply execute, with no eval() required.
I can't swear that this would work in old browsers, but it's a trick I've used a couple of times, and I've had no problems with it in Firefox, Chrome, or any of the later IE versions.
I think I see what you're asking here, from my understanding you want to send the new "page" asynchorously, and render the new javascript and html. It looks like you already got your request/response down, so i'm not gonna go and talk about sending JSON objects, and the whole "how-to" of sending html and javascript because it looks like you got that part. To do what you want and to dynamically add your javascript in, this stackoverflow question looks like it has what you need
Is there a way to create a function from a string with javascript?
So pertaining to your example, here is how it would look when you recieve the JSON string from your python script:
$("body").on("click", "#open_table", function() {
$.getJSON('/get_table', function(response){
$("#table_div").append(response.html);
/* Create function from string */
var newFunction = Function(response.javascript['param_1'], response.javascript['param_2'], response.javascript['function']);
/* Execute our new function to test it */
newFunction();
}
});
*Your actual function contents would be the string: response.javascript['function']
*Your parameter names if any would be in separate strings ex: response.javascript['param_1']
That is almost a direct copy of the "String to function" code that you can see in the linked question, just replaced it with your relevant code. This code is also assuming that your object is sent with the response.javascript object containing an array with your actual function content and parameter names. I'm sure you could change the actual name of the var too, or maybe put it in an associative array or something that you can keep track of and rename. All just suggestions, but hopefully this works for you, and helps you with your problem.
I am also doing similar work in my project where I had to load partial html using ajax calls and then this partial HTML has elements which requires events to be attached. So my solution is to create a common method to make ajax calls and keep a js method name to be executed post ajax call in html response itself. For example my server returns below html
<input type="hidden" data-act="onPartialLoad" value="createTableEvents" />
<div>.........rest of html response.....<div>
Now in common method, look for input[type='hidden'][data-act='onPartialLoad'] and for each run the method name provided in value attribute (value="createTableEvents")
Dont Use Eval() method as it is not recommended due to security
issues. Check here.
you can run js method using window["method name"]...so here is a part of code that I use.
$.ajax(options).done(function (data) {
var $target = $("#table_div");
$target.fadeOut(function () {
$target.html(data);
$target.fadeIn(function () {
try {
$('input[data-act="onPartialLoad"]', $target).each(function () {
try {
//you can pass parameters in json format from server to be passed into your js method
var params = $(this).attr('params');
if (params == undefined) {
window[$(this).val()]();
}
else {
window[$(this).val()]($.parseJSON(htmlutil.htmlDecode(params)));
}
} catch (e) {
if (console && console.log) {
console.log(e.stack);
console.log($(this).val());
}
}
});
}
catch (e) {
console.log(e.stack);
}
});
});
});
use jQuery.getScript() (as suggested by Kalimah Apps) to load the required js files first.
I am currently trying to convert a lot of backend code to front end (to lighten the load on a small system).
The code at the moment calls a PHP function to return specific information. (e.g. image locations, strings, styling)
I am converting this code to its js equivalent, the content from Mysql was converted to JSON and stored in a read only file and I am accessing that file using this code:
<script>
function jsread(tag) {
$.getJSON("/strings.json", function(result){
document.write(result[tag]['value']);
});
}
</script>
I want the function to "print" where ever it is invoked. document write writes the value to the page but stops all other loading and write only the value.
Let me be very clear on this: I DO NOT want to use anything that needs extra calls or references out side of this function, that will take months of work so no getting elements by their IDs I have already view many questions on this subject and none are what I can work with. I need something that can be applied to every situation. Other wise I will just have to read the JSON using PHP as a middle compromise.
The problem here is, document.write()'s behaviour is crazy across all the browsers, because, it directly modifies the document object and messes up with the events attached. So it is always better to avoid this function as each browser defines it differently and has a different effect on the same code, with different browsers.
Is there a way to use them without a direct reference?
Solution
The wise thing is, as I said in the comments, it is better to use one of the jQuery functions safely, which create a textNode and insert it the right way, without affecting the others:
<script>
function jsread(tag) {
$.getJSON("/strings.json", function(result){
$("body").append(result[tag]['value']);
});
}
</script>
In case, if you wanna do something like having a placeholder and doing stuff, then you can try giving something like this:
$(function () {
var data = "Dummy Data, that would probably get returned from the getJSON";
// Inside the Success function, do this:
$("span.placeholder-of-the-json").replaceWith(data);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="placeholder-of-the-json">This gets replaced</span>
So essentially I'm trying to build my own version of GitHub's tree slider. The relevant Javascript/JQuery code is:
// handles clicking a link to move through the tree
$('#slider a').click(function() {
history.pushState({ path: this.path }, '', this.href) // change the URL in the browser using HTML5 history module
$.get(this.href, function(data) {
$('#slider').slideTo(data) // handle the page transition, preventing full page reloads
})
return false
})
// binds hitting the back button in the browser to prevent full page reloads
$(window).bind('popstate', function() {
$('#slider').slideTo(location.pathname)
}
Ok, hopefully that's understandable. Now here's my interpretation of what's going on here, followed by my problem/issue:
The callback function for the GET request when navigating through the tree is the slideTo method, and an HTML string is passed in as an argument to that function. I'm assuming that slideTo is a function defined elsewhere in the script or in a custom library, as I can't find it in the JQuery documentation. So, for my purposes, I'm trying to build my own version of this function. But the argument passed into this function, "data", is just the string of HTML returned from the GET request. However, this isn't just a snippet of HTML that I can append to a div in the document, because if I perform the same GET request (e.g. by typing the url into a web browser) I would expect to see a whole webpage and not just a piece of one.
So, within this callback function that I am defining, I would need to parse the "data" argument into a DOM so that I can extract the relevant nodes and then perform the animated transition. However, this doesn't make sense to me. It generally seems like a Bad Idea. It doesn't make sense that the client would have to parse a whole string of HTML just to access part of the DOM. GitHub claims this method is faster than a full page reload. But if my interpretation is correct, the client still has to parse a full string of HTML whether navigating through the tree by clicking (and running the callback function) or by doing full page loads such as by typing the new URL in the browser. So I'm stuck with either parsing the returned HTML string into a DOM, or ideally only fetching part of an HTML document.
Is there a way to simply load the fetched document into a Javascript or JQuery DOM object so I can easily manipulate it? or even better, is there a way to fetch only an element with an arbitrary id without doing some crazy server-side stuff (which I already tried but ended up being too spaghetti code and difficult to maintain)?
I've also already tried simply parsing the data argument into a JQuery object, but that involved a roundabout solution that only seems to work half the time, using javascript methods to strip the HTML of unwanted things, like doctype declarations and head tags:
var d = document.createElement('html');
d.innerHTML = data;
body = div.getElementsByTagName("body")[0].innerHTML;
var newDOM = $(body);
// finally I have a JQuery DOM context that I can use,
// but for some reason it doesn't always seem to work quite right
How would you approach this problem? When I write this code myself and try to make it work on my own, I feel like no matter what I do, I'm doing something horribly inefficient and hacky.
Is there a way to easily return a JQuery DOM object with a GET request? or better, just return part of a document fetched with a GET request?
Just wrap it; jQuery will parse it.
$(data) // in your callback
Imagine you want to parse a <p> tag in your normal HTML web page. You probably would use something like:
var p = $('<p>');
Right? So you have to use the same approach to parse an entire HTML document and then, navigate through the DOM tree to get the specific elements you want. Therefore, you just need to say:
$.get(this.href, function(data) {
var html = $(data);
// (...) Navigating through the DOM tree
$('#slider').slideTo( HTMLportion );
});
Notice that it also works for XML documents, so if you need to download via AJAX a XML document from the server, parse the inner information and display it on the client-side, the method is exactly the same, ok?
I hope it helps you :)
P.S: Don't ever forget to put semicolons at the end of each JavaScript sentence. Probably, if you don't put them, the engine would work but it is better to be safe and write them always!
At first I made a function that received a parameter and returned jQuery such as:
function getjQuery(window)
{
/*jquery code*/(window);
return window.jQuery;
}
But then I got an email form the review and they told me I have to use jQuery file with the original file name and completely unmodified.
I started to search for an alternative and found this solution, but there is no way it work.
jQuery object is created, but I can't find any elements. $("#id").length is always 0. With the previous method it was always found.
My current code (which doesn't work)
AddonNameSpace.jQueryAux = jQuery;
AddonNameSpace.$ = function(selector,context) {
return // correct window
new AddonNameSpace.jQueryAux.fn.init(selector,context||contentWindow);
};
AddonNameSpace.$.fn =
AddonNameSpace.$.prototype = AddonNameSpace.jQueryAux.fn;
AddonNameSpace.jQuery = AddonNameSpace.$;
The jQuery file is loading on my browser.xul overlay:
<script type="text/javascript" src="chrome://addon/content/bin/jquery-1.5.2.min.js" />
Am I loading in the right place?
How can I use jQuery to modify the content on a page (HTML) with the original jQuery file, is it even possible?
You need pass the e.originalTarget.defaultView on the second parameter on jquery..
If you don't jquery will use window.document, which is the window.document from the xul.
Use
gBrowser.addEventListener("DOMContentLoaded", function (e) {
$("#id", e.originalTarget.defaultView).length
}, true);
instead of
$("#id").length;
And, for avoid conflicts with other extensions don't use script in the xul page, use MozIJSSubScriptLoader.
Components.classes["#mozilla.org/moz/jssubscript-loader;1"]
.getService(Components.interfaces.mozIJSSubScriptLoader)
.loadSubScript("chrome://youraddon/content/jquery-1.5.2.min.js");
If you use this method, you load jquery only when you need, avoiding memory leak.
The preferred way to load it is with mozIJSSubScriptLoader so you don't collide with other's extensions. I'm not sure why you're having problems, I can use jQuery in my addon like $("#id").hide() with no additional code (although from the sidebar, now browser.xul).
Either way, this blog post provides a pretty good guide and even has an example xpi to download.
Does anybody know how to execute javascript functions in an html that is loaded via ajax? I mean the html contains both plain text and javascript. In my case it seems that only the in-line javascript (eg. onclick="dosomething();return false") gets executed. The pre-defined functions which are wrapped by < script language = "javascript >are unfortunately ignored..
i have search couple articles through the site but the results are either use getScript to load a pure js or use eval. please help me out of this! Thank you very much!
File 1:
<script type="text/javascript">
function test() {
alert('i got loaded dynamically!');
}
</script>
File 2:
$.get('file1.html', function(html) {
$(document).append(html);
test(); // alerts "i got loaded dynamically!"
});
See it in action.
According to the doco, if you use $.ajax and specify a data type of "html", included script tags are evaluated when inserted in the DOM. Make sure your server is returning the correct data type, see Specifying the Data Type for AJAX requests for more info
If that doesn't help, Artem's approach also works well, providing you only make the request once. If you are making the same $.get call over and over, you'll end up with multiple copies of yourFunctionCall in the head, and Strange Things will happen :-)
Look up jquery event delegation, and the .live() method.
http://docs.jquery.com/Events/live#typefn
Event delegation is especially useful and efficient if you're working with a large piece of html that you've added dynamically.
I don't know if this fixes your problem... but if your loaded html also includes a link to jquery's code base, it can cause issues with the child-code not correctly linking with the handle to the jquery object ($).
If I understand you correctly, you receive from your AJAX call plain HTML mixed with javascript code, e.g. with tags. I'm didn't checked it, but you can try to do the following:
$.get( ajaxURL, function( data)
{
$( "head").append( $( data).find( "script"));
yourFunctionCall( );
});