3

If I want to remove/add element on DOM I just use ng-if and the code under it does not compile into to DOM, can I do the same using pure js? I don't want the HTML code inside my js code.

Hiding it using CSS:

<div id = "infoPage" style="display: none;">

Will still insert the element to the DOM.

EDIT

The condition for showing or not is based on a flag like:

var show = false; //or true
Itsik Mauyhas
  • 3,824
  • 14
  • 69
  • 114
  • 2
    Possible duplicate of [JavaScript DOM remove element](https://stackoverflow.com/questions/8830839/javascript-dom-remove-element) – Weedoze Aug 02 '17 at 07:39
  • @Weedoze No. Its about adding/removing element based on a flag. – Rajesh Aug 02 '17 at 07:39
  • @Rajesh - yes, my goal is that only flag will appear in js. – Itsik Mauyhas Aug 02 '17 at 07:43
  • @Rajesh The link will explain him how to remove the child. If only have to add an `if` condition to remove it or not. What does it need more ? – Weedoze Aug 02 '17 at 07:46
  • You can do it with removeChild. Just add if condition, and that's it. Same thing like ngIf – Dino Aug 02 '17 at 07:47
  • @Weedoze How would you add the element again? Where will you save the element if value is false and it is removed from DOM? – Rajesh Aug 02 '17 at 07:48
  • @Rajesh Ok the question I linked is not complete to answer OP's question but his question is actually a mix of existing questions on SO. – Weedoze Aug 02 '17 at 07:49
  • @Weedoze removeChild works after the DOM loaded, so in some stage of loading the code inside gets compiled on to the DOM, not the same as `ng-if` at all. – Itsik Mauyhas Aug 02 '17 at 07:49
  • @ItsikMauyhas Have you tried something ? – Weedoze Aug 02 '17 at 07:49
  • @Rajesh You can store the collection of DOM elements in a variable. This solves your issue – Dino Aug 02 '17 at 07:50
  • @ItsikMauyhas ng-if does the same thing. It compiles in the DOM, then removes it. Read documentation on ng-if – Dino Aug 02 '17 at 07:52
  • Yes but is the condition is false?`If the expression is falsy then the element is removed from the DOM tree. If it is truthy a copy of the compiled element is added to the DOM tree.` so if I understant right only true flag will make it compield. Posting a code based on the answers. – Itsik Mauyhas Aug 02 '17 at 08:01
  • @ItsikMauyhas Hope my answer helps in some way – Rajesh Aug 02 '17 at 09:21

1 Answers1

5

You can try something like this:

Idea:

  • Create an object that holds reference of currentElement and its parent (so you know where to add).
  • Create a clone of current element as you want to add same element after its removed.
  • Create a property using Object.defineProperty. This way you can have your own setter and you can observe changes over it.
  • To toggle element, check
    • If value is true, you have to add element. But check if same element is already available or not to avoid duplication.
    • If false, remove element.

var CustomNGIf = function(element, callback, propertyName) {
  var _value = null;

  // Create copies of elements do that you can store/use it in future 
  this.parent = element.parentNode;
  this.element = element;
  this.clone = null;

  // Create a property that is supposed to be watched
  Object.defineProperty(this, propertyName, {
    get: function() {
      return _value;
    },
    set: function(value) {
      // If same value is passed, do nothing.
      if (_value === value) return;
      _value = !!value;
      this.handleChange(_value);
    }
  });

  this.handleChange = function(value) {
    this.clone = this.element.cloneNode(true);
    if (_value) {
      var index = Array.from(this.parent.children).indexOf(this.element);

      // Check if element is already existing or not.
      // This can happen if some code breaks before deleting node.
      if (index >= 0) return;
      this.element = this.clone.cloneNode(true);
      this.parent.appendChild(this.element);
    } else {
      this.element.remove();
    }

    // For any special handling
    callback && callback();
  }
}

var div = document.getElementById('infoPage');
const propName = 'value';
var obj = new CustomNGIf(div, function() {
  console.log("change")
}, propName);

var count = 0;
var interval = setInterval(function() {
  obj[propName] = count++ % 2;
  if (count >= 10) {
    window.clearInterval(interval);
  }
}, 2000)
<div class='content'>
  <div id="infoPage"> test </div>
</div>

Community
  • 1
  • 1
Rajesh
  • 24,354
  • 5
  • 48
  • 79
  • **Note:** If you think something is wrong with the answer please share your feedback along with your vote. :-) – Rajesh Aug 02 '17 at 09:21