Home > Mobile >  Populating large HTML div in JavaScript, based on JSON response from AJAX call
Populating large HTML div in JavaScript, based on JSON response from AJAX call

Time:01-16

I currently have a significant amount of HTML inside a div which is generated within an iteration from a GET request to my .net core server.

Some of the values in the HTML is dynamic data returned from the server.

I've added a button to my website, which when pressed, makes an AJAX call to the server to return a JSON object representing the dynamic values for the next iteration.

So, I would like the JavaScript to add a new div to the DOM, which is the same, and has my dynamic values populated based on the JSON response.

For context, the DIV looks like this (which is from a bootstrap template I purchased):

   <div >
        <!-- Card header START -->
        <div >
            <div >
                <div >
                    <!-- Avatar -->
                    <div >
                        <a href="#!"> <img  src="@post.ProfileImageUrl" alt="profile picture"> </a>
                    </div>
                    <!-- Info -->
                    <div>
                        <div >
                            <h6 > <a href="#!"> @post.ProfileName </a></h6>
                            <span > @post.PostTime</span>
                        </div>
                    </div>
                </div>
                <!-- Card feed action dropdown START -->
                <div >
                    <a href="#"  id="cardFeedAction" data-bs-toggle="dropdown" aria-expanded="false">
                        <i ></i>
                    </a>
                    <!-- Card feed action dropdown menu -->
                    <ul  aria-labelledby="cardFeedAction">
                        <li><a  href="#"> <i ></i>Save post</a></li>
                        <li><a  href="#"> <i ></i>Unfollow lori ferguson </a></li>
                        <li><a  href="#"> <i ></i>Hide post</a></li>
                        <li><a  href="#"> <i ></i>Block</a></li>
                        <li><hr ></li>
                        <li><a  href="#"> <i ></i>Report post</a></li>
                    </ul>
                </div>
                <!-- Card feed action dropdown END -->
            </div>
        </div>
        <!-- Card header END -->
        <!-- Card body START -->
        <div >
            <p><strong>@post.PostBody</strong></p>
            <!-- Card img -->
            <img  src="@post.PostImageUrl" alt="Post">
            <!-- Feed react START -->
            <ul >
                <li >
                    <a  href="#!"> <i ></i>Liked (56)</a>
                </li>
                <li >
                    <a  href="#!"> <i ></i>Comments (12)</a>
                </li>
                <!-- Card share action START -->
                <li >
                    <a  href="#" id="cardShareAction" data-bs-toggle="dropdown" aria-expanded="false">
                        <i ></i>Share (3)
                    </a>
                    <!-- Card share action dropdown menu -->
                    <ul  aria-labelledby="cardShareAction">
                        <li><a  href="#"> <i ></i>Send via Direct Message</a></li>
                        <li><a  href="#"> <i ></i>Bookmark </a></li>
                        <li><a  href="#"> <i ></i>Copy link to post</a></li>
                        <li><a  href="#"> <i ></i>Share post via …</a></li>
                        <li><hr ></li>
                        <li><a  href="#"> <i ></i>Share to News Feed</a></li>
                    </ul>
                </li>
                <!-- Card share action END -->
            </ul>
        </div>
        <!-- Card body END -->
        <!-- Card footer START -->
        <div >
            <!-- Load more comments -->
            <a href="#!" role="button"  data-bs-toggle="button" aria-pressed="true">
                <div >
                    <span ></span>
                    <span ></span>
                    <span ></span>
                </div>
                Load more comments
            </a>
        </div>
        <!-- Card footer END -->
    </div>
    <!-- Card feed item END -->

Question:

There's a lot of HTML here. What's the best way to build this out in Javascript? Is it just a case of biting the bullet and writing all of the JS code to create each element/class?

Would this be the best practice? Because it effectively means I'm maintaining the HTML markup in two places..

Thank you..!

CodePudding user response:

I usually save the html of the template to be rendered inside an hidden element. Then I can always access it using that element.innerHTML. You could use specialized script tag instead. But the innerHTML part is the same.

