when use [name] vs [attr.name]? - html

Does anyone know why you can use [id] and you must use [attr.contenteditable] as property binding in Angular?
I have researched for some time and I can't find an answer.
Why some html native attributes can be modified just with its name while others need to be modified through the attr property?

(This answer assumes you're binding to a HTMLElement rather than an in-app model object. Given the [attr.{name}]-syntax is only supported for DOM HTMLElement objects this assumption should stand)
When working with the DOM, the DOM interfaces for certain elements define first-class/native properties (as in JavaScript properties) for certain HTML attributes.
For example, the HTMLElement DOM interface defines a first-class property id, which is why you can directly use it in a binding expression: [id]. Similarly the HTMLAnchorElement exposes the href property.
(I note that contenteditable is a a defined DOM interface property in WHATWG HTML LS, but not the W3C's DOM specs, interesting...)
However, arbitrary (ultra-modern, user-defined, and obsolete) HTML attributes are not exposed through DOM interfaces and so can can only be accessed via the attributes collection in the DOM. Angular requires you to use [attr.{name}] for non-DOM-property attributes so that it knows it has to use the attributes collection instead of assuming it can bind directly to a DOM property.
To answer your question more directly:
when use [name] vs [attr.name]?
Follow this flow-chart:
Is the value I'm after exposed as a DOM interface property?
Yes:
Use [propertyName]
No:
Is the value I'm after a HTML attribute without a corresponding DOM interface property?
Yes: Use [attr.{attributeName}]
No: Quit your job and let someone else deal with the emotional and mental stresses of the fast-moving JavaScript developer ecosystem.

From the docs
Though the target name is usually the name of a property, there is an automatic attribute-to-property mapping in Angular for several common attributes. These include class/className, innerHtml/innerHTML, and tabindex/tabIndex.
So not all attributes are mapped within Angular.
Using the attr. prefix will literally emit the suffix as a string attribute.
Take this example:
<div [attr.data-my-attr]="value"></div>
Will produce the following HTML, assuming that the component property value has a value of 5:
<div data-my-attr="5">
</div>
Why you must use [attr.contenteditable]="editable"?
This isn't true. This is one way of emitting the contenteditable="true" attribute. Another is to use the Angular attribute [contentEditable]="editable", assuming some component property editable exists.
<div [contentEditable]="editable"></div>
DEMO: https://stackblitz.com/edit/angular-ujd5cf

The reason is because most common HTML attributes have special #Input properties in angular itself. E.g. id class etc, but there are way too many attributes to have this for each of them, so those more specific require you to use attr. syntax. The same thing happens with shorthand binding e.g. [style.width.px], you cannot do this with every single property. Event bindings have similar behavior. E.g. you can say (keyup.enter) but not (keyup.j). Angular tries to make your life easier when it can with most common things, but it also provides option to do other things as well.
This also means that you can do e.g. [attr.id]=

Related

Attribute binding vs property binding for Component's string #Input properties in Angular?

To set string #Input() properties of the component, we can use two type of syntax:
<my-component caption="Hello there" type="primary" someThing="text value"></my-component>
OR:
<my-component [caption]="'Hello there'" [type]="'primary'" [someThing]="'text value'"></my-component>
I'm fully aware of the differences between those two types of bindings. The question is: If I have bunch of string #Input() properties that I want to set statically, can I use simple attribute binding syntax (first example) than more "meaty" property binding syntax (second example)?
What is the recommendation, and why? I.e. what are the trade-offs and is it preferable to use property-binding always, even for setting static string inputs?
Here are the few drawbacks I can think of:
Attribute bindings are actually applied as HTML attributes, and e.g.
user can see/alter them via browser's dev tools easily. Property
bindings are not part of the markup.
Attribute bindings might collide
with actual HTML attribute names (unless you prefix them with data-
which defeats the whole purpose of simplicity). Actual example that
already bit me is title attribute.
There is no intellisense in markup for attribute bindings with Angular Language Service.
But the major advantage is the simplicity. In the example above, you would agree that the first form is more elegant. In my projects it seems that big number of properties are constant (one-time-set) string properties, and the syntax makes actual difference in readability.
So... Is it a bad practice to use attribute-binding syntax for custom (non-HTML) string properties? (Given the fact that I'm aware/ok with above listed few limitations)
These are a couple of things I like to add:
Attributes are just plain static fields.
There is a fine line when attributes become properties.
Simplicity is not the goal here, modularity and reuse-ability is.
Property binding give you more control in your component and you can use a component in any like any data-driven or static scenario.
One component build right with property binding can be used in 20 different projects.
But if you got no such requirement then you can use attributes. They are fine.
I will not say which one is better, both have their use cases but overall property bindings are lot more powerful and flexible.
And last thing I like to mention for all readers:
In front-end development any one can modify the code. We use
validations just to provide a smooth user experience. Other than that
any one can get the code or alter HTML if they want to, that's why we
use server side validations. Angular pipe line is complex but
hack-able. A user can wrap a JSON object and send it to server
bypassing all our validations. So for all readers who are new front-end
devs, we don't bother too much about security, we try our best to give
a good user experience.

Is it good practice to use attributes just to mark html elements?

I have a doubt about good practices writing HTML with Javascript.
I've came up with an idea (probably not the first, but couldn't find a clear reference about that) to mark some elements as candidates to load some data when it's available (after some user interaction). Let me exemplify:
Suppose I have a request that returns the following:
GET /animals/dog
{
name: "Gutemberg",
race: "doberman",
age: "2y"
}
The code I wrote binds fields in the response to elements that are candidates to load such value.
For example: With the request above, I could use the following tags:
<input name="dog-name-field" data-load-dog-name type="text"/>
<input name="dog-age-hid" data-load-dog-age type="hidden"/>
Each tag would receive the property value because it's marked as a candidate to do so - dog-name-field will have a value of "Gutemberg" when everything executes . That will happen everytime the request is reloaded. For now, I just get the data type I've searched ("dog"), concat it with the property "name/age" to form the attribute data-load-type-property and set a value to everyone that has such attribute.
I have a feeling that attributes are not meant to be used just like that, but I'm not aware of any real downsides to that. As I could not find it for the lack of a clear name to this approach, I'd like some guidance.
Is there a name for such technique? Is it a bad practice? If so, why?
PS:
To comply with SO good practices, I'd like the answers to be reference-guided and not based solely on opinion whenever possible. If no reference is provided, please, let us have a solid, well described example.
I have a feeling that attributes are not meant to be used just like that
Let's see what custom data attributes are meant to be used for:
Custom data attributes are intended to store custom data private to
the page or application, for which there are no more appropriate
attributes or elements. These attributes are not intended for use by
software that is independent of the site that uses the attributes.
(from w3.org)
So whether using data-attributes is "appropriate" in your case depends on your needs: if the DOM API doesn't provide better attributes to do that then it's appropriate.
If your need is just to select some element to change the textContent then you have two more appropriate/simpler options:
1) Using the id attribute if your elements are going to be unique in the document
The id global attribute defines a unique identifier (ID) which must be
unique in the whole document. Its purpose is to identify the element
when linking (using a fragment identifier), scripting, or styling
(with CSS).
(from id on MDN)
2) Using the class attribute if your elements are going to be used in multiple instances in the document
The class global attribute is a space-separated list of the classes of
the element. Classes allows CSS and Javascript to select and access
specific elements via the class selectors or functions like the DOM
method document.getElementsByClassName.
(from class on MDN)
As #Supr says in his answer, what you are doing is a very simple implementation of data-binding. data-binding can involve a lot more complexity than what you are doing at the moment; for example you may want to:
keep in sync your UI with a Javascript object which represent your business model instead of directly injecting data coming from an Ajax call,
update other attributes (value, style) and not only innerHTML or textContent,
have your business model updated in reaction to changes on the UI (two way data binding)
To implement all these features, simple id and class selectors are not sufficient, and this is why frameworks which implement data-binding, like KnockoutJS or AngularJS, use the more flexible data-* attributes instead (AngularJS is actually using its own ng-* attributes, but allows to use the alternative data-ng-* syntax for using HTML validation tools).
Data attributes allow to describe much more complex bindings:
<input data-bind="visible: editing, value: name, hasFocus: editing" />
Check KnockoutJS documentation for the meaning of the above code, it is not relevant to this example but just imagine describing that with classes or ids, it wouldn't be very convenient.
TL;DR
If you don't plan to implement more complex features you might want to use class and id instead.
This is called binding. Sometimes data binding and sometimes template binding.
Various frameworks provide mechanisms for this, though the syntax varies.
AngularJS example:
<input ng-model="dog.name" />
Knockout example:
<input data-bind="textInput: dog.name" />
React example:
<input value={this.state.dog.name} />
These are all quite popular frameworks/libraries, so I think it's safe to say it is not considered bad practice. The main difference from your approach is that they use the value of the attribute to specify the reference into the model (i.e. the "dog.name" part of your attributes), while you are putting the reference in the attribute name. In practice this is mostly a matter of style. Separating the reference from the "marker" (i.e. "data-load") is perhaps a bit more readable.

