I found something that was the perfect example of my problem... this might be of help to you (I am not that good at reading other people's scripts).
######################################################################__
I noticed a lot of new comers asking this question: I want a select box to be updated using ajax when I change the current item in another select box .
So this is a quick tutorial on how to do exactly that.
Here is the scenario: We have a select box filled with categories, when we select a category, another select box is updated with article titles. Fair enough ?
First thing to do is create the DB tables:
PHP Code:
CREATE TABLE categories (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
name VARCHAR( 30 ) NOT NULL
);
CREATE TABLE articles (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
title VARCHAR( 30 ) NOT NULL ,
category_id INT UNSIGNED NOT NULL ,
INDEX ( category_id )
);
Ok next create the models, put them in app/models of course.
PHP Code:
<?php
// category.php
class Category extends AppModel {
var $name = ‘Category’;
}
?>
<?php
// article.php
class Article extends AppModel {
var $name = ‘Article’;
var $belongsTo = array(‘Category’);
}
?>
now comes the articles’ controller, we’ll have an action index where we’ll display the select boxes.
PHP Code:
<?php
// app/controllers/articles_controller.php
class ArticlesController extends AppController {
var $name = ‘Articles’;
var $helpers = array(‘Html’,‘Form’,‘Javascript’,‘Ajax’);
var $components = array(‘RequestHandler’);
function index() {
$this->set(‘categories’, $this->Article->Category->generateList());
}
}
?>
Nothing fancy for the moment, we add the Javascript and Ajax helpers to the list of helpers that will be available in the view domain ( layout + views ).
We use the RequestHandler component, it will detect ajax requests and set proper header and layout for us, sweet isn’t it!
Our next step is to create a layout, we could just use the default layout but we need to include the prototype and scriptaculous libraries. make sure you downloaded the files and put them in webroot/js
Add these two lines in the head section of your layout:
HTML Code:
echo $javascript->link(‘prototype’);
echo $javascript->link(’scriptaculous’);
If you’re using 1.2 ( not sure it’s available in 1.1 ) you can write it in one line of code:
HTML Code:
echo $javascript->link(array(‘prototype’,’scriptaculous’));
To be honest, you don’t need scriptaculous here, we’re not going to use it, just include prototype.
All right, all this above was basically just preparation, now here’s the view file of the index action. Create a folder named articles under app/views. Create a file in it, name it index.ctp if you’re using 1.2 or index.thtml if you’re using 1.1 (thtml works in 1.2 too but it’s depreciated).
Here is its content:
PHP Code:
<?php
// app/views/articles/index.(thtml|ctp)
echo $html->selectTag(‘Category/id’, $categories, null, array(‘id’ => ‘categories’));
echo $html->selectTag(‘Article/id’,array(), null,array(‘id’ =>‘articles’));
$options = array(‘url’ => ‘update_select’,‘update’ => ‘articles’);
echo $ajax->observeField(‘categories’,$options);
?>
In 1.2, selectTag() is depreciated, change it to select().
echo $form->select(‘Category.id’, array(‘options’=>$categories), null, array(‘id’ => ‘categories’));
echo $form->select(‘Article.id’,array(), null, array(‘id’ =>‘articles’));
All right, nothing fancy either, we create two select boxes, we populate one with category names set from the action. We give both selects an id and we call observeField. This method of the ajax helper basically observes a DOM element for a change, if it occurs, it calls an url and updates a DOM element with the content returned from that url.
Let’s move on to create the action that we’ll be requested by observeField.
In the ArticlesController add this code:
PHP Code:
function update_select() {
if(!empty($this->data[‘Category’][‘id’])) {
$cat_id = (int)$this->data[‘Category’][‘id’];
$options = $this->Article->generateList(array(‘category_id’=>$cat_id));
$this->set(‘options’,$options);
}
}
and it’s view..
PHP Code:
<?php
// update_select.(ctp|thtml)
if(!empty($options)) {
foreach($options as $k => $v) {
echo "<option value=’$k’>$v</option>";
}
}
?>
Fun fun..now populate the db tables with some dummy data and test it out.
This was just one way of doing it, we could return JSON, XML or a script that’ll get executed.
########################################___
or some code in here might help:
########################################____-
The Prototype Ajax.Updater object makes an out of band browser HTTP request. The request can be either synchronous or asynchronous – almost all calls are asynchronous. //todo: another example using POST method.
Syntax
new Ajax.Updater(container, url, options);
// make a HTTP request to the specified URL and update the 'container' element.
Note: to evaluate javascript responses set the ‘evalScripts’ option to ‘true’.
Note: to only update a div on success, you may optionally substitute a property list for a simply element id (ie {success:’div_name’} instead of ‘div_name’)
Options
Option Default value Description
asynchronous true Type of request
evalScripts false When true scripts in requested url are evaluated
method ‘post’ Lets you decide whether to use Get or Post for the request to the server
contentType ‘application/x-www-form-urlencoded’ Allows you to set the content-type sent to the server
encoding ‘UTF-8’ Allows you to determine the encoding type information given to the server
parameters ’’ Allows you to attach parameters to your AJAX request. Most common: parameters:Form.serialize(this)
postBody ’’ Specify data to post. Something like: postBody:’thisvar=true&thatvar=Howdy’ How does this differ from parameters?
username ’’
password ’’
requestHeaders ’’
onComplete ’’ Function to call on completion of request
onSuccess ’’ Function to call on successful completion of request
onFailure ’’ Function to call on failed request
onException ’’ Function to call on failed request (e.g. attempted cross-site request)
on + Status Code ’’ on404 etc. raise an event when given status code is encountered.
insertion None Instead of inserting the response in the existing content (possibly overwriting it) you can pass a valid Insertion object, such as Insertion.Top, Insertion.Bottom, Insertion.Before or Insertion.After.
Hint: If you have set evalScripts:true the script you call (the url parameter) must return a header of ‘Content-Type: text/javascript’ else the browser will not execute it.
(Can someone with more knowledge fill this up more? Please and thank you?)
Examples
Basic usage:
new Ajax.Updater('mydiv', '/foo/bar', {asynchronous:true});
// places result text in the browser object with the id 'mydiv': <div id='mydiv'></div>
Usage with options:
new Ajax.Updater('mydiv', '/foo/bar', {onComplete:function(){ new Effect.Highlight('mydiv');},asynchronous:true, evalScripts:true});
// this will evaluate any scripts in <script></script> blocks. Also it will hightlight mydiv on complete.
[...edit me and add more examples...]
Usage with server-side script:
Put this in the same directory as your HTML, and configure your server to run x.cgi scripts:
date.cgi:
#!/bin/bash
echo 'Content-type: text/plain'
echo ''
date
Create this HTML page:
date.html:
<script src="/scripts/prototype.js" type="text/javascript"></script>
<script>
var ajax = new Ajax.Updater(
'datestr', // DIV id (XXX: doesnt work?)
'date.cgi', // URL
{ // options
method:'get',
onComplete: showResponse
});
function showResponse(req)
{
$('datestr').innerHTML = req.responseText;
}
</script>
date is now: <div id="datestr">n/a</div>
Or like this :
date2.html:
<script src="/scripts/prototype.js" type="text/javascript"></script>
<script language="JavaScript" type="text/javascript">
var ajax;
function mydate() {
ajax = new Ajax.Updater(
'datestr', // DIV id must be declared before the method was called
'date.cgi', // URL
{ // options
method:'get'
});
}
</script>
date is now: <div id="datestr">n/a</div>
<script language="JavaScript" type="text/javascript">
mydate();
</script>
Usage as out-of-band form submit:
Ajax.Updater can be used to submit a form and insert the results into the page, all without a refresh. This works for all form elements except files.
<form action="/action/here" method="post" onsubmit="new Ajax.Updater('div_to_be_updated', '/action/here', {asynchronous:true, parameters:Form.serialize(this)}); return false;">
See Ajax.Request for Ajax calls that don’t expect to return rendered data.
Alternative out-of-band form submit:
Instead of using the onSubmit property of the form itself, use a simple button’s onClick value, and have the form’s onSubmit return false. This will stop users from being able to hit return and submit the form, but if you are trying to combine effects or functions (like resetting the form after the Updater finishes, as in the example) this may provide a working solution. Combining certain functions inside the onSubmit seems to create a few problems.
<form id="myform" action="/action/here" method="post" onsubmit="return false;">
<input type="text" name="myinput" />
<input type="button" value="Submit!" onclick="$('changeme').innerHTML = 'Refreshing...'; new Ajax.Updater('changeme', 'processmyform.php', {asynchronous:true, parameters:Form.serialize('myform')});$('myform').reset();$('myinput').activate( );return false;"
</form>
<div id="changeme">
</div>
Note for response containing javascript function declaration
When you have some javascript contained in the server side response, you have to use the evalScripts:true option of the Ajax object.
If you have some function declared in the response be warned that they wont be accessible at all unless you assign them to variables.
The reason for this is that the script is not appended to the page but evaluated, and this won’t create the function at all.
Invalid function definition response example :
<script>
//this won't work You MUST assign the function to a variable
function myresponsefunc(){
..do something..
}
</script>
<a href="javascript:myresponsefunc()">do my func</a>
working function definition response example:
<script>
//this one should work properly.
myresponsefunc = function(){
..do something..
}
</script>
<a href="javascript:myresponsefunc()">do my func</a>
Simple AJAX Form Validation Example
Hi, i try to do this code with Ajax.Request but maybe my XP restricts some request, don’t know but it wasn’t work . So,
i realize the example with Ajax.Update that let me post here my work ;-)
The script is divide in two files : in client-side => ‘NICOWEB.verifPseudo Get?.html’ , one server-side ‘get.verifierPseudo Scriptaculous?.php’ .
Another Example of Practical Usage
If your site regularly uses Ajax.Updater to view pages, it may be wise to implement something like the following:
function Request(page)
{
document.getElementById('content').innerHTML = 'Loading...';
new Ajax.Updater('content', 'pages/' + page + '.php', {asynchronous:true, evalScripts:true});
}
The above example shows how an elementary function can be used to replace the need to write out long calls to Ajax.Updater. One can now simply write “Request(‘index’);” to create a new instance of Ajax.Updater and load ‘pages/index.php’ into the main content window.
Description of ‘NICOWEB.verifPseudo Get?.html’
This file contains a html form who ‘onBlur’ test the value enter by the user and send an Ajax.Updater on the server side script.
=> sorry no example available, impossible to insert a controlled html image ;-)
Try at this url :
Online NICOWEB example
You like the “loginDiposnibility” example ? You might love the new Nicoweb.fr prototype.js online example at : CSS Beautifier Post
I hope you enjoy this one like the others ;)
Get another example in the usage of Ajax.Updater at Nicoweb.Auction-Bidder
You can almost try Nicoweb.ajaxStore
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>NICOWEB w/ Scriptaculous or Scriptaculous presented by NICOWEB</title>
<script language="javascript" type="text/javascript" src="js/prototype.js"></script>
<script type="text/javascript" language="javascript">
/* NICOWEB : 07/08/2006 :: script ajax prototype de vérification de disponibilité pseudo submate */
var imgPseudo = "";
function formVerifierDisponibilitePseudo (idImg)
{
var pseudoToTest = $('pseudo').value;
imgPseudo = idImg;
if (pseudoToTest != "")
{
alert('let\'s start the ajax process with "'+pseudoToTest+'".');
/*new Ajax.Request("http://ns34.hosteur.com/~learnc/espaceemploi/ajax/get.verifierPseudoScriptaculous.php?pseudo"+pseudoToTest, { method: 'get', asynchronous: true, onSuccess:succesRetourAjax, onFailure:erreurRetourAjax} );*/
new Ajax.Updater('retour','http://ns34.hosteur.com/~learnc/espaceemploi/ajax/get.verifierPseudoScriptaculous.php?pseudo='+pseudoToTest,{ method:'get' , onComplete: succesRetourAjax, onFailure: erreurRetourAjax});
}
else
{
alert('oops, broken.')
$(idImg).src = 'http://ns34.hosteur.com/~learnc/espaceemploi/ajax/images/champNonValide.gif';
return true;
}
}
function succesRetourAjax (t)
{
alert(t.responseText);
if (t.responseText == "succes")
{
alert('you can use this pseudo (ndr : test version).');
$(imgPseudo).src = 'http://ns34.hosteur.com/~learnc/espaceemploi/ajax/images/champValide.gif';
}
else
{
alert('you can\'t use this pseudo (ndr : test version).');
$(imgPseudo).src = 'http://ns34.hosteur.com/~learnc/espaceemploi/ajax/images/champNonValide.gif';
}
}
function erreurRetourAjax (t)
{
alert('Error ' + t.status + ' -- ' + t.statusText);
alert('you can\'t user this pseudo (ndr : test version).');
$(imgPseudo).src = 'http://ns34.hosteur.com/~learnc/espaceemploi/ajax/images/champNonValide.gif';
}
/* NICOWEB : 07/08/2006 :: fin script ajax prototype de vérification de disponibilité pseudo submate */
</script>
</head>
<body>
<div id="retour"></div>
<table>
<tr><td colspan="2"><input type="button" name="test" value="other"/></td></tr>
<tr>
<td>Enter a pseudo and test his disponibility :</td>
<td>
<input name="pseudo" type="text" id="pseudo" value="" class="input" onBlur="formVerifierDisponibilitePseudo('imgPse');"/>
<img src="http://ns34.hosteur.com/~learnc/espaceemploi/ajax/images/champNonValide.gif" alt="nicoweb/scriptaculous icone champ non valide" id="imgPse" />
</td>
</tr>
<tr><td colspan="2"><input type="button" name="test" value="other"/></td></tr>
<tr><td colspan="2">NICOWEB NOTES :: in the test version you can't user 'nicoweb', 'nicoweb.fr', 'bertelle nicolas', 'saved', 'ganjaman', 'feliz' as pseudo.<br/>All others are welcome ;-)</td></tr>
</table>
</body>
</html>
Description of ‘ajax/verifierPseudo Scriptaculous?.php’
This file, in this test version, compare the value enter by the user with values sotcked in an php array.
If the value is not present function return true else function return false.
The result is control by the javascript functions “succesRetour Ajax?” and “erreurRetour Ajax?” that changes
the value of control ajax return image ‘imgPse’.
<?
/*
* 08/08/2006 00:34am
* ajax/verifierPseudoScriptaculous.php
* test ajax file, no connection to bdd to preserve my bandwidth ;-)
*/
$tPseudo = array("nicoweb","nicoweb.fr","bertelle nicolas","saved","ganjaman","feliz");
$retour = "";
if ($_GET['pseudo'] != "")
{
$pseudo = $_GET['pseudo'];
if (in_array($pseudo,$tPseudo)) { $retour = ""; echo $retour; }
else { $retour = "succes"; echo $retour; }
}
else { $retour = ""; echo $retour; }
?>
Hope that code extraction can give wings to someone, help others, wish you best with scriptaculous ;-)
############################################################_
REF: http://wiki.script.aculo.us/scriptac...w/Ajax.Updater
REF: http://www.devmoz.com/blog/2007/04/0...box-using-ajax
Bookmarks