How to do condition drop-down's that link to a database

Status
Not open for further replies.

rob

Administrator
Moving on from the previous faq on conditional drop downs which you can find here:
http://fabrikar.com/index.php?option=com_smf&Itemid=9&topic=1858.0

What happens if instead of defining the drop downs in the javascript we want to get the drop down data from a database table?

in this example we have the following tables:

countries
--------------
id
label


towns
--------------
id
country_id (this foreign key states which country the town belongs to)
label

make sure you have some sensible data in both tables .e.g.

countries
id label
1 UK
2 France

towns
id country_id town
1 1 London
2 1 Birmingham
3 2 Paris
4 2 Tolouse

Our first drop down is a simple database join element, with the following options
table:countries
Table's Foreign Key Column: id
Table's Foreign Value Column: label

Our second drop down element, called 'town' is the one that will be updated by our selections in the first drop down, and is a dropdown element type with one sub-option:

value:''
label:'Please select a country'

We now should have the two elements set up on our form. Next we need to create a javascript action that occurs when you select an option in the country drop down:

- edit the country drop down
- select the javascript tab and add a new event.
- set the action to be "onchange"
- enter the following in the code text aread:

Code:
//get the country id that has been selected by the user
var cid = this.getValue();

// this is the database table name that contains the information you want to display in the town drop down 
var table = 'towns';

//these are the fields in the 'towns' table
var key = 'id';
var label = 'label';
var foreignkey = 'country_id';


// this is the html id of the drop down element we want to update
var dropdown = 'jos_fabrik_formdata_1___town';

//below here you shouldnt need to edit anything

//we want to create an ajax object to send a request to fabrik's userPluginAjax class - this call contains the variables 
//outlined above and update the second drop down with the data returned from the server

var url = 'index2.php?option=com_fabrik&no_html=1&task=userPluginAjax&method=getFields';
url += '&table=' + table;
url += '&val='+cid;

url += '&key='+key;
url += '&label='+label;
url += '&foreignkey='+foreignkey;

new Ajax(url, {
method: 'get',
update: $(dropdown)
}
).request();

Save your element.

Now so far this will not work, as we have not set up our userPluginAjax class on the server - this is the php code that responds to the ajax request and returns the matching data.
Fabrik provides a sample file for this which you can find in /components/com_fabrik/user_ajax_example.php, In this file Hugh has a great introduction to how this file is to be used, and its worth reading!

For the purposes of this example create new file called /components/com_fabrik/user_ajax.php

We now need to add in the method "getFields" to this script, that is to say the function name that is included in the "method=" part of the ajax url

Here's how my user_ajax.php script now looks

Code:
/* MOS Intruder Alerts */
defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );

class userAjax {
	
	function getFields(){
		global $database;
		//get all the variables passed in by the ajax objects url
		$table = mosGetParam($_REQUEST, 'table');
		$key = mosGetParam($_REQUEST, 'key', 'id');
		$label = mosGetParam($_REQUEST, 'label', 'label');
		$foreignKey = mosGetParam($_REQUEST, 'foreignkey', 'country_id');
		$val = mosGetParam($_REQUEST, 'val', '1');
		
		//run a query on the database to get the matching fields
		$sql = "SELECT $key AS value, $label AS label FROM $table WHERE $foreignKey = '$val'";
		$database->setQuery($sql);
		$rows = $database->loadObjectList();
		
		//write the results of the query back to the browser - the javascript code will then assign
		//the text to the second drop down
		foreach($rows as $row){
			echo "<option value=\"$row->value\">$row->label</option>";
		}
	}
}

Save this file

Now preview your form, and selecting the country should update the town drop down list
 
Rob, if my posting in this forum is inappropriate, please delete. ;)

...just wondering, though; do the hidden fields still get inserted in the database with, say, null values? I only ask as if I have a form that has 3 choices for the drop down and each displayed form has 10 fields (so 30 fields in total...10 shown for option 1, 10 for option 2, 10 displayed for option 3), the db could get quite large quite quickly, no? If this is the case, perhaps a stored procedure could fire to clear these records out?

Or is this no how it works and the point is moot? :)
 
Hi John

No its fine to ask specific questions about the FAQ here. We only more posts started by people looking for general help to more appropriate places.

Your form will post one record to its database table each time someone submits it, recording the selected country/town options. This isn't effected by using the technique outlined in this FAQ.
Your 30 options will be stored in a separate database table - which wont have records added to by the fabrik form.

