Saturday, February 28, 2015

View Exposed Filter with a dropdown/select and textfield

In this example, we'll edit the commerce orders view. We need to edit the exposed filters in the view's configuration so we can then modify it programmatically and add more form elements. Without a preexisting exposed filter, there won't be a form to modify.


If you want to follow this example, follow the steps exactly.

To simplify things, just remove all your exposed filters. If you have exposed date filter, however, you probably want to leave that in there.

Add the Order Status Type filter and check the "Expose this filter" checkbox. This will become our custom select field after we modify it.







Now we need to implement hook_FORM_ID_form_alter.

function my_module_form_views_exposed_form_alter($form, &$form_state) {
 if ($form['#id'] == 'views-exposed-form-commerce-orders-admin-page') {
  unset($form['#info']['filter-type']);
  $select_options = array(
   'commerce_order.order_id' => 'Order ID',
   'commerce_customer_profile_field_data_commerce_customer_billing__field_data_commerce_customer_address.commerce_customer_address_name_line' => 'Name',
  );
  $form['type'] = array(
   '#type' => 'select',
   '#title' => 'Select',
   '#options' => $select_options,
   '#name' => 'order_search_select',
   '#weight' => 0,
  );
  $form['order_search_text'] = array(
   '#type' => 'textfield',
   '#size' => 25,
   '#weight' => 1,
  );
  $form['submit']['#weight'] = 2;
  $form['type']['#validated'] = true;
 }
}
First, we unset the filter-type in the #info property because it leaves behind the label of the exposed filter are modifying. Second, we build our options array, with the key being the field in the query. Then, we modify the title, options, name and weight in the "type" form field. To get the query field names, look at the query in the update preview section of the view ("Show Query" must be enabled). See image below.













Now that we have our exposed form altered, we need to alter the view's query using hook_views_query_alter.


function my_module_views_query_alter(&$view, &$query) {
 if ($view->name == 'commerce_orders') {
  if (isset($view->exposed_input['order_search_select']) && trim($view->exposed_input['order_search_text']) <> '') {
   $query->add_where(0, $view->exposed_input['order_search_select'], '%'.db_like($view->exposed_input['order_search_text']).'%', 'LIKE');
  }
 } 
}
First, we check that the view's name is "commerce_order." Then, we ensure that our inputs are valid. And lastly, we add our own where clause.


That's it. This is an extremely basic example, but I'm sure you can see how easily this can be expanded. In another post, I will cover adding relationships and including shipping methods in the list, which is something that can't be done elegantly with views out of the box.

No comments:

Post a Comment