tal python expression with condition - plone

<tal:block tal:repeat="image project/images">
<div
tal:define="onlyone python:if repeat.image.length==1: return 'onlyone'"
tal:attributes="class python:'image-{}'.format(repeat.image.number)">
<img
tal:define="img image/getObject"
tal:replace="structure img/##images/image/custom_1280"
/>
</div>
</tal:block>
I already have a class the prints "image-N" based on the loop index, but how do I add another class if the length is "1"?
The documentation is NOT clear https://zope.readthedocs.io/en/latest/zopebook/AppendixC.html#tales-python-expressions, it says any valid python expression can be used but the syntax is always wrong for me.

Fixed it myself.
<tal:block tal:repeat="image project/images">
<div
tal:define="onlyone python:'onlyone' if repeat.image.length == 1 else ''"
tal:attributes="class string:image-${repeat/image/number} ${onlyone}">
<img
tal:define="img image/getObject"
tal:replace="structure img/##images/image/custom_1280"
/>
</div>
</tal:block>

You define onlyone inside repeat, i.e. every iteration - define it outside:
<div class="project-images"
tal:define="onlyone python: len(project.images)==1 and 'onlyone' or '';">
<tal:project-images repeat="image project/images">
<div tal:attributes="class string:image-${repeat/image/number} ${onlyone};">
<img
tal:define="img image/getObject"
tal:replace="structure img/##images/image/custom_1280"
/>
</div>
</tal:project-images>
</div>
But...
your task can (and should) be solved in CSS3 without additional html class:
.project-images div:first-child:nth-last-child(1) {
/**/
}
.project-images div:only-child {
/**/
}

Related

Thymeleaf fragment with parameters

I am quite new to Thymeleaf, I am trying to create a fragment and pass to it a variable in my Spring MVC application but I am stuck.
My code:
<div th:replace="fragments/utilities :: reviews(message=${reviews[0].review})"></div>
My fragments/utilities.html:
<div th:fragment="reviews(message)">
<div class="carousel-item">
<div class="border border-light rounded p-4 mb-3">
<div th:replace="utilities :: stars"></div>
<p th:text="message" class="mt-2"></p>
</div>
</div>
But it isn't working, I have also tried substituting th:replace with th:insert or th:include.
Note: I know for sure that reviews[0].review isn't empty
What am I missing?
The problem is with the way you want to display message
Instead of
<p th:text="message" class="mt-2"></p>
Try to use
<p th:text="${message}" class="mt-2"></p>

How to get selected row with custom action column using syncfusion in blazor?

I am using syncfusion grid in blazor.
Here is my Razor :
<div class="card-outer p-0">
<div class="grid-table">
<EjsGrid DataSource="#ManufacturedCoupons" AllowPaging="true">
<GridPageSettings PageCount="5" PageSize="5"></GridPageSettings>
<GridColumns>
<GridColumn Field=#nameof(Coupon.MaterialIdType) HeaderText="#CommonResource.MaterialID" Width="130" TextAlign="TextAlign.Center"></GridColumn>
<GridColumn Field=#nameof(Coupon.MaterialId) HeaderText="#CommonResource.MaterialID" Width="130" TextAlign="TextAlign.Center"></GridColumn>
<GridColumn Field=#nameof(Coupon.LotNo) HeaderText="#CommonResource.LotNo" Width="100" TextAlign="TextAlign.Center"></GridColumn>
<GridColumn Field=#nameof(Coupon.ArrivalDate) HeaderText="#CommonResource.DeliveryDate" TextAlign="TextAlign.Center" Width="150"></GridColumn>
<GridColumn HeaderText="#CommonResource.Action" TextAlign="TextAlign.Center" Width="120">
<Template>
#{
<div class="actions">
<img src="images/export.svg" alt="#CommonResource.SendToStock" #onclick="SendToStockClicked()">
</div>
}
</Template>
</GridColumn>
</GridColumns>
</EjsGrid>
</div>
</div>
this is my method in code behind file :
protected void SendToStockClicked(Coupon coupon)
{
}
I want to pass selected row data in this method on action button clicked.
How can I achive that ?
I'm not acquainted with syncfusion... I only know blazor. What I know from Blazor is that if you want to call a method and pass it a value you should use a lambda expression. Let's say that you have in your grid an object named MyCoupon of type Coupon, and you want to pass it to a local method called SendToStockClicked...This is how you call SendToStockClicked:
#onclick="#(() => SendToStockClicked(MyCoupon))"
Incidentally, this "javascript:void(0);" is JavaScript, and you shouldn't use JavaScript in Blazor...
Hope this helps...
EDIT
You are half right. It indeed help me so I am marking it true but still I have to do some fixes which I am putting it here.
<Template>
#{
var couponData = (context as Coupon);
<div class="actions">
<a href="javascript:void(0);"
title="#CommonResource.SendToStock"
#onclick="(()=> SendToStockClicked(couponData))">
<img src="images/export.svg"
alt="#CommonResource.SendToStock">
</a>
</div>
}
</Template>
Here I have to take couponData to send my custom method object.

Rename multiple css with identical name

