How to make ajax call from drupal pager - ajax

i'm new to drupal and using drupal6.. i have a module which fetches a set of employee details from database based on input fields.The submit button calls a JavaScript function in an emp.js file which generates an ajax call
xmlHttpReq.open('GET', "/empfinder.json&dept=" + dept + "&gender=" + gen+ "&age=" + age, true);
while i'm trying to use pager it directly make call as below and displays in a new page.
http://156.23.12.14/empfinder.json?page=1&dept=ACC&gender=Male&age=34
i need to display the results in same page. How should modify pager call to do this?

You should make your life easier by using the jquery utility functions when doing AJAX requests instead of doing them 'by yourself'. The jquery library is included in Drupal core (at least for Drupal 6). As for documentation, you could start with this post on Ajax in Drupal using jQuery.

I did a blog on this subject JS with AJAX and PHP and have pasted it below.
JS with AJAX and PHP
Drupal has extensive support for JS and AJAX as part of its standard forms and there are tutorials that explain how this works. However, I could not find a good tutorial to explain how Javascript can communicate with a Drupal module in an ad-hoc fashion. For instance, I wanted to be able to modify any arbitrary html based on state information available in the PHP. This technique is presented below.
You will see at the top of this page are tabs that by default in this theme are rather plain. I wanted to modify them such that the currently selected tab would stand out more. Of course, this could be done with just CSS but I wanted to develop this technique for cases where CSS alone would not be enough.
Below is the JS that can be added directly to the JS file described previously. There is a jQuery function that operates on the element with id 'main-menu-links' each time the page has been loaded and is ready. I get the innerHTML and use encodeURIComponent to convert it to a safe string that can be passed as a URL parameter. I had to do this because one of the tabs references a URL that passes a parameter.
var xmlhttp;
var childnodes;
// Send post to specified url
function loadXMLDoc(url,cfunc)
{
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=cfunc;
// alert("loadXMLDoc: " + url);
xmlhttp.open("POST",url,true);
xmlhttp.send();
}
// AJAX redirect to camr_custom/getvisits with callback function to replace the href
// with something to disable the link for nodes that have not been visited.
function getMenuTabs(str)
{
loadXMLDoc("?q=flashum_status/get_menu_tabs&block="+str,function()
{
// alert("getMenuTabs status: " + xmlhttp.status + " readyState: " + xmlhttp.readyState);
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
// alert("getMenuTabs: " + xmlhttp.responseText);
data= jQuery.parseJSON('['+xmlhttp.responseText+']')
$.each(data,function(){
// alert(this['block']);
document.getElementById("main-menu-links").innerHTML = this['block'];
});
}
});
}
// Locate book navigation block and send innerHTML to PHP module
$('#main-menu-links').ready(function() {
lis = document.getElementById("main-menu-links").innerHTML;
// alert("main-menu-links: " + lis);
// safe encode this block so that it can contain arbitrary urls in the href links
lis = encodeURIComponent(lis);
getMenuTabs(lis);
});
The jQuery function ends up calling loadXMLDoc which is where the AJAX post takes place specifying the URL that is captured by the hook_menu in the Drupal module. It also uses a callback function that is passed in the parameter cfunc. Upon return, the JSON response is parsed to convert it to HTML and this is stored directly back to the original innerHTML. Thus, whatever the PHP module did to the HTML replaces the original HTML.
On the PHP side there is first the array element of the hook_menu:
$items['flashum_status/get_menu_tabs'] = array(
'page callback' => 'get_menu_tabs',
'access arguments' => array('access flashum status'),
'type' => MENU_CALLBACK,
);
The callback function is then shown below. It first pulls out the block parameter and loads it into a DOM object so that it can be parsed. The simple_html_dom object is supplied by the simplehtmldom module, that you will need to install and enable. Don't forget to install the associated library as well. This should end up in /all/libraries/simplehtmldom/simple_html_dom.php.
function get_menu_tabs() {
// drupal_set_message(t("get_menu_tabs: #code", array('#code' => print_r(null, TRUE))));
if (array_key_exists ('block', $_GET)) {
$block = $_GET['block'];
// drupal_set_message(t("get_menu_tabs block: #code", array('#code' => print_r($block, TRUE))));
// Create a DOM object.
$html_obj = new simple_html_dom();
// Load HTML from a string.
$html_obj->load($block);
// remove href for nodes not yet visited
$index = 0;
foreach ($html_obj->find('li') as $li ) {
$start = strpos($li->innertext, 'href');
$end = strpos($li->innertext, '>', $start);
$start_html = substr($li->innertext, 0, $end);
$end_html = substr($li->innertext, $end);
if (strpos($li->innertext, 'active')) {
$li->innertext = $start_html.' style="color:red;border: solid red;margin-left:5px;margin-right:5px;"'.$end_html;
// drupal_set_message(t("get_menu_tabs html_obj: #code", array('#code' => print_r($li->innertext, TRUE))));
}
else
$li->innertext = $start_html.' style="color:black;border: solid #777;"'.$end_html;
$index++;
}
$str = $html_obj->save();
// drupal_set_message(t("get_menu_tabs str: #code", array('#code' => print_r($str, TRUE))));
// Release resources to avoid memory leak in some versions.
$html_obj->clear();
unset($html_obj);
return drupal_json_output(array('block'=>$str));
}
}
Finally, it loops through the li items adding an inline CSS style that changes depending on whether the tab is active or not. Then it just creates a string from the DOM object and returns it via drupal_json_output, which converts it to JSON format. This of course is received in the JS callback function.

