Tevon Strand-Brown
Tevon Strand-Brown

Reputation: 1708

Dynamically creating buttons for paragraphs with Angularjs

I want to dynamically create a button for each paragraph that is created inside a contenteditable div. I've been thinking a lot and can't come up with a good solution. The things I've thought about are

  1. putting the button and paragraph together into one directive and have the content editable add a new <button+p> tag each time the user hits return. This has the benefit of having both the button and the paragraph use the same controller, but it leaves the button in the content editable div so it can be deleted...

  2. Use the Model to maintain an array of all paragraphs in the div, then create buttons for each of the paragraphs in this array. My question here is: if I update the model with new paragraphs, will the buttons automatically be generated? If I use ng-repeat?

I'm kind of at a loss of the best way to approach this. Should I try to build the button and the paragraph together? Or is there a better way of separating them but binding them together so that when the button is clicked I can change the styling of the paragraph?

Upvotes: 2

Views: 1551

Answers (2)

quirimmo
quirimmo

Reputation: 9988

Create a directive and associate it to your div. Ex: Define as binding a parameter with two way data binding, the ones that will keep track of the p elements created inside the div and that will be passed from the the controller associated to your view.

Inject inside your link function of the directive the $element. Then bind to the div with contenteditable the input event in order to detect edits in the div. Inside this code get the total number of p children of your div, and associate it to the variable allowed from the directive. In this way your parameter is always sync with the number of p inside your div, and it can be accessed from outside scopes because you pass it from outside.

Then inside your view, use a ng-repeat iterating over this parameter you passed in the directive, and create your dynamic content inside the ng-repeat.

HTML Code:

<div ng-app="myApp">
  <div ng-controller="Controller">
    <div contenteditable="true" p-inspector p-elements="pElementsNumber">
      TEST
    </div>
    {{pElementsNumber}}
    <div ng-repeat="p in returnArrayFromNumber() track by $index">
      P detected
    </div>
  </div>
</div>

Here the JS code:

angular.module('myApp', [])
.controller('Controller', ['$scope', function($scope) {
    $scope.pElementsNumber = 0;
  $scope.returnArrayFromNumber = function () {
    return new Array($scope.pElementsNumber);
  };
}])
.directive('pInspector', function($rootScope) {
  return {
    restrict: 'A',
    scope: {
      pElements: '='
    },
    link: function ($scope, $element, $attrs) {
        $element.on("input", function(e) {
        var htmlString = $element.text();
        var regex = /<p>[^<p><\/p>]*<\/p>/gi, result, count = 0;
        var count = 0;
        while ( (result = regex.exec(htmlString)) ) {
            count++;
        }
        $scope.pElements = count;
        $rootScope.$apply();
      });
    }
  };
});

Here the running example: https://jsfiddle.net/a0jwmpy4/81/

Just one recommendation: if you want to detect more elements, make this directive dynamic accepting the name of the elements in the parameters and detecting all of them. Please do not create a single directive for every element you want to detect inside the div :)

Hope this helps

Upvotes: 1

Hassan Sani
Hassan Sani

Reputation: 124

Have you tried to use ng-repeat for each paragraph/modal then set all your code in each repeat something like below

<div>
<p ng-repeat="paragraph in paragraphs"> {{contentsOfParagraph}} <button ng-click="editParagraph(MayBeIDOfParagraph)">Edit</button></p>
</div>

now your js code will have a function editParagraph that pass the ParagraphID

Upvotes: 0

Related Questions