I got a strange behavior in XPage, with commented Code.
I had a textfield with a lot of code in it which outputs html where I hit this issue.
While developing I had a lot of trouble with some fields other fields so I decided -to get a better idea what the field is doing- to copy the code from the troublefields to a comment inside my textfield to have the other code at my sight. But then the xPage started to behave strange until I found the issue.
The Code below is a example what caused my issue, it has two text fields in it one which sets a scope var and also has a comment which sets the same var but commented, ant another one which shows the ScopeVar. I thought this would output 'where I am' in the second text box but instead I got the 'Huhu I am here'.
<xp:text escape="true" id="computedField7">
<xp:this.value><![CDATA[#{javascript://
sessionScope.put("findme","where i am");
/* #{javascript:sessionScope.put("findme","HuHu I am here!");} */
return sessionScope.findme;}]]></xp:this.value>
</xp:text>
<xp:br></xp:br>
<xp:text escape="true" id="computedField6"
value="#{javascript:return sessionScope.findme;}">
</xp:text>
In my original Code where I hit this issue I wanted to comment the old #{} el out to use a JavaScript instead but keep the el in comment in the middle of the code.. same result. It seams that if you use #{ or ${ in a comment it will always get computed!
Got this fixed in notes 9. I am currently using 8.5.3.
Update:
As a small note: Be careful when using the dojoAttribute queryExpr because the query Looks like SSJS "${0}" and also gets interpreted as SSJS. I now use this:
<xe:this.queryExpr><![CDATA[${javascript:"*$\{0}*";}]]></xe:this.queryExpr>
to make it work. Thanks to Paul Stephen Withers for the tip with the \{.
This is a funny bug.
It is caused by pre-processor functionality of JavaScript interpreter. Normally, you can write #{javascript:...} in CSJS code to replace parts of code before it gets put to rendered page.
In your case it is SSJS. Again, the interpreter replaces the #{javascript:...} inside your SSJS code and thinks, work is done. This way you see the code on rendered page instead the result of executed code.
As a workaround, just delete # from /* #{javascript... and it will work like expected.
Is there a reason for having #{javascript:...} nested inside #{javascript:...} in your example. I'd strongly recommend against that, I wouldn't expect it to give good results.
Please see my answer also to stopping getClientId() computations in JS code. I think you're expecting it to work in a way it's not designed and unlikely to be changed to work.
Properties are just strings read at runtime from left to right. If "#{javascript:", "${javascript:" or "#{.." are found, the resulting code is run. Wrapping "//" around them or "/" and "/" either side has no effect, nor would I expect it to. The whole string is not passed to the parser, just the bit after "#{javascript".
The benefits of this are that you can get better performance by combining languages because only part of it gets passed to the parser and literal string (which is what the "/*" bit is) is just passed to the browser as it is. It means you can include EL and SSJS in a single value. I'm not sure you'd be able to do that if the change you're looking for was made.
For queryExpr, I'd suggest using ${javascript:"${0}"} instead - just escaping the {. See p121 XPages Extension Library.
Related
I am trying to pass arguments to a managed bean.
The bean is configured and works, has two methods "getResponsible" and "setResponsible".
Calling "myLookup.responsible" works.
I cannot pass arguments to my bean, and can't figure out why.
The below code does not work.
<xp:comboBox id="comboBox1">
<xp:selectItems>
<xp:this.value><![CDATA[#{myLookup.setResponsible("Something")}]]>
</xp:this.value>
</xp:selectItems>
</xp:comboBox>
As soon as I type paranthesis ")", "(" or semicolon ";" i get error "Error in EL syntax". I guess I am making some fundamental mistake here.
The version of expression language does not allow parameters to easily be passed. This option may work http://blog.defrog.nl/2012/04/settings-bean-parameterized-method-call.html.
If parameters are required, I usually use SSJS, so:
#{javascript:myLookup.setResponsible("Something");
If the options won't vary during the page's life, you can always compute on page load, so:
${javascript:myLookup.setResponsible("Something");
I think you just made a simple "typo" as Paul stated indirectly in his reply. You wrote Javascript code but did not include the "javascript:" in the beginning of your expression.
If, however, you do want to use arguments with EL then have a look at this very interesting article. I haven't tried it out myself yet (but am going to do shortly) - but the two different examples (have a look at the comments) seem very interesting when you want to use EL. And I prefer EL over SSJS.
/John
when we type into autoComplete, primefaces automatically highlighted first shown item. so when we press enter key that item will be selected. how can i change the behavior of enter key, so when it pressed, just entered text be submitted in backing bean property.
I know we can hit ESC button then continue but but user don't like it.
I am using primefaces 5.0 & jsf 2.1.11
What helped me to solve the same issue where the answers here and here. Basically, you have to override 2 different behaviours.
First one is the default selection of the first result, that can be achieved adding this to your autocomplete (as stated by the accepted answer in the first link, available in primefaces for versions 5.1.5, 5.0.14 and 5.2):
autoHighlight="false"
The second thing you want to override is the behaviour when Enter is pressed, as you want the form that contains the autocomplete to be submitted. For doing so, just add this code to either the containing form or the autocomplete:
onkeyup="if (event.keyCode == 13) {
document.getElementById('[searchFormId]:[submitButtonId]').click();
return false; }"
Change the ids between square brackets for your own ones and it's done.
PS: I know this is a rather old question but it still applies to the current version of primefaces (6.1 when this question was answered). And I also think it can help to have both changes combined in one answer.
Truth be told, this feels like a bug. Richfaces do that implicitly (submit on enter while suggesting). I haven't found an official fix so I did some research and turns out the simplest way is to override the JS function that resolves key presses. The whole autocomplete js is here. You just need to override the bindKeyEvents function so you declare it likewise:
PrimeFaces.widget.AutoComplete.prototype.bindKeyEvents = function () {
Then add the rest of the code for this specific function from the JS I mentioned before. I've omitted that code so it's more readable. Then you want to find a switch that resolves different keys that have some behavior mapped to them. And under the code:
case keyCode.ENTER:
case keyCode.NUMPAD_ENTER:
Add something like:
if (highlightedItem.length == 0) {
document.getElementById("<your_form_id>").click();
_self.hide();
} else {
highlightedItem.click();
}
Also, make sure that you got forceSelection and the autohighlight off on the autocomplete component.
The problem in the JS is that even though you haven't selected any item from the suggestions it still triggers the event that tries to click the item... which doesn't even exist.
This is the simplest way as I said... you can also create your own autocomplete implementation and override the behavior there. But that's a lot of work and if you only need this one feature I suggest overriding the JS function.
In order to override the original JS with your custom one you need to make sure yours is loaded after the original one. To do that you can either use h:outputScript or simply just load the javascript like you're used to... but in the body (not the head).
Also there's probably a fancier way than having to specify the form id. But I just wasted too much time searching for a solution that I had to get it done real fast.
I'm having difficulty getting a dynamicContent control to work the way I would like it. I found this bit of code in pasteBin and I think it might just be what I need, but I would like to understand what it is doing before I try implementing it.
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
xmlns:xe="http://www.ibm.com/xsp/coreex">
<xp:button value="Switch!" id="switchButton">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="dynamicCustomControl">
<xp:this.action><![CDATA[#{javascript:viewScope.controlName = 'cc_test2.xsp';
getComponent('dynamicCustomControl').show(null)}]]></xp:this.action>
</xp:eventHandler></xp:button>
<xe:dynamicContent id="dynamicCustomControl">
<xp:include id="customControlInluder">
<xp:this.pageName>
<![CDATA[${javascript:viewScope.controlName||"cc_test1.xsp"}]]>
</xp:this.pageName>
</xp:include>
</xe:dynamicContent>
</xp:view>
In particular I don't understand the syntax of this line:
<![CDATA[${javascript:viewScope.controlName||"cc_test1.xsp"}]]>
I prefer to use viewScope.get("controlName") rather than the short form viewScope.controlName but I don't understand the significance of the || in this line of code.
also the line
<xp:include id="customControlInluder>
is probably an inconsequential typo.
The process looks fairly simple and would appears that it would do the job for me. Just want to make sure I understand it before going down that road.
Edit and update ---
This very brief code snippet might just be one of the best kept secrets around. I have just worked through it and each of the Custom Controls displayed withing the dynamicCustomControl contains a dynamicContent control. So was able to very nicely embedded a dynamicContent inside a dynamicContent. Which to this point I was never really able to get to work correctly. Now it works very smoothly with minimal fuss & muss. Thanks for the comments and assistance.
The JavaScript code viewScope.controlName||"cc_test1.xsp" returns as result the value of viewScope.controlName if it is not
0
null
undefined
NaN
"" or '' (=empty string)
false
Otherwise it returns "cc_test1.xsp". You can find a detailed explanation here.
This is a short and tricky way of
viewScope.controlName ? viewScope.controlName : "cc_test1.xsp"
or
if (viewScope.controlName) {viewScope.controlName} else {"cc_test1.xsp"}
The id in <xp:include id="customControlInluder"> is not used in code so it doesn't matter how it is called although "customControlIncluder" would sound much better.
I always use the short version for scope variables for getting and setting values and haven't had issues with that yet.
Bill, think it is just saying "use the viewscope control name, and if null then use cc_test1.xsp". If the first case is true, then the second isn't evaluated.
JavaScript OR (||) variable assignment explanation
Inside my "dom ready" function, I create a TabView on an HTML element and call tabview.getTab(0).blah(). Unfortunately every now and then I get an error that tabView.get("tabs") returned null in my javascript console (firefox).
YAHOO.util.Event.onDOMReady(function() {
tabview = new YAHOO.widget.TabView("content");
var tab0 = tabview.getTab(0);
...
tabview.getTab(0) is implemented as tabs.get("tabs")[0].
This happens sometimes but not every time. Does anybody have an explanation for why this happens sometimes? The DOMReady event occurs after the entire DOM is in place but before anything is displayed, right?
Speaking of which, sometimes I see flashing of data in some of the other tabs. That does not bode well I think for the nice, clean experience I was hoping for.
This is YUI 2.7.0/
OK - I believe the answer is, I was trying to use prototype and YUI at the same time. In theory I think that is possible but you need to pick one or the other when it comes to doing things on the "dom:loaded"/onDOMReady events, if you know what I mean.
So I don't know what was happening, but it was some sort of race, and once I picked a single mechanism for doing things when the dom was ready, everything is working fine.
I've been trying to solve this, and have been getting stuck, so I thought I'd ask.
Imagine two ActionBeans, A and B.
A.jsp has this section in it:
...
<jsp:include page="/B.action">
<jsp:param name="ponies" value="on"/>
</jsp:include>
<jsp:include page="/B.action">
<jsp:param name="ponies" value="off"/>
</jsp:include>
...
Take it as read that the B ActionBean does some terribly interesting stuff depending on whether the "ponies" parameter is set to either on or off.
The parameter string "ponies=on" is visible when you debug into the request, but it's not what's getting bound into the B ActionBean. Instead what's getting bound are the parameters to the original A.action.
Is there some way of getting the behaviour I want, or have I missed something fundamental?
So are you saying that in each case ${ponies} on your JSP page prints out "on"?
Because it sounds like you are confusing JSP parameters with Stripes action beans. Setting a JSP parameter simply sets a parameter on that JSP page, that you can reference as shown above, it doesn't actually set anything on the stripes action bean.
The reason that this wasn't working was because of massaging done by our implementation of HttpServletRequest.
It works fine with the "normal" implementation.