JSF2 ValueExpression in h:outputText does not evaluate to true despite same expression does in primefaces p:cellEditor - primefaces

I defined a value expression in 2 tags.
While both are defined as expecting a javax.el.ValueExpression,
<p:cellEditor rendered="#{!row.labelMode.toString().isEmpty()}">
works fine, while
<h:outputText value="#{msgs.pg_fieldMsg}"
rendered="#{!row.labelMode.toString().isEmpty()}"/>
always renders, obviously ignoring the rendered attribute or evaluating it wrongly or different.
LabelMode is an enum (kotlin).
Same is when I replace toString() by name().
This behaviour is independent from server (Jetty ot Tomcat)
Any ideas?

According to
h:outputText to conditionally render groups of JSF elements no longer working in JSF 2?
outputText is the "Wrong Tool™ for the job".
Despite that, the javadoc for outputText still names the render method as operative :-/

Related

Why is the "true" boolean value the "wrong attribute value"?

I have the following button:
<button id="=" style=width:150px;height:150px;font-size:100px; onclick="equalFunction()" disabled="true">=</button>
however in the disabled="true" my IDE recognizes the "true" value to be the "wrong attribut value" does anyone know how to solve this? The code still works, its just annoying to see it be highlighted.
You don't need to set it to true. Do something like this:
<button id="=" style=width:150px;height:150px;font-size:100px; onclick="equalFunction()" disabled>=</button>
According to the HTML5 spec:
A number of attributes in HTML5 are boolean attributes. The presence
of a boolean attribute on an element represents the true value, and
the absence of the attribute represents the false value.
If the attribute is present, its value must either be the empty string
or a value that is a case-insensitive match for the attribute's
canonical name, with no leading or trailing whitespace.
So with a boolean attribute like disabled, it's presence alone is enough and it needs no value, although virtually every web browser will still accept it. Therefore, you should use either disabled (alone) or disabled="disabled"

Polymer hostAttributes Error

I have been following along the Polymer 1.0 Developer guide and I stumbled when getting up to the specific part about hostAttributes.
When I take the example code from the docs:
hostAttributes: {
string-attribute: 'Value',
boolean-attribute: true
tabindex: 0
}
and add it to my prototype, the browser keeps throwing the error:
Uncaught SyntaxError: Unexpected token -
on the lines where there are dashes. Strangely, when I put quotes around string-attribute and boolean-attribute, it renders fine.
Is this an error on my part or is it an error in the docs somehow?
In The way that this example represented string-attribute, string-attribute refers to a string as an attribute that should be set on the label of your element declaration. Also, as you may have noticed by the way you are declaring string-attribute in the example, Javascript assumes that string-attribute is a variable, and variables can not be declared as "my-variable" are declared "myvariable", all strings together.
I think that's the reason why you should declared as follows:
hostAttributes: {
"my-var": 'Value',// Javascript assumes that my-bar is an string
my-var-two: 'value'// Javascript assumes that my-bar-two is a variable (this will fail)
tabindex: 0
}
I hope you have understood me, my English is very bad.
Edit
If a custom elements needs HTML attributes set on it at create-time, these may be declared in a hostAttributes property on the prototype, where keys are the attribute name and values are the values to be assigned. Values should typically be provided as strings, as HTML attributes can only be strings;
hostAttributes: {
string-attribute: 'Value', //string-attribute is a key, should be inside "" because javascript's keys doesn't accepts "-"
boolean-attribute: true//will fail because is not a key
tabindex: 0//this works because for javascript this is a correct key
}
...however, the standard serialize method is used to convert values to
strings, so true will serialize to an empty attribute, and false will
result in no attribute set, and so forth
As you can realize, only serialized string values, never mentioned that the keys are serialized as string as well. As I mentioned before, my English is bad and I understood that.

Is it safe (cross-browser) to omit the value of the contenteditable attribute?

