Not sure if this is a bug with HS or with the Taxonomy module itself, but if I create a taxonomy tree as a fieldset within, for example, another fieldset, the AJAX requests to retrieve elements further than 1-level deep in the tree fail.

Here is the sample post data (from Firebug) for each type:

As a top-level element (successfully retrieves child terms)
form_id search_form
form_token 5917571ac50ef394c71e2ed786ef97c9
hs_form_build_id hs_form_b80339aa77c3b3f50fb0953fb71a8fc2
hsid 0
keys
negative
or
phrase
taxonomy[16][hierarchical_select][selects][0] 119179

As a child element: (fails to retrieve child terms)
form_id search_form
form_token 5917571ac50ef394c71e2ed786ef97c9
hs_form_build_id hs_form_28c55be35479ff77bbc27a26f0f10346
hsid 0
keys
negative
or
phrase
taxonomy[16][hierarchical_select][selects][0] 119179

As you can see, both requests are nearly the same. Any thoughts as to why it fails as a child form element?

CommentFileSizeAuthor
#10 real_parents.patch1.67 KBwim leers

Comments

wim leers’s picture

Title: HS requests fail if taxonomy tree is not top level element in the form » Improve code that filters out the relevant part of the form in an AJAX request
Assigned: Unassigned » wim leers
Category: bug » task
Status: Active » Postponed (maintainer needs more info)

Please make sure #tree is set to TRUE on every level that leads to the HS and report back. I'm pretty sure that's the cause.

I'll have to make that part of the code more robust I guess.

jrbeeman’s picture

Yep, you got it. Adding #tree = TRUE to the levels above it does the trick. The problem with this particular case, and I see it being an issue elsewhere, is that I'm attempting to inject the HS into an existing form (the advanced search form). So, making everything be a tree will cause existing validation and processing to get hosed.

I don't want to cause any additional pressure on something you may not want to focus on yet, so I can handle this use-case via theming or some other work-around for now. It'd be nice to see it fixed at some point, but there's not rush. I'd be happy to dig into it myself a bit, if you might be able to point me in the right direction.

wim leers’s picture

I agree; that's why I wrote that I have to make this more robust in the first place.

I will have a look at how D6's Forms API handles this, I hope that they do support this, but I actually doubt it.

The cause is in either of these functions, or in how they work together:
- _hierarchical_select_collect_form_parents() -> stores $element['#parents'] in the database for each HS, so that we can find out which part of the form we should render in a AJAX update (AJAX updates happen in hierarchical_select_json())
- _hierarchical_select_get_form_element() -> retrieves an $element of a $form with the given $parents structure

The former stores an inaccurate #parents tree when #tree is FALSE somewhere along the line, the latter then can't find it. You could say we could "improve" the latter to find it anyway, but then you might end up with the wrong element or you might have to search for a long time. So we'll have to find a way to detect the "real" parents of the $element in the former (i.e. calculate our own #parents as if #tree was always set to TRUE along the line). The problem is we only get $element, not $form… (because _hierarchical_select_collect_form_parents() has to be called from the #process callback for the HS form element).

That will probably not be understandable or at least partly so, unless you know the Forms API very well. Let me know if you're going to give it a shot!

jrbeeman’s picture

The specific use case I was trying to do this for (altering the advanced search form to use hierarchical select for selected taxonomies) I've realized isn't a great use of my time, seeing as I can use View Fastsearch + HS Views to accomplish the same goal with finer-grained control.

That said, I'm experiencing a very similar issue when exposing a HS taxonomy in Views. It renders the top-level select element correctly, but fails to return any data from the AJAX request when an item is selected. Is this related, or a separate issue? If it is, should I focus my attention on it?

jrbeeman’s picture

Whoops - I meant to include the post data, as output by Firebug:

filter0
filter1[hierarchical_select][selects][0] 128365
form_id views_filters
hs_form_build_id hs_form_40691192dadbc260fe9ae1c79985e1cb
hsid 0

wim leers’s picture

Views exposed filters work just fine here.

wim leers’s picture

Status: Postponed (maintainer needs more info) » Active

I just remembered: I found a bug in Views, which caused this very problem. You have to install the 5.x-dev version of Views or apply this patch: http://drupal.org/files/issues/hs_compatibility.patch.

This *is* documented in the README:
* Views 5.x-1.x-dev tarball of May 11 or later (http://drupal.org/project/views)

This does not yet fix the #tree stuff though.

wim leers’s picture

My fears have been confirmed:

WimLeers: hm, while I accidentally pinged you, here's a FAPI problem I'm facing. I want to render a specific form item in an AHAH callback. No problem, store #parents, and then find it back. However, I also need it to work if somewhere in the form item hierarchy #tree == FALSE… Do you know of an *elegant* way?
WimLeers: chx ^^
chx: i think no

So, there are only 2 100% reliable ways around this:
1) set some recognizable form property (e.g. '#hs_anchor' => <random number>) and then scan the entire form for these properties with those specific random numbers in an #after_build callback. This allows us to do this "full form scan" only once, i.e. in the first rendering.
2) force form developers to add a new #real_parents property that the developer must fill out himself. This results in faster code, but slower development.

wim leers’s picture

I'm going for option 2. It's not *that* bad to expect this from the developer, and it prevents the code from getting complexer than it already is.

wim leers’s picture

Status: Active » Fixed
StatusFileSize
new1.67 KB

Fixed. Committed patch is attached.

As you can see, #real_parents will simply be used when it is set and is not the empty array.

Let me know if it works for you!

jrbeeman’s picture

In response to the View not working and needing a patch: that should take care of it. hs_views_taxonomy_requirements isn't returning a failure because it's not in a .install file. Moving it into one should help users get the right message.

jrbeeman’s picture

In response to the patch: This is great - I'll give it a shot and see if I can make it work.

wim leers’s picture

Good remark. I'll have to play a bit with the $phase parameter I guess.

Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.

wim leers’s picture

Status: Closed (fixed) » Active

Reopening.

As said in #8, there are only 2 reliable solutions. The first one requires no further work of the developer (it's "automatic"), but is more work. The second one is much easier but requires work of the developer for EACH form.

I implemented the second. But now I will have to implement the first, to solve these issues:
- http://drupal.org/node/260896
- http://drupal.org/node/273702
- possibly also http://drupal.org/node/266960

wim leers’s picture

Status: Active » Fixed

Implemented!

I'm now storing the #name property of each item to find the hierarchical_select form items back. While these properties are NOT guaranteed to be unique, it's up to the developer to make sure that they are. Even the Forms API itself assumes this, and unless you're doing something VERY, EXTREMELY, SUPERDUPER special, you should not bump into any issues.
I mean, if CCK, Views and other complex don't even notice this, we should be safe! :)

Almost forgot: thanks to Earl Miles (merlinofchaos) for the #name tip. I was adding a custom #tracker property, but this makes much more sense. #name is also based on #parents (it's basically: $form['#name'] = implode($form['#parents'], '-');), so I really should've thought of this myself. Thanks, Earl! :)

Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.