Problem/Motivation

Sometimes want to restrict matching autocomplete to strings that match only at the beginning, not anywhere.
Also, the size should be exposed, similar to the text field widget.

Proposed resolution

expose the size, create a match setting, expose it.

Remaining tasks

User interface changes

Yep. As described above: expose the size and match setting and when match is "starts with", the autocomplete will only match terms that match at the beginning.

Defaults on field edit tab:
tax-defaults-2012-12-24_0100.png

API changes

yes. add parameters for passing the entity and bundle to taxonomy_autocomplete() like:
function taxonomy_autocomplete($field_name, $entity_type, $bundle_name) .
[kept the field_name as the first parament.]
so can get the match setting from the instance returned from $instance = field_info_instance($entity_type, $field_name, $bundle_name);

Original report by @mstrom81

Hi there,

I noticed what is either a bug, or a UX issue with the autocomplete. Let's say the terms I have in the taxonomy are Architecture and Basketball. After typing in "a", you would expect to only see Architecture, however Basketball also shows up. That's because there's an issue with the db query.

Within taxonomy.pages.inc, there's a method called "taxonomy_autocomplete". It has the following db query code:

// Select rows that match by term name.
$tags_return = $query
->fields('t', array('tid', 'name'))
->condition('t.vid', $vids)
->condition('t.name', '%' . db_like($tag_last) . '%', 'LIKE')
->range(0, 10)
->execute()
->fetchAllKeyed();

The issue is with the following line:
->condition('t.name', '%' . db_like($tag_last) . '%', 'LIKE')

It's looking for LIKE %tag_last%, where it should be looking for LIKE tag_last%.
->condition('t.name', db_like($tag_last) . '%', 'LIKE')

For most use cases I've seen of autocomplete, it looks for terms beginning with whatever the user entered. It seems that most people wouldn't be used to the functionality of autocomplete as-is in this widget.

Any thoughts?

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

magnusk’s picture

Category: bug » feature
Status: Needs review » Active

It's not a bug, that's how it's designed to work. Maybe there should be a new option to constrain the autocomplete widget so it matches either at the beginning of the name or anywhere in the name.

Taxoman’s picture

Title: Term Reference Autocomplete widget - looks for entered text anywhere in term, not just at the beginning of the term » Term Reference Autocomplete widget - lookup anywhere in term, not just from the beginning
Version: 7.x-dev » 8.x-dev

Subscribing - goes against 8.x first.

xjm’s picture

Title: Term Reference Autocomplete widget - lookup anywhere in term, not just from the beginning » Term Reference Autocomplete widget - match only from beginning of term

Re-titling for clarity.

magnusk’s picture

Title: Term Reference Autocomplete widget - match only from beginning of term » Term Reference Autocomplete widget - match any part of term

The feature request is to match any part of the term, instead of current behaviour which is to match the initial letters only. I do think the option to pick one or the other behaviour would be useful. I have several times copied and modified autocomplete functions mainly because I wanted generalized matching.

xjm’s picture

FileSize
8.29 KB

#4: Sorry, I'm confused... the current behavior does match anywhere in the term. The initial post is a request to either match only from the beginning, or weight matches from the beginning first.
autocomplete.png

Taxoman’s picture

"anywhere in the term" also includes in the middle of any word, not just the first letter of any word in multi-word terms.

Edit: ah, and yes, initially this issue is about just the beginning of each word, so this seems to work like that anyway. I would personally prefer the possibility to at least configure this to match inside words too, but that might be for a different feature request.

magnusk’s picture

Title: Term Reference Autocomplete widget - match any part of term » Term Reference Autocomplete widget - add option to match only start of term

Sorry, I'm the one who got confused.

YesCT’s picture

FileSize
96.34 KB

Here is a first try at a suggestion for adding options to the autocomplete for terms.

tag-s01-2012-12-18_1114.png

YesCT’s picture

(the screenshot above is from 7.x, but 8.x is similar. this should be done first in 8.x)