I'm working inside a templated system where i can implement code, but i can't modified the core of the file. My layer are stacked like this:
<div class="layer1">
<div class="layer2">
<div class=" layer3">
<div class="layer4">
</div>
</div>
</div>
</div>
<div class="layer1">
<div class="layer2">
<div class=" layer3">
<div class="layer4">
</div>
</div>
</div>
</div>
<div class="layer1">
<div class="layer2">
<div class=" layer3">
<div class="layer4">
</div>
</div>
</div>
</div>
As you can see, my class all have the same name (layer1, layer2, etc...). I want to know if there's a way by using Javascript, Jquery or any other online client side library to modify the CSS class name so, for example, the first layer1 become level1 and the following layer1 become level 2?
Thank for your answer!
As other people already said, jQuery actually does what you want.
As long as you don't know the number of “layers” you have, you better find all elements by classname substring:
$('*[class^="layer"]')
Then you can get the list of the element classes and change old names to new ones.
Many different ways to do this:
Solution 1:
Use addClass() and removeClass()
$(".layer1").removeClass('old_class').addClass('new_class');
Replace old_class with your older class and new_class with your new class
Solution 2:
If you are able to get the element by ID
You can set the class by using .attr()
$("#id").attr('class', 'new_class');
an all around solution working with className :
var elem=document.querySelectorAll('[class^="layer"]') ;
for(i in elem){
x = elem[i].className;
var y=x.replace("layer" , "level");
elem[i].className=y||x;
}

Thymeleaf object created from extednd broadleaf processor is made null when using th:each and is accesible only ouside th:each

Code sample
'someproc' is a custom processor which extends org.broadleafcommerce.common.web.dialect.AbstractModelVariableModifierProcessor from broadleaf platform.
<myproc:someproc /> // as a result is objectCreatedInProcessor
<div th:classappend="${objectCreatedInProcessor==null?'null':'not_null'}></div>
<div th:classappend="${objectAddedToModelAndView==null?'null1':'not_null_1'}></div>
<div th:each="someVar : ${someVars}">
<div th:classappend="${objectCreatedInProcessor==null?'null':'not_null'}></div>
<div th:classappend="${objectAddedToModelAndView==null?'null1':'not_null_1'}></div>
</div>
<div th:classappend="${objectCreatedInProcessor==null?'null':'not_null'}></div>
<div th:classappend="${objectAddedToModelAndView==null?'null1':'not_null_1'}></div>
As a output result will be :
<div class='not_null'></div>
<div class='not_null_1'></div>
<div>
<div class='null'></div>
<div class='not_null_1'></div>
<div class='null'></div>
<div class='not_null_1'></div>
<div class='null'></div>
<div class='not_null_1'></div>
</div>
<div class='not_null'></div>
<div class='not_null_1'></div>
supposing we have three items into $someVars list.
The question is, why is $objectCreatedInProcessor beeing made NULL into th:each loop. And why variable $objectAddedToModelAndView isn't made NULL, and is accessible into th:each loop?
What I'm doing wrong? Is something what I miss?
EDIT1 : Closed conditional expression. This wasn't the reason of the problem, it was only a bad code sample.
EDIT2 : Closed classes into result display.
EDIT3 : Forogot to mention that $someVars is a variable added from a controller to spring ModelAndView.
It appears as if you are not properly closing the conditionals on your ternary functions. Add a } after the null and before the ? on each line.
Here is an example ternary from the docs for reference
'User is of type ' + (${user.isAdmin()} ? 'Administrator' : (${user.type} ?: 'Unknown'))

JSF RichFaces reRender event changes rich:dataGrid structure

I am looking for a hint on how to handle a strange effect on rerendering a datagrid. I have the following grid structure:
<rich:dataGrid id="allProductsGrid" value="#{allProducts}" var="_product">
<s:div styleClass="grid-element">
<s:link view="/product.xhtml">
<s:div styleClass="product-element">
<h:graphicImage value="/content/images?id=#{_product.image.id}&width=170"/>
</s:div>
<div id="title">
<h:outputText value="#{_product.name}" />
</div>
<f:param name="productId" value="#{_product.id}" />
</s:link>
</s:div>
</rich:dataGrid>
The grid gets reRendered on a onkeyup-event fired by an search input field. No magic so far. Now the problem is that the reRendering changes the structure of the html produced (DOM). As a result the links are not working anymore.
The firebug-html-inspect on the first rendering of the page is as follows:
<div id="j_id86:allProductsGrid:0:j_id124" class="grid-element">
<a id=".. " onclick=".." href="/portal/product.vc?productId=22&cid=69">
<div id="j_id86:allProductsGrid:0:j_id126" class="product-element">
<img src="/portal/content/images?id=&width=170">
</div>
<div id="title">Sample Product</div>
</a>
</div>
After reRendering the grid the html output is that:
<div id="j_id86:allProductsGrid:0:j_id124" class="grid-element">
<a id=".." onclick=".." href="/portal/product.vc?productId=22&cid=76"></a>
<div id="j_id86:allProductsGrid:0:j_id126" class="product-element">
<img src="/portal/content/images?id=&width=170">
</div>
<div id="title">Sample Product</div>
</div>
The result is that the a-tag is not wrapping the product-element anymore. Can anybody give me a hint on what might be wrong here??
Any help appreciated.
Thanks in advance.
josh
ps: using Seam 2.2.2 / JSF Mojarra 2.0.3 / RichFaces 3.3.3
Make sure your allProducts bean has ViewScope instead of RequestScope. So in rerender the data will persist in the call.

Resources