deferring JavaScript execution in document received via AJAX - javascript

I'm receiving this HTML document via AJAX:
<form enctype="multipart/form-data" method="POST" action="admin.php?do=media&action=file-upload">
<div id="uploadForm">
<div id="fileList">
</div>
[Select File]
[Start Upload]
</div>
</form>
<script type="text/javascript">
// $(function(){}); not working when data loaded with ajax request
var ajaxUpload = new plupload.Uploader({
runtimes: 'gears, html5, flash',
url: 'upload.php',
browse_button: 'selectFile',
});
ajaxUpload.bind('Init',function(param){
console.log(param);
console.log($('selectFile'));
});
$('#uploadFile').click(function(){
alert('Something');
});
ajaxUpload.init();
</script>
When I append this to the main document, the JavaScript inside it will immediately run and not be able to find the referenced DOM elements.
It works when I add a time-out on the code, but I would like to know a better way at achieving this.
Update
Modified to reflect the true intent of the question.

This is not possible in the manner which you've described, because the JavaScript is not bound to a condition to run, so it runs immediately.
The code inside the document you're receiving via AJAX should be wrapped inside a function by providing side:
function onDocumentReady()
{
// your code here
}
Then from the loading code:
// get the HTML and JavaScript in data
$('#container').append($(data));
// fire the function to let JavaScript run
onDocumentReady();
If you have multiple requests, the providing side should make the onDocumentReady function unique by adding random alphabets to the function name, e.g. onDocumentReady_123()

Wrap your code inside a $(document).ready. This will ensure that your JavaScript doesn't run until the DOM is loaded and the elements you're targeting will be available on the page:
$(document).ready(function() {
var ajaxUpload = new plupload.Uploader({
runtimes: 'gears, html5, flash',
url: 'upload.php',
browse_button: 'selectFile',
});
ajaxUpload.bind('Init',function(param){
console.log(param);
console.log($('selectFile'));
});
$('#uploadFile').click(function(){
alert('Something');
});
ajaxUpload.init();
});
For more information on how this works, see the documentation for jQuery ready. The site also has information on other useful jQuery commands that may be helpful, and I encourage you to check it out and try the examples that are there. Good luck!
UPDATE:
If I understand correctly, you're getting something like this HTML from the server:
<!-- Pulled HTML from the server using AJAX -->
<div id="uploadForm">
<div id="fileList">
</div>
[Select File]
[Start Upload]
</div>
And maybe trying to inject it dynamically into this:
<form action=""> <!-- inject HTML here --> </form>
If my understanding is correct, then this should allow you to inject the HTML and then only run the JavaScript once the AJAX request completes, and the new DOM has been injected. Keep in mind that, since I don't have all of your code, this is just a conceptual example:
$.ajax({ url:"/somepathtoGetData",
success: function(data) {
// your HTML is in the variable "data", and this injects the HTML into
// the form element on the page
$('form').html( data );
// now that the DOM elements are loaded from the AJAX request, do your
// other stuff with the uploader here
var ajaxUpload = new plupload.Uploader({
runtimes: 'gears, html5, flash',
url: 'upload.php',
browse_button: 'selectFile',
});
ajaxUpload.bind('Init',function(param){
console.log(param);
console.log($('#selectFile')); // added # for id attr
});
$('#uploadFile').click(function(){
alert('Something');
});
ajaxUpload.init();
}
});

UPDATE
Say I have two php files, one is main.php, having such codes: (not including jQuery src, please add your own)
<script type="text/javascript" charset="utf-8">
$(document).ready(function(){
$('#b').click(function(){
$.post("ajax.php",
{
taskaction: "getFormAndJs"
},
function(data){
$('body').append(data);
// $(document).trigger("ready");
},
"text");
})
});
</script>
<body>
aaaaaaaaaaaaa
<input type=button id="b" value="click" />
</body>
another is ajax.php, like this:
<?php
if ($_POST['taskaction'] == 'getFormAndJs') {
echo '
<div id="uploadForm">222</div> <input type=button id="a" value="upload" />
<script>
$("#a").click(function(){
alert(123);
})
</script>
';
}
?>
It seems work on my side (click button a and alert "123"), whether I add the
$(document).trigger("ready");
or not.
Does this look like your situation?

