📜 ⬆️ ⬇️

AngularJS adaptation of ui-select under x-editable with the additional ability to add objects on the fly

Hello!

I recently had the opportunity to adapt ui-select for x-editable in Angulyar and since I had to spend a certain amount of time for this, collecting the most acceptable option bit by bit, today I decided to share my work with you, in the hope that it would save someone time.

In short, the resulting directive replaces the standard editable-select, plus the additional ability to add objects on the fly.

Now more.
')
To begin, let me start from the end and give the directive code that allows you to add a button to ui-select. A function is hung on this button, in my case, a function that calls a modal window (ui-bootstrap modal) with a form for adding a new object:
app.directive("addNewItem", function($timeout) { return { restrict: "A", link: function(scope, e, attrs) { var method = attrs.addNewItem; var template = "<div class='add-new-item-container'>"+ "<button class='btn btn-xs btn-default pull-right'></button>"+ "<div class='clearfix'></div></div>"; e.find('li.ui-select-choices-group').append(template); e.find('div.add-new-item-container button').bind('click', function() { // workaround for closing ui-select $timeout(function() { e.trigger("click"); }); var searchResult = e.find('li.ui-select-choices-row').length; if ( ! searchResult ) { var value = e.find('input.ui-select-search').val(); scope[method].apply(null, [value]); } else { scope[method].apply(); } }); } } }) 


In principle, the code is extremely simple, so I’ll stop on a couple of moments. First, ui-select does not close after pressing a button, but closes if you click somewhere on the modal window. Therefore it was necessary to add a crutch with $ timeout.
Secondly, (regarding the last if else): if no elements were found in the ui-select search, I pass the search value to the method in order to auto-fill the form with this value in the future and thus save some time.

Now the main directive:

 app.directive('editableUiSelect', ['editableDirectiveFactory', 'editableNgOptionsParser', function(editableDirectiveFactory, editableNgOptionsParser) { var dir = editableDirectiveFactory({ directiveName: 'editableUiSelect', inputTpl: '<ui-select></ui-select>', render: function() { this.parent.render.call(this); var parsed = editableNgOptionsParser(this.attrs.eNgOptions); this.inputEl.attr('ng-model', 'editable.entity'); //  ,  , //  - ,          this.inputEl.attr('add-new-item', 'addNewItem'); //     ,     this.inputEl.attr('on-select', 'setModel($item)'); this.inputEl.attr('theme', 'select2'); this.inputEl.css('width', '200px'); var html = "<ui-select-match><span ng-bind='$select.selected.name'></span></ui-select-match>"+ "<ui-select-choices repeat='" + parsed.ngRepeat + "'>" + "<span ng-bind-html='" + parsed.locals.displayFn + "'></span></ui-select-choices>"; this.inputEl.removeAttr('ng-options'); this.inputEl.append(html); } }); return dir; }]); 


The directive was made in the image and likeness of standard xeditable directives, and then slightly redone.
One of the main problems I encountered while writing a directive was the impossibility of changing the model, so an additional method was added for on-select.

You can use all this as follows:

 <span data-pk="{{ entity.id }}" editable-ui-select="entity.property" ng-model="entity.property" e-ng-options="obj.id as obj.name for obj in objects | filter: $select.search track by obj.id" e-form="rowform"> {{ entity.property.name }} </span> 


And finally, a bonus. If you use this case in table-responsive (bootstrap), then the drop-down list can be blocked by a table (especially if it consists of a pair of rows). You can fix this by adding css:

 .table-responsive .ui-select-dropdown { position: relative !important; } 


Conclusion There are many options for implementing this directive, and there are probably better options than mine among them. I published my work only because there is no mention of support for ui-select in the official xeditable documentation , and also because I found little information on the topic, and the one that I found differs from each other.

I hope that the guru of the angulyar will help me to improve my directive, and also that this article will be useful to someone.

UPD . A small example: plnkr.co/edit/5dPKCnzbKE8D9XIR8ocX?p=preview

Source: https://habr.com/ru/post/277001/


All Articles