Forcing Script To Run In AJAX Loaded Page - javascript

So I am using an AJAX loader on my WP installation and one of the pages I am loading has a script in it.
<div id="register-form">
<div id="register-one"></div>
<div style="text-align:center;padding-top:10px;"></div>
<div class="horizontal-rule"></div>
<div id='register'>
<div id="register-character">
</div>
</div>
<div class="post">
<form action="" method="post" id="register-form" >
What's your Name:
<input class=in id='register_name' name="register_name" onkeydown='register_step1_keydown();' onkeyup='register_step1_keyup();'>
<input class="next-submit-button" type="submit" id="register-step-one" value="" />
<input type="hidden" name="submit" />
</form>
</div>
</div>
<script type="text/javascript">
$("#register-step-one").click(function() {
$.ajax({
type: "POST",
success: function() {
$('#register-form').html("Test");
}
});
return false;
});
</script>
The issue is however, when the page is loaded through the AJAX, the script doesn't work. Yet if I refresh the page the script works. Obviously the script doesn't like running from an AJAX call.
Is there a way to make the script work when it is loaded through an AJAX call? I know I could put the script in to the main page's footer or something but I was hoping I could get around this as I will end up with a ton of scripts in the main page.

Before anything else, you should wrap your function in a .ready() to ensure all DOM elements are loaded before you do something to those elements
Also, scripts within HTML that are returned via ajax functions in jQuery are executed only when the HTML is appended in the DOM. Since you did not append the html containing the code, the script in that returned content won't run.
Take a look at the .ajax() function's parameters, under dataType
dataType:
...
"html": Returns HTML as plain text; included script tags are evaluated when inserted in the DOM.
...

Related

capture submit event with dynamically added content with JavaScript

I am building a sort of page builder where the user can add blocks to the page and then save the layout. I have encountered a problem that I can't seem to figure out. I have a form that is dynamically added to the page with JavaScript containing a file input as so:
<form class="upload " action="" method="post">
<input id="" type="file" class="fill" name="upload">
<img src="/admin/img/default.png" alt="">
</form>
After adding the content I call the following function to add event listeners. $el corresponds to the file input.
function changeListen($el){
$el.addEventListener('change', function(){
$el.parentElement.submit();
});
$el.parentElement.addEventListener('submit', function(e){
e.preventDefault;
// call Ajax request...
});
}
I want to be able to update the database with an Ajax request when an image is selected, therefore I submit the form within the change event, so far so good, but for some reason the submit event is not taken into account and the page reloads. Any solutions or workaround appreciated, preferably not jQuery.
By using onsubmit event in HTML, you can call javascript function this way and do ajax calls.
Javascript sample
<script>
function doSomething() {
alert('Hello, World');
return false;
}
</script>
HTML Sample
<form onsubmit="return doSomething();">
<input type="submit" value="Submit" />
</form>
EDIT: return false in javascript so ? does not appear in URI after clicked

jQuery document.ready() not firing for dynamically loaded content

I've got a PHP file (called aboutMe.php) that contains some HTML as follows:
<script type="text/javascript" src="/aboutMe.js"></script>
<div id="aboutme-gender" class="aboutme-block">
<div class="aboutme-question">My gender is:</div>
<div class="aboutme-error">Please select your gender.</div>
<div class="aboutme-answer">
<input id="gender-male" name="the-gender" type="radio" value="1" />
<label for="gender-male">Male</label>
<input id="gender-female" name="the-gender" type="radio" value="2" />
<label for="gender-female">Female</label>
</div>
</div>
The aboutme.js file contains a function as follows:
jQuery(document).ready(function($) {.....does stuff to the tags in the HTML});
This all works fine if the page is loaded directly. However when another page wants to load this dynamically as follows:
$("#load-aboutme-here").load("aboutMe.php");
...the document.ready() event doesn't fire and things don't get tagged.
I've seen similar posts but can't quite get what I need from them. Have done things like substitute the document.ready() for window.load() but then it doesn't even work at all when the aboutMe.php page is loaded directly.
Any ideas much appreciated - this is driving me nuts although I suspect it's an easy fix!
Thanks
Iain
Note that the document is the main page...not subsequent files you retrieve
The document was ready long before the ajax is done so any $(document).ready() that is called after it is ready will fire immediately. In your case it will fire before the elements exist
Move the script tag below the html that the code is referencing
<div id="aboutme-gender" class="aboutme-block">
.......
</div>
<script type="text/javascript" src="/aboutMe.js"></script>
If I understood your problem correctly, I believe you could just create a callback for the .load() function like so:
$("#load-aboutme-here").load("aboutMe.php", null, function()
{
// Code to be executed when aboutMe.php is loaded.
// i.e. The code in aboutMe.js
});

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
});
});

cannot run JavaScript function from XSL

I have a form element in an XSL file. I want to have a JavaScript function in the same XSL file to enable the Submit button on checking a check box.
Here is the form -
<form action="NewUserNavigation" method="post" name="NewUserNavigationForm">
<input name="eventName" type="hidden" value="NewUserNavigationEvent"/>
<div class="sansIcon">
<input type="checkbox" name="chk" onClick="EnableSubmit()"><xsl:apply-templates select="content[#name='chkbox']" mode="impl_expandContent"/></input>
</div>
<div class="buttonBarPage">
<input name="Submit" class="primary" type="submit" value="Continue" disabled="true"/>
</div>
</form>
Here is the XML conetent that it is reading -
<content name = "chkbox">
Yes, I understand and agree to the T&C.
</content>
I am facing problem with the javascript, it gives error. I have put an alert to check if the function is being called on click of the checkbox.
here is the code I am using -
<script type="text/javascript">
function EnableSubmit()
{
alert("test");
if(document.NewUserNavigationForm.chk.checked==true)
{
document.NewUserNavigationForm.Submit.disabled=false;
}
if(document.NewUserNavigationForm.chk.checked==false)
{
document.NewUserNavigationForm.Submit.enabled=false;
}
}
</script>
I get this error....
org.xml.sax.SAXParseException: illegal top-level element
The end tag should be </script> rather than <script>.
By the way, did you know that with Saxon-CE you can do this without any Javascript? You can then write template rules in the stylesheet that respond to user input (such as button clicks) and modify the HTML DOM in arbitrary ways, without having to use the Javascript DOM API.
The javascript function needs to wrapped in a CDATA tag, as it is not valid XML. Anything that you wrap in CDATA will be output exactly as is to the file you are writing (ie, the html). So:
<script type="text/javascript"><![CDATA[
function EnableSubmit()
{
alert("test");
if(document.NewUserNavigationForm.chk.checked==true)
{
document.NewUserNavigationForm.Submit.disabled=false;
}
if(document.NewUserNavigationForm.chk.checked==false)
{
document.NewUserNavigationForm.Submit.enabled=false;
}
}
]]><script>

deferring JavaScript execution in document received via AJAX

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?

Categories

Resources