According to W3C spec...
The contenteditable attribute is an enumerated attribute whose keywords are the empty string, true, and false. The empty string and the true keyword map to the true state.
All of the examples and documentation I've found represent the "empty string" as follows:
<div contenteditable="">...</div>
I'm wondering if the following is equally valid (cross-browser) for the sake of cleaner, briefer code:
<div contenteditable>...</div>
It works just fine - at least on current versions of Firefox and Chrome. I'm just wondering if it's valid and reliable cross-browser. My thinking is that it's comparable to form attributes like readonly, disabled, selected, etc - which are commonly and reliably used without assigning a value.
SOLUTION:
Marc B pointed out the following from the W3C spec:
Note that empty attribute syntax is exactly equivalent to specifying the empty string as the value for the attribute.
...which basically confirms the interchangeability of absent and empty values for boolean attributes/properties, meaning both code snippets above are valid and (should be) treated identically across browsers. Thanks to all who answered!
As per the W3C specs:
In the following example, the disabled attribute is given with the empty attribute syntax:
<input disabled>
Note that empty attribute syntax is exactly equivalent to specifying the empty string as the value for the attribute, as in the following example.
<input disabled="">
Now, that's what the W3C says, and then there's what the browser makes read. You can be sure that Internet Explorer will translate/read that as "argle bargle screw the specs woofle" and do its own thing, probably treating "disabled" as "do_the_stupidest_possible_thing_repeatedly=true".
According to WHATWG leaving out the value should lead to inherit, and not true as the empty string does. Being different values, I would say it is not safe.
But if you want clear code, why not write true, since you need to ask this question you can't even read your own code. And I had to look up both what "" does and the missing value default for the attribute, that is not what I would call clear.
Here's a helpful link from Mozilla that should accurately answer your question.
Extract:
According to MDN the contentEditable property when set to true, or an empty string, indicates that the element is editable. Because the contentEditable attribute is enumerated and not Boolean if you leave off the value it is inherited from the parent element.
This is supported back to IE6, Chrome 11, Firefox 3.0 (Gecko 1.9), Opera 10.6, and Safari 3.2.

Setting false value vs. removing an attribute

I was reading something about boolean attribute here, which says that for a boolean attribute (in this particular example, loop attribute of <audio>), whatever value you set, it is going to be recognized as "true". In order to really set to falsy, you cannot set it like loop=false or with javascript as ['loop']=false, but have to remove the attribute such as by doing removeAttribute('loop'). Is this true?
I first believed it, but as far as checked it with Chrome, it seems that setting to ['loop']=false will actually do make it be recognized as falsy. I am not sure how robust this fact is when considered cross-browserly. Is there any difference among browsers?
Boolean attributes are explained here:
http://www.w3.org/TR/html4/intro/sgmltut.html#h-3.3.4.2
Some attributes play the role of boolean variables (e.g., the selected
attribute for the OPTION element). Their appearance in the start tag
of an element implies that the value of the attribute is "true". Their
absence implies a value of "false".
Boolean attributes may legally take a single value: the name of the
attribute itself (e.g., selected="selected").
So, while some browsers may interpret the string "false" as if the value was not set, others may not decide to (which is the correct behavior). Actually, as far as I know (or thought), any non-empty string usually sets the value to on/true (regardless of what the spec says is a legal value). I believe this is also undefined behavior, so this may change as well or be different from browser to browser (don't rely on it).
The bottom line is, just because a browser or two may deviate from the spec doesn't mean that you should. Removing the attribute entirely is the way to go.
Addendum: Looking at your comments and question a little closer, I think you may be confused about attribute values in general. In HTML, attr=false and attr="false" are exactly the same. Quotes are not required in any version of HTML (unless they are needed to remove ambiguity when the value contains spaces). For instance:
<input class=required>
<!-- This is fine -->
<input class=title required>
<!-- this is fine too, but "required" will be parsed as an attribute -->
<input class="title required">
<!-- To have two classes, we need the quotes -->
All attribute values (on elements that have them) are treated as strings. In other words, there is no such thing as a true boolean value (or NULL value) in HTML like there is in javascript.
Just so anyone who needs this in the future:
loop=false remains true unless the entire loop attribute is removed. Basically, the presence of just loop is what a tag needs to do something else. You need to use something like jQuery to remove the entier loop attribute (or at least that's what I would do). Now, if you set a different undefined attribute to false, then you are able to recognize it as false.
The audio element is an HTML5 element, so regarding its meaning, you should consult the HTML5 drafts. In this case, see the definition of boolean attributes in the developer version of the WHATWG draft. It says, in effect, a) that the presence or absence of the attribute determines whether the DOM attribute value is true or false, and b) as a requirement on documents, the value must be empty or (case-insensitively) the attribute name, in this case loop='' or loop="loop". The use of quotation marks around the value are defined elsewhere.
Thus, browsers are required to recognize loop=false to mean the same as loop=loop or loop=true, but authors must not use such constructs, and HTML5 checkers issue error messages about them.
(Basically, you’re supposed to use just loop in HTML serialization of HTML5 and loop="loop" in XHTML serialization.)
Thus, if you have a variable x in JavaScript with an audio element object as its value, x.loop has the value true or false whereas x.attributes['loop'].value indicates the value used in HTML markup (which is usually not interesting as such).
There’s a further complication as regards to Firefox: it still does not seem to support the loop attribute (see the question HTML5 Audio Looping). This means that if you set e.g. loop="loop", x.attributes['loop'].value will be loop but Firefox does not even set x.loop (i.e., it is undefined), still less implement the functionality.
You're confusing strings and real Boolean types. Javascript has a Boolean datatype with two possible values of true and false (without quotes). Strings can contain any text, so can they contain "true" and "false" with quotes. Setting a property to non-null and non-false yields true, so the following will accour:
var a = true; // true
var b = false; // false
var c = "true"; // true
var d = "false" // true
var e = null; // false;
var f = 0; // false
var g = 1; // true
Note the similarities with C.

