views:

108

answers:

6

Hi.

How can i start javascript via ajax ?

html file

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>FusionCharts 3.0 Dashboard</title>
<script language="JavaScript" src="../FusionCharts.js"></script>
<script language="JavaScript" src="../PowerMap.js"></script>
<script type="text/javascript">
function loadXMLDoc()
{
    if (window.XMLHttpRequest)
    {
         xmlhttp=new XMLHttpRequest();
    }
    else
    {
         xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange=function()
    {
        if (xmlhttp.readyState==4 && xmlhttp.status==200)
        {
            document.getElementById("ajax").innerHTML=xmlhttp.responseText;
        }
    }
    xmlhttp.open("POST","test.php",true);
    xmlhttp.send();
}
</script>
</head>
<body>
<div id="chart3" align="center"></div><br />
<div id="ajax"></div>
<input type="button" onclick="loadXMLDoc()" value="test" />    
</body>
</html>

php file

<?
$html = '<script type="text/javascript">
window.onload = function start() {
    onClick();
}

function onClick() {
var myChart = new FusionCharts("../Charts/HLinearGauge.swf", "chart3", "580", "80", "0", "0");
myChart.setDataXML("<chart bgColor=\'FBFBFB\' bgAlpha=\'100\' showBorder=\'0\' chartTopMargin=\'0\' chartBottomMargin=\'0\'\n\
upperLimit=\'30\' lowerLimit=\'0\' ticksBelowGauge=\'1\' tickMarkDistance=\'3\' valuePadding=\'-2\' pointerRadius=\'5\'\n\
majorTMColor=\'000000\' majorTMNumber=\'3\' minorTMNumber=\'4\' minorTMHeight=\'4\' majorTMHeight=\'8\' showShadow=\'0\'\n\
pointerBgColor=\'FFFFFF\' pointerBorderColor=\'000000\' gaugeBorderThickness=\'3\'\n\     baseFontColor=\'000000\'\n\
gaugeFillMix=\'{color},{FFFFFF}\' gaugeFillRatio=\'50,50\'>\n\
<colorRange>\n\
    <color minValue=\'0\' maxValue=\'5\' code=\'FF654F\' label=\'z\'/>\n\
    <color minValue=\'5\' maxValue=\'15\' code=\'F6BD0F\' label=\'x\'/>\n\
</colorRange>\n\
</chart>");
myChart.render("chart3");
}
</script> ';

echo $html;

?>
A: 

Using Javascript frameworks make things really easy. For example, if you use jQuery, you can do what you want this way:

$.getScript("test.php");

It gives you some advantages... for instance, you won't have to worry about problems with memory leaks in IE. It will work on most of the web browsers and it will make your code easier to read.

Cristian
A: 

You probably have to call the function you want, i.e. onClick, manually after setting the innerHTML.

Karl Bielefeldt
+2  A: 

For a start, you're defining a window.onload event AFTER the page has loaded - by the time the user clicks the button, that event will have been fired long ago

If you're using jQuery, change the window.onload = function start() to $(document).ready(function(), then add a ");" at the end of the function.

For Prototype, use document.observe("dom:loaded", function()

Though it'd probably make more sense to just call the function, or even just remove the function and execute the statements straight

As for the JS not executing - I've experienced that niggle before, it's because innerHTML doesn't run any JS that's inserted. If you're using jQuery, try $('ajax').append(xmlhttp.responseText), or Element.insert($('ajax'), xmlhttp.responseText) for Prototype.

Though judging by the fact you've implemented the AJAX call yourself, you're probably not using any libraries. In that case, it'd be easier to make your PHP file return just the JS without the tags, then just eval(xmlhttp.responseText)

If you don't want to do that, then you'll need to loop through all of the script tags in the response X(HT)ML and eval their contents 'manually'

Brian E
A: 

All of that javascript you have in the PHP file, you need to put that into the html file. Well, that's the way I'd do it at least. Otherwise, you'll have to use jQuery's live() function to call those javascript functions you have in the PHP file.

For instance, your script tag in the html file should look like this

<script type="text/javascript">
function Function4PHPHTML() {
var myChart = new FusionCharts("../Charts/HLinearGauge.swf", "chart3", "580", "80", "0", "0");
myChart.setDataXML("<chart bgColor='FBFBFB' bgAlpha='100' showBorder='0' chartTopMargin='0' chartBottomMargin='0'\n
upperLimit='30' lowerLimit='0' ticksBelowGauge='1' tickMarkDistance='3' valuePadding='-2' pointerRadius='5'\n
majorTMColor='000000' majorTMNumber='3' minorTMNumber='4' minorTMHeight='4' majorTMHeight='8' showShadow='0'\n
pointerBgColor='FFFFFF' pointerBorderColor='000000' gaugeBorderThickness='3'\n    baseFontColor='000000'\n
gaugeFillMix='{color},{FFFFFF}' gaugeFillRatio='50,50'>\n
<colorRange>\n
    <color minValue='0' maxValue='5' code='FF654F' label='z'/>\n
    <color minValue='5' maxValue='15' code='F6BD0F' label='x'/>\n
</colorRange>\n
</chart>");
myChart.render("chart3");
}
function loadXMLDoc()
{
    if (window.XMLHttpRequest)
    {
         xmlhttp=new XMLHttpRequest();
    }
    else
    {
         xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange=function()
    {
        if (xmlhttp.readyState==4 && xmlhttp.status==200)
        {
            document.getElementById("ajax").innerHTML=xmlhttp.responseText;
        }
    }
    xmlhttp.open("POST","test.php",true);
    xmlhttp.send();
}
</script>

Then, you have the AJAX, retrieve only HTML from that PHP file.. So that after you click that DIV and populate whatever, you already have the existing Javascript ready for the new html.

Zane Edward Dockery
A: 

Try to use jquery.live()

Tuong Le
A: 

The only way to do this is by, through some way or another, eval()ing the script that you're loading in via AJAX, in the AJAX call. Scripts are normally only evaluated if they're there on pageload, and new content loaded in via the DOM/AJAX isn't evaluated for scripts (for one thing, onload() fired a long time ago) so you have to manually call any scripts you're AJAXing in.

As has been mentioned above, frameworks make this easier - the evalScripts flag in Prototype, or just the evalScripts function, are really nice for this in my experience, and jQuery's live() or getScript are also an option.

If you're not using a framework, you'll have to do it manually, by calling eval() on the script that you're trying to load via AJAX. So your code would look something like this:

xmlhttp.onreadystatechange=function()
{
    if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
        document.getElementById("ajax").innerHTML=xmlhttp.responseText;
        eval(xmlhttp.responseText);

    }
}

You may not even need to set the innerHTML if the Javascript is all you're using it for. A caution: using eval() should as a rule make you wary due to the possibility of injection attacks. The frameworks above do some sanitizing and safety checks to more safely execute the scripts, but it's still a risky proposition.

If you can, you should consider rewriting your code to have the AJAX return JSON or some other data structure, and move the actual javascript into the recieve function (where I inserted the eval() above), to avoid such risks. In your code, depending on why you need to have the Javascript in the other file, you could probably easily pass the parameters you're generating the script for in a JSON array, and call the new FusionCharts() and mychart.render() within your AJAX call. That would look something like this:

xmlhttp.onreadystatechange=function()
{
    if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
        document.getElementById("ajax").innerHTML=xmlhttp.responseText;
        cd = JSON.parse(xmlhttp.responseText);
        var myChart = new FusionCharts(cd.chartPath, cd.chartID, cd.chartWidth, cd.chartHeight, 0, 0);
        myChart.setDataXML(cd.dataXML);
        myChart.render(cd.chartID);
    }
}

With your AJAX returned being:

{
  chartPath: "../Charts/HLinearGauge.swf",
  chartID: "chart3",
  chartWidth: "580",
  chartHeight: "80",
  dataXML: "<chart bgColor=\'FBFBFB\' bgAlpha=\'100\' showBorder=\'0\' chartTopMargin=\'0\' chartBottomMargin=\'0\'\n\ upperLimit=\'30\' lowerLimit=\'0\' ticksBelowGauge=\'1\' tickMarkDistance=\'3\' valuePadding=\'-2\' pointerRadius=\'5\'\n\ majorTMColor=\'000000\' majorTMNumber=\'3\' minorTMNumber=\'4\' minorTMHeight=\'4\' majorTMHeight=\'8\' showShadow=\'0\'\n\ pointerBgColor=\'FFFFFF\' pointerBorderColor=\'000000\' gaugeBorderThickness=\'3\'\n\     baseFontColor=\'000000\'\n\ gaugeFillMix=\'{color},{FFFFFF}\' gaugeFillRatio=\'50,50\'>\n\ <colorRange>\n\     <color minValue=\'0\' maxValue=\'5\' code=\'FF654F\' label=\'z\'/>\n\     <color minValue=\'5\' maxValue=\'15\' code=\'F6BD0F\' label=\'x\'/>\n\ </colorRange>\n\ </chart>"
}
cincodenada