the match anywhere only should show when the drop down is autocomplete.

(OR, should there be a configure link, as eventually each drop down might have some configurable options?)

Here is some related code

from core/modules/node/lib/Drupal/node/Plugin/views/wizard/Node.php

// Add the autocomplete textfield to the wizard.
$form['displays']['show']['tagged_with'] = array(
'#type' => 'textfield',
'#title' => t('tagged with'),
'#autocomplete_path' => 'taxonomy/autocomplete/' . $tag_field_name,
'#size' => 30,
'#maxlength' => 1024,
'#field_name' => $tag_field_name,
'#element_validate' => array('views_ui_taxonomy_autocomplete_validate'),
);

That has "settings" for size of the autocomplete.

Also the whole core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/widget/TaxonomyAutocompleteWidget.php
which shows

/**
 * Plugin implementation of the 'taxonomy_autocomplete' widget.
 *
 * @Plugin(
 *   id = "taxonomy_autocomplete",
 *   module = "taxonomy",
 *   label = @Translation("Autocomplete term widget (tagging)"),
 *   field_types = {
 *     "taxonomy_term_reference"
 *   },
 *   settings = {
 *     "size" = "60",
 *     "autocomplete_path" = "taxonomy/autocomplete",
 *     "placeholder" = ""
 *   },
 *   multiple_values = TRUE
 * )
 */

Seems like we can add a setting like "match_anywhere" = TRUE,

YesCT’s picture

Side thought. are there other settings that might want to be set? like size of the text field?

YesCT’s picture

while working on this, I found this error in saving any widget select form. #1872786: Can't change widget types

nod_’s picture

If we have the match "starts with" it will allow us to use the HTML5 datalist form thing. Which would be nice.

YesCT’s picture

would it be more clear to have a checkbox "match anywhere" where being checked means match anywhere and not being checked means "match starts with" ?

OR

have two radio buttons:
match anywhere (default)
match starts with

?

YesCT’s picture

Also, I dont know very much about plugins or widgets, from a code perspective:

Would this be better as

I. the same autocomplete widget, but exposing some of the "settings", as suggested above with a checkbox, or 2 radio button choices.

Or
II. making a different autocomplete widget, to make a total of 4 choices in the tags widget choice, adding "Autocomplete term widget (tagging) match starts with"

?

I'm guessing I. But I'm having trouble coding it up.

YesCT’s picture

Status: Active » Needs review
FileSize
2.2 KB

Well, for now, I'm thinking that just unchecking a "match anywhere" is not obvious to be "starts with". so trying to go with radio buttons.

Here is just a start. I still do not know how to get at the widget setting, or how to expose the widget settings form.

fenda’s picture

For reference I looked at the user autocomplete in core and that is only matching on the first character. Perhaps it's irrelevant.

$result = db_select('users')->fields('users', array('name'))->condition('name', db_like($string) . '%', 'LIKE')->range(0, 10)->execute();
fenda’s picture

Some comments on patch #15!

  • The default value is broken? I created a autocomplete tagging field for my content type. Then after I applied the patch, neither of the radio buttons were selected by default.
  • Shouldn't this new form element be present in the "Field Settings" tab as opposed to the "Edit" tab for the field?
  • The form element #description is a little hard to understand. Can it be simplified?
YesCT’s picture

@drupaljoe HA! you found the radio buttons? I could not find them. I was looking in field settings and the widget tab!
I did not even look in edit.

The default value is broken? I created a autocomplete tagging field for my content type. Then after I applied the patch, neither of the radio buttons were selected by default.

Please try applying the patch and then installing. (or maybe clearing the caches)
Here is an example of what I usually do to quickly clear a site and reinstall:

sudo rm -r sites
git checkout sites
drush -y si --account-pass=admin --db-url="mysql://root:root@localhost/d8-git" --site-name=autocomplete-15
Shouldn't this new form element be present in the "Field Settings" tab as opposed to the "Edit" tab for the field?

