Html attribute containing empty string doesn't show = operator - javascript

One use case is in jQuery:
$select.append('<option value="">All</option>');
It looks like it actually adds the element in HTML:
<option value>All</option>
Instead, what I want is to append to the element so that it gives an empty string to value:
<option value="">All</option>
Why doesn't that happen?

It actually add the element in HTML
No, it doesn't.
It adds the element to the DOM, not to the HTML.
When you look at the DOM, using your browser's developer tools, it will displayed using HTML-like syntax. In this syntax, a value attribute where the value is an empty string will be rendered without the ="" portion. (It is looking like that part of the syntax is actually valid HTML, but I haven't found the part in the spec which allows it.)
If you were (to use Chrome as an example), you could right click on its parent element and pick "Edit as HTML" at which point you would see the ="" again.
If you were to submit the form containing the select element you would see that the data sent would be: select_name=. This shows that the value was correctly set to an empty string. If it had not worked you would have got select_name=All since the element's text is used as the value if no value is set.

Your question seems to indicate a degree of confusion as to the meaning of the syntax in question. Based on the fact that the occurrence of value in your tag lacks a ="", you're inferring that this represents an HTML "value" element - that's not the case. What's actually happening here has to do with the fact that there's multiple ways in which the value of an HTML attribute can be represented. Let's explore those formats, to better understand what you're seeing.
Valid formats for HTML Attributes
The most common way you'd represent, say, a value attribute would be with quotes, as follows:
value="something"
However, if you look at the section of the HTML5 spec regarding attributes, it's actually also valid to represent attribute values in four different ways:
empty attribute syntax
unquoted attribute-value syntax
single-quoted attribute-value syntax
double-quoted attribute-value syntax
The format that specifically speaks to your case is "empty attribute syntax". Reading further, the spec describes the Empty Attribute syntax as follows:
Just the attribute name. The value is implicitly the empty string.
There's also a slightly more detailed explanation on the historical HTML 5 reference for attributes:
Certain attributes may be specified by providing just the attribute
name, with no value.
In the following example, the disabled attribute is given with the
empty attribute syntax:
<input disabled>
Note that empty syntax is exactly equivalent to specifying the empty
string as the value for the attribute, as in the following example.
<input disabled="">
As you're seeing, this means that for an HTML element, when representing a property with no value, the ="" is optional. As such, some browsers will just display the property without that unnecessary markup. Whether the property is rendered as value or value="", any standards compliant browser will know that value is a property which holds a string, so it will therefore always return either that property's contents, if any, or at minimum an empty string in absence of explicit contents.

$select.append($('<option>', { value: "", text: "All" }));

Related

How to check if an attribute is a Boolean attribute?

Is there any way to check if some HTML attribute are Boolean? for example:
<input type="text" name="input" disabled=""/>
Here the disabled attribute is Boolean, I have some code and I need check before setting value whether that attribute is Boolean or not.
Why I need this?
As mentioned here we can have either "" or property name itself as the valid value not true or false.
There's basically no distinction on the level of HTML. If the attribute is simply the name without value, e.g. <input disabled>, that's a sure sign that it's a boolean attribute. However, if it's using the name="value" notation, then there's no way to distinguish it. Is class="class" a boolean attribute? No, it's a classList with one entry "class". How about foo=""? Well, it's either a boolean attribute opting for the empty-value notation, or it's an attribute with no value set.
Only the interpreter assigns boolean-ness to an attribute; i.e. while parsing the HTML into a DOM, the interpreter sets DOM attributes like this, roughly speaking:
domElement.disabled = htmlElement.hasAttribute('disabled');
If you want to know what HTML elements are booleans, you need to do the same thing an interpreter does: keep a list of DOM elements whose attributes have types and interpret the HTML according to that specification.
To solve this issue, you have the typeof operand in the following way:
var check_input = document.getElementById("check-input");
if(typeof(check_input.disabled) === "boolean"){
alert('Yes');
}
Here is a JSfiddle with the complete code. I hope that my answer can help you!

will input default to a type of text?