Related

HighChart not working when called by ajax

Hi guys i have a page which is working perfectly it contains a highchart. I want to show this page on the existing page through an ajax call. My ajax is working perfectly but the highcharts are not displaying when i make ajax call.
link of my highchart is
http://www.rahatcottage.com/AI/J/examples/line-log-axis/index.php
And My ajax script goes here
var xmlhtt
function load(str,str1)
{
xmlhtt=GetXmlHttpObject();
if (xmlhtt==null)
{
alert ("Your browser does not support Ajax HTTP");
return;
}
var url="examples/line-log-axis/index.php";
url=url+"?q="+str;
url=url+"&q1="+str1;
xmlhtt.onreadystatechange=getOutpt;
xmlhtt.open("GET",url,true);
xmlhtt.send(null);
}
function getOutpt()
{
if (xmlhtt.readyState==3||xmlhtt.readyState==2||xmlhtt.readyState==1|
|xmlhtt.readyState==0)
{
document.getElementById("apDiv1").innerHTML="Loading ";
}
if (xmlhtt.readyState==4)
{
document.getElementById("apDiv1").innerHTML=xmlhtt.responseText;
document.getElementById("apDiv1").focus();
}
}
function GetXmlHttpObject()
{
if (window.XMLHttpRequest)
{
return new XMLHttpRequest();
}
if (window.ActiveXObject)
{
return new ActiveXObject("Microsoft.XMLHTTP");
}
return null;
}
I guess because highgraphs are using Jquery thats y ajax is not running them
EDITED
So what you are doing is, that you have a working chart page, and through ajax you wish to load that page into a div of another page. I don't think that will be possible, you can just do that, especially if that page has javascripts, what you are doing is just getting the generated html of the working chart page, and pasting it inside the div, this won't run the necessary javascripts for the chart generation.
Try using an iframe instead.
HTML
<iframe id="frame" />
SCRIPT
function load(str,str1)
{
$('#frame').attr('src', "examples/line-log-axis/index.php?q="+str+"&q1="+str1);
}
**OLD**
series: [{
data: JSON.parse("[" + text + "]")
}]
`text = ','`, hence a json parse error. Revisit your json building # php to correctly spit `text`

Issue submitting wysiwyg data through Ajax

