I have a problem calling a Javascript function that was inserted into a <div> via the innerHTML property. I have searched through similar threads in SO, but I wasn't able to find a solution to this problem.
In a simplified version, here is what I have:
MainPage.php
// ... Basic Headers
<div id = 'list'>
{include file="list.tpl"}
</div>
// More stuff...
<script type="text/javascript">
function callbackFunction(data) {
$('list').innerHTML = data.updatedListHTML;
updateCalculatedFields();
}
// Perform a Ajax POST Request with the callbackFunction()
</script>
List.tpl
{if $thereIsData}
// Create a table, populate its content...
<script type="text/javascript">
function updateCalculatedFields() {
// Change some of the values in the created table...
}
</script>
{/if}
With the code above, I get a ReferenceError in the callbackFunction(data) while trying to call the updateCalculatedFields() function. I have double-checked to see that the innerHTML has been properly updated;, the updateCalculatedFields() function (and the whole script tag) has been added to the div. However, Javascript cannot seem to find injected function.
With a small change, the functionality works. If the list.tpl were to be changed to:
List.tpl (version 2)
{if $thereIsData}
// Create a table, populate its content...
{/if}
<script type="text/javascript">
function updateCalculatedFields() {
// Change some of the values in the created table...
}
</script>
The different between the two scenarios is that in the second one, the updateCalculatedFields() function is loaded with the page right from the start. In the first one, it gets added later with the innerHTML. So, my conclusion is that Javascript will not register functions that get added via innerHTML. I highly doubt that this is the case though; so it would be great if someone could give an explanation on this issue.
JavaScript is not evaluated when inserted with innerHTML. You either need to eval() it yourself or append a new external script tag to the page.
Related
I have a PHP Function that I would like to integrate into my (existing) web page. Further, I would like it to execute when the user clicks a link on the page. The function needs to accept the text of the link as an input argument.
Everything I've researched for sending data to a PHP script seems to involve using forms to obtain user input. The page needs to accept no user input, just send the link-text to the function and execute that function.
So I guess the question is two-part. First, how to execute a PHP script on link click. And second, how to pass page information to this function without the use of forms. I am open to the use of other technologies such as AJAX or JavaScript if necessary.
EDIT:: Specifically what I am trying to do. I have an HTML output representing documentation of some source code. On this output is a series of links (referring to code constructs in the source code) that, upon being clicked, will call some python function installed on the web server (which leads me to think it needs called via PHP). The python function, however, needs the name present on the link as an input argument.
Is there some sort of interaction I could achieve by having JavaScript gather the input and call the PHP function?
Sorry for the vagueness, I am INCREDIBLY new to web development. If anything is unclear let me know.
You'll need to have a JS function which is triggered by an onclick event which then sends an AJAX request and returns false (so it won't be redirected to a new page in the browser). You can do the following in jQuery:
jQuery:
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript">
function doSomething() {
$.get("myfile.php");
return false;
}
</script>
And in your page body:
Click Me!
In myfile.php:
You can add whatever function you want to execute when the visitor clicks the link. Example:
<?php
echo "Hey, this is some text!";
?>
That's a basic example. I hope this helps.
You will need to use AJAX to accomplish this without leaving the page. Here is an example using jQuery and AJAX (this assumes you have already included the jQuery library):
First File:
<script language="javascript">
$(function(){
$('#mylink').click(function(){
$.get('/ajax/someurl', {linkText: $(this).text()}, function(resp){
// handle response here
}, 'json');
});
});
</script>
This text will be passed along
PHP File:
$text = $_REQUEST['linkText'];
// do something with $text here
If you are familiar with jQuery, you could do the following, if you don't want the site to redirect but execute your function:
in your html head:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
the link:
Execute function
in ajax.php you put in your function to be executed.
Maybe something like this:
....
<script>
function sendText(e)
{
$.ajax({
url: '/your/url/',
data: {text: $(e).html()},
type: 'POST'
});
}
</script>
You can use query strings for this. For example if you link to this page:
example.php?text=hello
(Instead of putting a direct link, you can also send a ajax GET request to that URL)
Inside example.php, you can get the value 'hello' like this:
<?php
$text = $_GET['hello'];
Then call your function:
myfunction($text);
Please make sure you sanitize and validate the value before passing it to the function. Depending on what you're doing inside that function, the outcome could be fatal!
This links might help:
http://net.tutsplus.com/tutorials/php/sanitize-and-validate-data-with-php-filters/
http://phpmaster.com/input-validation-using-filter-functions/
Here's an overly simplistic example of what you're trying to do..
Your link:
Some Action
Your PHP file:
<?php
if (isset($_GET['action']))
{
// make sure to validate your input here!
some_function($_GET['action']);
}
PHP is a server side language i.e. it doesn't run in the web browser.
If you want a function in the browser to operate on clicking a link you are probably talking about doing some Javascript.
You can use the Javascript to find the text value contained in the link node and send that to the server, then have your PHP script process it.
For a website I'm making for school, I'm trying my hand at using Jquery extensively for the first time, and even though I managed quite a bit so far, I'm stuck at two (most likely related) problems.
I'm aware that the upcoming case is somewhat long, but I feel it's necessary to submit all relevant code for everyone reading this to get a good image of what is happening.
Basically, the website is one index.html file, with the CSS thrown in, a few buttons, and one div with the ID content. I use this code to make this work:
<script type="text/javascript">
if ($('#content').innerHTML == " "){
$(document).ready(function(){
$('#content').load('main_text.html');
});
}
</script>
<script type="text/javascript">
function loadContent(elementSelector, sourceURL) {
$(""+elementSelector+"").load(""+sourceURL+"");
}
</script>
Then there is one content page, named search.html, which only contains a form that submits a search string to a search.php page (through ajax) that should then place the search results immediately back into a div called search_results in that same search.html file. The jquery that I use for this:
<script type='text/javascript'>
$(document).ready(function(){
$("#search_results").slideUp();
$("#search_button").click(function(e){
e.preventDefault();
ajax_search();
});
$("#search_term").keyup(function(e){
e.preventDefault();
ajax_search();
});
});
function ajax_search(){
$("#search_results").show();
var search_val=$("#search_term").val();
$.post("Functions/search.php", {search_term : search_val}, function(data){
if (data.length>0){
$("#search_results").html(data);
}
})
}
</script>
The issue that I'm having is as followed:
Before I had the first line of code: if ($('#content').innerHTML == " "){; implemented, I would open the site, main_text.html would nicely be loaded in, I could navigate to other subpages fine. But typing in something in the form field in search.html did not display any results (just typing should already trigger the function). When I hit the search button on this form, instead of seeing query results, the main_text.html file load again in the #content div. This made me assume that perhaps, somehow, that the code:
$(document).ready(function(){
$('#content').load('main_text.html');
});
was being called again unwanted. Hency why I implemented that check for whether innerHTML existed.
However, now, when I first load the page, the #content div does not load any initial content at all. (The section on the webpage just becomes black, like my page background) I have to click any button to get some content loaded again in my main content div. Also, when I now go back to the search.html, the typing anything to get results, like previously, still does not work. If I now hit the search button, I get the initial result again of what I'd see when I just opened the page: a blacked out #content div.
So somehow, the biggest issue is in the fact that the jquery to get results from my PHP do not seem to work. My problem with the content.innerhtml check might well be obsolete if the issue with the searchresults not displaying in the #search_result div on the search.html is fixed.
Anyone have any idea's what I could do to fix this. Or otherwise, what other approaches I could take for the kind of website I'm making. Since I'm trying to learn jquery here, better approaches are always appreciated, I'd rather learn myself doing this the right way and all. :)
Thanks for your time.
Few things to note here:
<script type="text/javascript">
if ($('#content').innerHTML == " "){
$(document).ready(function(){
$('#content').load('main_text.html');
});
}
</script>
<script type="text/javascript">
function loadContent(elementSelector, sourceURL) {
$(""+elementSelector+"").load(""+sourceURL+"");
}
</script>
In the above, you are testing to see if there is a space in the innerHTML of the element with an id of content.
jQuery uses .html() or .text() to make comparisons against the data being held within a container, so if you want to maintain using jQuery principles, change this line. Going along the same thought process, you are preparing an IF statement on an element before the document is actually ready and loaded.
You should move the document.ready function to the outside of the if statement. This will allow you to ensure that the element is available at DOM, and you can indeed perform checks against this element.
<script type="text/javascript">
$(document).ready(function(){
if ($('#content').html("")){
$('#content').load('main_text.html');
}
});
</script>
Also, while being readily provided and fully functional, I would recommend starting off using $.ajax instead of $.get / $.post. I have personal preferences as to why I think this, but I won't go into that, it's just that, personal.
$.ajax({
url: "Functions/search.php",
type: 'POST',
data: "search_term="+search_val,
success: function(data){
if (data.length>0){
$("#search_results").html(data);
}
});
Lastly, you should be using the GET method and NOT the POST method. Based on REST/SOAP practices, you are retrieving data from the server, and not posting data to the server. It's best practice to follow those two simple ideas. This isn't because web servers will have a difficult time interpreting the data; but, instead, it's to prepare you for working on larger scale application deployment, or future team-environments. This way everyone on the team has an expectation as to what method will be used for what purpose.
Anyway, long story short, you also leave semicolons off of the end of your closing }) brackets. While this is not an issue, nor will it cause flaws in your development, coding is all about uniformity. You've used the closing ; everywhere else, so try and maintain that same uniform design.
Best of luck.
We allow users to place a
<script language="javascript" src="oursite/script.php"></script>
tag on their page which should then embed some content from our site into their site. Currently script.php contains document.write("some content loaded from the database"), however there are some limitations.
Is there anyway I can have the same thing achieved using jQuery ? How do i tell jQuery to put a certain piece of HTML code EXACTLY where the script tag is ? document.write() can do this, but i'm not sure how to do this using jquery. (we are already providing the jquery js code to the client through script.php.
You don't need jQuery to do a document.write(). As long as it is executed inline (ie, not in an event handler such as $(document).ready()), it will work. Just make sure you escape the end script tag (like this: <\/script>), so that the HTML parser doesn't mistake it for an actual end script tag:
<script type="text/javascript">
document.write("<script language=\"javascript\" " +
"src=\"oursite/script.php\"><\/script>");
</script>
Alternatively, you could add the script using DOM manipulations. If you want to add the script after the page has loaded, this is your only option. To position it after the script tag that is calling it, give your script tag an id and use $("#myScript").after("<script>"):
<script type="text/javascript" id="myScript">
$(function () {
$("#myScript").after("<script>").attr({
language: "javascript",
src: "oursite/script.php"
});
});
</script>
You don't necessarily need to use jQuery, but you can.
The basic problem here is finding the script node as the page is loading.
You can give it an id and hope there are no duplicate ids on the other user's page.
But if you know the script will be evaluated as the page is loading, you can also do this:
(function(){ // this is just so you don't run into name collisions with the user's page
// Get all script elements
var scripts = document.getElementsByTagName('script');
// we know the last script element will be *this* one
var script = scripts[scripts.length-1];
var newp = document.createElement('p');
newp.textContent = 'inserted paragraph';
// now insert our new nodes after the current script
script.parentNode.insertBefore(newp, script.nextSibling);
})();
You can of course use jQuery as well with var $script = $('script:last');, but if you don't need it for anything else you can save some loading time by not using it.
jQuery(document).ready(function(){
jQuery(".test").click(function() {
alert(1);
});
});
When I try not to put :
jQuery(".test").click(function() {
alert(1);
});
inside a jQuery(document).ready() it won't work.
What do you think is the cause of that one? I already loaded the custom script that has that function.
<script type="text/javascript" src="/scripts/js/jquery.js"></script>
<script type="text/javascript" src="/scripts/js/customScript.js"></script>
Any answer would be appreciated and rewarded.
Thanks!
If you're loading it in <head>, then your .test hasn't loaded yet at the time when your code executes. Thus, jQuery(".test") returns [], so the click event gets attached to nothing. If you move your <script> to the last thing in <body>, it should work.
The behaviour you are seeing is normal and correct.
When you say:
jQuery(".test").click(function() {
alert(1);
});
It means "find all elements that exist right now with the class 'test' and assign a click handler to those elements". If you put such code outside the document ready then the browser will not have parsed any HTML that is after that bit of script so it will not find any elements defined further down the page - they don't exist in the DOM yet.
Putting the code inside document.ready (or in an onload event handler) means that it won't be run until the whole page has been parsed, at which point all elements will exist and can be accessed from your code. (It should also work if you put it right at the bottom of the page after all the HTML.)
For the purpose of testing (and making this question simpler) I have been using xajax to output a random number into a DIV on the page.
$output=rand(20,40);
$ajax_resp->assign('container','innerHTML', $output);
After the DIV container is loaded, I also load 1 line of Javascript to call the xajax function.
<div id="container"></div>
<script type="text/javascript">
xajax_refresh().periodical(2000);
</script>
As you can see, I'm using the MooTools function called periodical() to call the function again after x milleseconds. It calls the function fine at first, but not again.
It doesn't automatically refresh. Why?
You are not assigning a periodical to xajax_refresh function, you are calling that function (with xajax_refresh()). For instance, you're assigning its returned value to periodical (It can be everything, but nothing happens because that returned value is not a function :) ).
Therefore, the solution is this:
<script type="text/javascript">
xajax_refresh.periodical(2000);
</script>