daveycroqet
daveycroqet

Reputation: 2727

Changing only selective portions of a container dynamically

Fiddle: https://jsfiddle.net/1b81gv7q/

Apologies for the somewhat obscure title; I couldn't think of better phrasing.

Anyhow, let's say I have a container with content that I want to swap out dynamically.

How would I go about replacing everything in the template DOM node except for static-container? Please note that targeting h1 and p specifically is not a valid solution. The entire template container must be replaced, but static-container should be spared and should remain (structurally) where it is, as the last child of template.

Not seeking React/Vue/Angular/framework-dependent solutions. Pure JS or jQuery only, please.

$('button').click(function() {
  let newTemplate = $('.new-template').html();
  $('.template').html(newTemplate);
});
.new-template {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
  <div class="template">
    <h1>header #1</h1>
    <p>some text for #1</p>
    <div class="static-container">
      <div>
        <p>a b c 1 2 3</p>
        <p>d e f 4 5 6</p>
      </div>
    </div>
  </div>
</div>

<button>change template</button>

<div class="new-template">
  <h1>header #2</h1>
  <p>some text for #2</p>
  <div class="static-container"></div>
</div>

Upvotes: 0

Views: 39

Answers (3)

Joe Jankowiak
Joe Jankowiak

Reputation: 1159

You could loop through and check if the DOM has the static-container class and if not remove it. Then once only the static-container is left, prepend your new template to it so static-container stays as the last element.

$('button').click(function() {
  $(".template").children().each(function() {
    if(!$(this).hasClass("static-container")) {
      $(this).remove();
    }
  });

  var newTemplate = $('.new-template').html();
  $('.template').prepend(newTemplate);
});

Upvotes: 1

Kavindra
Kavindra

Reputation: 1707

When you create newTemplate variable, add the static-container's content into that variable.(concat all the elements you need to display in the new template)

var staticContainer = $('.static-container')
$('button').click(function() {
  let newTemplate = $('.new-template').html() + staticContainer.html();
  $('.template').html(newTemplate);
});
.new-template {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
  <div class="template">
    <h1>header #1</h1>
    <p>some text for #1</p>
    <div class="static-container">
      <div>
        <p>a b c 1 2 3</p>
        <p>d e f 4 5 6</p>
      </div>
    </div>
  </div>
</div>

<button>change template</button>

<div class="new-template">
  <h1>header #2</h1>
  <p>some text for #2</p>
  <div class="static-container"></div>
</div>

Upvotes: 1

CertainPerformance
CertainPerformance

Reputation: 371019

I'd just iterate over each child and test to see if it matches .static-container before replacing:

document.querySelector('button').onclick = function() {
  const newTemplate = document.querySelector('.new-template');
  [...document.querySelector('.template').children].forEach((child, i) => {
    if (child.matches('.static-container')) return;
    child.innerHTML = newTemplate.children[i].innerHTML;
  });
};
.new-template {
  display: none;
}
<div class="wrapper">
  <div class="template">
    <h1>header #1</h1>
    <p>some text for #1</p>
    <div class="static-container">
      <div>
        <p>a b c 1 2 3</p>
        <p>d e f 4 5 6</p>
      </div>
    </div>
  </div>
</div>

<button>change template</button>

<div class="new-template">
  <h1>header #2</h1>
  <p>some text for #2</p>
  <div class="static-container"></div>
</div>

Upvotes: 1

Related Questions