I wanted to populate a dropdown menu from a table. I tried this:


function shapeup_form_alter($form_id, &$form){
  //drupal_set_message("Shapeup_FORM: {$form_id} \n");
  //This will help you find the $form_id which you need in the first if statement
  
  if ($form_id == 'webform_client_form_4'){
    // load up the select box from the current list of schools
    // Get the cid for schools by looking in the database
    
    $result_school = db_query("SELECT DISTINCT data  FROM {webform_submitted_data}  
      WHERE cid = 1204274450
      ORDER BY data");
      
    $schools = array();  
    $schools[] = 'Select your school (type in the first few letters)';
    while ($school_obj = db_fetch_object($result_school)) {
        $sch_value = _webform_safe_name($school_obj->data);
       $schools[$sch_value] = check_plain($school_obj->data);
     }
     $form['submitted']['school']['#options'] = $schools;
     $form['#parameters'][1]->webformcomponents[1209763732]['extra']['items'] = implode("\n", $schools);

    drupal_set_message("<pre>Shapeup_FORM: $form_id \n".print_r($form, TRUE).'</pre>');

  }

}


The form as it goes to the user has the right data in it and the hidden/extra stuff in the form looks OK. But the data in the database ends up blank :{

Do I also have to update the serialized data in webform_component table? Is there a helper function that would make any or all of this easy?

Comments

ehowland’s picture

I should have said that in this example I had an initial webform that was being used to enter the schools that I then wanted to use in a second webform. Thats why the query is against the webform table.

quicksketch’s picture

Webform depends on the statically entered values of a select list to generate all results (and it seems save in your case). Instead of form_altering to change the form after it's been built, yes a better approach would be to dynamically add more values to the select list options in the webform_components table.

By the way, a very common request has been to make the select list component have a PHP field to retrieve options. Which would also solve your problem.

See this issue: http://drupal.org/node/151603

Seeing that you've got Drupal chops, if you implement the feature I'll definitely commit it. No one seems to step up and I don't have the time or need to implement.

ehowland’s picture

Thanks for being right on top of this.

I am interested in working on this idea. I looked at the dynamicselect patch and at the Webform 2.0 version for Drupal 6. And it seems like the patch would work best if it was part of select. It also looks like with a name change to the filter function that a patch could easily apply to both the Webform 1.0 and Webform 2.0 versions.

It seems like there are two issues 1) the user form for setting up the PHP and 2) the code to run the PHP. Focusing on the second part first (my itch):

Question 1. Where is the best place to add the call to the PHP. It looks like the calling sequence is:

  • webform_client_form
  • _webform_client_form_add_component (recursively)
  • _webform_render_select

It would be tidy to put the call to the PHP within the select.inc file but it looks to me like the entry to that is via the webform_render_select function and at that point the data is already loaded and if I change that data structure, I am right back to where I was with the hook_form_alter.

Now if I update the webform_component table at the same time (top of webform_render_select) that I change the $component then the data does go into the webform_submitted_data table. That seems sort of ugly, but moving select code out of select.inc also seems ugly. Is there a more elegant place to update the database??

Another recommendation for doing it no later than webform_render_select is that then both the _webform_filtervalues and the _webform_safe_name would be run on the output of the PHP. Correct?

Question 2. Are there some helper functions I should be using to update the option data. I looked at:

  • _webform_components_decode($components);
  • _webform_components_encode($components);

But at least if I keep working with _webform_render_select, I already have the component and it is already decoded. Should I be doing a node_load(nid) and then a webform_update(node);

It seems a little weird. I already have the component so to go back and fetch the parent node is kind of odd. But it might be the cleanest way to do it.

I guess, ultimately, this depends on the answer to question 1. What I got to work with depends on where I add the result of the PHP code.

quicksketch’s picture

You should definitely be working with select.inc to accomplish the task. You might look at the "taxonomy.inc" file another user created some time ago for reference, as it is basically the same task also (dynamically loading options from the database): http://drupal.org/node/162948

quicksketch’s picture

Status: Active » Closed (duplicate)

If you decided to implement this feature, please continue the discussion in #151603: Can I put options in a select field from a database query?