(Unless of course you create another fabrik form to edit this table to allow you to add drop down options )
 
Hi Rob, I got the form working with the help of a friend and Firebug :) Seems that the user_ajax.php must start with <?php tag, right ?
We had to change the user_ajax a bit, because it used parameters exept Countryid ( not a parameter) but after that it turned out ok.

My records are saved properly BUT they produce an error when i View them or try to open already saved records. Should i hide my elements with javascript, and make new elements to view existing records ?

and ... can i wish for cascading elements like this (without javascript) in the next release ? :)))

Yours
Dag
 
Dag,

I've been struggling with this user_ajax.php example for a couple of days now. Could you post your working version on here? It would help me, and probably a few others, if we could see it.

Thanks,

Bob
 
I'm still trying to understand this one. Is there anyone out there who has a working version of this user_ajax example?

I'm just looking for a solution that shows a dropdown with different regions to choose from based on the country that is selected.

I did take a look at the code with Firebug, and the only thing that seems to be happening is that it just hangs waiting for a response that is never sent. I can't track down the problem, although Dag mentions that country_id is not a parameter. I'm not an expert in php and and don't know what to replace mosgetparam with to make this thing work...

I think Fabrik is a very powerful tool, and for the most part easy to understand, but if I can't get this to work I'm going to have to switch over to a less powerful component. I'd rather not have to, because Fabrik offers endless configuration and reporting options that nothing else can match.

Any help would be greatly appreciated.
 
Is it possible to have multiple conditional dropdown fields? And if yes, how can this be done?

Example:

-> Product Category
-->a, b, c, d
-> Product Subcategory
-->aa; bb; cc; dd
-> Product Attribut
--> red, blue, yellow, green
-> Products
--> Link to Product Page

Thank you,

Stefan
 
Hi,
I tried following Rob's instructions for populating a dropdown from a table, I also used the example you give for the user_ajax file, but I cant seem to get it to work, I'm a graphic designer and have some experience with website design but I dont have much knowledge of databases or php. Probably I'm not replacing correctly some of the variables you use in your example with the corresponding values for my particular tables. How can you help me? It's been days trying to make this work and I'm starting to become hopeless.
The first thing would be to make the first conditioned drop down to work.
Next I need to make more drop downs based on the previous ones.
Please let me know what info I need to send you so that you can help me locate the mistake. ???

Thanks a lot !
Herta
PS. By the way, I already updated to SVN.
 
Is it possible to 'condition' text fields, per se? I am not sure what you call it, but have seen some forms that I would describe as ajax conditioning, for lack of proper jargon. ;)

When you start to type text in the field, a list of options already in the db appear under the text field, allowing you to click the displayed option and then, in turn, populating the field; a good example is on http://www.kayak.com/ In the "To" field, start typing a city or state or something and you'll see what I mean. Is this a form of "conditioning?" :) Looks like some fancy onkeypress trigger, but not sure how they get the data below the respective field. ;)
 
Hi Hugh,
Thanks for the reply.
Ok, my first table is

joomla_codarchivo1
id descripcion
1 REPBOL
2 PROGRAMAS BILATERALES, etc.

the second table
joomla_codarchivo2
id codigo descripcion
1 1 Legal
2 1 Planificación
3 2 PROMIC AC

The fabrik element where I need to load the drop down is called categor_a_secundaria
The first element is a simple database join to my first table called categor_a_primaria and this is the javascript I have used in it:

var cid = this.getValue();
var table = 'joomla_codarchivo2';

var key = 'id';
var label = 'descripcion';
var foreignkey = 'codigo';
var dropdown = 'joomla_fabrik_formdata_212___categor_a_secundaria';
var url = 'index2.php?option=com_fabrik&no_html=1&task=userPluginAjax&method=getFields';
url += '&table=' + table;
url += '&val='+cid;

url += '&key='+key;
url += '&label='+label;
url += '&foreignkey='+foreignkey;

new Ajax(url, {
method: 'get',
update: $(dropdown)
}

).request();


the ajax file code is:

<?php

/* MOS Intruder Alerts */
defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );

