views:

367

answers:

4

I am working with a hook_form_alter on a CCK type (for you drupal-ers). I have a field that is normally a select list in my node form. However, in this instance, I want to hide the select list, and populate its value in the form with an SQL query.

Everything was going nicely. I could see that my desired value was showing up in the HTML source, so I knew my query was executing properly. However, when I submit the form, it only inserts the first character of the value. A few of my tests were values of 566, 784, 1004 - the column values were 5,7,1, respectively.

At first I thought it had to be the DB column attributes, but when I removed my form_alter that makes the field hidden and select the value manually, the correct value is inserted?!?

   <?php
function addSR_form_service_request_node_form_alter(&$form, $form_state) {
       if (arg(0) == 'user' && is_numeric(arg(1))) {
        $account = arg(1);
        $club = 2589;
        $form['field_sr_account'] = array( '#type' => 'hidden',
        '#value' => $club
        );

           }
}


?>

Can anyone see why only the first character would be inserted??

Note: I have tried deleting and recreating the column, using #value & #default_value, and it is still submitting only the first character of the integer. Also, I eliminated the submit handler as a possible cause by removing it, which still resulted in only one character being submitted

More Updates - Still Searching! Okay, some good questions. Allow me to answer them:

  1. The DB column type is integer(4)
  2. The HTML the hook produces is :

    input type="hidden" name="field_sr_account" id="edit-field-sr-account" value="2589"

Latest Update: I think the issue has been narrowed to the structure of the array. When I do var_dump on this field after the form alter has been processed, this is what I get..

