pers3us
pers3us

Reputation: 243

Angular JS directive

I am trying to port an old app written in html/jquery to angularjs. The scenario is there is a list and on click of chevron it shows set of icons just below it (image below)

Screenshot

The way to go is directive, and I was trying to modify one to suit the scenario. What is unclear to me is how will i restrict only one set of icons at a time.

in Jquery it was fairly simple, all the icon sets had class as icon-set so you did $(".icon-set").hide() and it would hide all the icons and when required i.e. on click of chevron show the icons.

In case of angular, i have multiple problems. I have created this list

 <ul class="list" ng-repeat="file in files| filter: { folder:'false' }" >
        <li class="list-main" >
            <ext-img file-name="{{file['file-name']}}"></ext-img>
            <div class="list-info">
                <div class="list-header">{{file['file-name']}}</div>
                <div class="list-info-bottom dimfont"><small>{{ file['modified-timestamp'] | date:'medium' }}</small></div>
            </div>
            <action-button class="chevron" id="{{file['file-path']}}/{{file['file-name']}}"></action-button>
        </li>

    </ul>

the directive , is not working for element.bind() (code below) and how do i show it only for one of the list elements.

myapp.directive('action-button',function(){
 return {
    restrict: 'E',
    template: {

    },
    link: function(scope,element,attrs){
        // This populates the options mene, Bind onclick event
        element.bind("click",function(){
            // Append the options to it.
            var str = '';
            str += "<div class=\"options-box\">" ;
            str += "<ul class=\"options-inner\">" ;
            str += "<li class=\"options-item\">" ;
            str += "<a href=\"#\" ng-click = \"\">" ;
            str += "<img class=\"options-img\" src=\"images/share_file.png\">" ;
            str += "<div>Share</div>" ;
            str += "</a>" ;
            str += "</li>" ;
            str += "</ul></div>";
        element.replaceWith(str);
       }
        )

      }
   }
})

edit: I can fix the not-working issue what i am confused about is how to make it show only one icon set. edit: Fixed typo

Upvotes: 2

Views: 387

Answers (2)

Brian Genisio
Brian Genisio

Reputation: 48127

First, you want to use a template instead of link to hook up the HTML. Include a template that looks something like this:

<div class="chevron" ng-click="toggle()"></div>
<div class="content" ng-if="showContent">
    <div class="options-box">
    etc...
</div>

The ng-if directive will only include this DIV in the DOM if showContent is true. This is different from ng-hide and ng-show which simply hides/shows the content.

Next, you need a controller in your directive to define toggle() and showContent

This will handle the individual directive, but it won't communicate to the other directives.

To do this, you have several options.

One option is to use $scope.$broadcast and $scope.$on to broadcast/receive messages. One directive can tell all the others to hide before it shows itself. That is similar to using $('.icon-set').hide() before showing the individual.

Another option is to create a parent directive called action-buttons which is responsible for adding the action-button children. It has a function in its controller called hideAll() and the child directives will require: '^action-buttons'. This lets the parent controller get passed into a link function: link: function(scope, element, attrs, ActionButtonsCtrl where you can call hideAll() from the child.

You can also mess around with inherited scopes, but I recommend against that approach.

Good luck, Brian

Upvotes: 1

Julio
Julio

Reputation: 2523

In fact you are working with angularjs like you are working with Jquery. This is not the best way and you should not modify the dom yourself but use the template.

To solve your issue, you should move your str HTML code to the directive template:

template: '<div class=...>'

Then add a ng-hide attribute to your <div class=\"options-box\">element like that:

<div class=\"options-box\" ng-hide='showOption()'>

In the scope you need to define the showOption procedure:

scope: {
    showOption = function() { return ... }
} 

Upvotes: 1

Related Questions