This patch adds four options to multiselect widget form. Each of options can be turned on separatly and all are off by default not to brake current settings.

1) Add count - adds number of items for each facet as seen in other widgets.

2) Remove selected - removes active (selected) item from options (good for compability with 'current search block' that shows current item and allows to remove it and 'chosen' module)

3) Autosubmit - hides submit buttons and submits form after each choice

4) Act as single select element - this one needs little more explanation below...

I noticed that connected field facets are broken with multiselect. It is because fields are separated with ':' symbol and it is encoded in url. ':' between connected fields should be encoded twice, dont know why, but thats how stock 'Links' widgets works too. There is long comment in function getOptionKey() on why 'multiselect' widget implements it's own way of adding keys. Not to brake compability I added as option possibility to build keys as originally intended, togathet with other options, this makes sense. We can discuss about title of option "Act as single select element" is probably not very clear.

CommentFileSizeAuthor
#57 1806344.patch12.38 KBasherry
#54 interdiff.txt519 bytesarturs.v
#54 facetapi_multiselect-translatable-placeholder-1806344-54.patch12.31 KBarturs.v
#52 add_options_to_widget_disable_empty-1806344-52.patch12.3 KBfirestonej
#51 add_options_to_widget_disable_empty-1806344-51.patch12.27 KBfirestonej
#50 add_options_to_widget_remove_selected-1806344-50.patch11.54 KBfirestonej
#49 add_options_to_widget-1806344-49.patch11.45 KBfirestonej
#48 add_options_to_widget-1806344-48.patch10.73 KBfirestonej
#47 add_options_to_widget_placeholder-1806344-47.patch10.41 KBfirestonej
#44 add_options_to_widget-1806344-43.patch9.74 KBankur.addweb
#41 add_options_to_widget-1806344-41.patch9.68 KBankur.addweb
#40 facetapi_multiselect-1806344-40-new-features.patch9.11 KBjnettik
#37 facet-multiselect-1806344-37.patch6.96 KBjnettik
#36 facetapi_multiselect-1806344-36-new-features.patch8.15 KBgeek-merlin
#33 facetapi_multiselect-new_features-1806344-33.patch6.96 KBdobe
#26 facetapi_multiselect-new_features-1806344-26.patch7.55 KBrodrigoaguilera
#22 facetapi_multiselect-new_features-1806344-22.patch7.4 KBk.minkov
#21 facetapi_multiselect-new_features-1806344-20.patch6.86 KBk.minkov
#19 facetapi_multiselect-new_features-1806344-19.patch7.15 KBtauno
#18 facetapi_multiselect-new_features-1806344-18.patch6.08 KBtauno
#14 1806344.13.count_autosubmit_removeSelected.patch5.12 KBHaza
#11 new-options_autosubmit_remove-active_act_single_6.patch4.99 KBjlyon
#4 new-options_autosubmit_remove-active_act_single.patch4.23 KBmansspams
#3 new-options_autosubmit_remove-active_act_single.patch5.05 KBmansspams
#1 new-options_autosubmit_remove-active_act_single.patch4.94 KBmansspams
new-options_autosubmit_remove-active_act_single.patch4.97 KBmansspams
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

mansspams’s picture

Updated patch with better option #4 name and key. It is now "Use original option keys" and does exactly that.

mansspams’s picture

Title: Add options to widget form - » Add options to widget form - count, remove selected, autosubmit, use original keys

Better issue title.

mansspams’s picture