I am Using Cl Editor On a Cms in a working on, Everytime i submit data through ajax i am having problems with it.
Let's say i write 10 lines in my wysiwyg editor but i only receive 3 or 4 in php, after some debugging in firebug what i have noticed is the html i am sending through ajax contains a span with class "Apple-converted-space" <span class="Apple-converted-space"> </span> i am able to get everything before this span, but the text after this span is missing. I have no idea what it is. Let me write my code for better understanding.
To get cleditor data
var data = $(".cleditorMain iframe").contents().find('body').html();
Ajax Form Submission
if(window.XMLHttpRequest)
{
xmlhttp = new window.XMLHttpRequest();
}
else
{
xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
}
xmlhttp.onreadystatechange = function() {
if(xmlhttp.readyState == '4' && xmlhttp.status == '200')
{
}
}
parameters = 'data=' + data
xmlhttp.open('POST', 'libs/make_procedure.php', true);
xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xmlhttp.send(parameters);
return true;
I have also tried jquery ajax method.. same problem exists there, so please do not ask me to use the other way to submit data via ajax.
Thanks
You may want to check whether it is javascript that is not sending correct data or your backend that is not able to receive it.
So first you should debug in javascript by writing an alert(data); statement right after you get the data from that cieditor control, and see what do you get there. Use Firefox and you can also copy the html using mouse pointer from the alert box. (which is not possible in IE)
You should also check the cieditor specs to see if there is any easier way to get data in javascript.
You may also want to consider using CKEditor.
You are posting the data without escaping the contents of the data. Since the & is the seperator for different fields in a post, data will contain only the part up untill the first &. Use encodeURIComponent to escape the data value.
Change the line
parameters = 'data=' + data
to
parameters = 'data=' + encodeURIComponent(data);
See also: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/encodeURIComponent

jquery mobile ajax sends both GET and POST requests