What is "data-effect" attribute?

I recently downloaded a code and it shows
<button data-effect="st-effect-4">Slide along</button>
From what I figured out "st-effect-4" is a class name but can anyone tell me what this data-effect is for?
HTML5 allows for custom attributes, as long as they begin with "data-". This is a custom attribute with a specific value.
Those are called HTML5 Custom Data attributes.
Custom data attributes are intended to store custom data private to
the page or application, for which there are no more appropriate
attributes or elements. These attributes are not intended for use by
software that is independent of the site that uses the attributes.
Every HTML element may have any number of custom data attributes
specified, with any value.
The reason why you can't find it in Google is because those attribute are custom attributes generated by user for there own use.
It's not for anything.
HTML5 specifies that (just about) any element can have any "data-*" attributes it wants, which can hold any values they want (as long as they can be treated like strings, to store on the element).
So that might be part of a library, or it might just be somebody's CSS for a selector like:
button[data-effect] { background : blue; }
button[data-effect="st-effect-4"]:active { background : purple; }
Or it's being used as a query selector, in JS, for a game's controls...
Who knows?
Custom data attributes are intended to store custom data private to the page or application, for which there are no more appropriate attributes or elements.
These attributes are not intended for use by software that is independent of the site that uses the attributes.
Every HTML element may have any number of custom data attributes specified, with any value.
For Mary Lou's tutorial - this is to control the animation that brings in the menu.
This can be re-assigned to other trigger elements - however the code that makes it live is the DIV element that comes just before - st-trigger-effects.
If you look through the code and the CSS that controls it, you will be able to re-assign that to where-ever you need to use it.
I am currently using this in a bootstrap boilerplate for a University project.
src: http://tympanus.net/codrops/2013/08/28/transitions-for-off-canvas-navigations/