After having the HTML as string you have 2 options

  1. build the string with the values you want to populate, then add that as innerHTML to the target container.
  2. but a better approach is to create an element from that html (see function below) then append it and manipulate it otherwise.

// render 5 cards 
for (var i = 0; i < 5; i  ) {

  var html = document.querySelector("#card-template").innerHTML;
  var elem = elemFromString(html)

  // change something
  elem.querySelector(".card-body>p strong").innerText = "card "   i

  // append
  document.querySelector("#container").append(elem)
}


// usefull utility 
function elemFromString(html) {
  var dummy = document.createElement("div");
  dummy.innerHTML = html.trim();
  if (dummy.children.length > 1) {
    console.error("expecting one wrapping element for html. will return only firstChild")
  }
  var result = dummy.firstChild;
  result.parentNode.removeChild(result)
  return result;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI N" crossorigin="anonymous">

<div id="container">
</div>


<div id="card-template" style="display:none">
  <div >
    <!-- Card header START -->
    <div >
      <div >
        <div >
          <!-- Avatar -->
          <div >
            <a href="#!"> <img  src="@post.ProfileImageUrl" alt="profile picture"> </a>
          </div>
          <!-- Info -->
          <div>
            <div >
              <h6 > <a href="#!"> @post.ProfileName </a></h6>
              <span > @post.PostTime</span>
            </div>
          </div>
        </div>
        <!-- Card feed action dropdown START -->
        <div >
          <a href="#"  id="cardFeedAction" data-bs-toggle="dropdown" aria-expanded="false">
            <i ></i>
          </a>
          <!-- Card feed action dropdown menu -->
          <ul  aria-labelledby="cardFeedAction">
            <li>
              <a  href="#"> <i ></i>Save post</a>
            </li>
            <li>
              <a  href="#"> <i ></i>Unfollow lori ferguson </a>
            </li>
            <li>
              <a  href="#"> <i ></i>Hide post</a>
            </li>
            <li>
              <a  href="#"> <i ></i>Block</a>
            </li>
            <li>
              <hr >
            </li>
            <li>
              <a  href="#"> <i ></i>Report post</a>
            </li>
          </ul>
        </div>
        <!-- Card feed action dropdown END -->
      </div>
    </div>
    <!-- Card header END -->
    <!-- Card body START -->
    <div >
      <p><strong>@post.PostBody</strong></p>
      <!-- Card img -->
      <img  src="@post.PostImageUrl" alt="Post">
      <!-- Feed react START -->
      <ul >
        <li >
          <a  href="#!"> <i ></i>Liked (56)</a>
        </li>
        <li >
          <a  href="#!"> <i ></i>Comments (12)</a>
        </li>
        <!-- Card share action START -->
        <li >
          <a  href="#" id="cardShareAction" data-bs-toggle="dropdown" aria-expanded="false">
            <i ></i>Share (3)
          </a>
          <!-- Card share action dropdown menu -->
          <ul  aria-labelledby="cardShareAction">
            <li>
              <a  href="#"> <i ></i>Send via Direct Message</a>
            </li>
            <li>
              <a  href="#"> <i ></i>Bookmark </a>
            </li>
            <li>
              <a  href="#"> <i ></i>Copy link to post</a>
            </li>
            <li>
              <a  href="#"> <i ></i>Share post via …</a>
            </li>
            <li>
              <hr >
            </li>
            <li>
              <a  href="#"> <i ></i>Share to News Feed</a>
            </li>
          </ul>
        </li>
        <!-- Card share action END -->
      </ul>
    </div>
    <!-- Card body END -->
    <!-- Card footer START -->
    <div >
      <!-- Load more comments -->
      <a href="#!" role="button"  data-bs-toggle="button" aria-pressed="true">
        <div >
          <span ></span>
          <span ></span>
          <span ></span>
        </div>
        Load more comments
      </a>
    </div>
    <!-- Card footer END -->
  </div>
  <!-- Card feed item END -->
</div>

  • Related