Discourse.UserSelector = Discourse.TextField.extend({ didInsertElement: function() { var userSelectorView = this, selected = []; function excludedUsernames() { var exclude = selected; if (userSelectorView.get('excludeCurrentUser')) { exclude = exclude.concat([Discourse.User.currentProp('username')]); } return exclude; } $(this.get('element')).val(this.get('usernames')).autocomplete({ template: Discourse.UserSelector.templateFunction(), disabled: this.get('disabled'), single: this.get('single'), allowAny: this.get('allowAny'), dataSource: function(term) { return Discourse.UserSearch.search({ term: term, topicId: userSelectorView.get('topicId'), exclude: excludedUsernames(), include_groups: userSelectorView.get('include_groups') }); }, transformComplete: function(v) { if (v.username) { return v.username; } else { var excludes = excludedUsernames(); return v.usernames.filter(function(item){ // include only, those not found in the exclude list return excludes.indexOf(item) === -1; }); } }, onChangeItems: function(items) { items = _.map(items, function(i) { if (i.username) { return i.username; } else { return i; } }); userSelectorView.set('usernames', items.join(",")); selected = items; }, reverseTransform: function(i) { return { username: i }; } }); } }); Handlebars.registerHelper("showMax", function(context, block) { var maxLength = parseInt(block.hash.max) || 3; if (context.length > maxLength){ return context.slice(0, maxLength).join(", ") + ", +" + (context.length - maxLength); } else { return context.join(", "); } }); Discourse.UserSelector.reopenClass({ // I really want to move this into a template file, but I need a handlebars template here, not an ember one templateFunction: function() { this.compiled = this.compiled || Handlebars.compile( "
" + "" + "
"); return this.compiled; } }); Discourse.View.registerHelper('userSelector', Discourse.UserSelector);