Aaaaand... hopefully last fix to patch. Should have tested better :(

Fixed logic to properly remove selected elements and also made a bugfix that makes option #4 not really necessary. It turns out if we wrap 'field alias' in drupal_encode_path() we get proper working code. I left #4 right now to see if it helps with nice url paths over at #1805806: Make this module work with facetapi_pretty_paths.

mansspams’s picture

Removed option #4 as bugfix makes option not needed for correct functionality. I will take a look at pretty paths later.

N20’s picture

Patch dont work with latest dev:

patch < new-options_autosubmit_remove-active_act_single_2.patch
patching file facetapi_multiselect.module
patching file facetapi_multiselect_autosubmit.js
patching file facetapi_multiselect.inc
Hunk #1 FAILED at 27.
Hunk #2 FAILED at 68.
2 out of 2 hunks FAILED -- saving rejects to file facetapi_multiselect.inc.rej

as also mentioned here there's no js directory or files creted.

facetapi_multiselect.inc.rej:

--- facetapi_multiselect.inc
+++ facetapi_multiselect.inc
@@ -27,11 +27,14 @@
    * Builds an array of #options for our select element.
    */
   public function buildOptions($element) {
+    $settings = $this->settings->settings;
     $options = array();
     foreach ($element as $item) {
       if (empty($item['#item_children'])) {
-        $key = $this->getOptionKey($item);
-        $options[$key] = $item['#markup'];
+        if (!$item['#active'] || ($item['#active'] && !$settings['remove_selected'])) {
+          $key = $this->getOptionKey($item);
+          $options[$key] = $settings['add_count'] ? $item['#markup'] . ' (' . $item['#count'] . ')' : $item['#markup'];
+        }
       }
       else {
         // Recursively add any children of the item to the #options array (this
@@ -68,6 +71,56 @@
     // selected. We need to do it this way (rather than using $item['#query'])
     // so that multiple selections can be combined together in the form's
     // submit handler.
-    return $this->facet['field alias'] . ':' . $item['#indexed_value'];
+    return drupal_encode_path($this->facet['field alias']) . ':' . $item['#indexed_value'];
+  }
+
+  /**
+   * Allows the widget to provide additional settings to the form.
+   */
+  function settingsForm(&$form, &$form_state) {
+    $form['widget']['widget_settings']['links'][$this->id]['add_count'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Add count'),
+      '#description' => t('Add available item count in brackets.'),
+      '#default_value' => $this->settings->settings['add_count'],
+      '#states' => array(
+        'visible' => array(
+          'select[name="widget"]' => array('value' => $this->id),
+        ),
+      ),
+    );
+    $form['widget']['widget_settings']['links'][$this->id]['remove_selected'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Remove selected'),
+      '#description' => t('Remove selected options from select list.'),
+      '#default_value' => $this->settings->settings['remove_selected'],
+      '#states' => array(
+        'visible' => array(
+          'select[name="widget"]' => array('value' => $this->id),
+        ),
+      ),
+    );
+    $form['widget']['widget_settings']['links'][$this->id]['auto_submit'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Autosubmit'),
+      '#description' => t('Hide submit button and submit selection automatically.'),
+      '#default_value' => $this->settings->settings['auto_submit'],
+      '#states' => array(
+        'visible' => array(
+          'select[name="widget"]' => array('value' => $this->id),
+        ),
+      ),
+    );
+  }
+
+  /**
+   * Returns defaults for the settings this widget provides.
+   */
+  function getDefaultSettings() {
+    return array(
+      'add_count' => 0,
+      'remove_selected' => 0,
+      'auto_submit' => 0,
+    );
   }
 }
rp7’s picture

Tested the autosubmit functionality - works. Thanks!

heddn’s picture

Status: Needs review » Reviewed & tested by the community

#4 works for me, except for Date fields. But in general, Date fields don't work with this module at all. New issue to follow on *that* problem. For now, marking RTBC.

heddn’s picture

29axe’s picture

Tested autosubmit : works but the other options in the dropdown list are removed after the refresh.

pschuelke’s picture

The patch applied correctly although with some notes:

patching file facetapi_multiselect.module
patching file js/facetapi_multiselect_autosubmit.js
patching file plugins/facetapi/facetapi_multiselect.inc
patch unexpectedly ends in middle of line
Hunk #2 succeeded at 71 with fuzz 2.

I only used the auosubmit option and will verify it works.

jlyon’s picture

I got an error when I was trying to apply #4 because of the way the patch was formatted.

git apply -v < new-options_autosubmit_remove-active_act_single_2.patch
Checking patch facetapi_multiselect.module...
Checking patch js/facetapi_multiselect_autosubmit.js...
error: while searching for:

error: patch failed: js/facetapi_multiselect_autosubmit.js:0
error: js/facetapi_multiselect_autosubmit.js: patch does not apply
Checking patch plugins/facetapi/facetapi_multiselect.inc...

This patch worked for me with git apply -v.

dafeder’s picture

This change in the options logic:

--- a/plugins/facetapi/facetapi_multiselect.inc
+++ b/plugins/facetapi/facetapi_multiselect.inc
@@ -27,11 +27,14 @@ class FacetapiMultiSelectWidget extends FacetapiWidgetLinks {
    * Builds an array of #options for our select element.
    */
   public function buildOptions($element) {
+    $settings = $this->settings->settings;
     $options = array();
     foreach ($element as $item) {
       if (empty($item['#item_children'])) {
-        $key = $this->getOptionKey($item);
-        $options[$key] = $item['#markup'];
+        if (!$item['#active'] && $settings['remove_selected']) {
+          $key = $this->getOptionKey($item);
+          $options[$key] = $settings['add_count'] ? $item['#markup'] . ' (' . $item['#count'] . ')' : $item['#markup'];
+        }
       }
       else {
         // Recursively add any children of the item to the #options array (this

Made all my options disappear completely. The rest of #11 works perfectly for me. I don't understand the logic - only show items if "remove selected" is checked?

Haza’s picture

Same as dafeder, patch from #11 made my options disappears.

Haza’s picture

I guess that the "remove selected" just removes the options from the list/active item when they selected, which is not the default behaviour.

I've changed a bit the logic there and fix the missing options.

New patch attached.

Haza’s picture

Status: Reviewed & tested by the community » Needs review
milesw’s picture

Great features! I'm using patch #14 for counts and autosubmit. Working nicely, thanks.

boyan.borisov’s picture

Status: Needs review » Reviewed & tested by the community

Great features! Work perfect for me.

tauno’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
6.08 KB

Optgroups don't work well at all with taxonomies deeper than 2 levels, so I added an option to not use optgroups and instead prepend the options with hyphens like Drupal core does.

Could use some additional review.

tauno’s picture

FileSize
7.15 KB

Forgot to include the new javascript file from the earlier patches.

valderama’s picture

Patch from #19 works nicely here!

k.minkov’s picture

While using patch#19 and selected to display hierarchy with dashes (Nest hierarchical facets in optgroups - unchecked) and when you select a term for example 2 or 3 level deeper in hierarchy after submitting the form in the input is shown not only this term, but all his parents in the hierarchy.
With the following patch only the ones selected are displayed.

k.minkov’s picture

Forgot the autosubmit js file in the patch here is the patch with it.

Exploratus’s picture

Just installed #22. Works well! :)

Helrunar’s picture

Status: Needs review » Reviewed & tested by the community

Patch #22 works for me too

jibize’s picture

Status: Reviewed & tested by the community » Needs work

#22 is mostly working for me as well. The "Act as single select element" seems to be broken when multiple facets are selected. Maybe we should remove this option for now to get the reste committed ?
I mark this one as Needs work because of the above.

rodrigoaguilera’s picture

The array is not initialized in buildDefaultValue and I'm receiving notices because of this.

narkoff’s picture

I also was receiving the following error after applying #22 patch: Undefined variable: default_value in FacetapiMultiSelectWidget->buildDefaultValue()...

I then applied #26 patch and error went away. Thanks.

29axe’s picture

Hello
Did you find a solution for the "connected fields" multiselect issue? I really need this feature but I don't know how to make it work. The option "Act as single select element" does not work properly.
Even a hint on where I should start would really be appreciated. Do you know if it is possible to build a different path for connected fields without using ':' but eventually another safe character?

timodwhit’s picture

Patch in #26 seems to handle Issues: 1, 2, 3 well.

However, autosubmit seems to hide all submit buttons on multiselect fields. It was what I wanted but some people might be adverse to it.

alec-AW’s picture

Patch #26 works for issues 1, 2
I did not test it for issue 3

For issue 4: the problem is in the encoding of the value field of the select options
The values are for a connected field facet name field1:field2:value
It should be field1%3Afield2:value

So when the form is submitted, this string sould be double-encoded like the links widget : field1%253Afield2%3Avalue

In facetapi_multiselect/plugins/facetapi/facetapi_multiselect.inc
Line 86
I added an urlencode() for the field alias.

return urlencode($this->facet['field alias']) . ':' . $item['#indexed_value'];

It solved my problem

alec-AW’s picture

I had to add another urlencode.
If you are not using the "remove selected", you should add urlencode() also to the function buildDefaultValue()

Here is the complete code with precedent issue :

  /**
   * Builds a #default_value array for our select element.
   */
  public function buildDefaultValue($element) {
    $active_items = $this->facet->getAdapter()->getActiveItems($this->facet->getFacet());
    $default_value = array();
    foreach($active_items as $id=>$values) {
      $default_value[] = urlencode($values['field alias']). ":" . $id;
    }
    return $default_value;
  }


  /**
   * Gets the key to use for an item in the select element #options array.
   */
  protected function getOptionKey($item) {
    $settings = $this->settings->settings;
    if ($settings['act_single'] && isset($item['#query']['f'])) {
      return implode('&', $item['#query']['f']);
    }
    // Set the key to the filter that will appear in the URL if this item is
    // selected. We need to do it this way (rather than using $item['#query'])
    // so that multiple selections can be combined together in the form's
    // submit handler.
    return urlencode($this->facet['field alias']) . ':' . $item['#indexed_value'];
  }
Mac_Weber’s picture

@Alec-Serval your code needs some changes, as you can see at #2198337-2: URL encode for multi select values

dobe’s picture

Status: Needs work » Needs review
FileSize
6.96 KB

This attached patch implements what is brought up in #31 using the logic from #2198337-2: URL encode for multi select values. Seems like everything works now that I need.

geek-merlin’s picture

geek-merlin’s picture

Great thing!
Unfortunately: Autosubmit seems not to work with chosen.

Edit: no wonder: it looks like the autosubmit js from #26 is not in #33.

geek-merlin’s picture

FileSize
8.15 KB

This patch takes #33 and re-adds js from #26.

Please test and rtbc.

Memo: It would be quite useful if the js also disables other submit buttons on autosubmit.

jnettik’s picture

Status: Needs review » Needs work
FileSize
6.96 KB

I just discovered an issue with this patch and the auto-submit functionality. iOS has a bug in how it handles changes to multiselect fields. It considers the action of clicking into the field a change, so it fire's the jQuery .change() event and submits the form before you ever have a chance to select filters. The solution here is to use .blur() instead of .change(), as that will wait until the facet loses focus before submitting. Attaching an updated patch based on #36

jnettik’s picture

After more testing, my patch seems to break autosubmit functionality with the chosen module...

geek-merlin’s picture

Status: Needs work » Needs review

So we're back to testing #36 i suppose.

jnettik’s picture

The issue with #36 is how iOS handles multi select lists. Just clicking into the list to begin selecting options picks the first option, and fires the change event. So when the autosubmit option is enabled, it's impossible to actually use the filters on those devices. I found a solution that seems to work for me, but admittedly it's a little hacky since Drupal doesn't allow you to add option outside of `value` and `selected` on `options`.

The fix is based on this: http://stackoverflow.com/questions/34985606/ios-9-2-select-list-multiple.... Basically I'm adding an empty option to the beginning of the options list, and setting `value="disabled"`. Then in `#post_render` calling a function that parses the rendered select element, finds one with a value of disabled, removed the `value` attribute and sets the `disabled` attribute.

The drawbacks I've seen so far is that some browsers don't seem to hide the disabled option by default. Adding the following to my CSS fixes that.

option[disabled]:empty { display: none; }

The other one using "disabled" as the option value. That could create some naming conflicts, but I think the likelyhood of that is slim.

ankur.addweb’s picture

@All, the above patch is working perfectly fine but it doesn't support special characters.

Please find the attached patch - this patch would allow special characters and working perfectly fine.

Let me know if anyone have any queries/concern for the same.

Thanks!

saurabh.dhariwal’s picture

Status: Needs review » Reviewed & tested by the community
David_Rothstein’s picture

Status: Reviewed & tested by the community » Needs review

Comments at #2835107: Invalid HTML is generated and #2836051: Hard coded XMl (which were filed as separate issues but are actually about the most recent patch in this issue, specifically about the changes that were introduced as part of #41 above) suggest that maybe this needs more work?

ankur.addweb’s picture

Attached patch modifies the patch to solve #2835107: Invalid HTML is generated and #2836051: Hard coded XML.

NWOM’s picture

(Deleted)

firestonej’s picture

+1 for the patch from #44.

firestonej’s picture

Updated version of patch from #44 to include "data-placeholder" element for integration with Chosen module. Maybe it should be default HTML5 "placeholder" attribute, please advise.

firestonej’s picture

The widget doesn't render on some server configurations.

Since LIBXML_HTML_NOIMPLIED and LIBXML_HTML_NODEFDTD were introduced in version 2.7.8 of that extension, calling these constants is problematic. It can result in errors like these:

Notice: Use of undefined constant LIBXML_HTML_NODEFDTD - assumed 'LIBXML_HTML_NODEFDTD' in _facetapi_multiselect_disable_options()
Notice: Use of undefined constant LIBXML_HTML_NOIMPLIED - assumed 'LIBXML_HTML_NODEFDTD' in _facetapi_multiselect_disable_options()
Warning: DOMDocument::loadHTML() expects parameter 2 to be long, string given in _facetapi_multiselect_disable_options()

A simple fix is to just statically check the libxml/PHP version and ignore these optional constants if it's unlikely they'll be defined. Relevant code:

// Check PHP and libxml version.
  static $new_libxml;
  if (!isset($new_libxml)) {
    $new_libxml = version_compare(PHP_VERSION, '5.4', '>=') && defined('LIBXML_HTML_NOIMPLIED') && defined('LIBXML_HTML_NODEFDTD');
  }

...

  if ($new_libxml) {
    $select->loadHTML(utf8_decode($content), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
  }
  else {
    $select->loadHTML(utf8_decode($content));
  }

Patch included - tested on CentOS 6.8 with PHP 5.6 and libxml 2.7.6, which has the undefined constants.

firestonej’s picture

Another patch to improve Chosen theming – the facet counts really shouldn't appear on selected items, since Chosen will prepopulate them above the search results dropdown. Interacts correctly with add_count option.

Another option would be to add a tag around the counts and do it with CSS, but I think that's only a good idea if the user is using Chosen, since it's not HTML-correct to have other tags inside the element.

firestonej’s picture

Fixed broken logic from last patch, wasn't removing/adding counts correctly.

firestonej’s picture

One more option for this module: allow showing empty facets as disabled, which will let Chosen consequently handle them that way.

firestonej’s picture

Fixed some notices from the patch in #51.

marcmueller’s picture

Hi, I've got troubles to apply the latest patch. Firestonej, could you provide a patched tarball of the module?
Thanks, Marc

arturs.v’s picture

Small addition to allow translating the placeholder label. The patch applies cleanly to the latest commit in the development branch.

A.

NWOM’s picture

marcmueller’s picture

Thank you, NWOM. I've been using Netbean's apply patch function. Via git its working now.
Also, thanks to all of you contributors!

asherry’s picture

FileSize
12.38 KB

I just noticed an added line accidentally and one coding standards violation, but otherwise I think this patch should really be committed by now.

I think this project is in need of another co-maintainer so I'll fill out another ticket with that as we have this module in a major production site.

  • asherry committed 159b288 on 7.x-1.x authored by mansspams
    Issue #1806344 mansspams, jlyon: Add options to widget form initial work...
  • asherry committed 4d8c991 on 7.x-1.x authored by Haza
    Issue #1806344 by Haza: Changed logic and fixed missing options
    
  • asherry committed e823513 on 7.x-1.x authored by tauno
    Issue #1806344 by tauno: Optgroups don't work well at all with...
  • asherry committed 2cf08e9 on 7.x-1.x authored by k.minkov
    Issue #1806344 by k.minkov: Error with taxonomy term hierarchy
    
  • asherry committed d8ab5b0 on 7.x-1.x authored by rodrigoaguilera
    Issue #1806344 by rodrigoaguilera: Array is not initialized in...
  • asherry committed 1a69fb0 on 7.x-1.x authored by dobe
    Issue #1806344 by axel.rutz, dobe: URL encode for multi select values
    
  • asherry committed 499cd32 on 7.x-1.x authored by jnettik
    Issue #1806344 by jnettik: Issue with auto-submit functionality
    
  • asherry committed 16e3619 on 7.x-1.x authored by darshi.addweb
    Issue #1806344 by darshi.addweb: Invalid HTML is generated and hard...
  • asherry committed 66045ee on 7.x-1.x authored by firestonej
    Issue #1806344 by firestonej, arturs.v:
    - Include "data-placeholder"...
  • asherry committed ddf7598 on 7.x-1.x
    Issue #1806344 by asherry: Coding standards fixes
    
asherry’s picture

Status: Needs review » Fixed

Hello all -
Thanks to all who contributed to this patch. This was such a great combined effort that it would have been a shame not to make sure everybody got credit for the work they did.

I did my best to divide up the patch and make sure the commit was attributed to the actual code people changed.

Thanks everybody!

Any issues with the new codebase should now all be filed in separate tickets.

Status: Fixed » Closed (fixed)

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