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

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"

Related

Repeat the columns using data-sly-repeat based on the number entered in the cq dialog. Columns are not repeating

I want to repeat the parsys in the columns based on the number of columns added in cq dialog. I can only get one column and the numbers of columns as entered
<div class="items">
<div data-sly-repeat="${grid.cols}" class="col col-lg-4 col-md-2 pt-2 pb-2">
<div data-sly-resource="${'content-{0}' # format=[colList.index], resourceType='wcm/foundation/components/parsys'}"></div>
</div>
</div>
</div>
carousel.js:
"use strict";
use(function() {
var properties = granite.properties,
colCount = properties.numberofcolumns ? properties.numberofcolumns : 3,
cols = '';
return {
"cols" : colCount
};
});
data-sly-repeat expects a list, not a number. You're only returning the number of columns. If you return an n-element list, data-sly-repeat will render an element for each item in the list.
It's a bit of a hack but in your carousel.js, you'd have to return an array with a list of values. The primary use case of data-sly-repeat (and data-sly-list) is to iterate over the elements of a collection returned by the underlying Java/JS code and output the properties of each item in the list. In your case, the only difference between the repeated div elements is the index.
use(function() {
var properties = granite.properties,
colCount = properties.numberofcolumns ? properties.numberofcolumns : 3;
var resultList = [];
for (var i = 0 ; i < colCount ; i++) {
resultList.push(i);
}
return {
"cols" : resultList // data-sly-repeat expects a collection
};
});
On a more general note, it seems what you're aiming to do is to include a bunch of paragraph systems by name to achieve some sort of column layout. Before attempting this, I would consider using the OOTB Layout Container component, which can be resized in Edit mode to fit any number of columns without any new development.

ionic 3 input data binding is updating the different arrays of same type

I have a problem in input data-binding for one of our ionic 3 application. Whenever input changes which is changing the array values of different arrays of same type.
Here is my HTML
<ion-list>
<ion-item-sliding *ngFor="let item of storageItem ; index as i">
<div class ="itemList">
<input type="number" [value] ="item.storageOrderQuantity" (blur)="updateInputItemValue(item)"
[(ngModel)]="item.storageOrderQuantity" />
</div>
</ion-item-sliding>
</ion-list>
When ever input value changes, it is updating 'storageItem' array along with other arrays which has the same object(there are some other arrays 'item').
Here is my arrays declaration. Item is a model class.
item: Item[];
storageItem: Item[] = [];
storageItem' is a subset of 'item
Can anybody tell what would be the mistake in data-biding?
You have mentioned that storageItem is a subset of item
You probably already know this, Arrays and Object use concept of assign-by-reference. If you don't know this then read below article on Medium.
https://medium.com/#naveenkarippai/learning-how-references-work-in-javascript-a066a4e15600
So if you have the same object in both the arrays then updating one array will update the another,
const obj = { name : 'value' };
const arr1 = [1,2,3,obj];
const arr2 = [4,5,6,obj];
obj.name = 'yash'; // both arrays will have updated object
Now if you want to avoid this, then you can create a copy of the object before using it in another array.
Take reference from https://flaviocopes.com/how-to-clone-javascript-object/
item: Item[] = [
{ id : 'item1', list : [] },
{ id : 'item2', list : [] },
{ id : 'storageItem', list : [...storageItem] }
];
storageItem: Item[] = [list of storage items];
Now storageItem and item > id='storageItem' point to different arrays.
So your template will only update the storageItem now.

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>

Make a value appear first in drop down others after