#1855002: "Field settings" tab needs renaming to "Field storage settings" might help a bit.
It says that the field settings tab needs to be renamed global settings.
It also asks for discussion on renaming the edit tab to field settings.
My inability to find the radio buttons, that *I* wrote, would speak toward doing that!

The location these settings appeared might imply that the placeholder (and this) autocomplete match would not be global to everywhere this field is shared.
I find shared fields really hard to consider in terms of the correct behavior without a use case. So if someone could put forth a use case for shared fields and how the widget settings should or should not be shared, that might help.
Is the widget shared with a shared field? If not, that for sure puts these under the edit. (It's a bit hard to test that small part though, because I cannot save the widget tab right now... #1872786: Can't change widget types)

Well, here is a screen capture of the edit tab.
widget-in-edit-2012-12-23_0201.png

The form element #description is a little hard to understand. Can it be simplified?

Yes, the description should totally be clarified, shortened, etc. I wonder if it could even be eliminated with the right title and option word choices.
Suggestions for other description, title, and option choices are very welcome.

YesCT’s picture

I'm assuming that the placeholder and the match setting only show when the autocomplete widget is used. So those would not be on this edit tab with a different widget selected.

So, I think it would help to put them in a "Autocomplete" fieldset, grouped together.

OR

To call them
Autocomplete placeholder
Autocomplete match

But I suspect that that repeating of Autocomplete in their title is not elegant, and would not make sense when the widget settings are used in another setting.
I tried to see what other context these widget settings would show in, and views what the one I thought of, but I got a ton of errors when I tried to add a tags autocomplete exposed filter to an enabled front page view... so I could not test that.

If someone could give steps to reproduce how to see this tags autocomplete in another context, that would be really helpful.

YesCT’s picture

Since the text field widget exposes the size of the field, I think it makes sense for the autocomplete to do the same thing.

text_field_size-2012-12-23_0231.png

YesCT’s picture

I added some comments near the @todo with wild guesses for how to access the widget match setting.

Next step: getting hints or an actual way of accessing that, to get this to work.

Also, I added the field size, after we get this working, we can take that out and make a separate issue to add it in if that is needed. I modified the title to sort of make it clear that we are dealing with autocomplete settings without repeating "autocomplete" in each title.

YesCT’s picture

