#REDIRECT [[Wikipedia:User scripts/Guide]]
[[Ajax (programming)|AJAX]] (''asynchronous JavaScript and XML'') is a popular name for a web programming technique that queries the server or fetches content without reloading the entire page.
While programming AJAX can be complex, libraries of functions can make it much easier. MediaWiki's [{{SERVER}}/skins-1.5/common/ajax.js ajax.js] provides a small set of functions by default, and [[m:User:Pathoschild/Scripts/Ajax framework|Pathoschild's AJAX framework]] provides a more comprehensive library of functions. This page will document both libraries.
==Common problems==
AJAX programmers commonly run into problems if they don't account for AJAX's ''asynchronicity''. If you try to pop up a box with another page's content, you will almost certainly pop up a box containing <code>'''null'''</code>. This occurs because the script continued even though the query wasn't finished.
To correct the problem, you need to use [[w:callback (computer science)|callback functions]]. Place the next portion of code after a query into a function, and call the function when the query completes. (The [[m:User:Pathoschild/Scripts/Ajax framework|AJAX framework]] makes this very easy to do.)
==Code==
===Create an AJAX object===
Before you can query or fetch a page, you must create a query object. Different browsers use different objects, but MediaWiki provides the <code>sajax_init_object()</code> to do it in one step. The [[m:User:Pathoschild/Scripts/Ajax framework|AJAX framework]] equivalent is <code>ajax_create()</code>.
<source lang="javascript">
/************
* MediaWiki ajax.js
************/
var query = sajax_init_object();
/************
* AJAX framework
************/
var query = ajax_create();
</source>
===Fetch page content===
Fetching a page content can easily be done using [[GET]].
<source lang="javascript">
/************
* MediaWiki ajax.js
************/
// fetch
var api = sajax_init_object();
api.open('GET', 'http://example.com', true);
api.onreadystatechange = show_result;
api.send(null);
// handle response
function show_result(_api) {
if(_api.readyState==4) {
if(_api.status==200)
alert('The remote page contains:\n' + api.responseText);
else
alert('The query returned an error.');
}
}
/************
* AJAX framework
************/
ajax_get('http://example.com', show_result);
function show_result(_api) {
if(_api==null)
alert('An error occurred.');
else
alert('The remote page contains:\n' + api.responseText);
}
</source>
===Edit a page and other common actions===
Scripts can easily perform common actions (like editing, protection, blocking, deletion, etc) through the [{{SERVER}}/w/api.php API]. These actions require an edit token, which is valid for any action during the same session. (However, you should get a new token for different tasks in case this changes in the future.)
The code below shows how to edit a page, but it can easily be adapted to other actions by reading the [{{SERVER}}/w/api.php API documentation].
<source lang="javascript">
/************
* MediaWiki ajax.js
************/
// fetch token
var api = sajax_init_object();
api.open('GET', wgServer + '/w/api.php?format=json&action=query&prop=info&indexpageids=1&intoken=edit&titles=Whatever', true);
api.onreadystatechange = extract_token;
api.send();
function extract_token() {
if(api.readyState==4) {
if(api.status==200) {
var response = eval('(' + api.responseText + ')');
var token = response['query']['pages'][response['query']['pageids'][0]]['edittoken'];
edit_page(token);
}
else {
alert('The token query returned an error.');
}
}
}
// edit page (must be done through POST)
function edit_token(_token) {
var parameters = 'action=edit&title=User:Pathoschild&text=AJAX_test!&token=' + encodeURIComponent(_token);
api.open('POST', wgServer + '/w/api.php', true); // just reuse the same query object
api.onreadystatechange = alert_result;
api.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
api.setRequestHeader('Connection', 'keep-alive');
api.setRequestHeader('Content-length', parameters.length);
api.send(parameters);
// process response
function alert_result() {
if(api.readyState==4) {
if(api.status==200) {
alert('Page edited!');
}
else {
alert('The query returned an error.');
}
}
}
}
/************
* AJAX framework
************/
ajax_edit_token('edit', edit_page);
function edit_page(_token) {
var parameters = 'action=edit&title=User:Pathoschild&text=AJAX_test!&token=' + encodeURIComponent(_token);
ajax_post(wgServer + '/w/api.php', parameters, alert_result);
}
function alert_result(_api) {
if(_api==null) alert('An error occurred.');
else alert('Page edited!');
}
</source>
==Data sources==
===[{{SERVER}}{{SCRIPTPATH}}/api.php api.php]===
See [[mw:API]]. Usually used with [[JSON]] format.
===[{{SERVER}}{{SCRIPTPATH}}/query.php query.php]===
See [[User:Yurik/Query_API]]. This is older verison of API, can be used for some queries not yet implemented in API. Some Javascript examples can be found at [[User:Yurik/Query_API/User_Manual#JavaScript]]. As of early 2008, query.php was soon to be obsoleted: [http://en.wikipedia.org/w/index.php?title=Wikipedia:Village_pump_%28technical%29&oldid=189364461#query.php_interface_will_be_removed_soon].
===HTML===
You could fetch the whole article page or use <code>&action=render</code> URL parameter to get the content without all the menus ([{{fullurl:{{FULLPAGENAME}}|action=render}} example]). Also see [[mw:Manual:Parameters to index.php|Parameters to index.php]].
The result you could treat as a text but it's usually convenient to parse it as HTML document, e.g. using DOMParser object <small>(examples needed)</small>.
===Wiki code===
To get the wiki code you use <code>&action=raw</code> URL parameter ([{{fullurl:{{FULLPAGENAME}}|action=raw}} example]).
The result you treat as a text.
===Preview===
Sometimes you might want to use preview. For example, [[Special:Prefixindex]] won't work with <code>&action=render</code>. To get rid of the unnecessary menus you could submit <tt><nowiki>{{Special:Prefixindex/somepage}}</nowiki></tt> for a preview and get a "clean" list (nevertheless, it's better to use API for prefix index)
==See also==
===Code===
;User scripts
:* [[m:User:Pathoschild/Scripts/Ajax framework|Comprehensive AJAX framework]] (by [[user:Pathoschild|Pathoschild]])
:* [[User:TheFearow/simpleajax.js|AJAX editing]] (by [[user:TheFearow|TheFearow]])
:* [[User talk:Alex Smotrov/qpreview.js|Ajax preview]] (by [[user:Alex Smotrov|Alex Smotrov]])
:* [[User talk:Alex Smotrov/wlunwatch.js|Ajax unwatch from watchlist]] (by [[user:Alex Smotrov|Alex Smotrov]])
:* Various code with AJAX
:** [[Wikipedia:Tools/Navigation popups|Navigation popups]]
:** [[Wikipedia:WikiProject User scripts/Scripts/Twinkle|Twinkle]] (some code in [[User:AzaToth/morebits.js]], and good examples of AJAX are in the bottom of [[User:AzaToth/twinklespeedy.js]])
; Mediawiki
:* [{{SERVER}}/skins-1.5/common/ajax.js ajax.js] - some support functions
:* [{{SERVER}}/skins-1.5/common/ajaxwatch.js ajaxwatch.js] - watch/unwatch
:* [{{SERVER}}/skins-1.5/common/upload.js upload.js] - licenses preview on [[Special:Upload]]
:* Internal and disabled code
:** [http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/includes/AjaxFunctions.php?view=markup AjaxFunctions.php] has 2 main functions:
:**: wfAjaxWatch - server part of ajaxwatch.js
:**: wfSajaxSearch - disabled on WMF projects. If it was enabled, [{{SERVER}}/skins-1.5/common/ajaxsearch.js ajaxsearch.js] would be responsible for the client side. Also see [[mw:Manual:$wgAjaxSearch]].
:** [[mw:Manual:Live preview|Live preview]] ([{{SERVER}}/skins-1.5/common/preview.js preview.js])
===Alternatives===
* [[IFrame]]s are an obsolete older method (see [[User:TheFearow/ajax.js|a small untested library]] by [[user:TheFearow|TheFearow]])
* URL parameters: a script can call itself on a different by adding a custom URL parameter to the address bar. It can then check the address bar on every page load, and run code depending on the values of the custom headers. See [[User:Lupin/autoedit.js|an example unmaintaned library]] by [[user:Lupin|Lupin]]).
|