Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using AngularJS select ng-options with Semantic UI's dropdown

So Semantic UI appears to the latest 'hot' UI framework which I'm impressed with; however, their dropdown isn't an implementation of the HTML 'select' and 'option' tags but instead custom. For my project, I'm using AngularJS which is phenomenal JavaScript MVW framework.

How can I integrate AngularJS select ng-option with Semantic UI's dropdown? I'm not much of a JS pro. Here's the JSfidde: http://jsfiddle.net/fMUy3/

    <!doctype html>
<html ng-app="App">

    <body ng-controller="MainCtrl">
            <h3>Option 1 (standard)</h3>

        <select ng-model="selectedItem" ng-options="c as (c.id + ' - ' + c.name) for c in containers">
            <option value="">-- Pick A Container --</option>
        </select>
        <br>ID: {{selectedItem.id}}
        <br>Name: {{selectedItem.name}}
         <h3><a href="http://semantic-ui.com/modules/dropdown.html"> Semantic UI Dropdown</a></h3>

        <div class="ui selection dropdown ">
            <input name="id" type="hidden" value="0">
            <div class="text">-- Pick A Container --</div>  <i class="dropdown icon"></i>   
            <div class="menu transition hidden">
                <div class="item active">-- Pick A Container --</div>
                <div data-value="{{container.id}}" class="item" ng-repeat="container in containers">{{container.name}}</div>
            </div>
    </body>

</html>

JavaScript:

var app = angular.module('App', []);

app.controller('MainCtrl', function($scope) {
  $scope.containers = [
  {id: 1, name: 'Box1'},
  {id: 2, name: 'Box2'},
  {id: 3, name: 'Box3'}];

  //$scope.selectedItem = $scope.containers[0];
});

$('.ui.dropdown').dropdown();

Much appreciated!

like image 453
user1322092 Avatar asked Feb 14 '23 09:02

user1322092


2 Answers

There were a few things wrong with your fiddle. The first was that the semantic-ui JavaScript was being loaded before jQuery. It depends on jQuery so jQuery must be loaded first. (Also, loading jQuery before AngularJS is recommended.)

The second thing is that the semantic dropdown function was being called before AngularJS had a chance to unroll the repeater that creates the options. This means the options were not there when semantic did its dropdown thing. As a simple solution I made a timeout that would fire on the next processing loop; after AngularJS has done its thing. You can see that semantic dropdown now works

This is more of a simple proof of concept to demo the timing of things and should not be used.
http://jsfiddle.net/fMUy3/1/

$timeout(function(){
    $('.ui.dropdown').dropdown();
},0)

How this should be handled is with a directive that will take care of the timings so that you do not need to use the timeout and would not need to specify each dropdown in the controller. Here is the example using a directive (which would handle all cases)

http://jsfiddle.net/fMUy3/7/

app.directive('dropdown', function ($timeout) {
    return {
        restrict: "C",
        link: function (scope, elm, attr) {
            $timeout(function () {
                $(elm).dropdown().dropdown('setting', {
                    onChange: function (value) {
                        scope.$parent[attr.ngModel] = value;
                        scope.$parent.$apply();
                    }
                });
            }, 0);
        }
    };
});
like image 173
TheSharpieOne Avatar answered Mar 06 '23 05:03

TheSharpieOne


Your first problem is you need to include semantic.js after jquery.

Second, you can't use ng-options on a div repeater but you can simulate it by using a ng-click

HTML

 <div data-value="{{container.id}}" class="item" ng-repeat="container in containers" ng-click="select(container)">
     {{container.name}}
 </div>

JS

$scope.select = function(container) {
    $scope.selectedItem = container;        
};

see this updated fiddle

like image 31
Chris Montgomery Avatar answered Mar 06 '23 05:03

Chris Montgomery