How can I change the Bootstrap AngularJS dropdown / select so that it does not use jQuery?

I saw a really good example of an AnglerJS Bootstrap type for the Select directive:

http://jsfiddle.net/cojahmetov/3DS49/

This meets most of my needs, but uses jQuery, and we do not use this library.

The jQuery used in this example is very minimal, but I don’t know how I could replace element locators that look like this:

Can someone give me any directions as to how I could replace this:

switch (attrs.menuType) { case "button": $('button.button-label', element).html(item.name); break; default: $('a.dropdown-toggle', element).html('<b class="caret"></b> ' + item.name); break; } 

To make it work without jQuery ? Ideally, I hope someone knows enough to possibly come up with a version based on the version in ui-bootstrap . Perhaps this may be something that can be added to ui-bootstrap for other users.

+5
source share
3 answers

The idea is that Fiddle was nice, but I found the implementation kind of dirty. So what can be done? Well, write an alternative dropdown directive on top of ui-bootstrap , of course!

Hope you find this helpful. It should be very easy to use.

Using

 <dropdown is-button ng-model="vm.item" items="vm.items" callback="vm.callback(item)"> </dropdown> 

So, you go into the ng-model , which contains the original selection, if any. The new value is set in the directive. In items , you have a collection of id-name pairs for selection and callback if you need it. If you specify the is-button attribute, you will get a is-button dropdown control.

Then the controller may look as follows.

controller

 // Controller app.controller('Ctrl', function() { var vm = this; // items collection vm.items = [{ id: 0, name: 'London' },{ id: 1, name: 'Paris' },{ id: 2, name: 'Milan' }]; // current item vm.item = null; // vm.items[1]; // directive callback function vm.callback = function(item) { vm.fromCallback = 'User selected ' + angular.toJson(item); }; }); 

The logic for the dropdown directive is pretty simple, really.

JavaScript directive

 // Dropdown directive app.directive('dropdown', function() { return { restrict: 'E', require: '^ngModel', scope: { ngModel: '=', // selection items: '=', // items to select from callback: '&' // callback }, link: function(scope, element, attrs) { element.on('click', function(event) { event.preventDefault(); }); scope.default = 'Please select item'; scope.isButton = 'isButton' in attrs; // selection changed handler scope.select = function(item) { scope.ngModel = item; if (scope.callback) { scope.callback({ item: item }); } }; }, templateUrl: 'dropdown-template.html' }; }); 

HTML Directive Template

 <div class="btn-group" dropdown> <!-- button style dropdown --> <button ng-if="isButton" type="button" class="btn btn-primary" ng-bind="ngModel.name || default"> </button> <button ng-if="isButton" type="button" class="btn btn-primary dropdown-toggle" dropdown-toggle> <span class="caret"></span> </button> <!-- no button, plz --> <a ng-if="!isButton" class="dropdown-toggle" dropdown-toggle href ng-bind="ngModel.name || default"> </a> <span ng-if="!isButton" class="caret"></span> <!-- dropdown items --> <ul class="dropdown-menu" role="menu"> <li ng-repeat="item in items"> <a href="#" ng-bind="item.name" ng-click="select(item)"></a> </li> </ul> </div> 

Here is the appearance of the original implementation. In addition to the provided sample, you will return the entire object, not just the id .

enter image description here


The related Plunker is here http://plnkr.co/edit/bLWabx using angularjs 1.4.0-beta.3 and ui-bootstrap 0.12.0.
+14
source

This solution only supports IE9 + if you need to support legacy browsers. I can find another solution and update.

http://jsfiddle.net/3DS49/160/

 scope.selectVal = function (item) { function selector(sel, htmlCont) { var elems = document.querySelectorAll(sel); Array.prototype.forEach.call(elems, function(el, i){ el.innerHTML = htmlCont; }); } switch (attrs.menuType) { case "button": selector('button.button-label', item.name); break; default: selector('a.dropdown-toggle', '<b class="caret"></b> ' + item.name); break; } scope.doSelect({ selectedVal: item.id }); }; 
+3
source

Change I was right, you do not need to use .html () in this example, and this is bad practice in general. Notice how I used the scope object to achieve the same result: http://jsfiddle.net/3DS49/162/

In the minimum example given here, you can use angular.element instead of $ or jQuery . angular.element is a subset, but it supports .html ().

However, this is still bad practice, as the content can be placed in scope and the html content can be set as a direct binding in button templates.

Edit : angular. Element does not support selector. To do this, you should use your own approach (getElementById and his friends). However, make sure you are not using special jquery selectors, for example: first. For instance:.

 var elements = document.querySelectorAll(".myclass"); //it is up to you to iterate over the elements and call angular.element(element).html(yourValueHere) on each element. //NOTE: you can get document from $windowProvider.$get().document, or $window.document, depending on the place (you will use $window.document in this case). 

Edit : check browser support here - there is no built-in angular way to support selectors.

For practical implementation of a particular case, it is safe to see @ChrisFrank's answer. However, remember that you can wrap each of the elements, iterations (for example, in his answer), using the angular.element function to get jqLite (the built-in subset of jQuery in AngularJS - you do not need an additional library).

+2
source

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


All Articles