Sightly - Empty check on list HTL - aem

How to check the empty list on Sightly?
I wanted to prevent render the item-list DIV if there was no item on itemImgaeList. But it returns me one (1) always if there were no items while trying with -
LIST_SIZE_PRINT = "${container.itemImgaeList.size}"; // retrun 1
HTL:
<div data-sly-test="${container.itemImgaeList.size > 1}">
<sly data-sly-list.imageList="${container.itemImgaeList}">
<div class="item-list">
<picture>
<img alt="${imageList.qlImageText}" src="${imageList.qlImagePath}" />
</picture>
</div>
</sly>
</div>
Any help?

data-sly-list can be used for implementing the above requirement of rendering the list elements only when the list is not empty.
The use of 'data-sly-test' is not required for checking a list, as the check for emptiness is done inherently by data-sly-list.
Here is a working example using data-sly-list:
<div class="item-list" data-sly-list.item="${container.itemImgaeList}">
<picture>
<img alt="${item.qlImageText}" src="${item.qlImagePath}" />
</picture>
</div>
More information:
https://www.aemquickstart.in/2016/08/htl-sightly-notes.html

Related

Show Hide HTML Attribute in AEM

Let's pretend I have a boolean paratemeter called isDisabled. If isDisabled is true, we want to add a custom html attribute called data-enable-hide; otherwise, we will not show the html attribute.
The option I could think of is:
<div data-sly-test="${model.isDisabled}">
<div class="container" data-enable-hide>
Hello World
</div>
</div>
<div data-sly-test="${!model.isDisabled}">
<div class="container">
Hello World
</div>
</div>
This option would work but it would duplicate the inner HTML because the only difference is to show and hide the HTML attribute. Is there any specific syntax from AEM that would allow me to show/hide HTML attribute based on boolean condition?
You can make use of test conditions directly within the attribute as shown below
<div class="container" data-enable-hide="${isDisabled || ''}">
Hello World
</div>
This would output <div class="container" data-enable-hide="true"> if isDisabled is true or it will remove the whole attribute if it is false i.e., the output would be <div class="container"> when false
data-sly-test="${!model.isDisabled}"
What syntax is this?
Use an IF condition if possible:
#if(isDisabled)
{
<div class="container" data-enable-hide>
Hello World
</div>
}

AEM HTL repeating an element containing "data-sly-resource" using data-sly-repeat

I am trying to loop through an div element containing "data-sly-resource" to be able to include that component as a child.
I have a table element where each cell has an individual authoring interface using a child component. I get two counts that is rowCount as array of "x" and columnCount as array of "y". I'm able to iterate through the class="table-cell" and am able to add "y" number of columns with their respective child components using data-sly-resource . But when I'm trying to iterate through class="table-row" using rowcount it only iterates the content and adds "y" number of rows but doesn't add child components in the rows
thank you
<div class="table">
<sly data-sly-list.card="${rowCount.array}">
<div class="table-row">
<sly data-sly-list.card="${columnCount.array}">
<div class="table-cell" data-sly-test.resourceNode="${['cell', card.intValue] #join='-'}">
<div data-sly-resource="${ #path=resourceNode,
resourceType='example/components/content/tableLongForm/rte'}"
data-sly-unwrap="${!wcmmode.edit && !wcmmode.preview}" style="width:60px;"></div>
</div>
</sly>
</div>
</sly>
</div>
Authoring Interface Image
You are using the same identifier card for the list items in the nested loops, perhaps you meant it as:
<div class="table">
<sly data-sly-list.row="${rowCount.array}">
<div class="table-row">
<sly data-sly-list.card="${columnCount.array}">
<div class="table-cell" data-sly-test.resourceNode="${['cell', row.intValue, card.intValue] # join='-'}">
<div data-sly-resource="${ #path=resourceNode,
resourceType='example/components/content/tableLongForm/rte'}"
data-sly-unwrap="${!wcmmode.edit && !wcmmode.preview}" style="width:60px;"></div>
</div>
</sly>
</div>
</sly>
</div>

Skip a loop in alpine.js with x-if

I use this loop
<form action="/" method="POST">
<template x-for="(deck, index) in $store.cart.decks">
<div x-show="$store.cart.total(index) > 0">
<div><span x-text="$store.cart.total(index)"></span> Karten</div>
<div x-text="deck.price"></div> €
<input :name="'deck[' + index + '][name]'" :value="$store.cart.decks[index].name">
</div>
</template>
</form>
Which works fine and displays all items in my cart and hides those that have a total of 0.
But this will only set the item with 0 on display:none, which will still transfer the data in the POST request.
I tried to use x-if instead of x-show but that is only allowed on a tempate tag.
I tried to add the x-if on the template tag:
<template x-show="$store.cart.total(index) > 0" ...
this results in an error, because index is not set at that point
I tried to add another <template> tag inside the existing template, but then the variables index and deck are not available inside the second any more
How do I prevent the zero cart items being computed in my POST request?
I think something like the following would work, note the div inside both template elements.
<template x-for="(deck, index) in $store.cart.decks">
<div>
<template x-if="$store.cart.total(index)">
<div>
<!-- rest of the content -->
</div>
</template>
</div>
</template>

