0

I'm trying to create a directive for a label selector.

<label-selector label="label1">label1</label-selector>

label1 is the default label that should be selected, this value comes from the $scope in the controller for the view where the label-selector is present.

The behaviour I want is as follows, when a user clicks label1 a modal should open. This modal lists a collection of labels, (the collection should be loaded from some array somhere). label1 in the collection should be marked as selected, e.g. class="selected".

When I click another label say, label2, label2 should be selected and the modal should be closed. This event will also update label-selector.

<label-selector label="label2">label2</label-selector>

I would like to encapsulate both the label-selector element and the modal in the same directive.

Is this possible?

UPDATE

I'v done a small example here.

HTML

 <div ng-app="app" id="app">
    <div ng-controller="MainCtrl">
        <label-select color="{{color}}"></label-select>
    </div>
</div>

CSS

.flyout {
    position: absolute;
    top: 0px;
    right: 0px;
    z-index: 31101;
    background-color: lightgray;
    bottom: 0px;
    box-shadow: -4px 0 4px rgba(0, 0, 0, 0.2);
    overflow-y: auto;
    width: 500px;
    -webkit-transform: translate(100%, 0%);    
    -webkit-transition: all 0.2s ease-in-out;
}
.flyout.show{
    -webkit-transform: translate(0%, 0%);    
}

JS

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

app.controller('MainCtrl', function ($scope) {
    $scope.color = "#cecece";
});

app.directive('labelSelect', function ($parse, $location) {
    return {
        restrict: 'E',
        scope: {
            color: '@color'
        },
        template:
        '<a ng-click="selectColor()" style="color: {{color}}" class="label-color icon-bookmark">{{color}}</a><div class="flyout"></div>',
        link: function (scope, lElement, attrs) {
            scope.selectColor = function () {
                angular.element(".flyout").addClass("show");
            };            

        }
    }
});

http://jsfiddle.net/FrejNorling/bNumc/4/

The behaviour I try to create is that I want the flyout div to be filled with a list (ul list) of labels, and when I select one label in the list the the $scope.color in MainCtrl should be updated and the flyout should disapear/close.

dcodesmith
  • 9,590
  • 4
  • 36
  • 40
Frej
  • 320
  • 4
  • 14
  • Have you had a look @ [angular.ui.bootstrap](http://angular-ui.github.io/bootstrap/#/modal)? – dcodesmith Jul 31 '13 at 15:48
  • Looked at it a bit, but as far as I can see the angular.ui.bootstrap.modal uses vanilla HTML for the open button and do not load a anything from the parent $scope. – Frej Jul 31 '13 at 15:56
  • It does ... [here](https://github.com/angular-ui/bootstrap/blob/master/src/dialog/README.md#methods-1) – dcodesmith Jul 31 '13 at 15:58

1 Answers1

1

Like I said in the comment you can access the variables from the parent scope in the modal popups scope.

HTML

<div ng-app="app" id="app">
    <div ng-controller="MainCtrl">
        <label-select color="{{color}}"></label-select>
        <div class="flyout">
            <ul>
                <li ng-click="setColor(color)" ng-repeat="color in colors">{{color}}</li>
            </ul>
        </div>
    </div>
</div>

JS

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

app.controller('MainCtrl', function ($scope) {
    $scope.color = "#AAADDD";
    $scope.colors = ["#AAA", "#BBB", "#CCC", "#DDD", "#EEE"];
    $scope.setColor = function (color) {
        angular.element(".flyout").removeClass("show");
        $scope.color = color;
    }

});

app.directive('labelSelect', function ($parse, $location) {
    return {
        restrict: 'E',
        scope: {
            color: '@color'
        },
        template:
            '<a ng-click="selectColor()" ng-showstyle="color: {{color}}" class="label-color icon-bookmark">{{color}}</a>',
        link: function (scope, lElement, attrs) {
            scope.selectColor = function () {
                angular.element(".flyout").addClass("show");
            };
        }
    }
});

JSFIDDLE DEMO

dcodesmith
  • 9,590
  • 4
  • 36
  • 40
  • This example does not encapsulate things in a directive (?). It might not be clear from my question but I want to have a singel directive (label-selector) and use that to open a dialog/show a div with a list of labels. – Frej Aug 01 '13 at 09:31
  • Ok, but from the little code you've posted it's hard to debug the issue. Perhaps you could create a jsfiddle and then we can take it from there. – dcodesmith Aug 01 '13 at 09:42
  • Yes I know it's a bit meager information I gave. Will create a JS fiddle. Thank you for trying to help any way. – Frej Aug 01 '13 at 09:46
  • This is my first jsfiddle attempt. Updated question to clarify. http://jsfiddle.net/FrejNorling/bNumc/4/ – Frej Aug 01 '13 at 12:23
  • First draft . . [fiddle](http://jsfiddle.net/dcodesmith/a2EZn/), getting close? @Frej – dcodesmith Aug 01 '13 at 13:00
  • [Fiddle Update](http://jsfiddle.net/FrejNorling/meJJ5/6/) Forked your fiddle and added a new Controller and another directive. This way the MainCtrl is very clean. Problem now is scope isolation. Any ideas? @dcodesmith – Frej Aug 01 '13 at 14:17
  • @Frej, sorry I was busy. So what exactly is next now? Let's do this 1 step @ a time – dcodesmith Aug 01 '13 at 15:44
  • Thanks for everything. What I'm looking for now is how I should use isolated scope in the 2 directives so they don't interfear with each other. Made a quick search and found [this](http://stackoverflow.com/questions/14300986/angularjs-directive-isolated-scope-and-attrs) and [this](http://stackoverflow.com/questions/13639399/managing-communication-between-independent-angularjs-directives-independenly/14298481#14298481) that will help me. – Frej Aug 01 '13 at 20:08
  • Fixed it! Here is the final result: [Final result](http://jsfiddle.net/FrejNorling/meJJ5/8/) Thanks for your help. – Frej Aug 01 '13 at 21:10