Including conditional HTML tags inside a repeat

I would like to add sections within a repeat, to get something like this:

<section>
   record1
   record2
   record3
   record4
</section>
<section>
   record5
   record6
   record7
   record8
</section>

etc.

I though perhaps I could use a conditional region, eg so the opening <section> would be

<div dmx-bind:id="conditional_{{$index}}" is="dmx-if" dmx-bind:condition="$index % 4 == 0">
<section class="sheet padding-10mm">
</div>

This half works, but for some reason, while the opening section tag appears correctly every 4 records, the closing </section> is added automatically when the code is rendered in the browser. I suppose this is reasonable enough because the code above is invalid - as Wappler points out:

image

I want the conditional region to behave more like PHP.

I think I’m going about this in the wrong way. I probably need a nested loop, but can’t think how to do this. I would be grateful for any suggestions.

could you try please

<dmx-value id="var1" dmx-bind:value="'</section> <section>'"></dmx-value>

Thanks @s.alpaslan - that was a good idea. However…

I assume you meant creating the variable and using it here:

This got rid of the error message, and added the tags, but encoded, so the result was:

image

The HTML was
image

{{($index % 4 == 0) ? ' </section> <section> ' : a}}

That’s was another good idea as the conditional regional is not needed. However…
with the <> brackets, the code appear on the page:

image

So I tried:
{{$index % 4 == 0 ? ' &lt;/section&gt; &lt;section&gt; ' : ''}}

… now I get this again:

image

I think I’ll surrender for today, but thanks - and if you have any other thoughts that would great.

section is html element …
and I will look different ways .

1 Like

That is something difficult to realize with the repeater, here is my try (haven’t tested it myself but should help you on your way):

<section dmx-repeat="(myData.count() / 4).ceil()">
  <dmx-value id="section" dmx-bind:value="$index">
  <div dmx-repeat="4">
    <dmx-value id="record" dmx-bind:value="myData[section.value + $index]">
    {{ record.value.name }}
  </div>
</section>

myData is is used as source dataset. The .count() will return the number of records in it. The whole expression in the first repeater (myData.count() / 4).ceil() will return the number of sections, so with 8 records it will become 2, the repeater will repeat 2 times.

The index of the repeater is stored in a variable, this is done because the inner repeater also has an $index and by giving it a different name we can use it in the inner repeater.

The inner repeater just repeats 4 times, this should be improved when the last section would not be 4.

The actual index of the records will be the outer repeater index plus the inner index section.value + $index. So we access the actual record like myData[section.value + $index].

In my sample I store the record also in a variable and access the properties like record.value.name, but you could also leave the variable away and access it using myData[section.value + $index].name.

Other ways would be by creating a custom formatter or component.

Sample formatter:

dmx.Formatter('array', 'formatRecords', function(arr) {
  var html = '<section>';
  for (var i = 0; i < arr.length; i++) {
    if (i > 0 && i % 4 == 0) {
      html += '</section><section>';
    }
    html += arr[i].name
  }
  html += '</section>';
  return html;
});

usage:

<div dmx-html="myData.formatRecords()"></div>
2 Likes

Thanks very much Patrick - both of these solutions worked. With the first solution, it was necessary to make a minor change - to add the two closing </dmx-value> tags.

These techniques could be very useful in various situations. I imagine it would be difficult to incorporate a feature like this in the UI. The only slight issue is that the resulting HTML includes quite a few extra tags - probably not really a problem.

I’m not sure why my original solution didn’t work. Eg I can insert an <hr> tag every 4 rows, simply by including this line:
<div is="dmx-if" dmx-bind:condition="$index % 4 == 0"><hr></div>
within the repeat section.

However, using section tags in the same way didn’t work - presumably because the unpaired tags were invalid (but they wouldn’t have been once rendered) and Wappler was adding the missing tag. Assuming this was the issue, I thought this might work:
<span dmx-html="($index % 4 == 0 ? '</section><section>' : '') "></span>
Wappler doesn’t flag this as invalid, and yet extra tags* are added in this case too.

Anyway, thanks again for providing this solution, which I’m sure I couldn’t have discovered.

*Actually, extra tags are not added - the tags are reversed. Eg if I include this line in the repeat:
<span dmx-html="($index % 4 == 0 ? '</section><section>' : '') "></span>
then the HTML comes out as <section></section> - presumably at some point to ‘correct’ the tags. I wonder if there would ever be a need for this auto-correction, if that’s what it is. If not, I would have thought removing this would provide an easy solution to problems like the one I originally raised.

1 Like