Sorting numbers with typo3 fluid - typo3

In my extension, I'm trying to sort a date array in ascending order:
<f:for each="{data_eventarray}" as="data_item">
{data_item.data.eventdate}<br>
</f:if>
Output:
1645138800
1643756400
1643756400
1645052400
1660341600
1645657200
1646175600
Now I want to sort the numbers in ascending order:
1643756400
1643756400
1645052400
1645138800
1645657200
1646175600
1660341600
I've already tried the following without success:
<f:for each="{data_eventarray -> v:iterator.sort(sortBy: '{data.eventdate}' order: 'ASC')}" as="data_item">
{data_item.data.eventdate}<br>
</f:if>
Can someone help me?

the sortByparamter of the v:iterator.sort VH needs to be an attribute name. You used a (in this context) not defined variable which would result in a string replacement, which is the same for all array items. so no sorting will occur.
try: (Braces removed)
<f:for each="{data_eventarray -> v:iterator.sort(sortBy: 'data.eventdate' order: 'ASC')}" as="data_item">
{data_item.data.eventdate}<br>
</f:if>
----
wrong parameter:
... (sortBy:'{data.eventdate}' ...
correct prameter:
... (sortBy:'data.eventdate' ...

Related

Get an array with DomainObjects in a single Extbase ControllerAction argument

I'm creating an extbase extension to handle very simple product orders.
The model is:
Order --1:n--> OrderItem --1:1--> Product
To order a selection of products, the customer goes to checkout page and uses a Fluid based Order form. All selected products are available in the fluid template as {products}.
The OrderController->createAction processes new Orders by creating OrderItems from the given Products.
Writing the code I'd like to have would look like this:
class OrderController
{
public function create(Order $order, array $products)
{
foreach ($products as $product) {
$orderItem = new OrderItem()
->setProduct($product)
->setPrice($product->getPrice());
$order->addOrderItem($orderItem);
}
$this->orderRepository->add($order);
}
}
How to assign products to a Fluid form fields, in order to receive them as ControllerAction array argument?
How to trigger extbase to automagically provide an array of product objects to the ControllerAction?
I wonder if it is even possible to simplify the Controller createAction like shown below and assemble objects elsewhere:
public function create(Order $order) {
$this->orderRepository->add($order);
}
My suggestion for the fluid template would be:
// basic form with the order as main object
<f:form action="create" object="{order}">
// each order item with a product, using index to have no array with an empty index (Extbase does not like that)
<f:for each="{products}" key="index" as="product">
// Here you can set the product
<f:form.hidden prpoerty="orderItems.{index}.product" value="{product} />
</f:for>
</f:form>
This should be enough to use your single-line create action.
You can change the field type from select to whatever you want, but the __identity is mandatory to say Extbase which record it has to link.
When you want the orderItems to be new created, you need to remove the __identity field.

TYPO3 groupedFor viewhelper according to dates

I have a simple model "item" with 3 properties:
title, description, date
Now I want to have a list like this:
10.10.17:
title item 1
title item 5
12.10.17:
title item 8
and so on
According to groupedFor - grouping objects according to dates
I added a getter like
/**
* Get day month year of datetime
*
* #return int
*/
public function getDayMonthYearOfDatetime()
{
return (int)$this->datum->format('dmy');
}
My list view:
<f:groupedFor each="{items}" as="dayMonthYearOfDatetime" groupBy="dayMonthYearOfDatetime" groupKey="datum">
<tr>
<th>{datum}</th>
</tr>
<f:for each="{dayMonthYearOfDatetime}" as="calendar">
<tr>
<td>{item.title}</td>
</tr>
</f:for>
</f:groupedFor>
Now I get the following output:
101017
title item 1
title item 5
121017
title item 8
How to diplay the correct date "10.10.17" instead "101017"?
If I change my getter to:
return (int)$this->datum->format('d.m.y');
It doesn't work.
return (int)$this->datum->format('d.m.y');
Remove the (int)
You can't expect to have a grouping if you return int from a date-string with dots.
Either you need to return string (but I don't know whether the function is allowed to return anything else than int) or you need to calculate your datestring from the calculated integer.
Try a viewhelper which does integer caclulations ( % 100, / 100 %100, /10000) or simple substrings (,0,2 ,2,2 ,4,2) to extract the values for day, month, year for a following concatenation.
You can simply use the real date object of the first group-item.
So it would be
<f:format.date format="d.m.Y">{dayMonthYearOfDatetime.0.datum}</f:format>

In CrafterCMS, how can I query a model to get an array with all the fields in a repeated group?

In CrafterCMS, I have a component Team with a itemSelector field where I'm assigning some instances of another component TeamMember.
In the template of Team I'm using siteItemService.getSiteItem to get the model information of child components:
<#assign memberModel = siteItemService.getSiteItem(memberItem.storeUrl) />
Between the fields of type TeamMember I have:
Some fields of TeamMember
I'm able to get the value of skillTitle like this:
<#assign skillsTitle = memberModel.queryValue("//skillsTitle")!"" />
But I'm not able to get the value of the values in the repeating group.
I tried with:
<#assign skills = memberModel.queryValues("//skills")![] />
It returns an array of just one element, I think is an empty string
<#assign skills = memberModel.queryValues("//skills/item")![] />
It returns an array with the right number of elements, but I think all of them are empty strings
If I use:
<#assign skills = memberModel.queryValues("//skills/item/skillName")![] />
I get a correct array with all the skill names, but I need iterate over both values (skillName and skillLevel)
How can I query the model in order to get an array which elements have all the values in the repeated group?
Once you get the SiteItem with
<#assign memberModel = siteItemService.getSiteItem(memberItem.storeUrl) />
it works just like any other contentModel variable within a FreeMarker template. So, you can iterate it with
<#list memberModel.skills.item as skill>
${skill.skillName} = ${skill.skillLevel}
</#list>

How to generate input select in laravel blade form and customize its options value?

I'm trying to create a laravel form that have an input select generating from array of strings coming from controller.
How can I set values of options manually?
In controller :
public function create()
{
$eventTypes = EventType::all()->lists('title');
return View::make('events.create')->with(compact('eventTypes'));
}
In view (blade) :
{{ Form::label('eventType', 'Type') }}
{{ Form::select('eventType', $eventTypes, null, array('class'=> 'form-control')) }}
And select created as :
<select class="form-control" id="eventType" name="eventType">
<option value="0">Sport Competition</option>
<option value="1">Movie</option>
<option value="2">Concert</option>
</select>
I just want to set values manually.
The value in the options is just the key of the array. The second parameter to the lists() method will let you choose a field to use as the key:
// use the 'id' field values for the array keys
$eventTypes = EventType::lists('title', 'id');
If you want to do something more custom than that, you'll need to manually build your array with the key/value pairs you want.
Edit
As mentioned by #lukasgeiter in the comments, there is no need to call all() first.
EventType::all()->lists() will first generate a Collection of all the EventType objects. It will then call lists() on the Collection object, meaning it will loop through that Collection to build an array with your requested fields.
EventType::lists() will call lists() on the query builder object, which will just select the two requested fields and return those as the array. It will not build any EventType objects (unless you select a field built by a Model accessor).

How can we get all element values, when more than element hold same class name

How can we get all element values, when more than element hold same class name.
Eg:
Consider I'm having n number of elements that having same class name as follows
<span class="country-name">Country 1</span>
<span class="country-name">Country 2</span>
<span class="country-name">Country 3</span>
<span class="country-name">Country 4</span>
<span class="country-name">Country 5</span>
How can I get all the element values that having the class name as country_name.
Also I have tried as follows:
span(:country, :class => 'country-name')
puts country
When I execute it, It only printing the first value (Country 1) other values are not printed. How can I get all values?
Any suggestions?
You can create a collection accessor that returns all of the related spans (ie those with class "country-name").
In the page object, instead of calling span, call the pluralized version - spans:
class MyPage
include PageObject
spans(:country, :class => 'country-name')
end
This will create a country_elements method that return returns an array of all matching spans. You can iterate over this array to get the text of each country (element):
page = MyPage.new(browser)
page.country_elements.each{ |c| puts c.text }
#=> "Country 1"
#=> "Country 2"
#=> "Country 3"
#=> "Country 4"
#=> "Country 5"