zester
zester

Reputation: 175

Not able to insert elements dynamically into Semantic-UI Accordion

I am trying to insert dynamic content inside a Semantic-UI Accordion. Basically I have to render a JSON input to the html as an Accordion.

Here is the script and the html I am using for the above purpose:-

<script language='javascript'>

  $(document).ready(function(){
  
     $('.ui.accordion').accordion();
     
     $('.ui.accordion').accordion({onOpen: function() { // function for dynamically inserting content inside clicked element in accordion
      var id = $(this).attr('id'); //gets the id of the clicked element in accordion
      var obj = find_key_value(json_data, id); // a function for finding the key in the json and its corresponding value
      for (var prop in obj){ //appends new content inside the clicked element in the accordion
        $(`#${id}`).append(`
        <div class="title">
        <i class="dropdown icon"></i>
          ${prop}
        <div class="content"></div>
        `);
        $('.ui.accordion').accordion('refresh');   
            }
          }
        });
      });
    </script>
<div class="ui styled accordion">
  <div class="title">
    <i class="dropdown icon"></i>
    A
  </div>
  <div class="content" id="A"></div>
  <div class="title">
    <i class="dropdown icon"></i>
    B
  </div>
  <div class="content" id="B"></div>
  <div class="title">
    <i class="dropdown icon"></i>
    C
  </div>
  <div class="content" id="C"></div>
</div>

Also in the above script I am using the onOpen callback for accordion which is used to perform some action after an element is opened as mentioned in the Semantic-UI Docs

Suppose json_data is as follows:-

json_data = {
'A' : {
     'A1':{'A12':[]},
     'A2': [],
     'A3': [],
     }, 
'B' :  {
     'B1':[],
     'B2': [],
     'B3': {'B31':[]},
     }, 
'C' : {
     'C1':[]
      }
}

and if A is clicked then A1, A2, A3 should be dynamically inserted into A's content and similarly for B and C as well as for nested objects like A1, etc. So all the elements in the json should be inserted dynamically into the accordion only when the object key corresponding to it is clicked or opened.

There isn't much documentation for this on Semantic-UI and the code which I shared above does not work. Any idea how to do this?

[EDIT: This JSON has been created from a python dictionary so it might not look like a regular JSON]

Upvotes: 1

Views: 443

Answers (2)

Swati
Swati

Reputation: 28522

Instead of creating htmls whenever accordian is open you can create whole structure when page gets loads . So , firstly loop through outer array i.e : A , B , C then check if the data inside suppose A is object {} or array [] depending on this you need to change your logic and append whole html inside your dom.

Demo Code :

$(document).ready(function() {
  var json_data = {
    'A': [{
      'A1': {
        'A12': ["A12a"],
        'A13': ["A13a"]
      },
      'A2': ["az"],
      'A3': ["a3"],
    }],
    'B': [{
      'B1': ["b1"],
      'B2': ["b2"],
      'B3': {
        'B31': ["b31"]
      },
    }],
    'C': [{
      'C1': ["c1"]
    }]
  }
  var html = "";
  $.each(json_data, function(key, value) {
    //creating title for outer array
    html += `<div class="title">
        <i class="dropdown icon"></i> ${key}
      </div> <div class="content" id="${key}"><div class="accordion">`
    //child inside A,B,C( A1,A2..etc)
    $.each(value[0], function(k, v) {
      html += `<div class="title">
          <i class="dropdown icon"></i>
         ${k}
      </div>`
      //check if the value of object is {} or []
      if (Object.prototype.toString.call(v) === '[object Object]') {
        html += `<div class="content"><div class="accordion">`
        //i.e : A1 { A12 , A13}
        for (var i = 0; i < Object.keys(v).length; i++) {
          html += `<div class="title">
          <i class="dropdown icon"></i>
         ${Object.keys(v)[i]}</div>`
          //loop through i.e : A12 :[""]
          $.each(v[Object.keys(v)[i]], function(ky, vl) {
            html += `<div class="content">${vl}</div>`
          })
        }
        html += `</div></div>`
      } else if (Object.prototype.toString.call(v) === '[object Array]') {
        //simply get content []
        html += `<div class="content">`
        $.each(v, function(ky, vl) {
          html += `${vl}`
        })
        html += `</div>`
      }
    })
    html += `</div></div>`

  })

  $("#outer").html(html) //add to outer div
  $('.ui.accordion').accordion(); //intialzie


});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css" integrity="sha512-8bHTC73gkZ7rZ7vpqUQThUDhqcNFyYi2xgDgPDHc+GXVGHXq+xPjynxIopALmOPqzo9JZj0k6OqqewdGO3EsrQ==" crossorigin="anonymous" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.js" integrity="sha512-dqw6X88iGgZlTsONxZK9ePmJEFrmHwpuMrsUChjAw1mRUhUITE5QU9pkcSox+ynfLhL15Sv2al5A0LVyDCmtUw==" crossorigin="anonymous"></script>
<div class="ui styled accordion" id="outer">
</div>

Upvotes: 1

ANOL GHOSH
ANOL GHOSH

Reputation: 1

obj.forEach((v,i,a)=>{ //appends new content inside the clicked element in the accordion
    $(`${id}`).append(`
        <div class="title">
        <i class="dropdown icon"></i>
          ${a[i]}
        <div class="content"></div>
        `);
        $('.ui.accordion').accordion('refresh');   
})

Upvotes: 0

Related Questions