Skip to content
This repository was archived by the owner on Oct 2, 2019. It is now read-only.

tags do not save on blur, confusing users if in a ui-modal #1013

Closed
jwawi opened this issue Jun 15, 2015 · 5 comments
Closed

tags do not save on blur, confusing users if in a ui-modal #1013

jwawi opened this issue Jun 15, 2015 · 5 comments

Comments

@jwawi
Copy link

jwawi commented Jun 15, 2015

When using the tagging directives inside of a ui-modal, users are tricked into thinking that their tags have saved when they click the save button as this dismisses the modal, not realizing that they have to hit enter first.

Issue 894 has a local fix, but I use grunt/bower/npm in an automated build process, so copying that local fix in't really an option for our project.

Issue 894's on blur fix:
#894

@ghost
Copy link

ghost commented Aug 5, 2015

@jwawi
Copy link
Author

jwawi commented Aug 6, 2015

Your plnkr doesn't really address the issue at all. A working plnkr would work like this:

  1. I start typing a tag, but I don't hit the enter key (or comma or anything to commit the tag)
  2. I click outside of the ui-select and clicking outside of the ui-select adds a new tag

This functionality is "adding a tag on blur". In your plnkr, tags disappear on blur, which isn't useful to my use case. I ended up writing my own solution in a directive, but this functionality should really be enabled in ui-select so that developers don't have to keep rolling their own local fixes. I use grunt for automated builds, so I don't make local modifications to plugin source code, I have to make add-on directives which is somewhat inefficient.

I'll try to put together code for a pull request if someone else hasn't yet when I have time.

@jwawi
Copy link
Author

jwawi commented Aug 6, 2015

The use case is:

  1. I have a tagging button that triggers an angular-ui ui-modal
  2. The ui-modal has the ui-select in tagging mode, and it has a save button that posts the tags from the ui-select to a service and dismisses the modal in one click.
  3. A user types a tag, but DOESNT hit enter -
  4. They click save thinking that is all they need to do, but clicking save doesn't post their last tag and the modal is dismissed without posting that last tag, making them think something is broken.

The solution for me was to make a directive that will push the "in-progress" tag to my post array if they click anywhere outside the ui-select (on blur). This will allow the tag to be saved if they click on the save button, or anywhere else in the modal. This is how tagging works on most sites.

@jwawi
Copy link
Author

jwawi commented Sep 14, 2015

This is what I wrote in a controller. It also prevents duplicate tags from being added, which can break the UI unless you are using track by $index. I place this in a bootstrap-ui modal controller, but this could easily be placed in a directive's controller. If I get time today I will build a plnkr example with this in a directive. Let me know what you think

// DOCUMENTATION: Initialize data model used by tagging UI
$scope.tagModel = {tags:[]};

// DOCUMENTATION: filter duplicates or the ui-select will break
$scope.filterTagDuplicates = function(){

      if ($scope.blockFilterRecursion) {
          $scope.blockFilterRecursion = false;
          return;
      }

      var uniqueTags = [];
          angular.forEach($scope.tagModel.tags,function(obj,i){
              var dupe = false;
                  angular.forEach(uniqueTags, function(obj2,i2){
                       if (obj.name === obj2.name) dupe = true;
                  });
                  if (!dupe) uniqueTags.push(obj);
                  $scope.blockFilterRecursion = true;
                  $scope.tagModel.tags = uniqueTags;
          });
};

// DOCUMENTATION: if user hits enter or tab it won't trigger the on blur function
// need to filter any duplicates if found
$scope.$watch('tagModel.tags', function(tags) {
      if (!$scope.tagModel) return;
          $scope.filterTagDuplicates();
});

// DOCUMENTATION: wait for modal to render, then register event listener 
// listener adds tags on blur instead of just hitting enter
// this is kind of a hack until ui-select implements this. 
// can't modify their source code locally
// due to the bower/grunt automated build
$timeout(function(){
      $(".ui-select-search").on('blur', function(event){
          var newTag = ($(".ui-select-search").val());
              if ($(".ui-select-search").val() !== '') {
                  $scope.addTagIfUnique(newTag);
                  $scope.filterTagDuplicates();
                  $scope.$apply();
              }
      });
}, 1000); 
// timeout probably doesn't need to be so long, I wait so the modal is rendered

// DOCUMENTATION: dont allow duplicate tags or ui-select will break 
// ui-select uses ng-repeat which will break on duplicates if not tracking by index
$scope.addTagIfUnique = function(newTag) {
      var dupe = false;
      angular.forEach($scope.tagModel.tags, function(obj,i){
          if (obj.name == newTag) {
              dupe = true;
              return false;
          }
      });
      if (!dupe && $scope.tagModel.tags) $scope.tagModel.tags.push({"name":newTag,"type":"tag"});
      if (!dupe && !$scope.tagModel.tags) $scope.tagModel.tags = [{"name":newTag,"type":"tag"}];
};

@user378230
Copy link
Contributor

Closing as duplicate of #894

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants