How do I cycle an odd/even class as it loops over the items? - jquery-templates

Using the jquery-tmpl, I want to stripe presentation of the rows by adding a class to every second one, so from data ['Cat','Dog','Horse','Noddy'] it generates:
<li>Cat</li>
<li class="odd">Dog</li>
<li>Horse</li>
<li class="odd">Noddy</li>
The solutions suggested here looked like the start of something that could be further refined for easy digestion by us noddy's.

Never mind. Overcomplicating things as usual...
Just follow it up with the :odd selector with addClass...
$('#template').tmpl(data).appendTo('#list')
$("#list li:odd").addClass('odd')

Just found the solution after few trial and errors. You can use the {{= }} tag for evaluating expression:
{{each(i) Animals}}<li class="{{= i % 2 ? 'even' : 'odd'}}">...</li>{{/each}}
Of course you can modify it to suit your needs exactly - you can put the class inside and print empty value for odd or even.
Another solution would be to use a function (there is example of this in the jquery tmpl docs), but it is ugly.

#John Mee, I don't think you are overcomplicating.
Imho the template is the place where the addition of the odd-Class should take place. Logic and performance wise.
Here is a patch for having the index inside a nested template. If you like to have an additional $odd property it could be easily extended as follows:
jQuery.map( data, function( dataItem, index ) {
if(dataItem){
dataItem.$index = index;
dataItem.$odd = index % 2 === 1;
}

Related

Modify all text output by TYPO3

I would like to create a "cleanup" extension that replaces various characters (quotes by guillemets) in all kinds of textfields in TYPO3.
I thought about extending <f:format.html> or parseFunc, but I don't know where to "plug in" so I get to replace output content easily before it's cached.
Any ideas, can you give me an example?
If you don't mind regexing, try this:
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['cleanUpQuotes'][] = \NAMESPACE\Your\Extension::class;
Insert it into ext_localconf.php and this part is done.
The next step is the class itself:
public function cleanUpQuotes(TypoScriptFrontendController $parentObject)
{
$parentObject->content = DO_YOUR_THING_HERE
}
There also is another possibility which could replace any strings in the whole page - as it operates on the rendered page (and not only on single fields).
You even can use regular expressions.
Look at my answer -> here

How do I locate a custom tag like <g>?

I'm having to deal with some graphic items in a page that have <g> tags. I can do something like this to find them by dropping into selenium webdriver:
browser.wd.find_elements( :tag_name => "g" )
What would be the equivalent for watir webdriver?
Also, how would I convert those selenium elements into watir elements?
Could I add support for a <g> tag to watir locally somehow?
Solution 1 - Watir-Webdriver Equivalent:
The equivalent to what you were doing in selenium-webdriver is:
browser.elements( :tag_name => "g" )
So you can do something like this to output the text of each element:
browser.elements( :tag_name => "g" ).each do |x|
puts g.text
end
Solution 2 - Add Support for G Element:
After requiring watir-webdriver, add the following code:
module Watir
module Container
def g(*args)
G.new(self, extract_selector(args).merge(:tag_name => "g"))
end
def gs(*args)
GCollection.new(self, extract_selector(args).merge(:tag_name => "g"))
end
end
class G < Element
end
class GCollection < ElementCollection
def element_class
G
end
end
end
Then you can treat 'g' like any other element. For example:
puts browser.g(:index, 0).text
browser.gs.each{ |x| puts x.text }
The G and GCollection classes will support all the standard element methods. You can add additional methods to the class if there are things specific to that element.
Update - Example of Adding Custom Methods:
To get the cursor style, you would add a method to the G class like this:
class G < Element
def cursor_style()
assert_exists
return #element.style("cursor")
end
end
This will then allow you to get the cursor property like this:
puts browser.g(:index, 0).cursor_style
#=> move
Any custom methods that interact with the element need to start with assert_exists. Then, within the method, you can work with the element using the #element variable.
Note that because the G element inherits from the Element class, you could also have used the built in style method:
puts browser.g(:index, 0).style("cursor")
#=> move
There is no support for non-standard HTML tags in watir or watir-webdriver. In part because the list of possible tag names we'd have to support is endless.
You could monkeypatch in your own custom tags if you want to. In the long run, if you are going to have to deal with those custom tags a lot, that might be your best solution in terms of having stuff that acts just like other standard HTML elements supported by the Watir api.
You can use a CSS selector on the tag name, but that only works if you stick to element objects, as described in Watir::Exception::MissingWayOfFindingObjectException: invalid attribute: :css. Which kinda makes things a little less readable and/or useful if you ask me, but might be a quick and easy solution worth the slight cost in that regard.
Or you can use .driver or .wd methods to access webdriver functionality when you need it for something not supported by watir. (but that's also not quite as readable)

Smarty foreach:for every iteration add class

I have a foreach loop code in a tpl file like this:
[{foreach from=$oView->getArticleList() item=actionproduct name=test_articleList}]
[{include file="inc/product_alt.tpl" product=$actionproduct testid="action_"|cat:$actionproduct->oxarticles__oxid->value test_Cntr=$smarty.foreach.test_articleList.iteration}]
[{/foreach}]
the included file product_alt.tpl in the foreach loop contains a simple div container and get displayed for each product. Now i am looking for a solutions to add to every second div container a extra class.
I google a bit and found out (i think so) that I must work with even and odd. But i stucked how to apply this exactly to the foreach loop with the goal that every secod div container get an extra class.
You are looking for cycle. What you can do for instance is assign an extra $class variable in your include statement, that gets changed by the assign, like so:
{cycle values='yourClass1,youClass2' assign='class'}
That's probably where your odd/even thought comes from: the manual says
{cycle values='odd,even' assign='class'}
But those are just values. Anyeay, your variable 'class' now has alternating "yourClass1" and "yourClass2" (or odd/even) as content. If you assign this to your include, and then add something like
<div class="{$class}">
You get alternating classes. One of them is the one you want. the other can be empty..
check out the cycle manual: http://www.smarty.net/docsv2/en/language.function.cycle

jQuery+JS computed selector

Sorry for the bad wording of the title, but here's my problem. Suppose I have a list where every item has a class:
<ol>
<li class="chapter">Chapter 1</li>
<li class="chapter">Chapter 2</li>
...
I want to select the item which is corresponding to make the user's current chapter, which is known by javascript, in bold. So if the user is on Chapter 2 I would do something like:
$(".chapter:eq(2)").css("font-weight", "bold");
But I can't do
$(".chapter:eq("+currentChapter+")").css("font-weight", "bold");
as it gives me Uncaught SyntaxError: Unexpected identifier
Any help would be appreciated.
Edit: I'm using a template to insert the variables but I have verified that currentChapter is in fact defined and the number I expect it to be.
function fetchContent(startSlide) {ldelim}
var chapterSize = {$chapterSize};
var currentChapter = {$chapter};
var chapterName = "{$chapterName}";
alert(typeof(currentChapter)); // number
alert(currentChapter); //e.g. 3 works
alert(currentChapter + "aaa"); //e.g. 3aaa
$(".chapter:eq("+currentChapter+")").css("font-weight", "bold"); // doesn't work
Try a different approach, fetch all elements and then select only the one you want (I know it's best to select your element right in the selector, but just to try it out).
$(".chapter").eq(currentChapter).css("font-weight", "bold");
Also, looking at your code, it seems like currentChapter is a local variable inside the fetchContent function. Are you sure you can access that variable when you are calling the jQuery function? Try to check the existence and value of the currentChapter variable right before calling the jQuery function which is causing you problems.
EDIT
From the jQuery documentation jQuery :eq() selector
Because :eq() is a jQuery extension and not part of the CSS
specification, queries using :eq() cannot take advantage of the
performance boost provided by the native DOM querySelectorAll()
method. For better performance in modern browsers, use
$("your-pure-css-selector").eq(index) instead.

I'm trying to select the adjacent sibling of "this" in jquery

$(this+"p").slideDown("slow");
$(this)+$("p").slideDown("slow");
$("this+p").slideDown("slow");
does not work.
Yeah, your syntax is bad. You should use the jQuery Sibling function:
$(this).siblings().find("p").slideDown("slow");
The jQuery API site is awesome for looking stuff like this up, I rely on it nearly daily. I'd keep an eye on it.
Next.
$(this).next("p").slideDown("slow")
Make sure that the "p" element is directly adjacent, though. Otherwise you'll want to use nextAll.
jQuery have not seemed to apply this? Possibly the syntax we are trying to use is incorrect.
next() can only select elements with an ID or Class - Not just a naked dom element as expected.
Instead use. > means select first level decends only.
$('body > div').hide();
But this gives the exact same result
$('body').children('div').hide();
But,
Next
$('body + div').hide();
and
Previous
$('body ~ div').hide();
Do not seem to work as expected? But jQuery use it as example for CSS selection...
Possibly there is a complex syntax to achieve this but I could not figure it out...