Can I put options in a select field from a database query?
dolittle - June 13, 2007 - 21:12
| Project: | Webform |
| Version: | 6.x-2.8 |
| Component: | Code |
| Category: | feature request |
| Priority: | normal |
| Assigned: | whiteowl |
| Status: | patch (to be ported) |
Description
Hi,
Is it possible to write php code in the options field to automatically and dynamically populate
the list of options from a table in the database?
If it`s not possible, could you point me to another way of doing it?
What I want is that the different options will be the recent story posts on my site.
Thanks

#1
I need exactly the same thing. I have succeeded in adding the fields dynamically using hook_form_alter(). Unfortunately, I haven't been able to get Webform to accurately reproduce the dynamically generated content in the email or the submission view.
I'm very close. If anyone has other pieces to this puzzle I think we can make this work. Maybe even create a new component?
#2
Okay, I have found several other requests for this. I have pointed them all at this thread and closed them as duplicates. I will finish a preliminary hack for this soon.
#3
#4
I have finished a very preliminary hack. I have started documenting what I did, and I am providing the source code that I have developed so far. You can find all of this at:
http://www.irolo.net/drupal_webform_and_dynamic_checkboxes
I hope to polish this over the next few days.
#5
What about the Active Select module?
#6
I'm not sure that Active Select does what we need. Not only do you have to generate the selection dynamically, but you also have to save a submitted value to the database and retrieve it later.
#7
I have finished the final version of my dynamicselect component. Documentation and the file are available at:
http://www.irolo.net/drupal_webform_and_dynamic_checkboxes
In addition, a demonstration will be available for a while at my staging site:
http://immaculata.bydesign-area51.com/registration
At this point I think that I have provided enough of a framework for a developer to solve similar problems. I would like to encourage others to expand on what I have done, but I am closing this particular issue for now.
#8
Hi RoloDMonkey ,
Thanks for your tutorial and code. I have used it and ammended it to prepopulate the webform with data from the user profile table. That all works fine. However, I am having trouble getting the default value to set. Its probably really simple. I know this issue is closed, but I am not sure where else to post. Can I post my alterations here for someone to have a quick look?
#9
Hi,
I set this item to active if you don't mind, I was wondering what the status of this component is after release 1.8?
Will your dynamicselect component be part of webform components in this great module?
This way it will be possible to follow up webform development more quicker, right?
Thanks for your consideration already!
greetings,
Martijn
#10
Martijn,
The dynamicselect component that I created was only to meet my needs. I documented what I did so that other developers could create similar solutions.
I do not currently have any plans to turn the dynamicselect into a "real" webform component. I would love to see someone else build on what I did, but I simply do not have the time.
If you need a particular solution but you are not able to write it yourself, you can try the companies that provide Drupal Services or you can get bids from the Paid Drupal services forum.
#11
blairski,
Please post your code as an attached file and I will see if it is something easy to figure out.
#12
I'd certainly be up for including this as part of webform, though I'd like to wrap it into the existing select element as either a separate field or just a checkbox for "Use PHP to generate options" to reuse the existing textarea.
#13
When are you planning to implement this functionality?
I've tried webform 2.x but couldn't find it.
Thanks
#14
Yes, I've got a lot on my plate but I hope to get to this soon.
#15
RoloDMonkey,
Sorry it has take me a while to attach the file. I changed you function _dynamicselect_load_options() to bring in one of the user profile fields (counties). That works fine. I am just getting stuck on setting the default, which should be the users current county that they set in their profile.
#16
There is a beta1 release of webform 2.0.
Will the 2.0 version support this feature?
Please...
#17
No, the first release of 2.0 will not support this feature. I'm very busy with a lot of things.
Again, patches to add the feature would gladly be accepted as long as they are well-written and included in the current select.inc rather than as a another select list. This feature will only be included in the 2.x version as I'm trying to depreciate the 1.x version.
#18
Marked http://drupal.org/node/242644 as duplicate.
#19
I have downloaded the dynamicselect.zip file and looked at the code. Unfortunately, as a newbie it's beyond me as to how to make this work, or to make it into a patch.
It would be extremely useful if anyone could give some advice as to how to use this code.
#20
I can't get this patch to work... any help guys
#21
ok a little update,,
this works,, but for some reason the I can't get the selected fields to display into the submitted email..
I get all other fields but this one,,
is something missing?
#22
Marked #254169: Using hook_form_alter to change options. as duplicate.
#23
Here is a patch for select.inc that was made against 5.x-2.0. It adds a php fieldset which contains a boxes for adding php code that creates defaults and for options. In order to see the (collapsed) fieldset the user must have "use PHP for additional processing" permissions.
This patch also makes the Options box optional (since the php generated data overwrites anything in that field) but adds some error checking to make sure that there are either options or php.
Several weeks ago I looked at the differences between 5 and 6 and it looked to me like it might well apply cleanly against 6 but I have not tested it.
#24
UMM. It seems that the nesting caused an error message to show up when it should not have (claiming no data). A slightly better patch.
#25
Thanks for the patch whiteowl!
The approach in this patch seems a bit strange. Rather than evaluating the PHP when showing the form, you're evaluating when creating it. This makes it so that the select list can't contain truly dynamic values, you basically just saving a little bit of work when setting up the form initially.
This patch should be made to work on display, rather than inserting values and then letting Webform use those options as it did before.
#26
I agree that this is strange but I believe that it is not strange how you think it is strange.
Try adding this as the php Options:
return array('c'=>date('c'), 'r'=>date('r'), 'U'=>date('U'));Off topic here, but I get an error message (which I do not see the source of) about illegal choices if I do not make these associative arrays. Although the error message is different ("An illegal choice has been detected. Please contact the site administrator.") I thought it might be some sort of problem with the special characters, but I do not understand why date('U'), which is just a number, does not work. The patch only evaluates the PHP one time, but I wonder if the function is called several times and the discrepancy of the choices between these calls triggers an error which in turn generates the error message.
When you refresh the form each of these dates updates every time (at least for me).
Every time you generate the form you will see the values from the last invocation of the form in the Options box. This is because (and this is the slightly odd thing) every time the form is generated, the newly generated values are stuffed back in the database so that when the form is processed the data shows up as valid data. Without this step the data does not get entered into permanent storage. This is what you helped me with before in the issue http://drupal.org/node/254169. So the form administrator sees the historical data but the users do not!
So the summary is - yes some strangeness - no it works how you want (I think).
#27
One other thing I did not notice before is that this makes the reporting modules a bit wierd.
I am mostly interested in the table output and that works fine both for both my interest and for the dates (at least as associative arrays which renders the results to be unchanging - not the most useful case).
The odd behavior comes if you go to the results tab and click the view screen for a transaction. A new form is generated from the data, and that new form will have the current date (from the PHP) rather than the original date. This is OK if you are having your users pick a date format, but not if you wanted them to pick a specific time (One week from now, Two weeks from now, Never). This will not be specific to this date example, but to any changing data (sort of the point for using PHP in the first place). This is a wider issue and its solution will require more restructuring beyond the select.inc file.
#28
subscribe
#29
subscribe
#30
subscribe
Ok, I've seen a patch of a patch by whiteowl in #24.
Is it the full patch for the original select.inc, since there is no attached patch in #23?
#31
The full patch is in 24 as an update to the patch that as previously in 23.
#32
There is no patch in #23 and those "-" and "+" signs at the beginning of the lines just don't make sense if I apply #24 on the original select.inc file (I'm using webform 5.x-2.1.1). I've just reversed the logic: all "-" became "+" and now it works, but the result is not so stable.
#33
Hi Madjoe, Could you file your patch please?
Thanks a lot in advance,
greetings,
Martijn
#34
Since I don't know which version of webform do you use, here's the entire select.inc in the archive for 5.x-2.1.
It still have some weird bugs and it's not that stable so this code really does need work, and I'm playing with it right now.
@whiteowl: Is it possible that this does not work as select options with this PHP addition to a select component:
<?php$m = db_query("SELECT nid, title FROM table");
$f = array();
while ($nids = db_fetch_object($m)) {
$obj = check_plain($nids->nid) . "";
$obj_name = check_plain($nids->title);
$f[$obj] = $obj_name;
}
return $f;
?>
I've checked the same PHP code on page.tpl.php and I can see the array elements by doing print_r ($f); but I have problems with creating options for my select box by using this method.
Could you please check my select.inc... did I miss something with your patch?
If I try to Submit this custom PHP code while creating a new select component, and go to see the form, I could only see "select..." option with no other options inside of my "php select box", and if I refresh the same page, I can't see that select box anymore - it just vanishes somehow. Maybe we should escape double quotes before storing custom PHP code like this to the database?
#35
I've created a function func() in my template.php that returns array("A", "B", "C").
If I create a select component, this is what is stored in the database within extra field:
a:2:{s:3:"php";a:2:{s:10:"phpoptions";s:14:"return func();";s:10:"phpdefault";s:0:"";}s:6:"aslist";s:1:"Y";}After I visit the form for the first time, I could only see "select..." as an option in a select component.
After my visit to the form this is the content of the same extra field, but the select component is not visible in my future page visits:
pre_a:3:{s:3:"php";a:2:{s:10:"phpoptions";s:14:"return func();";s:10:"phpdefault";s:0:"";}s:6:"aslist";s:1:"Y";s:5:"items";s:5:"AB
C";}
Take a look at the prefix "pre_" that is the default prefix for my database tables?! The regular "Default value" becomes "pre_".
#36
subscribe
#37
subscribing
#38
-subscribe-
#39
To re-iterate, the approach in this patch is incorrect and need to be rewritten before it is included in the final project. Instead of pulling in the options when configuring the element, the options should be pulled in when displaying the element (or viewing results). This patch needs to be fixed before it's included in Webform.
#40
subscribing
#41
I am probably way off here, but:
You can put a token in the options field. I have experimented where I put %get[model] in the options field, which will show "blah-blah" as the (one) select option if URL to the form is /mywebform?model=blah-blah.
I know nothing about "token creation" but would there be a way to create a token whose value contains the result of a query to the database that brings back the stuff you want to show here? Then you could just put that token in the options field?
BTW this is all for Webform 6.x-2.3
I tried RoloDMonkey's method above but am lost because things have change so much from 5.x to 6.x-2
#42
I put together a 5.x module for dynamic selects. None of the other patches fit the bill for what I needed. It renders the options at display time. I'll gladly port it to 6.x if there is any interest. I currently have the module hosted at http://github.com/ngmaloney/dynamic_select/tree/master
#43
Wow that's great. I would greatly appreciate a port to 6 when you get a chance. I am working on a D6 project now that needs this.
#44
+1 D6, subscribing
#45
+1 for D6!
#46
D6 pls
Need it for emails of all employees in company and don't want to show email addresses on the site (neither displayed nor HTML code)
#47
I'm kind of desparate to get a dynamically created list of checkbox choices on a webform for a project I am working on (D6 and Webform 6.x-2.3). Wondering if there is some other option. Could I add the check boxes via hook_form_alter with a dbquery in there someplace or would that not work?
In a post above I was also wondering if somehow a token could be created (not sure how to create tokens) that could be put as default for this field.
If all else fails I guess I could forget abotu using webform for this particular form, create a content type for it instead and use messaging to email it.
Any direction anyone can give me would be appreciated. ;-)
#48
Here's an alternate rather crude solution that should work:
Create a markup field as your first field. In there, run whatever you need to generate your array of values (recipient names perhaps) for the form select. For each of those values, create and populate a custom session variable. You might want to use an array that uses some other related value (recipient's email address) as a key, so you can do a lookup later to extract that. Store that array in another session variable (or perhaps a global if you can get that to work). ie:
for($i = 0; $i < count($myvalues); $i++) {
$_SESSION['my_webform_var_'.$i] = $myvalues[$i];
}
$_SESSION['my_webform_vars_lookup'] = array_flip($myvalues);
In the webform select field, hand-populate the select entries with your session variables. You'll need to decide on some maximum number:
%session[my_webform_var_0]
%session[my_webform_var_1]
etc
Note you can't have separate value/display here using this syntax, so just make it the display version.
In the webform advanced settings "additional processing" field, grab the user-selected value, translate that into whatever you need the real value to be (like an email address - here's where that reverse-lookup array comes in handy), and place that wherever it needs to go. Finally, unset all your custom session variables.
Comments?
#49
+1 for D6
#50
Here is a 6.x port of the module you put together. I borrowed some of the code from the regular select box in order to email and display the multiple values.
#51
Subscribing
#52
bignab: Great work!
#53
dynamic_select worked for me in D6 to query a Taxonomy vocab and display it in it's proper hierarchical view.
Here's the code I used in the "options" setting for this form component:
$vid = 5;$tree = taxonomy_get_tree($vid);
$options = array('' => 'select...');
if ($tree) {
foreach ($tree as $term) {
$options[$term->tid] = str_repeat('-', $term->depth) . $term->name;
}
}
return $options;
#54
Hi, Where do you put this code from #53 in webform please?
thanks for your reply in advance,
greetings, Martijn
#55
If you have not already created one, add a new form component of type select, or edit an existing one. Either ways, while creating or editing that select component, there is an Options textarea there, copy and paste the code from #53 above.
#56
I get an error stating
Options within the select list must be unique. The following keys have been used multiple times:
* }
#57
same problem here, subscribing!
#58
Bignab and others who got this working,
How should one install this D6 version of dynamic_select?
I've added it to sites/all/modules and enabled the module but it doesn't work.
Do I have to patch my 6.x-2.7 version of webform module like needed when using the 5.x version of dynamic_select?
When I look at the code I see it uses a hook which isn't even available in 6.x-2.7 version of webform.
Please tell me how to get this working!!!
Bartezz
@ quicksketch; will this get into 6.x-3.x? It's a neat feature!
#59
Ok, I've got it working with the code supplied by bignab in #50 and the patch for D5 inserted by hand in the 6.x-2.7 version of webform.module.
To install Dynamic_select for D6;
- download http://drupal.org/files/issues/dynamic_select_6.zip
- unzip to sites/all/modules
- enable the module in admin/build/modules/list
- donwload the attached patch for webform.module 6.x-2.7
- apply the patch
- then in node/[nid]/edit/components you will find you can add a component of the type dynamic_select
- add one and within the settings for this component you can add php under 'options'
Sample code from strikeink, to list the terms of a taxonomy as selectable options;
// change vid to the taxonomy you want to use$vid = 1;
$tree = taxonomy_get_tree($vid);
$options = array('' => 'select...');
if ($tree) {
foreach ($tree as $term) {
$options[$term->tid] = str_repeat('-', $term->depth) . $term->name;
}
}
return $options;
Ofcourse you can implement anything you want as long as it returns an associative array!!!!
See the desciption under the option field;
$options = array();$options["yes"] = "YES";
$options["no"] = "NO";
return $options;
Hope this helps others and also hope quicksketch is willing to apply this to webform so the people can create their own components in the future :)
Cheers
Bartezz
PS. If you've downloaded, applied and tested PLEASE post your feedback here even if it works!!! I see many questions on this forum but not too many replies saying "thank you, the solution you gave me worked!". That doesn't help others nor help improving code!
#60
Another code snipplet...
This one is what I'm using to show titles of nodes of a certain type with a certain term as select options;
$result = db_query('SELECT node.nid AS nid, node.title AS node_title FROM {node} node INNER JOIN sgz_term_node term_node ON node.vid = term_node.vid WHERE (node.type in ("hulpverlener")) AND (term_node.tid = 12)');$arr = array();
while ($record = db_fetch_array($result)) {
$arr[check_plain($record['node_title'])] = check_plain($record['node_title']);
}
return $arr;
Tip: Because I'm not great at SQL I use VIEWS to create a MySQL query which is nice and easy :) Be careful with single and double quotes tho. Don't mix those within the query! And be sure to check_plain the output!
Cheers
#61
Thank you! This is just what I've been looking for. I'm able to use views to make the query and it all works as advertised.
I'm using the snippet above (#60), but I want to display the taxonomy term's value rather than it's numeric id - any tips on doing that? My php skills are pretty rudimentary.
Also, what about displaying several query values for each select component (eg. a taxonomy term and node title)? I've been playing with it for a while but ... you know... the sucking at php thing keeps getting in my way :)
James
#62
Hey James,
Not sure how you are using the snipplet in #60 to show taxonomy terms but anyway... play around with VIEWS!!! In the Views UI when you create a view which isn't anything more than a db query it will give you the query used to create that particular view. That way you can change the snipplet to output anything you want.
If you want to run multiple queries and output the options within the samen select you can do something like this (probably better ways but since you don't know much about php this is probably the easiest);
//define arr as an array
$arr = array();
// do a query
$result = db_query('SELECT node.nid AS nid, node.title AS node_title FROM {node} node INNER JOIN sgz_term_node term_node ON node.vid = term_node.vid WHERE (node.type in ("hulpverlener")) AND (term_node.tid = 12)');
while ($record = db_fetch_array($result)) {
//add each result to the arr array
$arr[check_plain($record['node_title'])] = check_plain($record['node_title']);
}
// do another query
$result = db_query('SELECT node.nid AS nid, node.title AS node_title FROM {node} node INNER JOIN sgz_term_node term_node ON node.vid = term_node.vid WHERE (node.type in ("dokter")) AND (term_node.tid = 16)');
while ($record = db_fetch_array($result)) {
//add each result to the arr array
$arr[check_plain($record['node_title'])] = check_plain($record['node_title']);
}
//when we're done with adding queries to the arr array then return the array
return $arr;
Cheers
#63
I need to have a dropdown in webform where I have to populate data from a view (of all the OG's say). Is this possible....??
#64
#60
Thank you! I've been looking for this functionality in Webform for years...
Maybe this will help someone:
If you want the select list to show more than one column from the query just concatenate the columns alias:
For instance, if we want a select showing node title plus node id with some kind of separator ("-"), all on the same line:
$result = db_query('SELECT node.nid AS nid, node.title AS node_title FROM {node} node INNER JOIN sgz_term_node term_node ON node.vid = term_node.vid WHERE (node.type in ("hulpverlener")) AND (term_node.tid = 12)');$arr = array();
while ($record = db_fetch_array($result)) {
$arr[check_plain($record['node_title'])] = check_plain($record['node_title']) . " - " . check_plain($record['nid']);
}
return $arr;
Just use Views to construct the query with the fields you want to show, and put the resulting SQL as the db_query parameter as shown above (to show the SQL query while editing the View you have to preview it).
As Bartezz said, don't forget to replace double quotes in the SQL statement with single quotes, ex:...WHERE (node.type in ("hulpverlener")) ... change to WHERE (node.type in ('hulpverlener')) )
EDIT
Replace single quotes in the SQL statement with double quotes, ex:
...WHERE (node.type in ('hulpverlener')) ... change to WHERE (node.type in ("hulpverlener")) )
#65
Think we can change the status now. Looks like it's working for everyone.
Hopefully it'll get comitted soon!!!
Cheers
#66
Created a small module called 'webfromredirect' to do that :)
<?php
function webformredirect_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
switch ($op) {
case 'load':
//Replace this number with your form node id
if ($node->nid == 6) {
//SQL query to get the data in the form of nid, title
$result = db_query("SELECT nid, title FROM {node} WHERE type = 'holy_destination' AND status = 1 ORDER BY title ASC");
$select_data = '';
while ($singlenode = db_fetch_object($result)) {
//Getting the data ready for the webform
$select_data .= $singlenode->nid . "|" . check_plain($singlenode->title) . "\n";
}
//Adding the data to the webfrom
//'4' is the select element id which I got from devel module Dev load option
$node->webform['components']['4']['extra']['items'] = $select_data;
}
break; //case break
} // switch end
} // function end
#67
I guess patch #59 doesn't work for 6.x-2.8 version?
#68
Could be I'll look into it asap (remind me when I forget, am very busy with some projects right now).
Hope that when I provide a 6.x-2.8 patch that everyone will test and post back AND that quicksketch will commit...
It's of not much use and rather contra productive to keep having to create new patches and patch new releases if the code has been reviewed and tested by the community.
Cheers
#69
Here ya go:To install Dynamic_select for D6;
- download http://drupal.org/files/issues/dynamic_select_6.zip
- unzip to sites/all/modules
- enable the module in admin/build/modules/list- donwload the attached patch for webform.module 6.x-2.8
- apply the patchPLEASE post back when you've tested!!! Also if it is working as expected....Cheers,Forget about this... posted a buggy patch.
Will work on this tomorrow....
#70
Was missing a line in my patch, dunno how that was possible but here's a proper patch.
To install Dynamic_select for D6;
- download http://drupal.org/files/issues/dynamic_select_6.zip
- unzip to sites/all/modules
- enable the module in admin/build/modules/list
- donwload the attached patch for webform.module 6.x-2.8
- apply the patch
PLEASE post back when you've tested!!! Also if it is working as expected....
Cheers,
#71
I tried this patch just now for the first time, but it works half...
D6 - 6.14
Webform 6.x-2.8
When I try the taxonomy (#53) way, it works. But when I try to get all the titles from a specific node type with a query, I get nothing. The SQL query is directly copied from views.
<?php
$result = db_query('SELECT node.nid AS nid, node.title AS node_title FROM node node WHERE node.type in ('training') ORDER BY node_title ASC');
$arr = array();
while ($record = db_fetch_array($result)) {
$arr[check_plain($record['node_title'])] = check_plain($record['node_title']);
}
return $arr;
?>
Please advice
EDIT
Ok I got it working by doing the opposite as discribed in #64. I changed the single quotes from the views query into dubble quotes and now it works.
<?php
$result = db_query('SELECT node.nid AS nid, node.title AS node_title FROM node node WHERE node.type in ("training") ORDER BY node_title ASC');
$arr = array();
while ($record = db_fetch_array($result)) {
$arr[check_plain($record['node_title'])] = check_plain($record['node_title']);
}
return $arr;
?>
EDIT 2
Doesn't work with Better select.
#72
The new patch works (webform 6.x-2.8, Drupal 6.12).
#71 is correct. In the View query, replace single quotes with double quotes.
#73
Oops my mistake :)
But I think the patch is ready to be committed then right?
Cheers
#74
Yes please, would be great if this would be committed!
Greetings,
Martijn