Related

ajax request on javascript not working

Here I create a form with iframe.
I want to save those data name and category using an ajax request.
Here's a google spreadsheet where I want to save those data https://docs.google.com/spreadsheets/d/1WXzTVsIAKsGvXgm4ivRzTPN2P8kupJDcnH5sHdc0Vhw/edit?usp=sharing
I'm using bookmarklet so this is a script of it.
when I do this nothing is done. No error and no console log? I don't get it? Please help me I'm new on this.
My code looks like this , this file is called script.js :
(function(){
var f = '<form action="" method="post"> Name: <input type="text" id="name" name="name">Category <select name="category" id="category"><option value="first">First</option><option value="second">Second</option><option value="third">Third</option></select><br><input type="submit"></form>';
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
iframe.contentWindow.document.open();
iframe.contentWindow.document.write(f);
iframe.contentWindow.document.close();
$("#submit").click(function(){
var name = $('#name').val();
var category = $('#category').val();
console.log("po ajax" , name , category);
$.ajax({
url: "https://docs.google.com/spreadsheets/d/1WXzTVsIAKsGvXgm4ivRzTPN2P8kupJDcnH5sHdc0Vhw/edit?usp=sharing",
data: { "name": name,"category": category},
type: "POST",
dataType: "xml",
statusCode: {
0: function () {
// window.location.replace("ThankYou.html");
console.log("error");
},
200: function () {
// window.location.replace("ThankYou.html");
console.log("ok");
}
}
});
});
})()
EDIT:
here is my index.html page where I defined my bookmarklet:
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<title></title>
</head>
<body>
<p> Bookmarklet</p>
</body>
</html>
You cannot bind event to element that is in iframe from parent page.
As you are adding your form in iframe, the javascript function for binding click event to submit button should be also in iframe.
And because you are using jquery, the Jquery reference should be also exists in iframe.
You are not making an ajax call, because your form is submitted the default way and therefore reloads the page before your js function. You need to prevent the form submission by changing $("#submit").click(function(){ to $("#submit").click(function(e){ e.preventDefault(); ...//continue with current code
$("#submit") wants an id to bind to so I suggest you rewrite <input type="submit"> to <input id="submit" type="submit">
Hmm. There are a whole lot of issues here.
the javascript code is separate from the iframe content. (This is the Sangram Parmar answer.)
I'd recommend getting rid of the iframe in test, and just add the <form> code block as raw html.
The jquery #submit identifier doesn't fit the situation. Personally, I'd add a <form id="form_id" ... term and then call it via $(#form_id)..click(function(e){... Oh, wait. This is the concern raised by P-A.
Good catch by Velimir Tchatchevsky on the prevent default behavior (but I do see action="" in the original code. I do think the prevent default behavior is a good practice.
Next we will start getting Cross-Origin Request (CORS) errors depending on which browser the user is using.
You can fix that by using jsonp instead of xml as the data type, but when you do that the error you will see is: Refused to execute script from 'https://docs.google.com/spreadsheets/d/1NTlfje4H-K3KyvBvUDqIA0z7pz_VQpijJV5…ery22304475027782793899_1462276071176&name=&category=first&_=1462276071177' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled. Sigh. Not sure what that is, yet...
Aha... I think this link will prove helpful. Look at the response by 'dev' and the links he has provided.

Form submition using AJAX is not working

Im tring to submit form to other page using ajax, but it doesn't send the post.
Javascript on top of page.
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script>
$(function(){
$(".button").click(function(){
event.preventDefault();
var name = $("#name").val();
var dataVar = "name=" + name;
$.ajax({
type: "POST",
url: "https://www.example.ee/index.php?e=area_sa&date=2010",
data: dataVar,
success: function() {
alert("works");
}
});
});
});
<script>
And HTML code:
<form>
<input type="text" name="name" id="name">
<input type="submit" name="submit" class="button" value="Add">
</form>
It's not working because you're trying to make a cross-domain AJAX request.
If you have a domain mywebsite.com, then all AJAX requests should be limited to this domain, e.g. mywebsite.com/example/ajax/request.
What you're trying to do (cross-domain request) is possible but involves a workaround that's a bit more complicated, and makes use of different library calls.
It seem that your click event is not bind to the .button,
That happen when the event is bind before the html element is loaded
few solutions :
1) encapsulate your JavaScript code inside an on-load event
2) place your JavaScript at the bottom of the page
3) use $(body).on('click', '.button' , function(){ /* your code here */})
also look like you posting to an external domain,
if you are the owner make sure you add the CORS policies.

TineMCE doesn't initiate ajax-loaded textarea

I use $.ajax() to load this piece of html into a div
<div class="board-container">
<form method="post" action="functions.php">
<input type="hidden" name="function" value="set_boards">
<div class="row-fluid">
<div class="span6">
<h3 class="dark">Student Board</h3>
<textarea id="board_students" name="board_students">
</textarea>
<br>
</div>
<div class="span6">
<h3 class="dark">Instructor Board</h3>
<textarea id="board_instructors" name="board_instructors">
</textarea>
<br>
</div>
</div>
Update Boards
</form>
</div>
<script src="libs/tinymce/tinymce.min.js"></script>
<script src="js/board.js"></script>
And in the board.js, there's simply a TinyMCE initiation function.
$(function()
{
tinymce.init({
menubar : false,
height: 700,
selector: "#board_students"
});
});
The ready() function should be called automatically due to ajax request. I've tested with alert and I know the function gets called.
The code works if the html is in the div by default, but when loaded through ajax, nothing happens. Why is that?
This happens because your ajax loads content asynchronously and your tiny initialization function happens synchronously, may be the initialization happens before the content is placed into your dom. The another thing is you shouldn't load scripts in html data .
To solve this
If you want to load script async means you have to create a script tag element using js like
var jsonp = document.createElement("script");
jsonp.type = "text/javascript";
jsonp.src = "libs/tinymce/tinymce.min.js";
document.getElementsByTagName("body")[0].appendChild(jsonp);
or You can include tinymce.min.js in page itself and initialize the div after the content is loaded like
$.ajax({
url: url,
type: type,
data: data,
success: function(htmlData){
$('#DivId').append(htmlData);
//here internalize tiny mice when its available in dom
tinymce.init({
menubar : false,
height: 700,
selector: "#board_students"
});
}
});
Try this and let me know if this works ... !!!
The reason this is happening is because, The ajax adds your content AFTER --page load--. Therefore, it's not reading and adding your code to the DOM, because you're adding this after the page is already loaded.
As many said, you can preload this info, or if you want to use AJAX.
The easiest way to initialize your code would be to add a .complete function at the end of your ajax call. This says that when the ajax function is done running, continue with this action.
$.ajax({
type: "POST", #GET/POST
url: "some.url",
data: {}
})
.complete(function() {
tinymce.init({
menubar : false,
height: 700,
selector: "#board_students"
}
});
Jquery Ajax Call
The <script> blocks in your case will start execute in the same moment asynchronous, and just because tinymce is the biggest script, tinymce.init will fail.
You need load the scripts as additional cascade of ajax call:
$.get(...., function (){// first level, getting the html
$.getScript(...., function (){// second level, getting <script src="libs/tinymce/tinymce.min.js"></script>
// executing or loading js/board.js
});
});

How do I use ajax to upload a text field and a file?

I'm new at AJAX and am working on an implementation of a form that will upload a name and a file to a php file that processes the data and sends it to a database for insertion using mysqli. I've tested the php file and it does work. My problem is in the AJAX code. I've tried an implementation using XMLHTTP and using jQuery. Both leave the page and open the PHP file in the browser. As a disclamer, I posted this question to another coding site, a fight ensued between two posters, and so I'm trying here to hopefully get a reasoned and calm response with productive suggestions.
I realize that currently "get" is being sent to the PHP file rather than "post", but PHPStorm tells me that "post" is not available in that form. What's my alternative? Am I on the right track or is there another direction I should go? How do I refresh only the form and keep the PHP page from loading?
Here's the relevant snippet of my code,
<!DOCTYPE html>
<html>
<head>
<script src="jquery.min.js"></script>
<script src="jquery.validate.js"></script>
<script>
$(document).ready(function() {
$('#addForm').validate({
submitHandler: function (form) {
$('input[name="usingAJAX"]', this).val('true');
var url = $(form).prop('action');
var dataToSend = $(form).serialize();
var callback = function(dataReceived) {
$(form).hide();
//result message
$('body').append(dataReceived)
};
var typeOfDataToReceive = 'html';
$.get(url, dataToSend, callback, typeOfDataToReceive),
return false;
}
});
});
</script>
</head>
<body>
<form id="addForm" action="addInfo.php" enctype="multipart/form-data">
<input type="hidden" name="usingAJAX" value="false"/>
<label for="aname">Name: </label>
<input type="text" name="aname" id="aname" class=required/>
<label for="aimage">Photo: </label>
<input id="aimage" type="file" name="aimage" class="required">
<input type="submit" value="ADD"/>
</form>
</body>
</html>
Until recently you could not upload files with ajax.
You still cannot upload the file directly with ajax, but you can do it programatically with HTML5 File API.
Still, if you are looking for simple solutions, try traditional IFrame approach.
If you want bleading edge technology, use File API. Here is some tutorial how to read files with javascript.
The steps to upload with ajax:
Read file with javascript FileReader API.
Post the content of the file, encoded to base64 or something, to the server.
Serverside, decode the contents of the file programatically.
When using this approach, the file will not be handled as a file upload by the server. It will be just another request field with text inside. It is up to you to decode it on the server side.
The filereader API allows you to read the file portion by portion and upload fragments of file, so it would be possible to upload huge files in chunks, but you need to handle it yourself.
Try using plugin jQuery form.js http://www.malsup.com/jquery/form/#file-upload You can upload files with ajax and jQuery. It is easy to use, just need to give #form-id in ajaxSubmit function.
<script>
$(document).ready(function() {
$('#addForm').validate({
submitHandler: function (form) {
$('input[name="usingAJAX"]', this).val('true');
var options = {
url : $(form).prop('action'),
dataToSend : $(form).serialize(),
callback : function(dataReceived) {
$(form).hide();
//result message
$('body').append(dataReceived) },
typeOfDataToReceive = 'html';
//your options here
};
$('#yourFormid').ajaxSubmit(options);
return false;
}
});
});
</script>

<script> not returned in AJAX

I am creating a WordPress theme and using AJAX to load new archive pages. The problem is that the whole < script type="text/javascript">//something//< /script> is not returned in the newly-acquired content.
Suppose I have these codes initially :
<div id="post-1">
<script type="text/javascript">
//some codes here//
</script>
<div class="content">
</div>
</div>
After navigating to the next page and back to this original page using AJAX, I will get these (in Firebug) instead :
<div id="post-1">
<div class="content">
</div>
</div>
The whole chunk of Javascript codes will not be returned, but under the 'Inline' script in 'Script' tab of Firebug, they are still there.
So, I'm wondering what have I done wrong in retrieving the new content using AJAX? Below is the code that I'm using :
jQuery('.ajax-pagination a').live('click', function(e){ //check when pagination link is clicked and stop its action.
e.preventDefault();
var link = jQuery(this).attr('href'); //Get the href attribute
jQuery.ajax({
url: link,
dataType: "text",
context: document.body,
beforeSend: function(){jQuery('#container').fadeOut(500)},
success: function(html) {
var newhtml = $('#container', $(html))
$('#container').html(newhtml);
$("container").find("script").each(function(i) {
eval($(this).text());
});
jQuery('#container').fadeIn(500);
},
error: function() {
alert('Error');
}
});
});
I am trying to run the Javacript loaded via AJAX, but the problem seems to be that the Javascript itself isn't even returned together with the rest of the content.
Thanks for reading such a long question and I really appreciate your help!
The .html() method strips <script> tags from inserted HTML.
You'll need to traverse the HTML before you try to insert it to find all of the script tags and then use jQuery.globalEval to execute their contents.
success: function(html) {
var newhtml = $('#container', $(html));
// execute included script tags - assumes inline for now
$('script', newhtml).each(function() {
$.globalEval($(this).text());
});
$('#container').html(newhtml).fadeIn(500);
}

Categories

Resources