2

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

2 Answers 2

1

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

Sign up to request clarification or add additional context in comments.

1 Comment

I finally got it working. You have no idea how thankful I am, I was stuck on it for more than 3 days. Thanks a lot. I used the first approach of $rootScope.$broadcast("hideAll"), and $scope.$on("hideAll", function(){}). here is my final code. play.golang.org/p/efMi8Mr05r Thanks again. :)
1

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 ... }
} 

2 Comments

Okay, I would do that, but won't this add the template to each and every line and just hide it? In jquery i was loading the content when clicked and for 2nd click i was hiding it. so that the option-box got loaded in the again as well, and previous one got hidden.
@pers3us In fairness, you didn't explain it that way in your post. You suggested that you use $('.icon-set').hide() which will keep it in the DOM and not hide it. If you'd like to keep all of these DIVs out of the DOM, you can change ng-hide to ng-if="!showOption()".

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.