Material: autocomplete: x icon issues and missing md-floating-label attribute in docs

Created on 5 May 2015  路  26Comments  路  Source: angular/material

According to the spec the "x" icon shouldn't be shown when your using md-floating-label. Also md-floating-label isn't in the docs list of attributes.

Spec for floating label style autocomplete(it's at the very bottom of the autocomplete stuff)
http://www.google.com/design/spec/components/text-fields.html#text-fields-auto-complete-text-field

Docs page missing md-floating-label under attributes
https://material.angularjs.org/#/api/material.components.autocomplete/directive/mdAutocomplete

Also the x icon should be just an x instead of the current circle with an x. This can be seen on the spec link above. Here is the icon from the official google material icons repo
https://github.com/google/material-design-icons/blob/master/navigation/svg/production/ic_close_24px.svg

nice to have Pull Request

Most helpful comment

quickfix:

HTML

<md-autocomplete md-floating-label="LABEL"
                 md-selected-item="$ctrl.model" md-search-text="$ctrl.searchText"
                 md-selected-item-change="$ctrl.itemChanged($ctrl.model)"
                 md-items="item in $ctrl.items" clear-autocomplete
                 md-autoselect="true" required>
  /* whatever you need, e.g. <md-item-template> or <md-not-found> tags */
</md-autocomplete>

None of the $ctrl attributes has to be named the way they are here, just call them whatever you like.

DIRECTIVE

angular
  .module('yourModule')
  .directive('clearAutocomplete', clearAutocomplete);

function clearAutocomplete($parse) {
  return {
    restrict: 'A',
    link: function(scope, element, attrs) {
      const button = angular.element('<md-button>').addClass('clear-autocomplete');
      button.append('<i class="material-icons">clear</i>');
      element.append(button);

      let searchTextModel = $parse(attrs.mdSearchText);

      scope.$watch(searchTextModel, function(searchText) {
        if (searchText && searchText !== '' && searchText !== null) {
          button.addClass('visible');
        } else {
          button.removeClass('visible');
        }
      });

      button.on('click', function() {
        searchTextModel.assign(scope, undefined);
      });
    }
  }
}

CSS (that's of course optional)

.em-clear-autocomplete {
  position: absolute;
  transform: translate(0, -100%);
  right: 8px;
  visibility: hidden;
  opacity: 0;
  transition: visibility 0s, opacity 0.25s linear;

  &.visible {
    visibility: visible;
    opacity: 1;
    cursor: pointer;
  }

  i {
    font-size: 20px;
  }
}

If you use pre ES16, just replace let and const by var.
If you have problems understanding the $parse, have a look at the official docu: https://docs.angularjs.org/api/ng/service/$parse

Huge thanks to @sebastianhenneberg !

All 26 comments

Would it be possible to keep the clear button but disabled by default ? So if we want to use it we can, because it's very convenient for the users, and the md-floating-label template integrates great with the other inputs styles.

Looking at http://www.google.com/design/spec/components/text-fields.html#text-fields-auto-complete-text-field there is no example with a floating label with autocomplete or im missing something, so i don't understand why you assumed the 'x' should be removed when used the autocomplete as a md-floating-label at least the 'x' makes a great experience allowing to clear the input since its an autocomplete we need a clear way to "reset" and start another "search" so
+1 to @jgoux of at least keeping it optional

+1

+1 for keeping this around but making it optional.
My customers find it very useful. I had to create a custom directive to add it back now :(

+1

+1

+1

I agree with everything that has been said since the closing of this issue. I feel this should be reopened and at least made optional. Though I appreciate the attempt to stick to the spec. The spec is not clear and the current interpretation provides a bad (or inconsistent) user experience.

+1 Fully agree with @steegi
Please allow to display the clear button if needed

+1
much required for streamlined designed and better UX

+1

+1

+1

+1

+1

quickfix:

HTML

<md-autocomplete md-floating-label="LABEL"
                 md-selected-item="$ctrl.model" md-search-text="$ctrl.searchText"
                 md-selected-item-change="$ctrl.itemChanged($ctrl.model)"
                 md-items="item in $ctrl.items" clear-autocomplete
                 md-autoselect="true" required>
  /* whatever you need, e.g. <md-item-template> or <md-not-found> tags */
</md-autocomplete>

None of the $ctrl attributes has to be named the way they are here, just call them whatever you like.

DIRECTIVE

angular
  .module('yourModule')
  .directive('clearAutocomplete', clearAutocomplete);

function clearAutocomplete($parse) {
  return {
    restrict: 'A',
    link: function(scope, element, attrs) {
      const button = angular.element('<md-button>').addClass('clear-autocomplete');
      button.append('<i class="material-icons">clear</i>');
      element.append(button);

      let searchTextModel = $parse(attrs.mdSearchText);

      scope.$watch(searchTextModel, function(searchText) {
        if (searchText && searchText !== '' && searchText !== null) {
          button.addClass('visible');
        } else {
          button.removeClass('visible');
        }
      });

      button.on('click', function() {
        searchTextModel.assign(scope, undefined);
      });
    }
  }
}

CSS (that's of course optional)

.em-clear-autocomplete {
  position: absolute;
  transform: translate(0, -100%);
  right: 8px;
  visibility: hidden;
  opacity: 0;
  transition: visibility 0s, opacity 0.25s linear;

  &.visible {
    visibility: visible;
    opacity: 1;
    cursor: pointer;
  }

  i {
    font-size: 20px;
  }
}

If you use pre ES16, just replace let and const by var.
If you have problems understanding the $parse, have a look at the official docu: https://docs.angularjs.org/api/ng/service/$parse

Huge thanks to @sebastianhenneberg !

+1

+1

+1

Wow nice guys you are going to add it?

Hi all,

I followed the same way and I'm not getting my text box cleared on clicking clear button.

Here is my autocomplete code.

         <md-autocomplete ng-required="true" flex  ng-disabled="!ctrl.enabled"
              md-input-name="autocompleteField"
              md-selected-item="ctrl.selectedCountry"
              md-search-text="ctrl.searchText"
              md-items="country in ctrl.countries | filter: ctrl.searchText"
              md-item-text="country.name"
              md-min-length="0"
              md-floating-label="Select country"  clear-autocomplete>
         <md-item-template>

where ctrl is my md dialog controller

+1

+1
Hope this become optional.

+1

+1

@surinderpalsingh I think need to add scope.$apply();

 button.on('click', function() {          
          searchTextModel.assign(scope, undefined);
          scope.$apply();
        });

also i think .em-clear-autocomplete in CSS need to clear to: .clear-autocomplete

Was this page helpful?
0 / 5 - 0 ratings