I have a MySQL table that contains sup_number and site fields amongst others. In my form I would like the user to enter the SUP number. That number will then get validated while the user is typing and populate another field next to it with the current site that this sup number is related to. The sup number must be a 6 digit number. I've already entered two sup numbers in the sup_number field to test.
It seems to me that I need to use AJAX in this case. I tried to follow the code example found on Chapter 12: Adding Advanced Features - Using Ajax to look up e-mail addresses in the Chronoforms for Joomla site Cookbook. So I copied all code to just make that work and then take it from there. The example should look up emails from the jos_users table and on focus out turn the input box green if the email exists or turn the input box red if the email doesn't exist. Here is the code taken from the book.
Form HTML box:
Form JavaScript code:
Extra code 1:
Now the example here works BUT when the email exists it turns the input box to RED and when it's non existent it turns the box to GREEN! Why is that happening instead of the other way round? Also how could I modify the script to fit what I want to do?
It seems to me that I need to use AJAX in this case. I tried to follow the code example found on Chapter 12: Adding Advanced Features - Using Ajax to look up e-mail addresses in the Chronoforms for Joomla site Cookbook. So I copied all code to just make that work and then take it from there. The example should look up emails from the jos_users table and on focus out turn the input box green if the email exists or turn the input box red if the email doesn't exist. Here is the code taken from the book.
Form HTML box:
window.addEvent('domready', function() {
// set the url to send the request to
var url = 'index.php?option=com_chronocontact&chronoformname=Email_Lookup&task=extra&format=raw';
var email = $('email');
email.addEvent('blur', function() {
// clear any background color from the input
email.setStyle('background-color', 'white');
// check that the email address is valid
regex = /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i;
var value = email.value.trim();
if ( value.length > 6 && regex.test(value) ) {
// if all is well send the JSON request
var jSonRequest = new Json.Remote(url, {
onComplete: function(r) {
// check the result and set the background color
if ( r.email_ok ) {
email.setStyle('background-color', 'green');
} else {
email.setStyle('background-color', 'red');
}
}
}).send({'email': email.value});
} else {
// if this isn't a valid email set background color red
email.setStyle('background-color', 'red');
}
});
});
Form JavaScript code:
window.addEvent('domready', function() {
// set the url to send the request to
var url = 'index.php?option=com_chronocontact&chronoformname=Email_Lookup&task=extra&format=raw';
var email = $('email');
email.addEvent('blur', function() {
// clear any background color from the input
email.setStyle('background-color', 'white');
// check that the email address is valid
regex = /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i;
var value = email.value.trim();
if ( value.length > 6 && regex.test(value) ) {
// if all is well send the JSON request
var jSonRequest = new Json.Remote(url, {
onComplete: function(r) {
// check the result and set the background color
if ( r.email_ok ) {
email.setStyle('background-color', 'green');
} else {
email.setStyle('background-color', 'red');
}
}
}).send({'email': email.value});
} else {
// if this isn't a valid email set background color red
email.setStyle('background-color', 'red');
}
});
});
Extra code 1:
<?php
// Code for Extra Code
// clean up the JSON message
$json = stripslashes($_POST['json']);
$json = json_decode($json);
$email = strtolower(trim($json->email));
// check that the email field isn't empty
$response = false;
if ( $email ) {
// Check the database
$db =& JFactory::getDBO();
$query = "
SELECT COUNT(*)
FROM `#__users`
WHERE LOWER(`email`) = ".$db->quote($email).";
";
$db->setQuery($query);
$response = (bool) !$db->loadResult();
}
$response = array('email_ok' => $response );
//send the reply
echo json_encode($response);
// stop the from running
$MyForm->stopRunning = true;
die;
?>
Now the example here works BUT when the email exists it turns the input box to RED and when it's non existent it turns the box to GREEN! Why is that happening instead of the other way round? Also how could I modify the script to fit what I want to do?
I just modified the bit of code in the Extra Code 1 box from
$response = (bool) !$db->loadResult();
to $response = (bool) $db->loadResult();
(took the "!" out) and it turns green when the email is found, which is good. I was wondering how I could modify the code to solve my problem now...
Hi quantum_leap ,
I think you need to amend the extra code to return the six digit number if one is found or an empty string if not and then alter the onComplete function in the JavaScript to set the value of the input using the result.
Bob
I think you need to amend the extra code to return the six digit number if one is found or an empty string if not and then alter the onComplete function in the JavaScript to set the value of the input using the result.
Bob
Hi. Assuming that I still want to keep the functionality of turning the sup_number field color green or red according to the value entered. I've modified the code accordingly and added an
The code is:
HTML:
Javascript:
Extra code box:
The color validation works fine but I have no idea how I can populate the site field depended on the value of the sup_number. It's really difficult for me to understand, could you maybe provide an example? It's just a case of matching the sup_number field with the site field but I have no idea how to do it!
var site = $('site');
variable in the javascript area. The code is:
HTML:
<div class="form_item">
<div class="form_element cf_textbox">
<label class="cf_label" style="width: 150px;">SUP Number</label>
<input class="cf_inputbox" maxlength="150" size="30" title="" id="sup_number" name="sup_number" type="text" />
</div>
<div class="cfclear"> </div>
</div>
<div class="form_item">
<div class="form_element cf_textbox">
<label class="cf_label" style="width: 150px;">Site</label>
<input class="cf_inputbox" maxlength="150" size="30" title="" id="site" name="site" value="" type="text" />
</div>
<div class="cfclear"> </div>
</div>
Javascript:
window.addEvent('domready', function() {
// set the url to send the request to
var url = 'index.php?option=com_chronocontact&chronoformname=SUP_Lookup&task=extra&format=raw';
var sup_number = $('sup_number');
var site = $('site');
sup_number.addEvent('blur', function() {
// clear any background color from the input
sup_number.setStyle('background-color', 'white');
// check that the email address is valid
if (sup_number.length = 6 ) {
// if all is well send the JSON request
var jSonRequest = new Json.Remote(url, {
onComplete: function(r) {
// check the result and set the background color
if ( r.sup_number_ok ) {
sup_number.setStyle('background-color', 'green');
} else {
sup_number.setStyle('background-color', 'red');
}
}
}).send({'sup_number': sup_number.value});
} else {
// if this isn't a valid sup number set background color red
sup_number.setStyle('background-color', 'red');
}
});
});
Extra code box:
<?php
// Code for Extra Code
// clean up the JSON message
$json = stripslashes($_POST['json']);
$json = json_decode($json);
$sup_number = $json->sup_number;
// check that the sup number field isn't empty
$response = false;
if ( $sup_number ) {
// Check the database
$db =& JFactory::getDBO();
$query = "
SELECT COUNT(*)
FROM `_jos_installations`
WHERE `sup_number` = ".$db->quote($sup_number).";
";
$db->setQuery($query);
$response = (bool) $db->loadResult();
}
$response = array('sup_number_ok' => $response );
//send the reply
echo json_encode($response);
// stop the from running
//$MyForm->stopRunning = true;
//die;
?>
The color validation works fine but I have no idea how I can populate the site field depended on the value of the sup_number. It's really difficult for me to understand, could you maybe provide an example? It's just a case of matching the sup_number field with the site field but I have no idea how to do it!
I know I can set the value of site in the javascript area by referencing
$('site').value
but I don't know what value should that be. Obviously it will have to come from the PHP extra box so all I am asking is the query that would create a variable so I could then assign in the javascript box. The problem is that when I set a simple variable in the php box $response2 == "test"
and then doing a $('site').value = response2;
in the javascript box, nothing is coming back from php. Pretty desperate here...
Took me 3 days of continous digging and searching to pin it down.
Form HTML::
Form JavaScript:
Extra code 1:
Form HTML::
<div class="form_item">
<div class="form_element cf_textbox">
<label class="cf_label" style="width: 150px;">SUP Number</label>
<input class="cf_inputbox" maxlength="150" size="30" title="" id="sup_number" name="sup_number" type="text" />
</div>
<div class="cfclear"> </div>
</div>
<div class="form_item">
<div class="form_element cf_textbox">
<label class="cf_label" style="width: 150px;">Site</label>
<input class="cf_inputbox" maxlength="150" size="30" title="" id="site" name="site" value="" type="text" />
</div>
<div class="cfclear"> </div>
</div>
Form JavaScript:
window.addEvent('domready', function() {
// set the url to send the request to
var url = 'index.php?option=com_chronocontact&chronoformname=Installations&task=extra&format=raw';
var sup_number = $('sup_number');
var site = $('site');
sup_number.addEvent('blur', function() {
// clear any background color from the input
sup_number.setStyle('background-color', 'white');
// check that the email address is valid
if (sup_number.length = 6 ) {
// if all is well send the JSON request
var jSonRequest = new Json.Remote(url, {
onComplete: function(r) {
// check the result and set the background color
if ( r.sup_number_ok ) {
sup_number.setStyle('background-color', '#66cc99');
site.value = r.sup_number_ok;
} else {
sup_number.setStyle('background-color', 'red');
site.value = "No site associated with that SUP number";
}
}
}).send({'sup_number': sup_number.value});
} else {
// if this isn't a valid sup number set background color red
sup_number.setStyle('background-color', 'red');
site.value = "No site associated with that SUP number";
}
});
});
Extra code 1:
<?php
// Code for Extra Code
// clean up the JSON message
$json = stripslashes($_POST['json']);
$json = json_decode($json);
$sup_number = $json->sup_number;
// check that the sup number field isn't empty
$response = false;
if ( $sup_number ) {
// Check the database
$db =& JFactory::getDBO();
$query = "
SELECT `site`
FROM `_jos_sup`
WHERE `sup_number` = ".$db->quote($sup_number).";
";
$db->setQuery($query);
$response = $db->loadResult();
}
$response = array('sup_number_ok' => $response );
//send the reply
echo json_encode($response);
// stop the form running
//$MyForm->stopRunning = true;
//die;
?>
Hi quantum_leap,
I'm not quite sure what you are returning. Browser web developer tools are invaluable in letting you look at the actual values.
In the code I posted r is the JSON value returned so if you had sup_number in the array then I'd expect you to use
But . . . your Extra code 1 box appears to be using JavaScript instead of PHP so I don't think it will do anything. Maybe you posted the wrong code block there?
Bob
I'm not quite sure what you are returning. Browser web developer tools are invaluable in letting you look at the actual values.
In the code I posted r is the JSON value returned so if you had sup_number in the array then I'd expect you to use
$('site').value = r.sup_number;
But . . . your Extra code 1 box appears to be using JavaScript instead of PHP so I don't think it will do anything. Maybe you posted the wrong code block there?
Bob
Sorry you are right, I've just updated the code!
But i've also noticed that the behaviour only works in Firefox and Opera and NOT in IE, Chrome and Safari...
But i've also noticed that the behaviour only works in Firefox and Opera and NOT in IE, Chrome and Safari...
I've just noticed that the javascript code I am importing for the hideable inputs(found in the Chronoforms book) clashes with the javascript being used for the ajax functionality. It only works in Firefox and Opera. Is there a way I could make them work together?
Hi quantum_leap,
There shouldn't be a clash between them unless the same variable is being re-defined. What error messages do you see in the JavaScript console?
Bob
There shouldn't be a clash between them unless the same variable is being re-defined. What error messages do you see in the JavaScript console?
Bob
Hi Bob. The error message is
SCRIPT5007: Unable to get value of the property 'addEvent': object is null or undefined
index.php?option=com_chronocontact&chronoformname=Installations, line 115 character 2
Whenever I remove the usable_forms.js script which I've imported, it works fine but obviously I don't get hideable inputs functionality. The code is this:
Once I import it back, I get the in IE Console found in the previous post. Any news on that?
The console highlights this code.
That particular addEvent seems to be empty.
/*****************************************/
/** Usable Forms 2.0, November 2005 **/
/** Written by ppk, www.quirksmode.org **/
/** Instructions for use on my site **/
/** **/
/** You may use or change this script **/
/** only when this copyright notice **/
/** is intact. **/
/** **/
/** If you extend the script, please **/
/** add a short description and your **/
/** name below. **/
/*****************************************/
var containerTag = 'DIV';
var compatible = (
document.getElementById && document.getElementsByTagName && document.createElement
&&
!(navigator.userAgent.indexOf('MSIE 5') != -1 && navigator.userAgent.indexOf('Mac') != -1)
);
if (compatible) {
document.write('<style>.accessibility{display: none}</style>');
var waitingRoom = document.createElement('div');
}
var hiddenFormFieldsPointers = new Object();
function prepareForm()
{
if (!compatible) return;
var marker = document.createElement(containerTag);
marker.style.display = 'none';
var x = document.getElementsByTagName('select');
for (var i=0;i<x.length;i++)
addEventUF(x[i],'change',showHideFields)
var x = document.getElementsByTagName(containerTag);
var hiddenFields = new Array;
for (var i=0;i<x.length;i++)
{
if (x[i].getAttribute('rel'))
{
var y = getAllFormFields(x[i]);
x[i].nestedRels = new Array();
for (var j=0;j<y.length;j++)
{
var rel = y[j].getAttribute('rel');
if (!rel || rel == 'none') continue;
x[i].nestedRels.push(rel);
}
if (!x[i].nestedRels.length) x[i].nestedRels = null;
hiddenFields.push(x[i]);
}
}
while (hiddenFields.length)
{
var rel = hiddenFields[0].getAttribute('rel');
if (!hiddenFormFieldsPointers[rel])
hiddenFormFieldsPointers[rel] = new Array();
var relIndex = hiddenFormFieldsPointers[rel].length;
hiddenFormFieldsPointers[rel][relIndex] = hiddenFields[0];
var newMarker = marker.cloneNode(true);
newMarker.id = rel + relIndex;
hiddenFields[0].parentNode.replaceChild(newMarker,hiddenFields[0]);
waitingRoom.appendChild(hiddenFields.shift());
}
setDefaults();
addEventUF(document,'click',showHideFields);
}
function setDefaults()
{
var y = document.getElementsByTagName('input');
for (var i=0;i<y.length;i++)
{
if (y[i].checked && y[i].getAttribute('rel'))
intoMainForm(y[i].getAttribute('rel'))
}
var z = document.getElementsByTagName('select');
for (var i=0;i<z.length;i++)
{
if (z[i].options[z[i].selectedIndex].getAttribute('rel'))
intoMainForm(z[i].options[z[i].selectedIndex].getAttribute('rel'))
}
}
function showHideFields(e)
{
if (!e) var e = window.event;
var tg = e.target || e.srcElement;
if (tg.nodeName == 'LABEL')
{
var relatedFieldName = tg.getAttribute('for') || tg.getAttribute('htmlFor');
tg = document.getElementById(relatedFieldName);
}
if (
!(tg.nodeName == 'SELECT' && e.type == 'change')
&&
!(tg.nodeName == 'INPUT' && tg.getAttribute('rel'))
) return;
var fieldsToBeInserted = tg.getAttribute('rel');
if (tg.type == 'checkbox')
{
if (tg.checked)
intoMainForm(fieldsToBeInserted);
else
intoWaitingRoom(fieldsToBeInserted);
}
else if (tg.type == 'radio')
{
removeOthers(tg.form[tg.name],fieldsToBeInserted)
intoMainForm(fieldsToBeInserted);
}
else if (tg.type == 'select-one')
{
fieldsToBeInserted = tg.options[tg.selectedIndex].getAttribute('rel');
removeOthers(tg.options,fieldsToBeInserted);
intoMainForm(fieldsToBeInserted);
}
}
function removeOthers(others,fieldsToBeInserted)
{
for (var i=0;i<others.length;i++)
{
var show = others[i].getAttribute('rel');
if (show == fieldsToBeInserted) continue;
intoWaitingRoom(show);
}
}
function intoWaitingRoom(relation)
{
if (relation == 'none') return;
var Elements = hiddenFormFieldsPointers[relation];
for (var i=0;i<Elements.length;i++)
{
waitingRoom.appendChild(Elements[i]);
if (Elements[i].nestedRels)
for (var j=0;j<Elements[i].nestedRels.length;j++)
intoWaitingRoom(Elements[i].nestedRels[j]);
}
}
function intoMainForm(relation)
{
if (relation == 'none') return;
var Elements = hiddenFormFieldsPointers[relation];
for (var i=0;i<Elements.length;i++)
{
var insertPoint = document.getElementById(relation+i);
insertPoint.parentNode.insertBefore(Elements[i],insertPoint);
if (Elements[i].nestedRels)
{
var fields = getAllFormFields(Elements[i]);
for (var j=0;j<fields.length;j++)
{
if (!fields[j].getAttribute('rel')) continue;
if (fields[j].checked || fields[j].selected)
intoMainForm(fields[j].getAttribute('rel'));
}
}
}
}
function getAllFormFields(node)
{
var allFormFields = new Array;
var x = node.getElementsByTagName('input');
for (var i=0;i<x.length;i++)
allFormFields.push(x[i]);
var y = node.getElementsByTagName('option');
for (var i=0;i<y.length;i++)
allFormFields.push(y[i]);
return allFormFields;
}
/** ULTRA-SIMPLE EVENT ADDING **/
function addEventUF(obj,type,fn)
{
if (obj.addEventListener)
obj.addEventListener(type,fn,false);
else if (obj.attachEvent)
obj.attachEvent("on"+type,fn);
}
addEventUF(window,"load",prepareForm);
/** PUSH AND SHIFT FOR IE5 **/
function Array_push() {
var A_p = 0
for (A_p = 0; A_p < arguments.length; A_p++) {
this[this.length] = arguments[A_p]
}
return this.length
}
if (typeof Array.prototype.push == "undefined") {
Array.prototype.push = Array_push
}
function Array_shift() {
var A_s = 0
var response = this[0]
for (A_s = 0; A_s < this.length-1; A_s++) {
this[A_s] = this[A_s + 1]
}
this.length--
return response
}
if (typeof Array.prototype.shift == "undefined") {
Array.prototype.shift = Array_shift
}
Once I import it back, I get the in IE Console found in the previous post. Any news on that?
The console highlights this code.
sup_number.addEvent('blur', function() {
// clear any background color from the input
sup_number.setStyle('background-color', 'white');
// check that the email address is valid
if (sup_number.length = 6 ) {
// if all is well send the JSON request
var jSonRequest = new Json.Remote(url, {
onComplete: function(r) {
// check the result and set the background color
if ( r.sup_number_ok ) {
sup_number.setStyle('background-color', '#66cc99');
site.value = r.sup_number_ok;
} else {
sup_number.setStyle('background-color', 'red');
site.value = "No site associated with that SUP number";
}
}
}).send({'sup_number': sup_number.value});
} else {
// if this isn't a valid sup number set background color red
sup_number.setStyle('background-color', 'red');
site.value = "No site associated with that SUP number";
}
});
That particular addEvent seems to be empty.
I activated the System - Mootools Upgrade plugin in Joomla and it seems to be working😑 . Judging by my current Chronoform version I might have lost some backend functionality by having the plugin activated but for the time being I am willing to take that risk!
Hi quantum_leap,
Please turn off the MooTools Upgrade plug-in and post (or PM) a link to the form so I can take a quick look.
Bob
Please turn off the MooTools Upgrade plug-in and post (or PM) a link to the form so I can take a quick look.
Bob
PM sent!
Hi quantum_leap,
I got the PM but there was no link in it, should there have been?
Bob
I got the PM but there was no link in it, should there have been?
Bob
Sorry, just pmed the link!
Hi quantum_leap,
This appears to be working OK in FireFox, and IE9 in IE8 & IE9 mode - it fails for me with IE9 in IE7 mode and in Chrome. Though these differences may be a timing issue.
It is failing on the line
The answer is to add a check to make sure that sup_number exists before running the addEvent and then finding a way to re-add the event when the input is 'un-hidden'.
Bob
This appears to be working OK in FireFox, and IE9 in IE8 & IE9 mode - it fails for me with IE9 in IE7 mode and in Chrome. Though these differences may be a timing issue.
It is failing on the line
sup_number.addEvent('blur', function() {
and I think that what is happening is that the hideable forms code removes this input from the HTML when it hides it and then the Ajax code can't find it. The answer is to add a check to make sure that sup_number exists before running the addEvent and then finding a way to re-add the event when the input is 'un-hidden'.
Bob
In such a case it shouldn't be working in all browsers. And why does it work when I activate the moo tools upgrade plugin?
Hi quantum_leap,
It works when you turn off the hideable inputs or upgrade the MooTools library (which breaks the hidable input code) because then none of the inputs are hidden and so the Ajax addEvent code always finds the input.
The differences between browsers are because their JavaScript interpreters behave in slightly different ways when they find an error :-( There may also be some timing differences here about whether or not the input is already hidden when the Ajax addEvent is run.
Bob
It works when you turn off the hideable inputs or upgrade the MooTools library (which breaks the hidable input code) because then none of the inputs are hidden and so the Ajax addEvent code always finds the input.
The differences between browsers are because their JavaScript interpreters behave in slightly different ways when they find an error :-( There may also be some timing differences here about whether or not the input is already hidden when the Ajax addEvent is run.
Bob
This topic is locked and no more replies can be posted.