Dynamic class name in Batman.js view - javascript

My question is very close to Setting id and className dynamically in Backbone.js views, but for batman.js.
In batman there are data-addclass method, but I need something like this:
<span data-class="item.color"></span>
What will produce for example:
<span class="yellow"></span>
What is the best practice to perform such things in batman.js? Maybe I should use data-bind and detect class with jquery?

The easiest way to do that would be to just perform a data-bind- directly onto the attribute you would like to change, in this case class.
<span data-bind-class="someBatmanVariable">Here is my content</span>
Where someBatmanVariable is just something you've set up in the controller which resolves to the class you'd like the span to have.
You can take it further and put whatever you'd like just about anywhere. You can bind to most attributes and they'll update. Don't forget that by not specifying an attribute (a vanilla data-bind) Batman will default to something logical, usually the contents of the tag or, in the case of input elements, the value.
Finally, be sure to take a look at the Batman view filters. You can massage the output quite a bit.

Related

Aurelia - render custom element by name

Suppose we have a custom element that renders a list of something. It is a selector element, so it does not atter how this something is rendered.
The problem is that this something is quite generic and there are custom elements to actually render it. For example, for countries we add a flag image, for general elements - a fontawesome icon, reputation for users, etc.
What I would like to have
And now I would like to pass the name of the custom element I want to render something with. So instead of this
<selector data.one-way="options" selected.two-way="selected"></selector>
Have something like
<selector element="country" data.one-way="options" selected.two-way="selected"></selector>
And in the selector I would like to have
<${element} content.one-way="el" repeat.for="el of data"></${element}>
What I get
Unfortunately, the code above renders as htmlescaped
<country content.one-way="el" repeat.for="el of data"></country>
So,
Is there a more or less clean way to achieve that? Basically I would like to pass the specify custom elements I want to render in my selector custom element. This post and the answer there have nothing to do with my question.
Using compose as described here... well, it is an option, but I would like to have different custom elements and a slightly different logic in CustomElement js files.
Thanks!
UPD
Well, there's an obvious way to do that by just adding something like a switch statement in the view
<country ... if.bind="el.type === 'country'"></country>
<phone ... if.bind="el.type === 'phone'"></phone>
<user ... if.bind="el.type === 'user'"></user>
But that would make the selector element dependent on country, user etc. So I would not like that.
I believe easiest way is using the compose tag (like you've mentioned):
<compose model.bind="item" view-model="widgets/${item.type}"></compose>
I found couple possible solutions, they may seems more complicated then compose.
#bindable({
name:'myProperty', //name of the property on the class
attribute:'my-property', //name of the attribute in HTML
changeHandler:'myPropertyChanged', //name of the method to invoke when the property changes
defaultBindingMode: ONE_WAY, //default binding mode used with the .bind command
defaultValue: undefined //default value of the property, if not bound or set in HTML
})
You can find more details there http://www.sitepoint.com/extending-html-aurelia-io-way/

Is it bad form to use html class attribute as a variable

I am wondering if the html class attribute should only be used for styling. Is there any drawback to using the class attribute as a variable. The W3 spec http://www.w3.org/TR/html5/dom.html#classes does not specify one way or another but, all examples and training point in the direction of styling only for multiple objects.
In my case I want to use the class attribute as variable that matches the key value in a object array. For example in my Javascript code I have an object that has a number of key/value pairs. On my web app I have a number of save buttons. When a save button is clicked I grab the parents class attribute value and use it as the key for the object to know which value to change. The class attribute on the parent has not other value than to let me know which key value pair to change in my object
While I'm sure it's possible to use classes that way, it's certainly not their intended purpose. html has data attributes that provide the functionality you want, for example
<button data-key="some value" name="" id="">click me</button>
You can then get that value (onClick if you like) and use it as a key for your object/data structure. Theres a good overview here
While it is not bad, it neither is best practice.
You can, instead of using the class attribute, define explicit data attributes. Using the class attribute would mean that you could not use several classes (because that would be a weird key to search for in an object, right?).
For instance:
<div class="any classes you like" data-mykey="searchforthiskey">
<button></button>
</div>
In jQuery:
$('button').click(function() {
var key = $(this).closest('div').attr('data-mykey');
});
From a functional perspective, there's no reason to NOT use the class attribute to store information about that element. You can access a class attribute as easily as you can a data attribute.
From a standards perspective, it is probably better to use a data attribute. Why? Well, if you are the only person working on your front-end, no big deal. If you are one of many on a team of front-end developers, who works specifically on the javascript side of things, you may run into a conflict with another front-end developer who works on the HTML/CSS side of things. They may remove a class from the element, not realizing that its also being used as your javascript hook into that element. In that case, you're better off creating your own data attribute, which then makes it clear that this attribute is probably data related and won't be molested by someone just trying to fix the styling of that element.

