Difficulty with using contextual parameters in for loop, in JSRender - for-loop

I'm using JSRender 1.0.5, and the docs on this page: https://www.jsviews.com/#contextualparams
suggest I can do this:
"A contextual parameter is defined by simply writing ~myValue=... (for any expression) on any block tag, such as {{if}} or {{for}}."
But when I use it on a for loop, I cannot get it to work. I've spent hours on this - very frustrating.
{{for data.collection ~collectionIdx=#getIndex()}}
<div id="someDiv">Index = {{:~collectionIdx}}</div>
{{/for}}
What I really want to do is pass the index of the outer loop into an inner loop, but I can't even get the basic functionality to work. If I spit out {{:#getIndex()}} inside the loop, it works fine - I just can't assign it to a contextual parameter.
What's the fix?

#index, or #getIndex() return the index of an 'item view' - when your context is within a {{for someArray}} which loops over an array.
But if you are not within a loop (over an array) the #index is undefined so renders as an empty string...
In your example your contextual parameter, ~collectionIdx=#getIndex() is in the outer context, so it stores the value undefined.
But if you have nested loops then it will correctly render the index values at the appropriate level:
{{for outerArray}}
{{for innerArray ~collectionIdx=#getIndex()}}
<div>Outer Index = {{:~collectionIdx}}</div>
<div>Inner Index = {{:#getIndex()}}</div>
{{/for}}
{{/for}}

Related

How to count number of matches using page object?

My application has a list and it's size changes very regularly. So I need to get the li count before starting the test cases. So this is how I used to get the count
b.lis(:xpath => "//ul[#id='global_nav']/li[contains(#id, 'nav-')]").count
Now I need to achieve this in page object way. I declared the list in my page file as below.
list_item(:global_nav_count, :xpath => "//ul[#id='global_nav']/li[contains(#id, 'nav-')]")
If I try to get count as below
page.global_nav_count_element.count
It returns method not found error. Can any one suggest any solution to achieve this in page object way ?
The list_item accessor is similar to Watir's li method in that it returns the first matching element. If you want a collection of elements, you need to tell the page object.
The accessor for a collection of li elements is list_items (note the plural):
list_items(:global_nav_count, :xpath => "//ul[#id='global_nav']/li[contains(#id, 'nav-')]")
The method created to access the collection is also pluralized:
page.global_nav_count_elements.count

How to refer to position when using xf:setvalue function with iterate

Considering this code example and this post
...
<xf:action>
<xf:setvalue
iterate="instance('fr-send-submission-params')/#*"
ref="."
value="event(name(context()))"/>
</xf:action>
...
How can refer to current iterated position? Like value="position()"
Can i use this position as variable to xpath expressions? Like ref="/AnotherElement[position()]"
The following works:
<xf:action iterate="instance('fr-send-submission-params')/#*">
<xf:var name="p" value="position()"/>
<xf:setvalue ref="." value="$p"/>
</xf:action>
I don't think you can get away just with xf:setvalue, because ref changes the evaluation context of the expression to a single item which means that position() returns 1 within value.
A warning as I see that you iterate on attributes: I don't think that attribute position is guaranteed to be consistent.
Update:
The following works if you have elements, but then you need to have knowledge of the items iterated within the xf:setvalue:
<xf:setvalue
event="DOMActivate"
iterate="value"
ref="."
value="count(preceding-sibling::value) + 1"/>
So I think that the option with an enclosing action is much clearer.

Ember's select options are wrong when using RESTAdapter

I use a RESTAdapter model to fill a Ember's select view with options.
The contentBinding is mapped the a property in the controller, where I use this.set('myProperty', model.find(someQuery)).
model.find(someQuery) with 1 result works perfect, but model.find(someQuery) with many results have a weird effect. The last object from the result is showed as many times as the length of the result.
{{view Ember.Select contentBinding="myProperty" optionValuePath="content.id"
optionLabelPath="content.name"
selectionBinding="selectedResult"
prompt=" "}}
Interesting. At first glance the code you included in your question looks fine. To debug:
1) Check to be sure the query results are what you expect.
content = model.find(someQuery); //with many results
// wait for results...
console.log(content.getEach('id')); //expect array of ids
console.log(content.getEach('name')); //expect array of names
2) examine contents of myProperty - from template:
{{#each myProperty}}
<pre>{{id}}.{{name}}</pre>
{{/each}}
Expect template to output id/name for each option.

Express JS Jade Engine If statement nested in For loop

I can't seem to find a solution to this.
I'm trying to nest a if statement inside a for loop in Jade engine (using express js).
The base code is shown below:
form
select
for obj, i in phoneModel
option(value='#{i}') #{obj.phone_model}
What I would like to do is to have a IF statement inside the for loop to check to see if a varaible "deviceIndex" is a certain value. Eg. If deviceIndex == i, then do something, else do some other thing.
I have tried the code below:
form
select
for obj, i in phoneModel
- if(phoneIndex == #{i})
option(value='#{i}') #{obj.phone_model}
- else
option(value='#{i}' selected='selected') #{obj.phone_model}
It gives the "expect indent, but got newline" error. I expect it is my placement of the if statement inside the for loop; however, I have tried just about every combination of tabs and spaces as well as putting the "option(val..." line inside a bracket on the same line as the if statement.
What's with the typeof around a boolean? And shouldn't the phone with phoneIndex == i be the one selected? Also, the point of Jade is to have much cleaner code. Tell me if this works:
form
select
for obj, i in phoneModel
option(value=i, selected=phoneIndex==i)= obj.phone_model

ruby block questions loop variables

comics = load_comics( '/comics.txt' )
Popup.make do
h1 "Comics on the Web"
list do
comics.each do |name, url|
link name, url
end
end
end
I am new to ruby. This is a piece of code from a ruby website.
I cant find what 'link' and 'list' keyword in the menu.
can someone explain it a little bit those two keywords, and where is the definition of those two keyword .
I am also confused on how they read the variables name and url, they are reading it by the space at the same line or what?
so if I have
Comics1 link_of_comics_site_1
Comics2 link_of_comics_site_2
Comics3 link_of_comics_site_3
so for the first iteration, name=Comics1, and url =link_of_comics_site_1
Thanks.
That's not just Ruby. That's a template for a webpage using ruby add-on methods for HTML generation.
But presumably, the result of the call to load_comics is a Hash, where the keys are names and the values are URLs. You could make one of those yourself:
my_comics_hash = { "name1" => "url1", "name2" => "url2" }
which you can then iterate over the same way:
my_comics_hash.each do |name, url|
puts "Name #{name} goes with URL #{url}"
end
In your code, it's building up an HTML list inside a popup window, but it's the same idea. The each method iterates over a collection - in this case a Hash - and runs some code on every item in that collection - in this case, each key/value pair. When you call each, you pass it a block of code inside do ... end; that's the code that gets run on each item. The current item is passed to the code block, which declares a variable to hold it inside the pipes right after the word do. Since we're iterating over key/value pairs, we can declare two variables, and the key goes in the first and the value in the second.
In ruby function, parenthesis is optional and the ";" end of statement is also optional. ej
link "click here" , "http://myweb.com"
is equivalent to :
link("click here", "http://myweb.com");
But If you have more than one statement in a line the ";" is a must, ej
link("click here1", "http://myweb.com"); link("click here2", "http://myweb.com");
In your code it could be written in
link(name, url)
or just
link(name, url);
or
link name, url
But it is highly recommended to put parenthesis around function parameters for readability unless you have other reason . The ";" is not common in ruby world .

Resources