I've posted this up various places for a while, but have had no luck finding somebody willing to/who knew how to help me out. So, although it seems to me like a rather simple problem, I've turned to the paid forum for assistance.
I have a "review" content type where users submit reviews of "businesses", which are linked by a reference field in the review. In one field of the review content type, users select whether or not they had a bar tab. They are given the options of None, Drinks, Food, and Both. When they submit their option it is stored in the database as a float value, with None being stored as 0, Drinks as 1, Food as 2, and Both as 3. I then avg all of these values into a single field, using computed field, to display on the pages of the businesses. So, if the a business has an average value of .5 for bar tab it shows up as "None", a value of 1.2 as "Drinks", etc.
I then have a view which displays teasers of all business pages, and the users can filter the results by the results of fields on the business page. One such filter is the Bar Tab, and other filters are for fields with the same functionality. I have used hook_form_alter to change the text field filter into dropdown menu to display the options for the filter, so users have a selection of words instead of filtering by entering numbers, which makes no sense from the user's perspective:
<?php
function dropdown_bartab_form_views_exposed_form_alter(&$form, &$form_state) {
$field_id = 'field_venue_bar_tab';
// Only alter forms with the necessary field
if (isset($form[$field_id .'_value'])) {
// Build a query to get all node ids having the specified field
$query = new EntityFieldQuery();
$results = $query->entityCondition('entity_type', 'node')
->fieldCondition($field_id, 'value', 'NULL', '!=')
->fieldOrderBy($field_id, 'value', 'ASC')
->execute();
// Attach the field values to the nodes
$nodes = $results['node'];
field_attach_load('node', $nodes, FIELD_LOAD_CURRENT, array('field_id' => $field_id));
// Add a default so the filter is optional
$options = array(
'' => 'Any',
'0' => 'None',
'1' => 'Drinks',
'2' => 'Food',
'3' => 'Both',
);
// Alter the field
$form[$field_id .'_value']['#type'] = 'select';
$form[$field_id .'_value']['#options'] = $options;
$form[$field_id .'_value']['#size'] = 1;
}
}As you can see, if a user selects "Drinks" as the option in the filter, only pages with a value of 1 in the float field will show up. However, as far as the user is concerned, their selection of "Drinks" should filter all pages with a displayed "Drinks" value, or a float value of >.75 && <=1.5.
Somehow, I'd like to alter the functionality of this filter so that it works as it should, as perceived by the user. The best suggestion that I've had on how to fix this is by altering the entry before submission. Based on this, I'd like to intercept the integer values submitted by this dropdown value before they are submitted, and alter them into a range. In another module, I used a #validate function of $form_state['values'] = str_ireplace(".", '', $form_state['values']); to replace a comma with nothing. Could I use a similar strategy to, let's says, replace 1 with >.75 && <=1.5?
Otherwise, are there any suggestions for another way to go about tackling this issue? Since I'm here, I'd also like to alter the form into checkboxes instead of a dropdown if possible. This way, users could filter by venues that have a value of both Drinks and Food, or Drinks and Both, at the same time instead of having to perform multiple filtered searches.
I have little-to-no budget, so let me know what you deem appropriate. My deadline is ASAP. The rest of the site is built, and although it functions without this feature, I'd like to have it in before the site goes live on Aug 1. Whatever is developed may be contributed back to the drupal community, although I'm not sure how useful it will necessarily be to others. Thanks in advance for any and all assistance.
Comments
At first glance you seem to
At first glance you seem to be going at this hard way.
It seems bar tab is optional and can have two values, Drinks and Food
I would have use a vocabulary, add the values Drings and Food, then added a taxonomy term reference field to the content type making it optional and allowing multiple values. You can then add a filter on the new field.
You could also use an integer list for the field type
Either approach gets rid of the math and is more direct
Hmm, I guess that does make
Hmm, I guess that does make sense for this field in particular. However, there are some others, one in particular, where I don't think that it would work. The site is for rating music venues in some fashion, and one thing that users are asked to give feedback on is what degree of sound reinforcement they had. The set-up is the same as the bar tab field, except that the options are None, Vocals Only, Partial, or Full Reinforcement. In this situation, it seems that the result has to be an average of user experiences to show the correct value.
But, you just made me realize also, that in this situation, if there was one review of "none" and one of "partial", then it would display as vocals only...which is even less accurate. Maybe I do need to revisit my model...
That sucks, but I guess it's better than having an unnecessarily complicated aspect of the site.
However, if using the taxonomy model, how would I get those values to show up in the referenced node? I need to be able to get the values from the reviews, to display on the related business page. And while doing that, do you know if there would be a way to only show the term with the most instances? The term entered by the greatest number of people?
I would use a module like
I would use a module like Rate or Fivestar and then rate on items that work with this approach, so instead of "sound reinforcement", something like "Vocals", "Clarity" and what ever. By using field group module you can group related rating together.
Unfortunately, the site setup
Unfortunately, the site setup is dependent on the Reviews and the Businesses being separate entities. I don't know how I'd aggregate ratings on the reviews to display in the business. But I realized that I can keep the site setup how it is, and avoid the issue by selecting the most common value in the database (as per this) instead of storing an average value. This avoids the issue of assigning a range to the filter options. I guess I'd still need to figure out how to change the form into checkboxes, but that's less of an issue.