0

I'm trying to remove a div dynamically added by clicking on the remove button. I've created this fiddle https://jsfiddle.net/y4punqp3/2/ for convenience.

The remove function

$scope.removeUnavailability = function () {
    --numUnavail;
    document.getElementById("tempUnavail").remove();
}

The corresponding line should be deleted when clicking on the remove button. What am I missing?

Dad85
  • 33
  • 1
  • 1
  • 9
  • 1
    You're using angular wrong. You don't want to manually manipulate the DOM, you want to have a model in your controller to represent the current state of your application, and your template should automatically accommodate to that data... Gimme a few moments and I'll change your fiddle to be in an angular way. – Fissio Mar 07 '17 at 10:12
  • The code in your question is not an [mcve]. You need to provide a MCVE **in the question itself**. The code linked to on JS Fiddle **doesn't match the code in the question**. – Quentin Mar 07 '17 at 10:13
  • @Quentin `The code linked to on JS Fiddle doesn't match the code in the question.` The fiddle is close enough to the question in the code that it shouldn't be an issue – Fissio Mar 07 '17 at 10:14
  • This is a jQuery way of approaching this. You should be using a template that gets added with the help of ng-repeat directive and a collection that can hold zero or more items. Then you can make use of push and slice methods on array which changes your data and this will reflect back in your view. – KKS Mar 07 '17 at 10:14
  • @Fissio — It's calling `remove()` on `.innerHTML`! – Quentin Mar 07 '17 at 10:15
  • I see I'm doing it in a wrong way. Just learnt about angular 2 days ago. I'm also using Jquery for other parts in my page, so didn't care about not being "angular-ish". in the question I've just posted the function that was not working for me. I've also removed the innerHTML part – Dad85 Mar 07 '17 at 10:20

1 Answers1

1

Check the updated fiddle for a clean solution: https://jsfiddle.net/y4punqp3/5/

In Angular, you want to have the data in your controller represent the model, and your template to draw stuff based on that model. You don't want to manually add/remove HTML or edit the DOM in any way outside of directives, otherwise you're just shooting yourself in the foot and you're not really using angular in any meaningful way.

JS:

var app = angular.module("satUnav-app", []);
app.controller("satUnav-ctrl", function($scope) {

  $scope.unavailabilities = [];

  $scope.addUnavailability = function () {
    $scope.unavailabilities.push({});
  }

  $scope.removeUnavailability = function (idx) {
    $scope.unavailabilities.splice(idx, 1);
  }
});

HTML:

<div ng-repeat="unavail in unavailabilities">
    <select ng-model="unavail.selection">
        <option>PRN 01 (ID:401)</option>
        <option>PRN 02 (ID:402)</option>
        <option>PRN 03 (ID:403)</option>
        <option>PRN 04 (ID:404)</option>
    </select>
    <label for="tempUnavail">Start</label>
    <input type="datetime-local" ng-model="unavail.start">
    <label for="tempUnavail">Stop</label>
    <input type="datetime-local" ng-model="unavail.stop">
    <button type="button" data-ng-click="removeUnavailability($index)">Remove</button>
</div>

Now we have nice and clean Angular code where it's easy to add/remove divs just by editing the array scope variable based on which the view is drawn - none of that silly DOM manipulation.

EDIT: And as always in these jQuery-Angular questions, check out the answer here: https://stackoverflow.com/a/15012542/3368834

Community
  • 1
  • 1
Fissio
  • 3,748
  • 16
  • 31
  • Thanks Fissio. It works fine. Despite that, I'm having a hard time trying to understand the ng-model concept. I know it provides a sort of "bridge" between html inputs and angular variables, but still it is not clear to me how it works. As far as I can see, with "unavail.selection, unavail.start and unavail.stop" you are creating 3 variables which represent what the user select. These variables than could be processed in the angular script (e.g. for validation). Is it correct? – Dad85 Mar 07 '17 at 11:03
  • @Fisso: how could I modify your fiddle such that the first option in the select menu that appears on click is not an empty selectable cell but a title like "select one"? – Dad85 Mar 07 '17 at 11:37
  • @Dad85 at your first comment, yeah that's pretty much it - you can check the docs for ng-model for how it works with different inputs etc. As for your second question, here's an updated fiddle with a default selected option, basically you just set `value=""` to the option you want as selected: https://jsfiddle.net/y4punqp3/6/ – Fissio Mar 07 '17 at 13:06