Here is the problem:
By default jQuery Mobile is using GET requests for all links in the application, so I got this small script to remove it from each link.
$('a').each(function () {
$(this).attr("data-ajax", "false");
});
But I have a pager in which I actually want to use AJAX. The pager link uses HttpPost request for a controller action. So I commented the above jQuery code so that I can actually use AJAX.
The problem is that when I click on the link there are two requests sent out, one is HttpGet - which is the jQuery Mobile AJAX default (which I don't want), and the second one is the HttpPost that I actually want to work. When I have the above jQuery code working, AJAX is turned off completely and it just goes to the URL and reloads the window.
I am using asp.net MVC 3. Thank you
Instead of disabling AJAX-linking, you can hijack clicks on the links and decide whether or not to use $.post():
$(document).delegate('a', 'click', function (event) {
//prevent the default click behavior from occuring
event.preventDefault();
//cache this link and it's href attribute
var $this = $(this),
href = $this.attr('href');
//check to see if this link has the `ajax-post` class
if ($this.hasClass('ajax-post')) {
//split the href attribute by the question mark to get just the query string, then iterate over all the key => value pairs and add them to an object to be added to the `$.post` request
var data = {};
if (href.indexOf('?') > -1) {
var tmp = href.split('?')[1].split('&'),
itmp = [];
for (var i = 0, len = tmp.length; i < len; i++) {
itmp = tmp[i].split('=');
data.[itmp[0]] = itmp[1];
}
}
//send POST request and show loading message
$.mobile.showPageLoadingMsg();
$.post(href, data, function (serverResponse) {
//append the server response to the `body` element (assuming your server-side script is outputting the proper HTML to append to the `body` element)
$('body').append(serverResponse);
//now change to the newly added page and remove the loading message
$.mobile.changePage($('#page-id'));
$.mobile.hidePageLoadingMsg();
});
} else {
$.mobile.changePage(href);
}
});
The above code expects you to add the ajax-post class to any link you want to use the $.post() method.
On a general note, event.preventDefault() is useful to stop any other handling of an event so you can do what you want with the event. If you use event.preventDefault() you must declare event as an argument for the function it's in.
Also .each() isn't necessary in your code:
$('a').attr("data-ajax", "false");
will work just fine.
You can also turn off AJAX-linking globally by binding to the mobileinit event like this:
$(document).bind("mobileinit", function(){
$.mobile.ajaxEnabled = false;
});
Source: http://jquerymobile.com/demos/1.0/docs/api/globalconfig.html

TinyMCE not working in http request xhr ajax generated page

So i I have a page that contains links that call an httpRequest. The request calls a php file that grabs data from mysql and pre populates a form which is then returned to the browser/webpage. My problem is that when the page is returned to the browser via the httpRequest/ajax the text area does not display the tinymce editor, it just displays a normal text area. It looks like my request and ajax is working fine the text area just doesn't have the tinycme editor on it.
When i don't use ajax it works fine but when i put it in a separate file and call it via ajax it doesn't bring in the tinymce editor.
Does anyone know how to fix this problem so that my ajax generated page displays the text area with the tinymce editor. Thank you.
Lets presume that your thinyMCE instance is initialized with code below
// initialize tinyMCE in page
tinyMCE.init({
mode: "textareas",
theme: "advanced"
});
and you have some kind of button somewhere in the page. For purpose of this tip, i will not give it any ID but you may. Now, using jQuery you can easily attach event handler to that button which will call through AJAX your server and take content which you want to put tinyMCE editor. Code which will do such job would look somehow like below.
$(function() {
$("button").bind("click", function() {
var ed = tinyMCE.get('content');
ed.setProgressState(1); // Show progress
$.getJSON('/page/12.json', { /* your data */
}, function(data) {
ed.setProgressState(0); // Hide progress
ed.setContent(data["body"]);
}
});
});
});
You can see that on button.click ajax will call url /page/12.json which will return JSON as response. bare minimum of that response could be:
{
title: "Page title",
body: "<html><head><title>Page title</title>......</html>"
}
I attached anonymous function as callback which will handle response from server. and hide progress indicator which is shown before ajax call.
About JSON
JSON is shorten of JavaScript Object Notation. It is JavaScript code!!! So don't be confused about it. Using JSON you can make javascript object which can have attributes you can use later in your code to access particular peace of data which that object "holds". You can look at it as some kind of data structure if it is easier to you.
Anyway, to show you how this JSON can be created by hand look at examples below
var data = new Object();
data.title = "Page title";
data.body = "<html....";
or
var data = {
title: "page title",
body: "<html...."
};
it is very same thing.
If you want to learn more about JSON point your browser to http://json.org.
===== alternative =====
Alternative to json solution could be just plane ajax call to server and response can be plain HTML (from your question I can assume that you have something like this already). So instad of calling $.getJSON you can use $.get(url, callback); to do same thing. The code at the top of my answer will not dramatically change. Instead of geting JSON in response you will get string which is HTML.
----------- BOTTOM LINE -------
I prefer JSON since it can be easily extended later with other attributes, so there is no painful code changes later ;)
Problem here will be that when you return the full page and render it using the ajax response, your tinymce instance has not been shut down before.
In order to do this you can call this small piece of code before you render the ajax response:
tinymce.execCommand('mceRemoveControl',true,'editor_id');
In this case the editor should initialize correctly. You are not allowed to initialize a tinymce editor with the same id before shutting the first one down.
Strangely i ran into this problem yesterday. Following code should work, but YMMV. Trick is to use the correct steps in ajax events. I used the Regular TinyMCE and made use of the jQuery library already included.
Following goes into your tinyMCE initialization tinyMCE.init() . All of the below block should be outside the document.ready.
myTinyInit = {
//.......All essential keys/values ...........
setup : function(ed) {
ed.onChange.add(function( ed ) {
tinyMCE.triggerSave();
}) }
//.....................
};
// Init the tinyMCE
tinyMCE.init(myTinyInit);
This ensures the content is being saved regularly onto the textarea that holds the value. Next step is setting up the request events.
Normally tinyMCE mceAddControl before the ajax post and mceRemoveControl after the ajax success should do the trick. But I found that often does not work.
I used the form as the jQuery selector in my case.
jQuery( '.myForm' )
.find( 'textarea#myTextArea' )
.ajaxStart(function() {
// If you need to copy over the values, you can do it here.
// If you are using jQuery form plugin you can bind to form-pre-serialize event instead.
// jQuery( this ).val( tinyMCE.get( jQuery( this ).attr( 'id' )).getContent() );
}).ajaxSend( function() {
// ! - step 2
// My case was multiple editors.
myEds = tinyMCE.editors;
for( edd in myEds ) {
myEds[ eds ].remove();
}
// tinyMCE.get( 'myTextarea' ).remove();
// strangely mceRemoveControl didnt work for me.
// tinyMCE.execCommand( 'mceRemoveControl', false, jQuery( this ).attr('id'));
}).ajaxSuccess(function() {
// Now we got the form again, Let's put up tinyMCE again.
txtID = jQuery( this ).attr( 'id' );
// ! - step 3
tinyMCE.execCommand( 'mceAddControl', false, txtID );
// Restore the contents into TinyMCE.
tinyMCE.get( txtID ).setContent( jQuery( this ).val());
});
Problems i came across :
Using mceRemoveControl always gave me r is undefined error persistently.
If you get a blank tinyMCE editor, check the DOM whether the ID of the textarea is replaced with something like mce_02, this means that TinyMCE is being initialized again or something is wrong with the order. If so, the tinyMCE is duplicated with each save.
if you are new to JS, I recommend using jQuery with the form plugin, it might be easier for you. But do use the regular non-jquery tinyMCE, as it is well documented.
I fixed this problem by recalling the function after the ajax call. In this part of my ajax:
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("Content").innerHTML=xmlhttp.responseText;
tinymce();
Now it works fine.

