And more precisely, one using a custom field. I'm trying to achieve an interval based filter with a select list for the interface.
As of now, I managed to make the filter appear by implementing hook_views_data :
function interval_select_views_data() {
$data['node']['field_pv_value'] = array(
'group' => t('Annonce'),
'title' => t('Prix de vente du bien'),
'help' => t('Filtrer sur intervalles de prix.'), // The help that appears on the UI,
'real field' => 'field_pv_value',
'filter' => array(
'handler' => 'interval_select_handler_filter_interval',
),
);
I wrote a custom handler derived from views_handler_filter_numeric ; the filter is taken into account and shown when I expose it, and the query is affected so I guess I did fine so far.
But whenever the query gets executed, I got an "Exception: SQLSTATE[42S22]: Column not found" error, because the query searches for the field on the node table where it isn't, because the data is in the field table (field_data_field_pv in this case).
I tried several join parameters in the views_data hook (Views 2 style), joining the node table with the other via entity_id, but couldn't manage to make the thing work.
I think I'm close, but would welcome some help because I'm stuck and can't find any info on this particular case.
| Comment | File | Size | Author |
|---|---|---|---|
| #14 | interval_select.zip | 8.55 KB | Countzero |
Comments
Comment #1
merlinofchaos commentedYou need to paste your handler code.
Comment #2
Countzero commentedIt's still very messy and far from production state, but here it is :
It's basicaly a cut and paste from the original handler. The query seems correct except for the wrong field :
Comment #3
merlinofchaos commentedWell, you've attached you field ot the node table:
So that is the table that it thinks it's going to add it to. You probably need to attach it to the table that field API is using, which I believe is the actual name of the table the field is on.
Comment #4
Countzero commentedI tried this code :
... simply replacing 'node' with the field's table name, and got this error :
... repeated four times.
Comment #5
merlinofchaos commentedAdditional comments:
1) Since you're modifying existing tables, not declaring your own, you should be using hook_views_data_alter
2) If that field exists, probably the array_merge_recursive() is what's screwing you up there. Use the hook_views_data_alter() and make absolutely sure you're not colliding with already existing field. YOu can use a pseudo field and use 'real field' to make sure the field name is correct.
Comment #6
Countzero commentedIt worked ! And in the meantime, I understood something new : I really thought hook_views_data was mandatory for any handler.
For the record, here's the definitive code I placed in my .views.inc:
Thanks a lot for your time.
As usual, I'm amazed at the same time at how the solution was elegant and how hard it was to find the info.
Comment #7
neoglez commentedThis is an enormous important piece of info that should be included in the docu, all we know so far (as per docu.) about hook_views_data_alter is that it should be in my_module.views.inc.
Comment #8
neoglez commentedComment #9
Countzero commentedSorry to reopen (kind of), but I have another problem : I stumble on the 'An illegal choice has been detected' issue filed here http://drupal.org/node/1177882.
I suspect my select lists are causing the trouble. They're produced that way (same as above, just repeating for convenience) in the value_form method :
And here is the op_between method overwritten by my handler :
I couldn't grep the message in Views code to see what triggers it.
The view works fine otherwise, except it seems to limit the results even if the default choice of 'Any' ('Indifférent' in french) is chosen in the list.
Comment #10
Countzero commentedI noticed that my selects don't get the 'Any' value, so I looked into exposed_translate in views_handler_filter.inc.
If I comment this part :
... the view generates one more message. What's strange is that dpm'ing $form['#options'] never outputs my custon filters but does print info about regular ones (mean : normal filters based on select widget fields).
So, the message is related to my issue, but the code doesn't seem to affect the custom selects.
Not sure about anything now ; I'm just trying to help people helping me.
Comment #11
Countzero commentedProgressed a bit : One of my two very similar filters was causing the loss of records, because null values are not considered. So the issue actually splits in two, but all two problems are about filter handlers writing, so I'm sticking with this issue alone.
Here are the two issues :
1 - How to modify the query in case of a select widget filter to add an OR clause to pull rows with NULL values for the field ?
2 - How to explain, and get rid of, the error message 'An illegal choice was detected etc.' ?
Hope it's clear and interesting enough to obtain help from experimented views devs.
Comment #12
Countzero commentedFor point 1, I managed to condition the add_where to fit my needs, and saw some examples of adding OR clauses elsewhere in the code. Just for the record it's done like that :
So only the "Illegal choice" message needs to be explained, given it doesn't seem to prevent the view from functioning, except for the preview and th annoying message.
Putting this issue back to 'Support Request' until some kind of answer is given, or until a maintainer wants to discard it.
Comment #13
dawehnerSuch errors are hard to track from just looking at it. Perhaps it would help if you could bundle this into a module
so it's reusable.
Comment #14
Countzero commentedHere is the module. It's very case specific, so please don't take it for anything pretending to be universal.
Comment #15
Countzero commentedAnother information : when I set the filter values to be remembered, they are not.
Comment #16
Countzero commentedAfter further investigation, including dumping info from form.inc, I'm pretty sure this has something to do with my handler not providing a default value.
If I set the #value in value_form, the error disappears. Of course, it's not a solution because then the filter always behaves like the user had entered the value I set, but it's the best hint I got yet.
So I'm gonna look at the original handler code and try to figure what method I should override to provide a default value. Any clue would be welcome as I'm at the very limit of my skills here.
Comment #17
dawehnerSo the default value is something like $this->value['value'] but you probably want perhaps $this->value['interval']
Comment #18
Countzero commentedSorry but I'm not sure where to put this code.
Comment #19
dawehnerOh this is just a quote from your code, you expect something like value['value'] in the quoted code.
But your form looks totally different.
Comment #20
Countzero commentedWell, I just added an ['interval'] element and try to manage it as I can. As I don't really understand the processing of all this, it's hit and miss.
Setting something in option_definition doesn't seem to do any good.
I tried
But it doesn't work either. I'm a bit lost.
Before your post, I was reduced to comment the form validating code in form.inc. I know it's genocidal from a kitten point of view, but the view works perfectly that way. I can't of course go production with this but it'll have to do as of now.
If you'd be glad enough to explain to me the basics of default values in filter handlers, I could try to do something, but as of now I'm clueless.
Comment #21
Countzero commentedI tried various combinations with this array and cannot change anything. Even removing it entirely dosn't affect the handler's behavior.
I looked into the code of many (MANY) other handlers and couln't figure out how these defaults are handled. Googling about filters handlers led me to examples but no really meaningful explanation.
So I'll stick with my kitten slaughtering solution as of now and see if I can wrap my mind around this problem next week.
Thanks for your help.
Comment #22
dawehnerYou could probably use the same kind of structure.
Comment #23
jphil commentedHow did this turn out in the end?
Comment #24
Countzero commentedIt's been a while now, but if I remember correctly, kittens got killed in the process, because I couldn't figure out how to implement the correct default values.
Comment #25
ejustice commentedI don't know if this will help you, but I've got a custom widget that has an optgroup for the select. For my view I wanted to allow users to select based on the values from this select. This was causing havoc with selecting all. I ended up creating my own custom views_handler_filter that extends views_handler_filter_in_operator. Then I created my own get_value_options(). In here I could set $this->value_options to my 2D array for the optgroup so that the drop down would look like the expect and then a 1D array version of the data to $this->value. The main downside I've found is that the fact that "select all" is the default isn't reflected in the views UI.
Comment #26
kars-t commentedDear fellow Drupal enthusiasts,
this issue is now lasting for a very long time in the issue queue and was unfortunately never solved. As Drupal is a open source project everyone is helping on voluntary basis. So that this is was not solved is nothing personal and means no harm. But perhaps no one had time to deal with this issue, maybe it is too complex or did not describe the problem comprehensibly.
But this issue is not the only one. There are thousands of issues on Drupal.org that have never been worked on or could not be processed. This means that we are building a wave that is unmanageable and just a problem for the Drupal project as a whole. Please help us keep the issue queue smaller and more manageable.
Please read again, "Making an issue report" and see if you can improve the issue. Test the problem with the current Core and modules. Maybe the problem doesn't exist anymore, is a duplicate or has even been solved within this issue but never closed.
Help can also be found for it on IRC and in the user groups.
In order to remove this issue, I have set this issue to "fixed".
If there is new information, please re-open the issue.
--
This issue was edited with the help of Issue Helper
Comment #28
tuwebo commentedHi all,
Sorry, but I'm opening this issue, since looks like it never got solved with a clear solution, and I have one that it is working for me, and for my case.
In my case, I wanted to filter a view by a price_field using a custom checkbox exposed filter and "between" operator (pretty similar to what we have in the issue's description, which uses a select list instead).
I just come up with this solution, that it is working for me (I didn't test it very much, but maybe you guys could help me here).
You have to take in account that:
The "key" for me was views_handler_filter::value_form(&$form, &$form_state) function which I have overwritten inside my custom class in this way:
After this code, every time I check/unckeck one checkbox, the view gets updated "magically" (thanks merlin) with the correct min/max values. It means, that it will get the lowest and highest price selected from all checkboxes that have been checked.
Hope this help, and hope you guys send some feedback here since I don´t know if I am doing it right or wrong, but it is done ;)
Comment #29
mustanggb commented