What are "data-url" and "data-key" attributes of <a> tag?

I've faced two strange attributes of an html tag . They are "data-url" and "data-key".
What are they and how can they be used?
For some reasons i can't show the exact example of the HTML file I've found them in, but here are some examples from the web with such tags:
data-key
data-key
data-url
PS: I've tried to Google, but no useful results were found.
When Should I Use the Data Attribute?
Custom data attributes are intended to store custom data private to the page or application, for which there are no more appropriate attributes or elements.
This time the data attribute is used to indicate the bubble value of the notification bubble.
Profile
This time is used to show the text for the tooltip.
This is the link
When Shouldn’t I Use the Data Attribute?
We shouldn’t use data attributes for anything which already has an already established or more appropriate attribute. For example it would be inappropriate to use:
<span data-time="20:00">8pm<span>
when we could use the already defined datetime attribute within a time element like below:
<time datetime="20:00">8pm</time>
Using Data Attributes With CSS (Attribute selectors)
[data-role="page"] {
/* Styles */
}
Using Data Attributes With jQuery (.attr())
Google
$('.button').click(function(e) {
e.preventDefault();
thisdata = $(this).attr('data-info');
console.log(thisdata);
});
Examples and info from here
Those are called HTML5 Custom Data attributes.
Custom data attributes are intended to store custom data private to
the page or application, for which there are no more appropriate
attributes or elements. These attributes are not intended for use by
software that is independent of the site that uses the attributes.
Every HTML element may have any number of custom data attributes
specified, with any value.
The reason why you can't find it in Google is because those attribute are custom attributes generated by user for their own usage.
From seeing your code it seems:
The person who has written this code, wants to store some additional
information with the elements. Not sure he may handle this in
Javascript too.
What you should do is to check the Javascript code completely,
whether he is handling those data attributes or if possible check
with him.
Since you code is using jQuery library, check for .data()
method. After a complete code review, if you find it has no use,
then feel free to remove.
data-* attributes are for adding arbitrary data to an element for use solely by the code (usually client side JavaScript) running on the site hosting the HTML.
In order to tell what the three examples you give are for, we would have to reverse engineer the code that comes with them (unless they are documented on the sites) since they don't have standard meanings.
A new feature being introduced in HTML 5 is the addition of custom data attributes. Simply, the specification for custom data attributes states that any attribute that starts with “data-” will be treated as a storage area for private data (private in the sense that the end user can’t see it – it doesn’t affect layout or presentation). This allows you to write valid HTML markup (passing an HTML 5 validator) while, simultaneously, embedding data within your page. A quick example:
<li class="user" data-name="John Resig" data-city="Boston"
data-lang="js" data-food="Bacon">
<b>John says:</b> <span>Hello, how are you?</span>
</li>

What is this data-folder attribute?

I am seeing an anchor tag with a data-folder attribute. What is this for? I researched it but found no info on it.
Also, I see that it has a data-toggle="dropdown" attribute. I researched that and see that it is a HTML 5 attribute used with the Bootstrap jQuery plugin (dropdown.js). So it's: data-toggle="dropdown".
Departments<span class=" caret"></span>
data-folder is custom made data-* attribute that later is used by some other tool, like CSS or JS/jQuery.
By the name of this attribute folder we can tell that it's indicating some reference to folder on server system (maybe ID of departments group?). Not knowing more about what you use we can't tell exactly.
If you are using one of supportable libraries (like jQuery), than you can use Visual Events to check what events does this specific element has.
This is a Custom Data Attribute as specified in W3C HTML5 specification.
Some libraries have methods developed around these type of attributes for easy storing and retrieval of data. Look at the JQuery .data method. This method retrieves/stores values via data attributes.
In your case the the following statement will return the value 4590.
$('<a>').data('folder')