I have a collection of Industries that I am displaying in a drop down using this code:
<%= ff.select :area_of_business_id, Industry.all.map { |x| [x.name, x.id] }, {include_blank: "Select an industry"}, class: 'droplist default-droplist required' %>
I would like one of the specific Industries from the list to appear first in the dropdown and the rest to appear after that in alphabetical order. For example, if I have this list:
Airlines
Broadcasting
Chemicals
Entertainment
Insurance
And, I would like Entertainment to appear first, then I want the order to be changed to this:
Entertainment
Airlines
Broadcasting
Chemicals
Insurance
What is the cleanest way to do this?
Yes possible as below. Say you have a instance variable inside the controller:
#option_values = Industry.order("name <> 'Entertainment', name asc")
.pluck(:name, :id)
Now do,
<%= ff.select :area_of_business_id, #option_values, {include_blank: "Select an industry"}, class: 'droplist default-droplist required' %>
That part order("name <> 'Entertainment', name asc") will put the record with name = 'Entertainment' first, then the rest in decreasing order.
Rails support priority of options out of the box for time_zones only. In all other cases you should do it manually use something like this:
<% industries = [Industry.find_by(name: 'Entertainment')] + [Industry.where.not(name: 'Entertainment')] %>
<%= ff.select :area_of_business_id, industries.map { |x| [x.name, x.id] }, {include_blank: "Select an industry"}, class: 'droplist default-droplist required' %>
but I recommend to add additional filed to Industry model for specify position in lists and sort by this filed.

Zend Framework : Setting up default values for part of the multicheckbox element options not possible

I'm writing this question cause I have difficulties setting up default values for a _MultiCheckbox element of a Zend Framework 1.9.3.
I create Zend_Form_Element_MultiCheckbox with multiple options like this:
$multiCheckbox = new Zend_Form_Element_MultiCheckbox( 'elId',
array ( 'disableLoadDefaultDecorators' =>true ) );
$multiCheckbox ->setName( 'elId' )
->setLabel('elId')
->setRequired( false )
->setAttrib('class', 'inputtext')
->setDecorators( array( 'ViewHelper' ) )
->setMultiOptions( $options );
where the $options array is an associative array 'key' => 'value'. The field is displayed just fine and I can get all the checked values for that element.
When returning to that page I need to restore from the DB the whole list of options again and mark the checked ones. I have tried to do it like that:
$multiCheckbox ->setValue( $defaults );
where $default is array, containing elements of type 'checked_option_field_id' => true(eg. array( '1222' => true, '1443' => true ) ). That action checks ALL the checkboxes and not only the once I need and I have passed to the setValue() method.
I have tried to pass just an array containing elements of type 'checked_option_field_id', (eg. array( '1222', '1443' ) )but that also doesn't work - NONE of the checkboxes is checked.
I have used the form setDefaults() method with those two kinds of arrays, but the results are same - as this method uses again setValue() for each element.
MultiCheckbox element is rendered like that ( result when try to set checked value for only one option ):
<label for="elId-1222"><input type="checkbox" name="elId[]" id="elId-1222" value="1222" checked="checked" class="inputtext">BoRoom </label><br />
<label for="elId-1443"><input type="checkbox" name="elId[]" id="elId-1443" value="1443" checked="checked" class="inputtext">BoRoom Eng2 </label><br/>
That element populates the checked option values in the elId[] array. That is the element name.
setDefaults() form method gets all form elements by name and commit their default values by calling setDefault() form method and after that setValue() element method. So my multicheckbox element has name elId ( it does not get all the element options one by one ) and set default values for all options instead of just the given in the array.
That is how I see it and I can't find solution how to set default values only for some of the options of a multicheckbox element.
Chris is correct that setValue() expects an array of values to be 'checked' (not an array of bool values keyed by your option IDs).
If you are looking for the logic behind the form generation, don't look at the Zend_Form_Element object (or the many extended elements from it), look at the Zend_View_Helper objects. Specifically the Zend_View_Helper_FormRadio object.
When generating the HTML the options array is looped, then the value is checked against the value array - the array passed to setValue(), using in_array().
From Zend_View_Helper_FormRadio line: 150
// is it checked?
$checked = '';
if (in_array($opt_value, $value)) {
$checked = ' checked="checked"';
}
Not sure what that's not working for you, but if you're passing:
$element->setMultiOptions(array('1111' => 'Some Label',
'2222' 'Some Other Label',
'3333', 'Not Selected Label'));
$element->setValue(array('1111','2222');
It should work. Maybe if you could include some code it would be easier to see what's going on?
The setValue() expects a array with those values that need to be checked, in this case for example you need to pass a array with values 1222, 1443 for them to be marked as checked.
You need to serialize the checkbox value before insert in database. To show the database value selected again you have to unserialize the data to show.
The details you can read from following link
http://abser-web-tips.blogspot.com/2010/09/zend-framework-multiple-check-box.html
Thanks