How can I use a class instead of id for new YT.Player() - youtube-iframe-api

In the example given here https://developers.google.com/youtube/iframe_api_reference you can see that instead of using standard css selector syntax there's a custom string syntax that seems to only refer to id.
<div id="player"></div>
// note no 'var' and yet this will work in strict mode
// since 'player' is being implicitly grabbed from the dom
player = new YT.Player('player', ...);
This of course creates the problem of leaking a global variable for whatever the id is named, which is something that I try to avoid (because it creates a loophole for strict mode and is just confusing and unexpected behavior).
A workaround is to hyphenate the name so that it can't be accessed from the global space
<div id="js-player"></div>
// now window['js-player'] is guarded from accidental access
var player = new YT.Player('js-player', ...);
but the bottom line is that using ids is just bad practice and I prefer to avoid them altogether since classes work nicely and don't have the weird side affects.

Might be a bit late for an answer but anyways ...
Just pass the selector like so
var player = new YT.Player(
document.querySelector('.your-class'),
... API Stuff ...
);
Of course, you could use jQuery or any other vanilla JS method for selecting elements.
var player = new YT.Player(
$('.your-class')[0],
... API Stuff ...
);
If you use a method that returns a node list be sure to loop trough the items like so: Todd Motto - Looping Through NodeLists / Arrays

Related

How would I pass an array to a template as an attribute and then use the array, then use the template recursively?

I've been working with ColdFusion CFML for a few months after using JSP for several years and there are still some things I'm having trouble figuring out in this language. Google, CFDocs, and Adobe have been no help with this particular question.
I'm building a feature to display comments below an article, where a comment can also have child comments. I have all the data imported and it looks great. I'm using a query that returns an array of structs, it gets each first-level comment for the article and I loop back through that array and attach an array of structs to each comment-struct that has children.
I've written a template to loop through and display the list of first-level comments but I'd like it to call itself recursively on each comment that has child comments until it has displayed all of the child comments of each comment. I'd assume that the best way to accomplish this would be for the template to call itself while passing it the array of child comments.
I've read several articles that explain how to create a CFModule but NONE that say how to actually use the attribute that you pass it. Here's one of the things I've tried:
(in the original template):
<h4>Comments</h4>
<div id="comments" name="comments">
<cfmodule template="comments.cfm" comments="#Variables.page.comments#">
</div>
(in the template that I want to eventually call recursively):
<cfoutput>
<cfloop array = "#comments#" index = "comment">
<div>#comment.commenter_name# says</div>
<div>#comment.created#</div>
<div>#comment.content#</div>
</cfloop>
</cfoutput>
I can't just use Variables.page.comments in the second template because the template's going to call itself recursively; for instance, I'll want the array at Variables.page.comments[2].comments the next time, Variables.page.comments[2].comments[5].comments the time after, etc
You could generate your hierarchical view by wrapping your rendering logic around
<cfscript>
cfsavecontent variable="html" {
do logic stuff here
}
writeOutput(html);
<cfscript>
which will store your output into a variable. Then output the variable.
You could also write a recursive function to do it, and then simply output the returned string, like below. You might want to add some limit logic so you don't output the entire discussion at once, depending on how big the discussion are.
string function outputComments (
required array comments) {
var html = "";
for (var comment in arguments.comments) {
html &= "<li>#comment.message#";
if (comment.children.length) {
html &= outputComments(comment.children);
}
html &= "</li>";
}
if (html != "") {
html = "<ul>#html#</ul>";
}
return html;
}
writeOutput(outputComments(comments));
Having done a bunch of this kind of work, you may want to consider rendering your comments/replies in some sort of JavaScript ajax-driven widget, using a service that returns comments data in JSON, where you get a page of comments or replies at a time. I wrote a Facebook-style comment widget that worked that way, and the advantage is that you don't have to worry about conversation size.

Detect template change in Meteor

