0

I am trying to create buttons (using ng-repeat) that when clicked will create other buttons that when these are clicked will display the information I am looking for. I was told that an Angular Directive would do the trick. I have created a custom directive and am trying to incorporate the ng-repeat directive inside of my new directive. I have already looked at this StackOverflow discussion StackOverflow Discussion 2, but I am still having some confusion on how to best get his implemented. As it stands the new directive is being made, but no text is being appended to the button. Also only one button is being generated instead of two in this case. Below is my code (HTML and JavaScript)

HTML: <div ng-app="anniversaries" class="row" ng-controller="annList"> <yearbuttons></yearbuttons> </div>

JavaScript:

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

annApp.controller('annList', function ($scope) {
  $scope.anns = [
  //January 
    {'date':'January 2015','year': '45', 
    'names': ['Sample Name']},
     {'date':'January 2015','year': '34', 
    'names': ['Sample Name2']}

  ];
});

annApp.directive('yearbuttons',function(){
  return {
    restrict: "E",
    compile: function compile(element, attrs)
    {
      element.attr('ng-repeat', 'years in anns');
      element.attr('class', 'btn btn-default');
      element.append('{{year}} Years');
    }
  }
});
Community
  • 1
  • 1
Coded Container
  • 863
  • 2
  • 12
  • 33
  • I understand the basic concept of what you're trying to do, but I don't see the need to do anything fancy here. I would probably just build this the way you would with a view and a controller. If it needs to be reusable, then use a directive. `ng-repeat`, `ng-hide`, `ng-show`, `ng-if`, and `ng-switch` should get you a long way toward what you want to do without the need to muck about with complex directive plumbing. If you decide you need to re-use it later, just plop your template and controller into a directive and you should be good to go. – nbering Sep 09 '15 at 14:47
  • 1
    Declaring template: '
    ' actually do same as your code probably should.
    – Petr Averyanov Sep 09 '15 at 14:49
  • I was just about to add the same as above. Manually adding all these attributes from code is unnecessary. Use a template, it'll be much easier to reason about. If you don't want to add another layer of nested elements (for example because CSS selectors become too complex), then use `replace: true` property on your directive definition. – nbering Sep 09 '15 at 14:52
  • This doesn't work especially if I set a variable inside of ng-click. – Coded Container Sep 09 '15 at 15:12
  • @Balrog30 This [StackOverflowDiscussion](http://stackoverflow.com/questions/32466226/create-dynamic-buttons-that-when-clicked-create-more-dynamic-content/32469580#32469580) will make more sense as to the direction I am trying to go. I have been working on this for hours without a solution. – Coded Container Sep 09 '15 at 15:17
  • Ya, I wouldn't do anything close to that. That is a very jQuery way of thinking. Nothing wrong with it, just that AngularJS comes with it's own design patterns, and what that answer suggests is not common practice as far as I have seen. I would just make an ng-repeat of buttons. If they all need their own different click event handlers, you can just put them as functions on the objects in whatever array you bind your ng-repeat to. `{label: 'My Button', click: function(){$log.info("My Button got clicked.");}}` – nbering Sep 09 '15 at 15:26
  • @Balrog30 Is the code you shared what you would add for a unique directive? – Coded Container Sep 09 '15 at 15:29
  • One second. It probably won't be your answer, but I'll hack something together in an answer where I have more room. – nbering Sep 09 '15 at 15:31
  • @Balrog30 It is strange because if I set a variable in ng-click with something like {{ann.date}} it transforms this into the correct value in the elements property however, when I add the variable such as {{variable}} inside of the tag, it does not render the first transformed value but instead returns "{{ann.date}}. Maybe there is a way to set the priority and don't append until the variable is registered as a string. – Coded Container Sep 09 '15 at 15:42

1 Answers1

0

I personally wouldn't use a directive for this at all unless it needed to be used repeatedly. But if it does, this could easily be converted to a directive just by sticking the template and controller into a directive. Directives can take controllers instead of link functions.

JavaScript

(function(){
  angular.module('myApp', [])
    .controller('BunchOfButtonsController', BunchOfButtonsController);

  BunchOfButtonsController.$inject = ['$scope', '$log'];
  function BunchOfButtonsController($scope, $log){
    $scope.buttons = [];
    $scope.nextLabel = "Some Text";

    $scope.firstButtonClick = function(labelValue){
      $scope.buttons.push({
        label: labelValue,
        click: function(){
          $log.info(labelValue + " was clicked.");
        }
      });
      $scope.nextLabel = "Another " + $scope.nextLabel;
    };
  }
})();

HTML

<div ng-app="myApp" ng-controller="BunchOfButtonsController">
  Label: <input type="text" ng-model="nextLabel"/>
  <button ng-click="firstButtonClick(nextLabel)">Click Me!</button>
    <button ng-repeat="button in buttons" ng-click="button.click()">{{button.label}}</button>
</div>
Community
  • 1
  • 1
nbering
  • 2,725
  • 1
  • 23
  • 31
  • I tried this on [Stack Overflow](http://jsfiddle.net/codedcontainer/amat25oL/1/) without any luck. – Coded Container Sep 09 '15 at 15:47
  • I like what you did. Is there a way to have unique buttons with unique values with labels that create other buttons. I can't say I need a button generator. – Coded Container Sep 09 '15 at 16:06
  • Umm... yes. How you would build it depends on your overall requirements. Does it need to load stuff from a server? Are the values based on user input, or just a bunch of fixed values? What are the buttons actually going to do? All things to take into consideration. – nbering Sep 09 '15 at 16:08
  • You could build something almost like a choose your own adventure just based on nested JSON objects if that's what you're looking for. – nbering Sep 09 '15 at 16:09
  • There is no values based on user input. I have all the data inside of a JSON object attached to the scope. I have years, months, and names in the JSON file. When a unique month is clicked it should display the years for that month. When a year is clicked it will display the names for that year. – Coded Container Sep 09 '15 at 16:19
  • This isn't exactly what I was thinking. – Coded Container Sep 09 '15 at 17:14