How to execute a page ,that contains JS ,in AJAX ,using innerHTML?

I send GET data with AJAX to another file.And on the another file I have echo "<script>alert('Something');</script>";.This is displayed dynamicly with AJAX ,i.e
var ajaxDisplay = document.getElementById('edit');
ajaxDisplay.innerHTML = ajaxRequest.responseText;
puts the <script>alert('Something');</script> to div with name edit.
But it doesn't alert anything.
How to get it work?
I have mixed html/javascript.
Here is the code.
function ajaxFunctions(){
var ajaxRequest; // The variable that makes Ajax possible!
try{
// Opera 8.0+, Firefox, Safari
ajaxRequest = new XMLHttpRequest();
} catch (e){
// Internet Explorer Browsers
try{
ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try{
ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e){
// Something went wrong
alert("Your browser broke!");
return false;
}
}
}
// Create a function that will receive data sent from the server
ajaxRequest.onreadystatechange = function(){
if(ajaxRequest.readyState == 4){
var ajaxDisplay = document.getElementById('edit');
ajaxDisplay.innerHTML = ajaxRequest.responseText;
}
}
var namef = document.getElementById('nameed').value;
var queryString = "?namef=" + namef;
ajaxRequest.open("GET", "try.php" + queryString, true);
ajaxRequest.send(null);
}
Maybe to find the script tags and to eval them?
But how to find the script tags?
Instead of trying to inject a script element in the DOM, just have your script return:
alert('Something');
And then use eval(response); to run it. Or you could add a script element with the src attribute pointing to the page that returns your JavaScript into the <head> (which is the preferred method).
function loadScript(url) {
var head = document.getElementsByTagName("head")[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
head.appendChild(script);
}
Keep in mind that this wont work for cross-domain requests--the script has to have the same origin as the page running your code. To get around this, you'll have to use a callback.
It looks like the only purpose of setting innerHTML is an attempt to get the JS to execute. But once the page is loaded, JS won't 'know' that it needs to parse and execute the new text you've changed, so your method won't work. In this case, what you want is a callback function:
http://api.jquery.com/jQuery.ajax/
I haven't used jQuery, but it looks like you'd simply add a 'complete' property to the settings object you pass to the .ajax() call, like so:
$.ajax({
// ......
complete: function(){
alert('Something');
}
// ......
});
In this case, the callback function would execute once the ajax call has completed. You can pick other events, such as on success, on failure, and so on, if you need to attach your code to a different event.
But how to find the script tags?
Well, parent.getElementsByTagName('script') and then evaling the data of the text node inside will do it.
However, inserting content that includes script tags is unreliable and works slightly differently across browsers. eg. IE will execute the script the first time the script node is inserted into any parent, inside the document or not, whilst Firefox will execute script the first time a subtree including the script is added to a node inside the document. So if you're not extremely careful, you can end up executing scripts twice on some browsers, or executing the script at the wrong time, following a further page manipulation.
So don't. Return script that you want to execute separately to any HTML content, eg. using a JSON object containing both the HTML and the JavaScript seperately.

Resources