+++ b/core/modules/taxonomy/taxonomy.pages.incundefined
@@ -140,11 +140,27 @@ function taxonomy_autocomplete($field_name) {
+    // @todo Get the match anywhere value from the field widget setting.
+    // $match = $field->getWidget->getSetting('match');
+    // $match = drupal_container->get('something')->createInstance['widget']['settings']['match'];

Here is the wild guess part.

chx’s picture

What you need is to pass an entity and a bundle besides the field name to taxonomy autocomplete so that you can retrieve the instance.

YesCT’s picture

This tries to send the entity and bundle every time. I wonder if I can do this though, because maybe the vocabulary is used across entities or bundles.

Also, this is not working: [edit: I forgot to reinstall, so the reason it is not working is different] there is no autocomplete... in the autocomplete field. I'll take a break for a while...

Status: Needs review » Needs work

The last submitted patch, drupal-taxonomy_autocomplete_match_anywhere-1120144-24.patch, failed testing.

YesCT’s picture

Status: Needs work » Needs review
FileSize
1.94 KB
9.69 KB

with help from chx to point out the cause of the fail...

but still need to look at why it's not autocomplete anymore.

YesCT’s picture

ah ha. found where the widget itself was needing the additional arguments. now the autocomplete is back.

YesCT’s picture

oops. forgot to uncomment the actual implementation that pays attention to the match setting. this does that.
So! this is ready for review.

Next steps:

  • needs tests
  • review

To test:

  1. apply patch and fresh install
  2. create an article with a tag like "one" (OR add a term "one" to the tags vocabulary)
  3. create another article with a tag like "another one" (OR add a term "another" to the tags vocabulary)
  4. create an article, type "one" in the autocomplete and see two tags: "one" and "another one"
  5. edit the tags field on article and pick the starts with match setting.
  6. create an article, type "one" in the autocomplete and see only one tag (matching starts with) "one"
YesCT’s picture

Title: Term Reference Autocomplete widget - add option to match only start of term » Term Reference Autocomplete widget - add option to match only start of term and expose settings (size, match)
FileSize
21 KB
29.21 KB
93 KB

edit the field, shows the size and match (in addition to the placeholder) widget setting

tax-defaults-2012-12-24_0100.png

If change settings to size 20, placeholder "type tags", match "starts with" and follow the steps to test, where tags "one" and "another one" exist.

new-settings-2012-12-24_0104.png

only see "one" since setting is "starts with"

starts-2012-12-24_0108.png

I'll update the issue summary.

Status: Needs review » Needs work

The last submitted patch, drupal-taxonomy_autocomplete_match_anywhere-1120144-28.patch, failed testing.

Frank Ralf’s picture

JFTR
The error message from the test bot:

 Drupal\taxonomy\Tests\TermTest
 			
 Undefined index: match	taxonomy.pages.inc 149	taxonomy_autocomplete()
Frank Ralf’s picture

@drupaljoe (#16)

Thanks for the pointer! JFTR the corresponding code in taxonomy.pages.inc (D7) is:

// Select rows that match by term name.
    $tags_return = $query
      ->fields('t', array('tid', 'name'))
      ->condition('t.vid', $vids)
      ->condition('t.name', '%' . db_like($tag_last) . '%', 'LIKE')
      ->range(0, 10)
      ->execute()
      ->fetchAllKeyed();

So it's just the additional "%" in the condition which makes the input match elsewhere as only the start of the string.

YesCT’s picture

Right, see the variable: $condition_pattern in the patch.

But @nod_ in #12:

If we have the match "starts with" it will allow us to use the HTML5 datalist form thing. Which would be nice.

I'm not sure if we want to do that here, or in a follow-up... since I'm not sure exactly what "using" that means exactly.

YesCT’s picture

Assigned: Unassigned » YesCT

I think I'll try this again later tonight. I might know more now than I did last time I tried. :)
I'll also go for a follow-up for the html5 concern since no-one felt strongly one way or the other.

YesCT’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests

Status: Needs review » Needs work
Issue tags: +Needs tests

The last submitted patch, drupal-taxonomy_autocomplete_match_anywhere-1120144-28.patch, failed testing.

YesCT’s picture

custom taxonomy stuff might be going away in #1847596: Remove Taxonomy term reference field in favor of Entity reference

how would that effect the ability to do this in 7.x?

YesCT’s picture

the fail in EditorSelection looks like a random failure to me, as that test passed locally.

for my curiosity, how do I get the settings 'match' index declared? adding match to the plugin in the comments did seem to do it.

I want to use index 'match' like: $match = $instance['widget']['settings']['match'];
in core/modules/taxonomy/taxonomy.pages.inc

I thought some magic in core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/widget/TaxonomyAutocompleteWidget.php
adding match to settings in the plugin definition would take care of that.

but it is not enough because getting the warning:
"Drupal\taxonomy\Tests\TermTest Undefined index: match taxonomy.pages.inc 149 taxonomy_autocomplete()"

Where can I look for how to use/modify plugins?

andypost’s picture

+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/widget/TaxonomyAutocompleteWidget.phpundefined
@@ -35,12 +36,32 @@ class TaxonomyAutocompleteWidget extends WidgetBase {
+      '#type' => 'radios',
+      '#title' => t('Match'),
+      '#default_value' => $this->getSetting('match'),
+      '#options' => array(
+        'anywhere' => t('Anywhere'),
+        'start' => t('Starts with'),
+      ),
+      '#description' => t('Where the autocomplete matches values: either anywhere, or only at the beginning of a term.'),

I'd prefer to see this setting as Checkbox according core UI suggestions

+++ b/core/modules/taxonomy/taxonomy.pages.incundefined
@@ -140,11 +144,25 @@ function taxonomy_autocomplete($field_name) {
+    $match = $instance['widget']['settings']['match'];
+    switch ($match) {
+      case 'start':
+        $condition_pattern = db_like($tag_last) . '%';
+        break;
+
+      case 'anywhere':
+      default:
+        $condition_pattern = '%' . db_like($tag_last) . '%';
+        break;
+    }

This would be simple if() else {}

YesCT’s picture

da_wehner seemed to think it could be done with something to do with views.

I'll keep my eye on that, and try and get it in as part of views conversion.

tstoeckler’s picture

Version: 8.x-dev » 7.x-dev

In fact we can move this issue to 7.x directly. Even though the taxonomy term reference does not support this feature currently, the generic entity reference does. See \Drupal\entity_reference\Plugin\field\Widget\AutocompleteWidgetBase::settingsForm(). And as @YesCT posted, the taxonomy reference is being deprecated in favor of just that.

I will re-roll the patch for 7.x in a minute.

tstoeckler’s picture

FileSize
13.3 KB

Here we go. I added some tests for the taxonomy itself but we should also test the widget settings form. Maybe we could get some feedback on the backportability. I think as the strings added (not modified!) here are in Drupal 8 it would seem like a sensible choice IMO.

Oh, and I just now saw that this is still assigned to YesCT. Sorry, if you were working on this. I really gotta check that more often...

tstoeckler’s picture

Status: Needs work » Needs review
FileSize
3.28 KB
10.96 KB

This time with less debug and less commented out test methods.

Also some notes for reviewers:
* I directly used the code that is in the entityreference autocomplete in D8. Therefore this patch should be basically immune to UI reviews, as anything that isn't OK with this UI should be fixed in D8 first in a separate issue.
* I also changed the form values, form API keys, etc. to match those in D8. In D8 the values match the EntityQuery operators, which don't exist in that form in D7, but I don't see any reason to change them to anything else.
* Because it was impossible to actually re-roll this, I had to more or less re-write (or actually re-copy-paste) this from scratch. Therefore I took the liberty of changing a few trivial things. Most noticable is that I changed the URL to be $entity_type/$field_name/$bundle, because field_info_instance() is called in that order. And conceptually we're passing instance information, it's just that instances have no unique identifiers in D7.

tstoeckler’s picture

Oh, also: as can be seen in the interdiff, I forgot to change the order of the arguments in the place where the URL is actually requested. Therefore if #42 *passes* comes back green, we need additional tests as it really shouldn't.

YesCT’s picture

Assigned: YesCT » Unassigned

No worries, I was waiting to see how the depreciate went in d8. :)
Unassigning from me.

YesCT’s picture

Status: Needs review » Needs work

needs work per #44

YesCT’s picture

Issue summary: View changes

update issue summary to use issue summary template, clarify remaining tasks, and add screenshot of current fix.

dariogcode’s picture

I'm very interested in this too. I have a taxonomy with city names with state for example Alcaraz; (Albacete), Almansa (Albacete), etc and the "anywhere" search produce no good result when the user search city starting with "Alba"

I know this is a important change but do you think is possible to have in the next Drupal 7 releases? I want to use the patch but my concern is if this won't be merged in the future and the client update the core, this changes will be lost.

Thanks!

dariogcode’s picture

I tried the patch in #43 and when used the autocomplete I got the following error:

Taxonomy field node not found.

YesCT’s picture

#2372225: Add sort setting for taxonomy term autocomplete results is (for a little bit) exploring adding a setting per bundle similar to what this was doing back in #28.

djpable’s picture

1120144-43.patch

There is something wrong in the #43 patch.
I'm submitting mine fore those who:

  1. Use autocomplete to transform a textfield to an autocomplete box (autocomplete not associated to a field)
  2. Don't like core functions to be modified in parameters
giupenni’s picture

Work for me

giupenni’s picture

Strange, works in my local installation but not works in production site.

vbouchet’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 50: 1120144-50.patch, failed testing.