So I have a rather random question but here we go. I am working on some trickery with Javascript for a plugin. Say I have an input that looks like this:
<input type='cc' id='cc' class='' />
Obviously the type cc is not a valid input type. Does html automatically just default the unknown type to text, or will it have an adverse effect?
Quoting directly from W3.org
An input element with no type attribute specified represents the same thing as an input element with its type attribute set to "text".
If the value of the input type is not known or not supported in the browser, it'll default to "text".
tl;dr: If you pass an invalid value for an enumerated attribute, it will use the invalid value default instead. If that doesn't exist, it will use the missing value default instead.
The input type attribute doesn't define a invalid value default, but it defines a missing value default, which is text.
Hence using an invalid value will default to text.
From the WHATWG HTML spec:
2.4.3 Keywords and enumerated attributes
Some attributes are defined as taking one of a finite set of keywords. Such attributes are called enumerated attributes. [...] In addition, two default states can be given. The first is the invalid value default, the second is the missing value default.
[...]
If the attribute value matches none of the given keywords, but the attribute has an invalid value default, then the attribute represents that state. Otherwise, if the attribute value matches none of the keywords but there is a missing value default state defined, then that is the state represented by the attribute. Otherwise, there is no default, and invalid values mean that there is no state represented.
<input> specifies a missing value default, which is text:
The missing value default is the Text state.

Why are directly assigned attributes ignored by document.querySelector()?