How to use result of .length in selector Cypress

I'm trying to perform an action based on the results of an earlier assertion. I have the following situation, I want to determine the number of versions for a document, this is represented in the follwing html:
<ul data-testhook-id="accordion-body">
<li data-testhook-id="accordion-body-item">
<div>
<div data-testhook-id="version-1">
<div data-testhook-id="avatar">
<div data-id="tooltip">John Doe</div>
</div>
</div>
<span data-testhook-id="content">1. 17-08-2018 at 15:26</span>
</div>
<div data-testhook-id="version-2">
<div data-testhook-id="avatar">
<div data-id="tooltip">John Doe</div>
</div>
</div>
<span data-testhook-id="content">2. 20-08-2018 at 13:05</span>
</div>
<div data-testhook-id="version-3">
<div data-testhook-id="avatar">
<div data-id="tooltip">Jane Doe</div>
</div>
</div>
<span data-testhook-id="content">3. 20-08-2018 at 13:11</span>
</div>
<div data-testhook-id="version-4">
<div data-testhook-id="avatar">
<div data-id="tooltip">No Body</div>
</div>
</div>
<span data-testhook-id="content">4. 21-08-2018 at 13:11</span>
</div>
<svg width="12" height="12" data-testhook-id="icon-active-version"><path d="path-here"></path></svg>
</div>
</div>
</li>
Each element with test id data-testhook-id="version-xxx" is a line containing version information and its these div elements I want to count. for this I have set up the following:
cy.get('[data-testhook-id="accordion-body-item"] > div > div').its('length').as('versions')
Now if I add the following assertion, this passes without any problem
cy.get('#versions').should('equal', 4)
But if I try to use the outcome of the number of div's found as a variable in a console.log I no longer get '4' but [object, Object]. Tried this by:
var size = cy.get('[data-testhook-id="asset-versions"] [data-testhook-id="accordion-body-item"] > div > div').its('length')
console.log('foo ' + size)
Which results in foo [object Object] being printed to the console.
What I want to do is use the number of items in a selector to select an element, like:
cy.get('[data-testhook-id="accordion-body-item"] > div > div:nth-child(' + size + ')').find('svg').should('have.attr', 'data-testhook-id', 'icon-active-version')
But as the var is not a number I get the msg
Error: Syntax error, unrecognized expression: :nth-child
[data-testhook-id="asset-versions"] [data-testhook-id="accordion-body-item"] > div > div:nth-child([object Object])
Is it possible to use the number of elements found as a variable for a next selector?
Try this:
cy.get('[data-testhook-id="accordion-body-item"] > div > div').its('length').then((size) => {
cy.get('[data-testhook-id="accordion-body-item"] > div > div:nth-child(' + size + ')').find('svg').should('have.attr', 'data-testhook-id', 'icon-active-version')
});
You cannot assign or work with the return values of any Cypress command. Commands are enqueued and run asynchronously. What commands really return are Chainable<typeOfValueYouWant>, in another words, it's kind of queue object which resolves with desired value.
Read more here
BTW: I think you should consider change your approach for selecting elements. Read more here.
For those who are using Typescript - I wrote plugin for tslint which prevents making this mistake: https://github.com/krzysztof-grzybek/tslint-plugin-cypress

In JSSOR, how to access the current caption via Javascript?

I would like to pass a value from a slide out of JSSOR to other parts of the DOM.
Markup:
<div class="slide">
<img data-u="image" src="bilder/bild2.jpg" />
<div class="caption" data-u="caption" ><p>Caption text</p></div>
</div>
JS:
jssor_slider1.$On($JssorSlider$.$EVT_PARK,function(slideIndex,fromIndex){
$(".outer-caption").text(currentCaption);
});
The custom JSSOR Event, EVT_PARK, works fine. But what's missing is how to get the caption of the current slide and put it into the variable currentCaption. How to do that?
And if so, where could I have found that out on my own?
Please have a full test of following code,
<div class="slide">
<img data-u="image" src="bilder/bild2.jpg" />
<div class="caption" data-u="caption" id="caption-slide-0"><p>Slide 0 Caption</p></div>
</div>
jssor_slider1.$On($JssorSlider$.$EVT_PARK,function(slideIndex,fromIndex){
$("#outer-caption").text($("#caption-slide-" + slideIndex).text());
});