[43] => Array
        (
            [#type] => hidden
            [#default_value] => 2589
            [#post] => Array
                (
                )

            [#programmed] =>
            [#tree] =>
            [#parents] => Array
                (
                    [0] => field_sr_account
                )

            [#array_parents] => Array
                (
                    [0] => field_sr_account
                )

            [#weight] => 0.016
            [#processed] => 1
            [#description] =>
            [#attributes] => Array
                (
                )

            [#required] =>
            [#input] => 1
            [#process] => Array
                (
                    [0] => form_expand_ahah
                )

            [#name] => field_sr_account
            [#id] => edit-field-sr-account
            [#value] => 2589
            [#defaults_loaded] => 1
            [#sorted] => 1
        )

What is the structure of the field that I can set the form value to. It's gotta be something like what abhaga is suggesting..

A: 

Ok take a look at http://api.drupal.org/api/drupal/developer--topics--forms_api_reference.html#hidden versus http://api.drupal.org/api/drupal/developer--topics--forms_api_reference.html#value

It is also recommended you use value instead of hidden. You can find this info on http://api.drupal.org/api/drupal/developer--topics--forms_api.html/6

Also, type hidden is not allowed to have properties your assigning to it so this may be causing a problem. Any usage problems you may be having with the forms API should be answer in those resources as I"m still a little unclear on what you're trying to accomplish... specifically with the submit button.

Old answer:

Ok if I understand this correctly $club is not being set correctly. If the first result from your query is the number your looking for then this should work.

Try calling

<?php print_r(db_fetch_array($result)) ?>

to get a look at everything returned from the query.

I'm a little unclear as to what is being set incorrectly. If it's #value inside your associated array then the culprit must be the query. If #value is being set correctly and whatever your doing with it later may be the culprit (not shown here). If its the values in your $form_state I don't see that your using $club here at all.

Also, in your addSR_submit_function you don't seem to be using the $form variable, or using $club for anything except for setting the message which appears at the top of the page your on when it's called.

I may need some further clarification as to what exactly is going wrong.

Also, when you're calling drupal_set_message function, are you just doing this for debugging purposes?

Derek Litz
It's a little tough because there are elements in the form alter that don't pertain at all to the issue. 1-the drupal_set_message is for debugging. 2-The reason $club isn't called in the submit function is that all the elements of the form should be submitted with custom submit handler, even if not explicitly called, right? I could be wrong on this, but why would it submit only the first character? 3- I can verify that the result of the SQL query is correct by looking at the HTML source of the input element through firebug.
cinqoTimo
Updated answer, hope that sheds some light on your problem.
Derek Litz
I tried #value (in current post) and #hidden, as well as with and without the added attributes (#size and #maxlength), with no success. The other code in the submit function is overridding the uid of the node for a reason that is specific to my application, but unrelated to this issue.
cinqoTimo
A: 

Shouldn't you check

drupal_set_message($form_state['values']['field_sr_account']);

instead of

drupal_set_message($club);

in addSR_submit_function ?

OK, just a quess: not sure what type db_result returns for your query, may be it has something to do with types conversions? So this is to make sure value is int.

'#value' => (int)$club
Kniganapolke
drupal_set_message($form_state['values']['field_sr_account']); outputs the correct value on the following page (after insert), but the database value is the same (first char only)
cinqoTimo
Could you post the code that does INSERT into database?
Kniganapolke
No code for that - Drupal brings it in automatically with form submission. Besides, SQL is reliable, so it is either the format of my array, or a bug in the way CCK handles the field. In other words, the fact that the correct first character makes it to the DB every time makes me trust the SQL and be suspicous of the code...
cinqoTimo
A: 

cinqoTimo, Out of curiosity what kind of CCK field is this? Is it a Integer, Decimal, Float? and do you have any special parameters on that field not normally on by default? What is the column type in the db?

Can you post the html output of the form. That might give a clue as to what might be going on.

Are you using any javascript to edit any values for this field?

Have you tried outputting the value results from addSR_form_service_request_node_submit hook? Any difference there.

Sorry for all the questions. Just thinking out loud as it seems you have covered most of your bases.

Jeremy Heslop
+2  A: 

Since the field you are trying to change was originally using a select widget, CCK will be looking for $form_state['values']['field_sr_account'][0]['value']. By setting the field to a #hidden type and setting #value, you will get its value in $form_state['values']['field_sr_account']. CCK will try to access the first element of that and end up with the first character of the value.

Updated: The easiest way to achieve what you need would be to do something:

function addSR_form_service_request_node_form_alter(&$form, $form_state) {
   if (arg(0) == 'user' && is_numeric(arg(1))) {
    $account = arg(1);
    $club = 2589;
    // Use this property to store the value to restore back
    $form['#field_sr_account'] = $club;
    $form['field_sr_account'] = array( '#type' => 'hidden','#value' => $club);
   }
}

/*in your submit handler, restore the value in the proper format*/
$form_state['values']['field_sr_account'] = array('0' => array('value' => $form['#field_sr_account']));

Old Answer

One way of accomplishing what you are trying to do is to copy the whole $form['field_sr_account'] into $form['#field_sr_account'] and then provide the value through the SQL query in the right format in the submit handler itself.

abhaga
Thank you, the best explaination I've heard for why this is happening. I'm a little unclear about the second part. Do you mean that I should set the field to hidden in the form alter, then do a query in the submit handler? Like $form['field_sr_account'] = $sql_query and then $form['#field_sr_account'] = $form['field_sr_account'] ---Is that what you mean by copy?
cinqoTimo
I have suggested a easier way to achieve what you need although it doesn't feel quite the Drupal way :)
abhaga
hmm, something is amiss here. When I run that snippet, I get warning: preg_match() expects parameter 2 to be string, array given in bootstrap.inc on line 777. I checked that function and it is - function drupal_validate_utf8($text) { ~777~ return (preg_match('/^./us', $text) == 1); so it is failing to validate as utf8. The HTML value for the field is null.
cinqoTimo
Hmm.. strangely I didn't get an error when I tried but looking at the official documentation, `#value for type #hidden` can only be `text or number`. Hence using an array as value is problematic.You can instead keep the value in a different property in `$form`and assign it back in `$form_state['values']` in the submit handler.
abhaga
@abhaga - When we settled this, I was able to assign the value in the form_alter, and then reassign it in the submit handler and it worked. I am running into the same issue but with a select list, meaning I can't assign it in the form_alter. Is there another way to do this?
cinqoTimo