Conditional HTML Attributes using Razor

The variable strCSSClass often has a value but sometimes is empty.
I do not want to include an empty class="" in this input element's HTML, which means if strCSSClass is empty, I don't want the class= attribute at all.
The following is one way to do a conditional HTML attribute:
<input type="text" id="#strElementID" #(CSSClass.IsEmpty() ? "" : "class=" + strCSSClass) />
Is there a more elegant way of doing this? Specifically one where I could follow the same syntax as is used in the other parts of the element: class="#strCSSClass" ?
You didn't hear it from me, the PM for Razor, but in Razor 2 (Web Pages 2 and MVC 4) we'll have conditional attributes built into Razor (as of MVC 4 RC tested successfully), so you can write things like this:
<input type="text" id="#strElementID" class="#strCSSClass" />
If strCSSClass is null then the class attribute won't render at all.
Further Reading
Jon Galloway - ASP.NET MVC 4 Beta Released!
Conditional Attributes in Razor View Engine and ASP.NET MVC 4
Note you can do something like this(at least in MVC3):
<td align="left" #(isOddRow ? "class=TopBorder" : "style=border:0px") >
What I believed was razor adding quotes was actually the browser. As Rism pointed out when testing with MVC 4(I haven't tested with MVC 3 but I assume behavior hasn't changed), this actually produces class=TopBorder but browsers are able to parse this fine. The HTML parsers are somewhat forgiving on missing attribute quotes, but this can break if you have spaces or certain characters.
<td align="left" class="TopBorder" >
OR
<td align="left" style="border:0px" >
What goes wrong with providing your own quotes
If you try to use some of the usual C# conventions for nested quotes, you'll end up with more quotes than you bargained for because Razor is trying to safely escape them. For example:
<button type="button" #(true ? "style=\"border:0px\"" : string.Empty)>
This should evaluate to <button type="button" style="border:0px"> but Razor escapes all output from C# and thus produces:
style="border:0px"
You will only see this if you view the response over the network. If you use an HTML inspector, often you are actually seeing the DOM, not the raw HTML. Browsers parse HTML into the DOM, and the after-parsing DOM representation already has some niceties applied. In this case the Browser sees there aren't quotes around the attribute value, adds them:
style=""border:0px""
But in the DOM inspector HTML character codes display properly so you actually see:
style=""border:0px""
In Chrome, if you right-click and select Edit HTML, it switch back so you can see those nasty HTML character codes, making it clear you have real outer quotes, and HTML encoded inner quotes.
So the problem with trying to do the quoting yourself is Razor escapes these.
If you want complete control of quotes
Use Html.Raw to prevent quote escaping:
<td #Html.Raw( someBoolean ? "rel='tooltip' data-container='.drillDown a'" : "" )>
Renders as:
<td rel='tooltip' title='Drilldown' data-container='.drillDown a'>
The above is perfectly safe because I'm not outputting any HTML from a variable. The only variable involved is the ternary condition. However, beware that this last technique might expose you to certain security problems if building strings from user supplied data. E.g. if you built an attribute from data fields that originated from user supplied data, use of Html.Raw means that string could contain a premature ending of the attribute and tag, then begin a script tag that does something on behalf of the currently logged in user(possibly different than the logged in user). Maybe you have a page with a list of all users pictures and you are setting a tooltip to be the username of each person, and one users named himself '/><script>$.post('changepassword.php?password=123')</script> and now any other user who views this page has their password instantly changed to a password that the malicious user knows.
I guess a little more convenient and structured way is to use Html helper. In your view it can be look like:
#{
var htmlAttr = new Dictionary<string, object>();
htmlAttr.Add("id", strElementId);
if (!CSSClass.IsEmpty())
{
htmlAttr.Add("class", strCSSClass);
}
}
#* ... *#
#Html.TextBox("somename", "", htmlAttr)
If this way will be useful for you i recommend to define dictionary htmlAttr in your model so your view doesn't need any #{ } logic blocks (be more clear).