I've recently discovered a very fundamental difference between the 2 methods of setting custom DOM attributes in Javascript. The difference is in how the HTML5 Selectors API interacts with those attributes (ie, in document.querySelector() and friends).
<button id="b3">View</button>
<script>
document.getElementById('b3').shape = 'square';
console.log( document.querySelector('*[shape]') ); // FAIL: returns null
document.getElementById('b3').setAttribute('shape','square');
console.log( document.querySelector('*[shape]') ); // WORKS: returns element
</script>
So basically if you apply attributes to an element without using .setAttribute() then you cannot later select the element by the attribute name.
BTW. This behaviour is consistent across browsers which makes me think it might be addressed by the standard, however I can't see it:
http://www.w3.org/TR/css3-selectors/#attribute-selectors
http://www.w3.org/TR/selectors-api/
The selectors API standard doesn't appear to care:
Selectors allow the representation of an element's attributes. When a
selector is used as an expression to match against an element,
attribute selectors must be considered to match an element if that
element has an attribute that matches the attribute represented by the
attribute selector.
The entire attribute matching rule seems to boil down to "if the element has an attribute" and you would think that someElement.someAttribute = something would meet the criteria of "having an attribute" but for whatever reason it doesn't.
My question is basically why the difference? Is it actually part of a standard or just an identical implementation quirk in all the major browsers (IE11, FF38 and Chrome 43)?
The reason is very simple - getElementById and all of those kind return an Element Object (see specs: http://www.w3schools.com/jsref/met_document_getelementbyid.asp)
Which means you set property shape on an object. Then you try to do a query selector, but you haven't modified the html that's queried. They are different things.

HTML: Can always the same identifier be used for name and id attributes?

Basically the "name" attribute is used in server-side programming (name/value pairs are sent in requests) and the "id" attribute is used in client-side programming (i.e. Javascript and CSS).
But both fulfill essentially the same function - provide a unique identification of an element. And to complicate things not too much, it is useful if a thing has only one identifier.
Therefore the question(s) - for tags that need both "id" and "name":
Is there any reason to choose different identifiers for the name and id attributes? Are there any use-cases for which different identifiers are required? Are there any differences in syntax? (for example you can use "myarray[123]" for the name attribute and PHP will understand that correctly and create an array, can that also be used in a similar manner for id-attributes in Javascript or CSS - and if not, is that a syntax-error or is it simply a valid identifier with brackets in it?) Are both case-sensitive?
Is there any reason to choose different identifiers for the name and id attributes?
Yes. IDs must be unique, names don't have to be. Names must be the same for members of a radio group, so they can't all have the same id—well, they can in practice but accessing the elements by ID will be problematic. And if you don't access them by ID, why have it?
Are there any use-cases for which different identifiers are required?
Yes, radio buttons. Only one can have an id that is the same as its name. But otherwise, there are few restrictions, such as than never give form controls the name or id of a method or property of the form itself, like "submit", as it will mask the same–named property of the form.
Also, names "_charset_" and "isindex" are special.
Are there any differences in syntax? (for example you can use "myarray[123]" for the name attribute and PHP will understand that correctly and create an array, can that also be used in a similar manner for id-attributes in Javascript or CSS - and if not, is that a syntax-error or is it simply a valid identifier with brackets in it?)
Yes. The rules for name and id attribute values are similar but an ID must not contain spaces (and some values for name are special, see above). There were more restrictions on id attributes in HTML4 (e.g. ids couldn't start with a number), but in practice they weren't implemented in browsers.
Some characters that are valid in names and ids must be quoted to use as CSS selectors, e.g. for:
<div id="d[]">
the CSS selector is:
#d\[\]
and for use with the Selectors API:
#d\\[\\]
(e.g. document.querySelector('#d\\[\\]').
Are both case-sensitive?
Yes.
To answer the question in the title: Yes, whenever the syntax of an element allows a name attribute, its value may be identical with the id attribute value. This follows from the declarations of the name attribute: its value is any string, and the only constraint imposed relates to the a element; and for it, the requirement is that the name attribute value must not match the id attribute value of another element (but must match the id attribute value of the same element if present).
To address the assumptions in the question: The name attribute in form field elements is indeed primarily for server-side processing; but various other elements may have a name attribute, for different uses. The id attribute is helpful in client-side programming, but it also has the effect of creating a destination anchor so that the element can be referred to by a link in the same document or another document. There is technically no tag that “needs” both id and name, or even one of them; whether they are used depends on practical purposes. The name attribute is not required to be unique, and it is not meant to provide unique identification. You can, for example, have an arbitrary amount of input elements with the same name attribute.
The syntax of id has traditionally been restricted in HTML specifications, but browsers have been much more permissive, and HTML5 PR imposes no other restrictions than the following: the value must not be empty (i.e. it must contain at least one character), it must not contain space characters, and it must be unique within the document (i.e. no two elements can have the same id attribute value).
The syntax of name has always been free. Apart from the special rules for the a element, the only restriction is that the value must not be empty.
Both id and name attribute values are case-sensitive. The special rules for the a element impose restrictions involving case-insensitivity, for legacy reasons.
There are many possible reasons why you might want to make id and name different for an element. For example, when interfacing to an existing server-side script that requires very long and complicated names for the fields, you have to use them in name attributes, but you are free to choose your id attributes.
The choices made when writing id and name attribute values have their consequences, but they depend on the contexts where the values are used. For example, if an id attribute value starts with a digit, it cannot be directly used in a CSS selector due to CSS syntax (but must be escaped). Similarly, the ways you can use the values in JavaScript depend on the syntax you have used, but you can always refer to them some way.
name attribute usually doesn't need to be unique. A given HTML document may have several forms, and each of them might have elements having names identical to names in the other forms.
If you're using PHP, saying:
<form>
<input type="text" name="foo[]" />
<input type="text" name="foo[]" />
</form>
would cause, PHP to read this name as array and all entries will contained within it. Names could possibly be used as attributes for non-form elements, however, they're most frequently used only within form.
id attribute on the other hand, needs to be able to uniquely identify a given DOM element within the document. You're not forced to use it this way. Browser doesn't blow up if you use same id on two different elements. But if you have two elements with same id, the last one you add prevails over the previous ones. So,
document.getElementById( 'foo' )
// or
$( '#foo' )
will return just one element of several.
id can be used to identify any element within the document and is not constrained to be within a form

How to read all style properties a browser supports

I made a simple Javascript routine that reports all the style properties present in a browser.
var list = new Array();
var div = document.createElement('div');
for (var style in div.style)
list.push(style);
And it works. The results are in JavaScript format, so for instance borderTopLeftRadius means the CSS property border-top-left-radius, MozAnimationTimingFunction means -moz-animation-timing-function and so on.
Here is a fiddle where you can see it live.
(The list is flawed, by the way. For instance, in Firefox and IE, the list doesn't even contain float, but it does in Chrome. Firefox and IE have cssFloat. Oh well, I can live with that.)
So far, so good.
However, my goal is to have only a list of CSS property names. But the results also include entries that are not property names at all, like getPropertyPriority and length. And my question is, how can I filter these out? How to differentiate between these entries (some are Javascript functions, some are read-only properties) and the actual CSS property names?
Edit:
I don't mind about the properties that apply to SVG only; it's OK to keep those.
Also, while most of the offending ones can be filtered out by checking if the property has type 'string' as Mr_Green pointed out (see updated fiddle), there are still some entries in the list that are not CSS property names, such as cssText and marks (the latter only in some browsers). I want to filter those out as well, but haven't found a way to do so.
The W3C mentions a function called supports() but I haven't been able to make that work. Can anybody find me an example?
I don't know if your goal is to check whether a property is supported or not but
function isPropertySupported(property)
{
return property in document.body.style;
}
can check whether a property is supported or not. I hope it helps. Correct me if I am wrong.
Check whether a CSS property is supported or not
EDIT:
Check this out CSS Supports
supports(DOMString property, DOMString value), returns boolean
supports(DOMString conditionText), returns boolean
When the supports() method is invoked with two arguments property and value, it must return true if property is a literal match for the name of a CSS property that the UA supports, and value would be successfully parsed as a supported value for that property. (Literal match means that no CSS escape processing is performed, and leading and trailing whitespace are not stripped, so any leading whitespace, trailing whitespace, or CSS escapes equivalent to the name of a property would cause the method to return false.) Otherwise, it must return false.

Categories