Problem/Motivation

The redhen filter form used to filter entity lists includes filters for a certain subset field values. Custom code is used to generate the filters, with a generic textfield default supplemented by special handling for date fields and fields configured to use select lists.

While this approach allows some basic filtering, it has several limitations:

  • Only a single column is allowed per field, preventing filtering by multiple column fields.
  • Only the generic 'value' and the taxonomy term reference 'tid' columns are supported.
  • The text input in many cases makes input difficult. For example, date fields would be more easily handled with multiple selects or a Javascript date picker.
  • Selects may be broken in cases where their values are not loaded from an allowed values array. For example, taxonomy term selects are broken (with the exception of note_type selects, which are handled by code in an alter hook implementation in redhen_note).
  • Handling of additional field types may require extensive custom coding.

Proposed resolution

Replace the current custom code with code using the field API's built-in form element generation. That way we'll get the specific input widgets for each field. For example, for address fields, we'll get the full address element (country, province, city, street, etc.) complete with its Ajax behaviour when the country is switched.

  • In redhen_filter_form(), call field_default_form() to generate form elements for fields based on their configured widgets. Manipulate the widget settings to prevent any field from being required. This usage parallels what's done in the field configuration screen when generating a form element for setting the field's default value.
  • In redhen_filter_query(), process input for all valid columns.
  • For date type fields, invoke the to date behaviour to have two date inputs and process accordingly.

Remaining tasks

  • Redhen email fields are not working as expected. They lack a title and formatting. Troubleshoot.
  • Ensure that all filters default to a state where they are not active. Currently, for example, date fields use their widget's configured default. If that's 'now', they are in effect not optional, since leaving them as is will produce filtering. Specific subtasks:
    • Set defaults for date and other elements to zero length strings where available.
    • Determine what to do about checkbox elements, especially boolean ones, which can't effectively be inactive. Simply remove them? Convert them to radios with a skip option?
    • Handle country field in address fields. Add a zero length string select option?
  • Some field types won't work by default. For example, float fields will never be matched and, like date fields, would require a range. Geographic fields might require proximity handling for point data or other special handling for lines or polygons. Do we explicitly limit support to fields with known support?

User interface changes

Filter form elements use native field input widgets.

API changes

n/a

Comments

nedjo’s picture

Status: Active » Needs review
StatusFileSize
new8.56 KB

Here's a patch and an accompanying screenshot, which shows the filters for a few fields and also highlights the issue with

Overall I think this is a promising direction, since it vastly expands the ability to filter while minimizing the need for custom coding as most of what we need is already handled by the field API.

Several issues outstanding as noted in the summary, but I'm setting to needs review for feedback on the approach.

nedjo’s picture

StatusFileSize
new49.51 KB

Screenshot.

levelos’s picture

Status: Needs review » Needs work

This is great @nedjo, clearly the right approach. I spent some time testing the patch with mixed results. I can confirm the issues you already identified. Some thoughts:

  • For redhen_email field issues, I believe the best bet would be to wrap it in a fieldset in redhen_filter_form_fields().
  • Clearing the default for dates was straightforward in my testing, so that should be good to go.
  • We need to remove the ajax postback for the address country field. It destroys the form state and prevents proper form submission.
  • For bool checkboxes, couldn't we just detect if unchecked and then skip them?

I think we should keep either a white or black list of fields to allow filtering for. I'd rather not have a filter available than have it cause a WSOD or worse. Thanks again, this is a huge improvement.

nedjo’s picture

For redhen_email field issues, I believe the best bet would be to wrap it in a fieldset in redhen_filter_form_fields().

I haven't looked to see why the email field behaves this way. If we could get it working through changes in the field rather than customizations in the filter form that might be best, as then it would be more flexible and we might also get the expected layout.

We need to remove the ajax postback for the address country field. It destroys the form state and prevents proper form submission.

This is going to be tricky because it's difficult to use the form unless you can trigger changes when the country changes since each country has a different set of elements and labels. It would be worth digging to see if we can troubleshoot the form state issues. A fallback would be to use the site's default country's format and as you say unsetting the ajax properties.

For bool checkboxes, couldn't we just detect if unchecked and then skip them?

What we'd lose is the ability to filter by FALSE, e.g., for a "Has graduated" boolean field, show only contacts that haven't graduated. That said, doing it this way would be an okay initial step.

I think we should keep either a white or black list of fields to allow filtering for.

Yes, a whitelist is probably the way to go.

Questions arising:

  • Most of what we're doing here is generic to entity filtering rather than being closely tied to RedHen entities. At some point we might consider pulling this into a separate project at some point. Worth looking at existing modules like http://drupal.org/project/entity_list_display and http://drupal.org/project/entitylist to see if this might fit there.
  • We should look for ways to abstract out the handling for specific fields rather than burdening the code with a lot of workarounds for each separate field type. Like registering a set of callbacks per field type that would handle tasks like form element generation and query building.
levelos’s picture

Assigned: Unassigned » levelos
levelos’s picture

First pass committed. The summary is updated with remaining tasks. @nedjo, would love to you get your initial feedback and we can keep working on this together. I agree with both your summary questions in #4 and we should address both as time allows.

levelos’s picture

Status: Needs work » Fixed

Status: Fixed » Closed (fixed)

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

Anonymous’s picture

Issue summary: View changes

Updated issue summary.

  • Commit 4adf46c on 7.x-1.x, tests, redhen-donation by levelos:
    #1801390: Use native field API to generate filters in redhen_filter_form...

  • Commit 4adf46c on 7.x-1.x, tests, redhen-donation, relation-roles by levelos:
    #1801390: Use native field API to generate filters in redhen_filter_form...