I'm looking to make an element flash on screen when the underlying collection is updated.
It seems to me that it would make to have an equivalent of Template.my_template.rendered = function(){} which is fired every time the template is updated.
Ideally, this function would not fire the first time the template is rendered.
This is seems like such an obvious use case, am I missing something?
For Meteor < 0.8
You should use Template.myTemplate.created to do something for the very first time. From the docs Template.myTemplate.rendered is fired everytime there is a change including the first time. If you want to limit it to only the second time and changes after that (I'm guessing this is what you want), you have to write some custom logic. Currently there is no Meteor api that supports that.
For Meteor-0.8
It seems like this API underwent some backwards incompatible changes in Meteor-0.8.
There is an elegant way to achieve this as described Adaptation to the new Meteor rendered callback here. Bascially you should modify whatever function you are attaching to the variables inside your Template's javascript by calling a helper function once. For example,
var renderCount = 1;
var myHelper = function () {
console.log("rendered #" + renderCount);
renderCount++;
};
Template.myTemplate.myVariable = function () {
myHelper();
return this.name;
};
Hope this helps. There is also another alternative approach in that same repo. You might like that one.
There is no simple solution; more discussion here: https://groups.google.com/forum/#!topic/meteor-talk/iQ37mTP3hLg

How to add a property to a map dynamically in velocity?

I have the following code
$pageName = "test";
$Container = {};
I like to set a property of $Container by a variable. I tried $Container.set("test", $pageName);. It didn't raise any errors, but $Container.test or $Container.get("test"); display nothing.
How do I fix it?
The problem is that set is the wrong method. You need to do a put. Remember - Velocity is calling the Java methods. There is no "set" method on a Map object.
Specifically, you can do
$Container.put("test", $pageName)
Now, one weird thing is that this will print "true" or "false" in the page, since the Map.put() method returns a boolean. So I always do
#set($dummy = $Container.put("test", $pageName))
which does the put and stores the result in another reference (which you can then ignore) instead of rendering it to the page.
Hey I ran into the same problem is the "true" or "false" printed on the page, and there is a simpler way to handle it. What I did is a little weird, and I did it Confluence, which of course uses Velocity under the covers. I mention that because I understand Velocity can be used in may different applications.
With a Confluence user macro, I check for a previously created attribute on the req variable, the request variable, i.e. "myPageVars". Then I use the put method to put a new key-value pair, based on the macro parameters. By using the $! prefix, rather than just $, the output isn't sent to the screen.
...
$!req.getAttribute("myPageVars").put( $paramKey, $paramValue )
...
I'm somewhat new to Velocity, so I can't guarantee this will work in every context, but it seems syntactically easier than the whole #set ($dummy etc. line.

Fastest way to get an Objects values in as3

Ok, so I swear this question should be all over the place, but its not.
I have a value object, inside are lots of getters/setters. It is not a dynamic class. And I desperately need to search an ArrayCollection filled with them. The search spans all fields, so and there are about 13 different types of VOs I'll be doing this with.
I've tried ObjectUtil.toString() and that works fine and all but it's slow as hell. There are 20 properties to return and ObjectUtil.toString() adds a bunch of junk to the output, not to mention the code is slow to begin with.
flash.utils.describeType() is even worse.
I'll be pleased to hear I'm missing something obvious.
UPDATE:
I ended up taking Juan's code along with the filter algorithm I use for searching and created ArrayCollectionX. Which means that every ArrayCollection I use now handles it's own filters. I can search through individual properties of the items in the AC, or with Juan's code it handles full collection search like a champ. There was negligible lag compared to the same solution with external filters.
If I understand your problem correctly, what you want is a list of the getters defined for certain objects. As far as I know, you'll have to use describeType for something like this (I'm pretty sure ObjectUtils uses this method under the hood).
Calling describeType a lot is going to be slow, as you note. But for only 13 types, this shouldn't be problematic, I think. Since these types are not dynamic, you know their properties are fixed, so you can retrieve this data once and cache it. You can build your cache up front or as you find new types.
Here's is a simple way to do this in code:
private var typePropertiesCache:Object = {};
private function getPropertyNames(instance:Object):Array {
var className:String = getQualifiedClassName(instance);
if(typePropertiesCache[className]) {
return typePropertiesCache[className];
}
var typeDef:XML = describeType(instance);
var props:Array = [];
for each(var prop:XML in typeDef.accessor.(#access == "readwrite" || #access == "readonly")) {
props.push(prop.#name);
}
return typePropertiesCache[className] = props;
}

How to read xml tags and its data using flex?

I need to read xml tags and its datas from one file and then write it to another xml..how to do it?? please let me know immediately...?
See http://livedocs.adobe.com/flex/2/langref/XML.html . I find it hard to believe you googled this before asking.
You can use the FileReference.save() method to save XML data to a local file. It will prompt the user for a location to save the file first and then save the data.
Here's an example:
var xml:XML = <root><someXmlTag/></root>;
var fileReference:FileReference = new FileReference()
fileReference.save(xml, "myfile.xml");
As far as I knew, Flex wasn't able to write to files!
I use a HTTPService to load the XML file and a result even handler to access it.
<mx:HTTPService id="service" url="myXml.xml" result="ServiceResult (event)"/>
Do not specify a result format in the HTTPService tag.
This is the code for the result event handler.
private function ServiceResult (e : ResultEvent) : void {
e.result.XmlTag.AnotherXmlTag;
}
You can also use service.lastResult to access the last result returned by the HTTPService. The result is fully compatible with the dataProvider property, especially in arrays and chart series.
var series : LineSeries = new LineSeries ();
series.dataProvider = e.result.XmlTag.AnotherXmlTag;
This will take the value in all AnotherXmlTag tags within XmlTag. For series, though, you should also specify either a yField or and xField, but it digress :-)
If it doesn't work, you can also cast it using the as keyword, example:
series.dataProvider = e.result.XmlTag as ArrayCollection;
I haven't actually tried casting it in this scenario, but the bottom line is that XML tags are vary compatible with arrays and ArrayCollections.
In your case, you would just use e.result to get the complete XML file, assign it to a variable, and write it using Ben's method. You can also create an array from individual values using the way I explained above, and manually insert tags and such if you need. The advantage of this is that you have all the values ready in an array would you need them later on. If you loop through the indices, this won't require a lot of work, and it would be the way I'd do it.
Hope this helps!

Resources