Store "templates" of children

I am new to JavaScript so forgive me if the question comes around as dumb.
I know that appendChild() allows me to add a child element to an existing element. However, the problem is that I want to add an element which has an image on the left and a series of text boxes on the right and I need to add it over and over again on button click.
Adding simple elements like p, a , etc can be done by a single call to appendChild(), however for the above scenario, it will be a little messy.
Is there some way that I can define the custom element that I want to append and then just add it with a single call to appendChild()
Are you using jQuery? If it is a really complicated template, you could use .load() to ajax in an template and populate it with whatever you have to. You wouldn't need to dynamically create all of the elements using javascript, only populate it. This would would also allow you to change your template if need be very easily.
It seems you need cloneNode:
target.appendChild(template.cloneNode(true)); // If you want to clone template
// with all its descendants
target.appendChild(template.cloneNode(false)); // If you want to clone template
// without its descendants
I do this quite a bit. My code generally looks like this:
<div class="template" style="display: none;">stuff</div>
then:
$('.template').clone(true).removeClass('template').show().appendTo(someElement);
Since you're not using jQuery, have a look at the clone function here:
http://code.jquery.com/jquery-1.11.0.js
(search for "clone: function" to find it)
You can steal the relevant bits if you can't actually use jQuery itself.

How binding attribute of inputText can effect javascript method?

I am using jsf and liferay. I am very new to it. For any javascript method which select any element of jsf for some javascript or jquery method I need to set it like.
<h:inputText id="abc" binding="#{abc}"/>
Please note that I have set binding same as id, somebody has told me to do like that. Without setting binding like that I was not able to select any element in my javascript method. I really dont know the reason. Since this was working for me so I have used it, without going in detail
But now for some functionality I really need actual use of binding, bind UIInput to managed bean. So I have changed my tag like.
<h:inputText id="abc" binding="#{mybean.uiAbc}"/>
In this case my javascript method like
function doSomething(){
$("##{abc.clientId}").val("hello everyone");
}
its not working. Its giving me exception like... # is undefined..
In javascript I have nothing to do with binding so why it stops working now? And why it was working earlier with same value of binding as id have?
If you replace binding="#{abc}" by binding="#{myBean.uiAbc}", then you should obviously also change #{abc.clientId} elsewhere in the view by #{myBean.uiAbc.clientId}.
function doSomething(){
$("##{myBean.uiAbc.clientId}").val("hello everyone");
}
That the id and binding need have to be the same name is complete nonsense.
The only problem which you may face is that the default JSF naming container separator character, :, is a special character in CSS selectors, like as used in jQuery, and thus this construct would possibly fail. This construct would only work if you've manually reconfigured your JSF webapp to use a different, CSS-safe, character like - or _. If you indeed use the default of :, then you should use
function doSomething(){
$("[id='#{myBean.uiAbc.clientId}']").val("hello everyone");
}
See also:
How to use JSF generated HTML element ID with colon ":" in CSS selectors?
Your myth for following is wrong, i.e. to have same id and binding attribute.
id="abc" binding="#{abc}"
JSF renders component with id which provided by us with preceding by form id. e.g. in your case it will be,
:formId:abc
to avoid prepending form id just set prependId attribute to false. it will render the component with id "abc" only.
Also if your component is naming container e.g. dataTable. Then you the method accessing client id is different.
In short just right click in your browser and check the element's id and you can find the id to the jQuery.

Dynamically give HTML element a custom attribute

Is it possible to give a HTML element a new custom attribute?
You know how a "img" html element has the attribute .src:
imgEle.src = "";
Can I dynamically give a HTML element my own custom attribute .animationInterval? Is it as simple as this?...
imgEle.animationInterval = setInterval(...,10);
Maybe I do it the xml kindof way?...
imgEle.setAttribute("animationInterval", setInterval(...));
Whats the best way to do this?
The best way is to use html5 data- attributes:
$(imgEle).attr("data-animateinterval", "12");
Which can then be read back with
$(imgEle).data("animateinterval");
Which of course can also be added directly to your markup
<img src="foo.png" data-animateinterval="12" />
Also, if you're not concerned about whether a new attribute is added to the actual html element, but just want some arbitrary data associated with it, you can simply do this:
$(imgEle).data("animateinterval", "12");
And retrieve it like this:
var animateInterval = $(imgEle).data("animateinterval");
Note however that as Esailija explains, this may or may not actually add a new attribute to your element; it may just store this data internally. If that's not a concern for you, and I can't think of any reasons why it should be, then you may prefer this more succinct syntax.
To be clear, no matter which way you store it, $(imgEle).data("animateinterval"); will still work just fine.
The first way (element.something) sets a property and can be anything.
Th second way (element.setAttribute) sets an attribute, which must be a string (or serialisable as one via its toString() method).
So in this case either way works, but I would recommend the first.

Categories