class userAjax {

function getFields(){
global $database;
//get all the variables passed in by the ajax objects url
$table = mosGetParam($_REQUEST, 'table');
$key = mosGetParam($_REQUEST, 'key', 'id');
$label = mosGetParam($_REQUEST, 'label', 'label');
$foreignKey = mosGetParam($_REQUEST, 'foreignkey', 'codigo');
$val = mosGetParam($_REQUEST, 'val', '1');

//run a query on the database to get the matching fields
$sql = "SELECT $key AS value, $label AS label FROM $table WHERE $foreignKey = '$val'";
$database->setQuery($sql);
$rows = $database->loadObjectList();

//write the results of the query back to the browser - the javascript code will then assign
//the text to the second drop down
foreach($rows as $row){
echo "<option value=\"$row->value\">$row->label</option>";
}
}
}
?>

I'm sending you a PM with the link to my form. I'm sorry I didn't use the proper code formating in this post but it's not working in my browser.

Thanks in advance for your help.
Herta
 
I think you are targetting the wrong ID. Try joomla_corresp2008___categor_a_secundaria as the dropdown variable.

-- hugh
 
Hugh,
Thanks so so much¡ It works now. It was just that.
Now, for adding more drop downs based on the last one, I imagine I follow the same procedure, do I need to add code also to the ajax file?

Thanks you ;D

Herta
 
Well the main problem there is that the technique we're using in this example uses a built in feature of the mootools Ajax routine to replace the content of a specific HTML element id. Updating more than one element would either mean customizing the javascript to manually process the returned content, or add another AJAX call for each element you want to update.

So yes, you can use the same technique, but you'll have to add another Ajax call (and function in user_ajax.php) for each element you want to update.

-- hugh
 
Thanks again for your help.

I´ve been trying to make it work, what I did was add the javascript to the second element to update the third and paste again the same function you gave us in your example in the ajax file, I just duplicated it. But it does not work. My ajax file looks like this now, please I really appreciate your help, If I get this right I´m sure I will be able to continue on my own.

Code:
/* MOS Intruder Alerts */
defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );

class userAjax {
	
	function getFields(){
		global $database;
		//get all the variables passed in by the ajax objects url
		$table = mosGetParam($_REQUEST, 'table');
		$key = mosGetParam($_REQUEST, 'key', 'id');
		$label = mosGetParam($_REQUEST, 'label', 'label');
		$foreignKey = mosGetParam($_REQUEST, 'foreignkey', 'codigo');
		$val = mosGetParam($_REQUEST, 'val', '1');
		
		//run a query on the database to get the matching fields
		$sql = "SELECT $key AS value, $label AS label FROM $table WHERE $foreignKey = '$val'";
		$database->setQuery($sql);
		$rows = $database->loadObjectList();
		
		//write the results of the query back to the browser - the javascript code will then assign
		//the text to the second drop down
		foreach($rows as $row){
			echo "<option value=\"$row->value\">$row->label</option>";
		}
	}

}


class userAjax {
	
	function getFields(){
		global $database;
		//get all the variables passed in by the ajax objects url
		$table = mosGetParam($_REQUEST, 'table');
		$key = mosGetParam($_REQUEST, 'key', 'id');
		$label = mosGetParam($_REQUEST, 'label', 'label');
		$foreignKey = mosGetParam($_REQUEST, 'foreignkey', 'codigo');
		$val = mosGetParam($_REQUEST, 'val', '1');
		
		//run a query on the database to get the matching fields
		$sql = "SELECT $key AS value, $label AS label FROM $table WHERE $foreignKey = '$val'";
		$database->setQuery($sql);
		$rows = $database->loadObjectList();
		
		//write the results of the query back to the browser - the javascript code will then assign
		//the text to the second drop down
		foreach($rows as $row){
			echo "<option value=\"$row->value\">$row->label</option>";
		}
	}

}

?>
Thank you
 
OK, put the user_ajax back the way it was (get rid of the stuff you copied).

Now just edit the javascript on the third menu to use the correct table, key, foreignKey, etc.

BTW, I can no longer access the edit form. You'll have to create me an account if you want me to look at the javascript again.

-- hugh
 
Ok, I changed back the ajax file, I also put the onchange javascript on my third element menu, not on the second element as I thought. But it still not changing. The table to populate the third drop down is called joomla_codarchivo3, and my third element is 3ra_categor_a, a drop down, with value '' and label select a category. I have changed the permissions so you can access again through the same link I sent you.

I appreciate very much your help.

Herta
 
It'll be quicker if I just do this for you. Can you PM me a backend login. Do you have JoomlaExplorer or xTplorer installed?

-- hugh
 
Status
Not open for further replies.
We are in need of some funding.
More details.

Thank you.

Members online

Back
Top