I have a simple code that does validation upon click of a button (not a submit button). Whatever data save/processing I want to do, I am doing at the server side via SSJS.
Situation: If I write a simple alert("Hi") under Client events (onCLick), it gives me an alert upon click and proceeds to SSJS.
But if I try to read any field using document.getElementByID("inputText1").value, it does not respond to clicks neither executes alert() which is there after the above line.
Tried to change the way id is passed as #{id:inputText1} also but nothing works.
FYI: I am doing a partialRefresh() on that button event and the only way I have to stop processing the unfurnished data is using cancelPartialRefresh() which is defined below (got this famous code from stack-overflow only).
function cancelPartialRefresh(){
var response = facesContext.getExternalContext().getResponse();
response.setHeader("X-XspRefreshId", "#none");
response.reset();
response.commitResponse();
facesContext.responseComplete();
}
This is not giving any message to user that something is missing but is not letting the refresh from happening though.
Please let me know what I am missing.
document.getElementByID("inputText1").value
doesn't work on CSJS. You have to use
document.getElementByID("#{id:inputText1}").value
with quotation marks. #{id:inputText1} gets calculated on server side and returns the actual id like "view:xxx:inputText1". This id is placed into the client side code and has to be framed with quotation marks so it is a string parameter.
As Knut already mentioned always use the #{id:comp} to get the Id of a xpage component.
Maby you need something like this:
<xp:inputText
id="inputText1"
required="true"
disableClientSideValidation="true">
<xp:this.validators>
<xp:validateRequired message="required!"></xp:validateRequired>
</xp:this.validators>
</xp:inputText>
<xp:message
id="message1"
for="inputText1">
</xp:message>
<xp:button
value="Validate"
id="button1">
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript://Serverside Validate}]]></xp:this.action>
<xp:this.script><![CDATA[var value = dojo.byId("#{id:inputText1}").value;
window.alert("Your value "+value+" will be validatet");]]></xp:this.script>
</xp:eventHandler>
</xp:button>
This code will popup the entered value from the inputText1 before it will sent to the ServerSide Validation. Be aware you have to disable client side Validation otherwise the only message you will get is the "required" message. If you add return false; to the code the serverside Validation will not get executet!
All,
Thanks alot for the responses. Finally I could fix it with the below code from Thomas Adrian.
var subject = x$("#{id:inputText1}").val();
if(subject==""){
alert("Please enter description")
return false
}
Related
UPDATED at bottom...
I have a custom control that contains an input field with typeAhead enabled:
<xp:inputText id="UTAN1" value="#{document1.UTAN}"
maxlength="5" styleClass="dbListFieldData" style="width:60px;font-size:13px;">
<xp:typeAhead mode="full" minChars="2">
<xp:this.valueList><![CDATA[#{javascript:var key = getComponent("UTAN1").getValue();
var path = new Array("","utans.nsf")
#Unique(#DbLookup(path,"(UTAN Lookup)",key,1,"[PARTIALMATCH]"));}]]></xp:this.valueList>
</xp:typeAhead>
<xp:eventHandler event="onchange" submit="true"
refreshMode="partial" refreshId="utanPanel1">
<xp:this.action>
<!-- DO SOME STUFF -->
</xp:this.action>
</xp:eventHandler>
</xp:inputText>
If I use the control inline on an xpage, typeAhead works fine.
However, if I insert the control in a dialog and call it to open:
<xp:link escape="true" id="link3" styleClass="dbListFieldData" >
<xp:eventHandler event="onclick" submit="false" id="eventHandler3">
<xp:this.script><![CDATA[XSP.openDialog('#{id:miniDialogUTAN1}');]]></xp:this.script>
</xp:eventHandler>
<xp:image id="image2" url="/edit2.png" style="height:16px;width:16px;" alt="Edit UTAN"></xp:image>
</xp:link>
The typeAhead seems to be partly crippled.
If the field is already empty, suggestions comes up fine.
If the field has an existing value, backspacing only shows the existing value as a suggestion.
Overwriting the value entirely gives no suggestions at all.
The only thing that will get the typeAhead working is to change the value and hit Enter. Basically, trigger an onChange. After that, ALL the typeAhead fields start working.
Any ideas on how to correct this behavior? FYI, I'm an xpages noob, so please go easy on me.
UPDATE 6/29/2021:
I'm still desperately in need of help with this. I've been playing around with Firebug and found something interesting.
In type-aheads on a normal Xpage form (where type-ahead works), entering each character calls a POST every time. However, when the type-ahead is in a dialog, typing in characters calls GETs. If I hit Enter or tab out of the field (triggering onChange), I get a single POST, and then clicking back into the field and typing, it starts using GETs again and it pulls valid suggestions as long as I don't backspace and type something different. Then the suggestions go away. This would be expected since GETs are cached and POSTs are not.
So what's going on with type-aheads in dialogs that makes them use GET, and how to I force it to use POST on every key press?
To people of the future...
After weeks of fretting over this and finally giving up I stumbled upon the solution by accident.
My dialog opens in read mode. I have both an Edit button and a Cancel button at top and bottom that were originally hard coded in both spots of the dialog custom control. Later I went to clean some stuff up and decided to create a single custom control for both sets of buttons. Once I did that, suddenly the type-aheads worked!
It turns out that when I copied and pasted the XML from the (supposedly) duplicate button panels to the new custom control, I had copied from the bottom button panel (which I rarely used while testing).
When I compared the XML for the top and bottom Edit Buttons, I found that the top one had the following attributes in the onClick:
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
while the bottom one had:
<xp:eventHandler event="onclick" submit="true" refreshMode="partial" refreshId="dialogOuterPanel1">
So, the full refresh broke my type-aheads and a partial refresh fixed them.
It's been 3 weeks since I've been struggling with this problem
onClick eventHandler rejects to show any signs of being working properly when it goes hand in hand with refreshMode="complete"
The code is below:
<xp:button id="begginYOU"
style="float: right; margin-right:20px;"
value="Send">
<xp:eventHandler event="onclick" refreshMode="complete"
submit="true">
<xp:this.action><![CDATA[#{javascript:
print("I will never get this message printed with complete refreshMode");
}]]>
</xp:this.action>
</xp:eventHandler>
</xp:button>
I've tried everything - setting properties of id (on eventHandler itself), adding CSJS code which returns true (the message which I've added to console.log was always printed btw), setting disableValidators to true
I've even tried to remove all the inputs and just leave this one button on the entire page - nothing helped
Whenever I click the button - all I get is just a loading next to the tab's icon in the browser for just half a second and nothing, literally NOTHING happens
It ONLY works with refreshMode and execMode set to partial (provided that I provide ids respectively) but I have no idea why
It really drives me around the bend
But anyway I hope to receive experts' opinion on that problem, because I've run out of ideas
Many thanks in advance
I have SSJS code behind a button. When i click the button that code creates a document in another database.
When i click the button It Works fine but I look at the Domino Admin COnsole I realize that The code behind to button Works twice.. I think When the page is refreshed It Works again? How can i prevent it?
What is it thet I miss?
<xp:button value="Label" id="button1">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:print("Before createNewDoc()");
createNewDoc();
print("After createNewDoc()");
}]]></xp:this.action>
</xp:eventHandler></xp:button>
Add print statements to the beforePageLoad, afterPageLoad etc events to confirm where it is running. Also, it's worth using XPages OpenLog Logger or some other logging framework that can output a full stack trace. That might identify whether the code is running twice in the refresh, and where from.
There is no reason the code should be running twice from the button. I'm assuming this is an SSJS function in a Script Library, maybe something else is triggering that.
I'm setting value of input field on click event of the check box. The editable field is used to validate group of check boxes. This code works in one xpage. When I tried to replicate this code in other xpage, it is not working.
Here is a working code:
<xp:checkBox
text="pH"
id="checkBox1"
value="#{document1.PH}"
checkedValue="pH">
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="partial"
refreshId="routineSectionInput1"
execMode="partial">
<xp:this.action>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:var
checkBox1:com.ibm.xsp.component.xp.XspInputCheckbox = getComponent("checkBox1");
var routineSectionInput1:com.ibm.xsp.component.xp.XspInputText = getComponent("routineSectionInput1");
if (checkBox1.getValue()=='pH'){
routineSectionInput1.setValue('Selected');
} else {
routineSectionInput1.setValue('');
}}]]></xp:this.script>
</xp:executeScript>
</xp:this.action>
</xp:eventHandler>
</xp:checkBox>
I used same field names and same code on another xpage and it is not working. What I'm doing wrong?
Best regards
When you work with component logic where binding is involved, don't go after the component, go after the data that defines their value. So your code would rather look like this:
<xp:checkBox text="pH" id="checkBox1"
value="#{document1.PH}" checkedValue="pH">
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="partial"
refreshId="routineSectionInput1"
execMode="partial">
<xp:this.action>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:var chkValue = document1.getItemValueString("PH");
viewScope.routineSection = (chkValue=="pH") ? "Selected" : "";
}]]></xp:this.script>
</xp:executeScript>
</xp:this.action>
</xp:eventHandler>
</xp:checkBox>
<xp:text id="routineSectionInput1" value="#{viewScope.routineSection}"></xp:text>
Hope that helps
If there are validation errors or components have data that is of the wrong data type (e.g. text that cannot be parsed as a number in a component bound to a Number field, so conversion errors), any SSJS will fail.
I'd recommend adding a print statement at the start of the SSJS to check whether it's firing. (If you're more confident with XPages, use a PhaseListener to check the correct phase is being triggered).
Also, it's worth adding an Display Errors control to catch any validation errors caught during the partial refresh, ensuring it's within the refresh area (otherwise the errors will not be displayed in the browser).
"Process data without validation" option may be of use here, it you want to skip validation. Note that conversion errors will still prevent SSJS running.
As Stephan says, use the datasource rather than the component, if possible. The datasource will have been updated before the SSJS fires.
Removed the checkboxes, compacted the database with -c and added back those checkboxes with the same code. It is working now.
to perform a fulltext search users want to simply enter their query into a simple inputText. Then as soon as they hit ENTER the search itself should kick in.
Currently we tried to solve it like this:
the inputText is bound to a sessionScope variable myQuery
the input also has an OpenPage action bound to its onchange event
the page that is to be opened contains a viewPanel with a search filter bound to our sessionScope variable, as well as some more FT filtering fields.
This works fine in Firefox and Chrome but not in IE; obviously IE isn't recognizing the ENTER key as an onchange-trigger.
So I tried to record and analyze the keystrokes using the control's onkeyup event using something like
var q=sessionScope.get("myQuery");
return q.charCodeAt(q.length-1);
Works fine for all standard characters, but not for the ENTER key (where I would have expected to receive code 13).
I currently do have some kind of workaround using CSJS code in the control's onkeyup event as in:
if(event.keyCode===13){
var p=location.pathname.split("/");
p.pop();
location.replace(p.join("/") + "/search.xsp");
}
But this has some side effects which has some potential to make things more complicated, and it feels a bit like some hack. So I'd prefer to solve it using server side scripting.
Question is:
is there a way to capture an ENTER key stroke so that we can react to it?
or are we maybe on a completely wrong track here?
In IE the onchange event is not fired until the input loses focus: http://komlenic.com/231/internet-explorer-onchange-on-enter/
So you could use some CSJS to catch the ENTER press in IE, and drop focus from the input using .blur() method, which will in turn trigger the onchange event
A quick example I tried out that seems to work:
<xp:inputText id="inputText2" value="#{document1.text1}">
<xp:eventHandler event="onkeyup" submit="false">
<xp:this.script><![CDATA[
var kc = thisEvent.keyCode?thisEvent.keyCode:"";
if(kc != "" && kc == "13") {
var input = dojo.byId("#{id:inputText2}");
input.blur();
}]]>
</xp:this.script>
</xp:eventHandler>
<xp:eventHandler event="onchange" submit="true" refreshMode="complete">
<xp:this.action>
<xp:openPage name="/formInput.xsp"></xp:openPage>
</xp:this.action>
</xp:eventHandler>
</xp:inputText>