0

I have a site where I'm rendering blocks from a JSON file where the user can then sort blocks if they want it in another way that I then save to the database. My problem is how to keep the same structure as it's not a flat JSON structure.

Example from JSON file:

[{
    "part": 0,
    "blocks": [
        {
            "type": "template",
            "id": "SOME_ID_0"
        },
        {
            "type": "template",
            "id": "SOME_ID_1"
        },
    ]
},
{
    "part": 1,
    "blocks": [
        {
            "type": "template",
            "id": "SOME_ID_2"
        },
        {
            "type": "template",
            "id": "SOME_ID_3"
        },
    ]
}]

From the JSON file, each object within "blocks" are rendered and can be rearranged so block in part 0 could have 3 blocks, and part 1 could have only one block etc. The reason for why each block is within "part" and not just flat is because I render only some parts in some special cases.

HTML example:

<div class="blockContent" data-blockcontent="ADD 'part' JSON HERE SOMEHOW?">
  <div class="blockContent" data-blockcontent="{&quot;type&quot;:&quot;template&quot;,&quot;id&quot;:&quot;SOME_ID_0&quot;}">Some info 1</div>
  <div class="blockContent" data-blockcontent="{&quot;type&quot;:&quot;template&quot;,&quot;id&quot;:&quot;SOME_ID_1&quot;}">Some info 2</div>
</div>
<div class="blockContent" data-blockcontent="ADD 'part' JSON HERE SOMEHOW?">
  <div class="blockContent" data-blockcontent="{&quot;type&quot;:&quot;template&quot;,&quot;id&quot;:&quot;SOME_ID_2&quot;}">Some info 3</div>
  <div class="blockContent" data-blockcontent="{&quot;type&quot;:&quot;template&quot;,&quot;id&quot;:&quot;SOME_ID_3&quot;}">Some info 4</div>
</div>

For the jquery/ajax code, I use push:

  // Save block structure for ÅR
  var blockContent=[];
  $("#myForm").find('.blockContent').each(function(i,item){
    blockContent.push($(item).data('blockcontent'));
  });

$.ajax({
url:"/ajax/saveBlockStructure",
method:"POST",
async:true,
data: {
  id: "{{ $id }}",
  _token: "{{ csrf_token() }}",
  blockStructure: JSON.stringify(blockContent)
}

}); }

For the PHP/Laravel code, I just have a loop that iterates the json file and I don't think that is necessary to show here.

I don't know how but I guess I should somehow add the start of the part/blocks in the parent div and end it and then start on the next part?

1
  • You would want a different class for the part wrapper element and pass the part value to an attribute. Then loop all those part elements with internal loop to build it's blocks array Commented Jul 18, 2019 at 15:38

2 Answers 2

1

Simply change the outer class to part and use a data-part attribute.

Then it is a simple nested map() to create the data

const data = $('.part').map(function() {
  const $el = $(this),
    blocks = $el.children().map(function() {
      return $(this).data('blockcontent');
    }).get()

  return {
    part: $el.data('part'),
    blocks: blocks
  }

}).get()

console.log(data)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="part" data-part="0">
  <div class="block" data-blockcontent="{&quot;type&quot;:&quot;template&quot;,&quot;id&quot;:&quot;SOME_ID_0&quot;}">Some info 1</div>
  <div class="block" data-blockcontent="{&quot;type&quot;:&quot;template&quot;,&quot;id&quot;:&quot;SOME_ID_1&quot;}">Some info 2</div>
</div>
<div class="part" data-part="1">
  <div class="block" data-blockcontent="{&quot;type&quot;:&quot;template&quot;,&quot;id&quot;:&quot;SOME_ID_2&quot;}">Some info 3</div>
  <div class="block" data-blockcontent="{&quot;type&quot;:&quot;template&quot;,&quot;id&quot;:&quot;SOME_ID_3&quot;}">Some info 4</div>
</div>

Sign up to request clarification or add additional context in comments.

1 Comment

Worked just the way I wanted it!
1

You can do like this, by selecting only the direct children each step, this is an example that will work only with one level deep.

I personnaly would choose to distinguish semantically the classes and data attributes though (for example with .blockPart and data-blockpartid) but it really depends how far you want to go in the nesting and how you build your HTML.

// Save block structure for ÅR
var blocks=[];
//you might need to adapt the selector if "part" blocks are not on top level of the form
$("#myForm").find('> .blockContent').each(function(i,item){
  var part = {
    id: $(item).data('blockcontent'),
    blocks: [],
  };
  blocks.push(part); //filling it after works because of reference
  $(item).find('> .blockContent').each(function(i2,subitem){
    part.blocks.push($(subitem).data('blockcontent'));
  });
});

console.log(blocks);
console.log(JSON.stringify(blocks));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="myForm">
  <div class="blockContent" data-blockcontent="0">
    <div class="blockContent" data-blockcontent="{&quot;type&quot;:&quot;template&quot;,&quot;id&quot;:&quot;SOME_ID_0&quot;}">Some info 1</div>
    <div class="blockContent" data-blockcontent="{&quot;type&quot;:&quot;template&quot;,&quot;id&quot;:&quot;SOME_ID_1&quot;}">Some info 2</div>
  </div>
  <div class="blockContent" data-blockcontent="1">
    <div class="blockContent" data-blockcontent="{&quot;type&quot;:&quot;template&quot;,&quot;id&quot;:&quot;SOME_ID_2&quot;}">Some info 3</div>
    <div class="blockContent" data-blockcontent="{&quot;type&quot;:&quot;template&quot;,&quot;id&quot;:&quot;SOME_ID_3&quot;}">Some info 4</div>
  </div>
</form>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.