Download & Extend

Form rebuild overwrites selected values

Project:Hierarchical Select
Version:7.x-3.x-dev
Component:Code - Taxonomy
Category:bug report
Priority:normal
Assigned:Unassigned
Status:active

Issue Summary

Problem:
Using preview resets the HS-taxonomy field.

Detail:
Preview uses form rebuild ($form_state[rebuild] = true). If form rebuild is activated, the function "form_hierarchical_select_process" is called twice. First time calling hierarchy is drupal_process_form > form_builder > form_hierarchical_select_process (-> $element is generated correctly). Second time calling hierarchy is drupal_rebuild_form > form_builder > form_hierarchical_select_process (-> $element is generated with empty default values). Second call overwrites first call, therefore the generated element is empty.

Is there anybody who can confirm this? Or is there any related issue I didn't saw?

Comments

#1

I can confirm this is occurring with latest version of Hierarchical Select.

At least now I know why it's happening!

#2

I can confirm this too. Is there already a solution found for this?

#3

Does it maybe has something to do with the caching on the javascript side?

#4

I found out that I can fix it with an own process function called before 'form_hierarchical_select_process', where I unset the #value property of the element array.

#5

@robinvdvleuten: could you please post a patch to that purpose?

#6

It isn't a patch for the module itself. I wrote a function for my form where I unset the values;

<?php
/**
* Hierarchical select form element type #process callback.
*/
function educatief_relation_form_hierarchical_select_process($element, &$form_state, $complete_form) {
    if (isset(
$form_state['storage']['hs']['last_hsid'])) {
       
$form_state['storage']['hs']['last_hsid'] = -1;
    }

    if (isset(
$form_state['storage']['hs']['js_settings_sent'])) {
        unset(
$form_state['storage']['hs']['js_settings_sent']);
    }

    return
$element;
}
?>

The function is added in the config array of my hierarchical select like this;

<?php
$form
['educatief_relation'] = array(
       
'#type' => 'hierarchical_select',
       
'#required' => TRUE,
       
'#process' => array(
           
// Add our process function before the original proces function.
           
'educatief_relation_form_hierarchical_select_process',
           
'form_hierarchical_select_process',
        ),
       
'#config' => array(
           
'module' => 'hs_smallhierarchy',
           
'params' => array(
               
'hierarchy' => $tree,
               
'id' => 'educatief-relation',
               
'separator' => $separator,
            ),
           
'save_lineage' => FALSE,
           
'enforce_deepest' => FALSE,
           
'entity_count' => FALSE,
           
'require_entity' => FALSE,
           
'resizable' => FALSE,
           
'level_labels' => array(
               
'status' => FALSE,
               
'labels' => $labels,
            ),
           
'dropbox' => array(
               
'status' => FALSE,
            ),
           
'editability' => array(
               
'status' => FALSE,
            ),
           
'animation_delay' => 300,
           
'exclusive_lineages' => array(),
           
'render_flat_select' => 0,
        ),
       
'#default_value' => $lineage,
       
'#weight' => $weight,
    );
?>

It looks like the module is tricked and thinks that it has to re-render the hierarchical select dropdowns.

#7

Thanks @robinvdvleuten - I was able to use your answer to help solve a different issue I was running into. Documented in #1843722: Form rebuild doesn't preserve input values or #default_value.

#8

@covenantd Good to hear :) Does it also help for solving this issue?

#9

We had this same issue when used with EntityConnect module.
When returning from a "child" node form, the values were reverted to none.

Commenting out the [code]drupal_array_set_nested_value($form_state['input'], $element['#array_parents'], array());[/code] in hierarchical_select.module (line 808) seems to fix the issue when used with EntityConnect.
I haven't noticed any adverse effects from commenting it out (yet).

If the maintainer could clarify why is that command needed in the code, or provide an alternative fix, I'd be happy.

AttachmentSize
1764350-9-hierarchical-select-does-not-preserve-values-on-form-rebuild.patch 789 bytes

#10

#9:

Well, the clarification why that specific line is needed is just above the line that you commented out ;) It's a pretty extensive explanation; more than most other Form API black magic.

It's nice that this solves the problem for you, but that doesn't imply this is a structural solution. To come to a structural solution, you'd need to test whether this adversely affects other HS API implementations (especially the most used one: Taxonomy), in different configurations (i.e. with and without save_lineage , with and without enforce_deepest ; at least those 4 combinations). Besides that, you would need to research why this behavior was necessary in Drupal 7 and is no longer needed in Drupal 8.

I know, that's a lot to ask for. But this is a deceivingly complex module on the inside, because Form API is not well-designed enough to support as complex form elements as Hierarchical Select. It's also the only way to prevent us from fixing one (narrow) use case and at the same time breaking many others.

#11

Ok, we did run into some issues with that patch.
Occasionally, when deleting items from Dropbox, HS would decide to clear that specific dropbox completely.

To combat that, I made a new patch that makes sure the drupal_array_set_nested_values gets called on ajax requests only (when adding/removing items from dropbox).

It should be possible to make some extra checks for when JS is disabled, but Dropbox doesn't seem to work without javascript anyway (well, adding items atleast).

AttachmentSize
hierarchical_select_does_not_preserve_values_on_form_rebuild-1764350-11.patch 859 bytes

#12

Rerolling patch, caused Undefined index warnings (why can't PHP just gracefully check for isset when calling for something..).

AttachmentSize
hierarchical_select_does_not_preserve_values_on_form_rebuild-1764350-12.patch 903 bytes