QueryDocumentDelete in Xpages - xpages

The QueryDocumentDelete in Database script only seems to run from the Notes UI client when a document is deleted. Is there a similar event when a document is deleted with the Delete Selected Documents simple action?

You're right, QueryDocumentDelete in database script is a Notes UI function and runs only from the Notes client.
Unfortunately, there is no similar event in simple action Delete Selected Documents.
An easy workaround is to write the whole functionality of "Delete Selected Documents" on your own. This way you can do things you want to before documents get actually deleted or prevent certain documents from deletion.
Here is a sample code for a button "Delete Selected Documents" which deletes documents in a view panel (with id "viewPanel1"):
<xp:button
value="Delete Selected Documents"
id="button1">
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="complete">
<xp:this.script><![CDATA[
if(!XSP.isViewPanelRowSelected("#{id:viewPanel1}", "_colcbox")){
XSP.alert("Please select one or more documents to delete.");
return false;
}
if (!XSP.confirm('Are you sure you want to delete selected documents?')){
return false;
}]]></xp:this.script>
<xp:this.action><![CDATA[#{javascript:
var viewPanel = getComponent("viewPanel1");
var selectedIds = viewPanel.getSelectedIds();
for(i=0; i < selectedIds.length; i++) {
var docId = selectedIds[i];
var doc = database.getDocumentByID(docId);
// do things here you would do on QueryDocumentDelete
doc.remove(true);
doc.recycle();
}}]]></xp:this.action>
</xp:eventHandler>
</xp:button>

Related

Xpages - Document refreshing with old values

I have some code, that if a user selects a "NO" answer on a certain field (Q1), it removes the answers of sub question related to Q1, and also hides them in the UI.
This works fine, and I do a partial refresh on the div containing all the questions. However, when I then click on the same question selecting answer "Yes" which then shows all the sub questions, so the user can answer them again, they still have the old values attributed.
When I remove the fields, the backend document reflects this correctly, but then when I click the question which then shows the fields again in the UI, they appear in the backend document again, with their original value. If I do a context.reloadPage() at the end of my code, everything works as expected, but this breaks other functionality and I only want a partial refresh. Any ideas? Thanks
try{
if (compositeData.onClickCode) {
compositeData.onClickCode.invoke( facesContext, null );
}
document1.save();
var fieldName:string = compositeData.fieldName;
//Blank all IFM fields if user selects no IFM *CHANGE FIELDS ARRAY TO GET FROM KEYWORD*
if (fieldName == "Q1") {
print("Yes Q1");
if(document1.getItemValueString(fieldName)=="No") {
print("NO IFMS");
var questionsIFM = ["Q1a", "Q1b", "Q1c", "Q3IFM", "Q3bIFM", "Q3cIFM", "Q3dIFM", "Q4", "Q4a" ,"Q5IFM", "Q6IFM", "Q6aIFM", "Q7IFM",
"Q7aIFM", "Q7bIFM", "Q8", "Q8a", "Q9IFM", "Q9aIFM", "Q9bIFM", "Q10IFM", "Q11IFM"];
var len = questionsIFM.length;
for (i = 0; i < len; i++) {
print("Field Name: " + questionsIFM[i]);
document1.removeItem(questionsIFM[i]);
}
document1.save();
//context.reloadPage();
}
}
var guidanceOptions:string = "";
if (compositeData.guidanceOptions) {
if(#IsMember(document1.getItemValueString(fieldName), compositeData.guidanceOptions)){
guidanceOptions = document1.getItemValueString(fieldName);
}
}
viewScope.guidance = compositeData.fieldName+guidanceOptions;
}catch(e){
openLogBean.addError(e,this.getParent());
}
Instead of changing the backend document you could update the datasource with doc.setValue('fieldName','')
Alternativly, you could change the scope of the datasource to "request", this forces the datasource to reload the backend document for every request.
EDIT:
Here is an example for updating the datasource directly (Button 'Clear') which always works and updating the component (Button 'Update').
If the button 'Reload' is clicked, changes to in the fields are "stored" in the component. The button 'Update' does a partial refresh (which hides the input field), so the value is lost.
<?xml version="1.0" encoding="UTF-8"?>
<xp:view
xmlns:xp="http://www.ibm.com/xsp/core">
<xp:this.data>
<xp:dominoDocument
var="document1"></xp:dominoDocument>
</xp:this.data>
<xp:div
id="refreshMe">
<xp:inputText
id="inputText1"
value="#{document1.foo}"></xp:inputText>
<xp:inputText
id="inputText2"
value="#{document1.bar}"
rendered="#{javascript:facesContext.isAjaxPartialRefresh() == false}">
</xp:inputText>
</xp:div>
<xp:button
value="Update"
id="buttonUpdate">
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="partial"
refreshId="refreshMe">
</xp:eventHandler>
</xp:button>
<xp:button
value="Clear"
id="buttonClear">
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="partial"
refreshId="refreshMe">
<xp:this.action><![CDATA[#{javascript:document1.setValue('foo', '');document1.setValue('bar', '')}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:button
value="Reload"
id="buttonReload">
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="complete">
</xp:eventHandler>
</xp:button>
</xp:view>
I might be late to this party, but I found a way to force a reload from the back-end document. All you have to do is change the id for the dataSource a little, by adding or removing a "0" prefix to the documentId. Something like this:
return (viewScope.idPrefix? "0":"") + param.documentId
and when you want to force a reload during a partial refresh, just set
viewScope.idPrefix= !viewScope.idPrefix;
Don't forget to set ignoreRequestParams to true.

How to pass variable from CSJS to SSJS in read mode

I want to be able to prompt the user for a comment and then be able to send this variable comment in an email. However, I'm unable to pass that variable from CSJS to SSJS. My document is in read mode.
Here is a sample button code where I can't seem to pass my comment.
Does anyone know how to do this?
Thanks in advance :)
<xp:panel readonly="false">
<xp:inputHidden id="inputHidden1" value="#{viewScope.tester}">
</xp:inputHidden>
</xp:panel>
<xp:button value="Reject" id="button7" style="margin-right:5.0px"
save="false">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action>
<xp:actionGroup>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:var doc:NotesDocument = currentDocument.getDocument();
doc.replaceItemValue("status", "0");
doc.save();
database.updateFTIndex(false);
var comment = viewScope.tester; /* HOW DO I GET COMMENT FROM CSJS TO HERE */
var ndoc = database.createDocument();
ndoc.appendItemValue("from", "tome#somewhere.com");
ndoc.appendItemValue("SendTo", "someone#somewhere.com);
ndoc.appendItemValue("subject", "My Subject");
var rti:NotesRichTextItem = ndoc.createRichTextItem("Body");
rti.appendText("Reason:" + comment + "\n\n");
ndoc.send()
}]]></xp:this.script>
</xp:executeScript>
<xp:openPage name="/mainpage.xsp"></xp:openPage>
</xp:actionGroup>
</xp:this.action>
<xp:this.script>
<xp:executeClientScript>
<xp:this.script><![CDATA[
var comment = XSP.prompt("Please enter a comment:");
XSP.getElementById("#{id:inputHidden1}").value = comment;
/*
XSP.partialRefreshGet("#{id:computedField1}",
{
params:{"para1":"1", "para2":"2"}
});
*/
]]></xp:this.script>
</xp:executeClientScript>
</xp:this.script>
</xp:eventHandler>
</xp:button>
XSP.prompt will use the default browser prompt window. You will have limited functionality from it and, in my opinion, not a great user experience. I would recommend having your reject button open an XPages Extension Library dialog with an Edit Box to enter the comment. Bind the Edit Box to a requestScope variable - you won't need the value after the dialog closes, so you would need it at a higher scope level. In the "OK" button of the dialog run your SSJS and use the SSJS hide() method of the Dialog component to close the dialog, adding a parameter for a component on the page if you need to partially refresh it.
Don't bind that field to your document (in read mode). Bind it to viewScope or requestScope variable.
Also, look here for inspiration.
To accomplish this in the past, I have used CSS to hide the input fields and buttons. The client-side script is defined separately from the button actions.
<xp:text escape="false"><xp:this.value><![CDATA[
<script>
function promptBox(){
// ... do whatever to get the data input into
// XSP.getElementById("#{id:inputText1}").value
// OR if using JQuery $('.tester).val()
// then click hidden Save button
$('.reject').click()
// OR
XSP.getElementById("#{id:button1}").click()
}
</script>
]]></xp:this.value></xp:text>
<!-- hide the input field with CSS -->
<xp:inputText
id="inputText1"
value="#{viewScope.tester}"
defaultValue="#{viewScope.tester}"
styleClass="tester hidden">
</xp:inputText>
<!-- hide the button with CSS -->
<xp:button
value="Reject"
styleClass="reject hidden"
id="button1">
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action>
<xp:actionGroup>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:var doc:NotesDocument = currentDocument.getDocument();
doc.replaceItemValue("status", "0");
doc.save();
database.updateFTIndex(false);
var comment = viewScope.tester; /* scoped variable already set */
var ndoc = database.createDocument();
ndoc.appendItemValue("from", "tome#somewhere.com");
ndoc.appendItemValue("SendTo", "someone#somewhere.com);
ndoc.appendItemValue("subject", "My Subject");
var rti:NotesRichTextItem = ndoc.createRichTextItem("Body");
rti.appendText("Reason:" + comment + "\n\n");
ndoc.send()
}]]></xp:this.script>
</xp:executeScript>
<xp:openPage name="/mainpage.xsp"></xp:openPage>
</xp:actionGroup>
</xp:button>
<!-- use link for button - style it with CSS -->
Reject
I do not like having both client-side and server-side scripts bound to the same button, the execution order of the code is not easily managed. There are other ways to combine these client side fields and server side scripts, but this is a simple demonstration.

XPages typeahead: do like Google

UPDATE
This is now what I have in my xpage:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:panel id="ContainerPanel">
<xp:inputText id="typeAhead">
<xp:eventHandler event="onchange" submit="true"
refreshMode="norefresh">
<xp:this.action><![CDATA[#{javascript://code here to trap the click in the list of values
//displayed by the type ahead. Code redirects to another page
//the goal here would be to avoid the full/partial update and only use the CSJS
//code to trigger the button's partial/full refresh so we can avoid having the onchange code
//trigger a refresh when the user decides to click the button instead of clicking on a suggestion
//that is offered by the typeahead
//I thought of using the temporary field and use it to store the value selected in the type ahead list,
//so the code knows wheter we are running the CSJS from the type ahead list or from the button (the onchange
//of the type ahead will fill this field so we know wether to trigger the CSJS partial refresh }]]></xp:this.action>
<xp:this.script><![CDATA[var selectedValue = document.getElementById("#{id:typeAhead}").value;
var targetField = document.getElementById("#{id:temporaryField}");
alert("typeAhead CSJS onchange: " + selectedValue);
targetField.value = selectedValue;
//init the partial refresh here!!!]]></xp:this.script>
</xp:eventHandler>
<xp:typeAhead mode="partial" minChars="2">
<xp:this.valueList><![CDATA[aaaa
bbbb
cccc
dddd]]></xp:this.valueList>
</xp:typeAhead></xp:inputText>
 
<xp:button value="GO" id="button1">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript://same call to the code called in the onchange event of the typeahead field
mySSJSFunction();}]]></xp:this.action>
</xp:eventHandler></xp:button>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:inputText id="temporaryField"></xp:inputText>
</xp:panel>
</xp:view>
Because the problem comes from the fact that the typeahead's onchange event is triggered even though the user just wants to type in something and go click on the button (therefore triggering the partial update of the event, so the code can call a SSJS function), I thought I'd get rid of the type ahead field's partial update and try to trigger it manually from CSJS.
I am trying to use a temporary field to store the value selected in the type ahead so I can figure out if I need to run the SSJS function right away (the user selected a value in the list) or just don't do nothing as the user just wants to go and click on the button.
Unfortunately, the code is at the office and I'm home right now, but the comments in the above code should give an idea of what I'm trying to achieve.
Not sure either if I should use XSP._partialRefresh(), XSP.PartialRefreshGet() and which control ID should I use (if it has any importance).
Hope it all makes sense... Just trying to give the user the possibility to select a value in the type ahead list, or type something in the field and click the search button, both cases calling the same SSJS function (using either the value selected in the type ahead list or what has been typed in the field).
FIRST POST
I have a page with a field and a button, just like the Google page. I have type ahead set up so it returns a list of documents title that correspond to the "search" term entered. Because I want the application to load a page when the user clicks on an item from the type ahead list, I added some code to the onChange event of the type ahead field. That works great, but...
Let's say a user wants to go ahead and click on the button anyways, because the list displayed by the type ahead field only show the top 10 search results, and the document he is looking for is not in that list, so he wants to trigger a "full search" by clicking on the search button. What happens is that the onchange code of the field is triggered before the onclick code of the button, and due to a fullrefresh on the type ahead field, this triggers a page refreshand the user needs to click a second time on the button to actually open the search page.
The question is quit esimple: how can I get the same behaviour as the Google page, opening up the page if I click on one of the suggestions, but also opening up a search page/search results page when clicking on the button?
Here is the code so far:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
xmlns:xc="http://www.ibm.com/xsp/custom"
xmlns:xp_1="http://www.ibm.com/xsp/coreex" dojoParseOnLoad="true">
<xp:this.resources>
<xp:script src="/xpSortedSearches.jss" clientSide="false"></xp:script>
<xp:script src="/xpadSearch.jss" clientSide="false"></xp:script>
<xp:dojoModulePath loaded="true"
url="/xsp/.ibmxspres/dojoroot/dojo/dojo.js">
</xp:dojoModulePath>
</xp:this.resources>
<xp:panel id="PanelSearch" style="text-align:right;">
<xp:inputText id="inputSearch"
style="width:225px;height:20px;font-size:10pt;font-family:sans-serif;padding-left:5.0px;padding-top:5.0px;padding-bottom:2.0px; border:1px solid gray;"
tabindex="0" disableClientSideValidation="false"
disableModifiedFlag="true">
<xp:this.attrs>
<xp:attr name="placeholder">
<xp:this.value><![CDATA[#{javascript:if(sessionScope.lang=="fr") {
"Entrez votre recherche ici ...";
} else {
"Enter your search query here...";
}}]]></xp:this.value>
</xp:attr>
</xp:this.attrs>
<xp:typeAhead mode="full" minChars="3" valueMarkup="true"
var="searchQuery" ignoreCase="true">
<xp:this.valueList><![CDATA[#{javascript://TODO Memory management???
getTypeAheadValuesFromSearchBar(getComponent("inputSearch").getValue());}]]></xp:this.valueList>
</xp:typeAhead>
<xp:eventHandler event="onchange" submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:var key:String = getComponent("inputSearch").getValue();
if(!!key) {
getDocFromSubject(key);
}
}]]></xp:this.action>
<xp:this.script><![CDATA[showStandBy();
return true;]]></xp:this.script>
</xp:eventHandler>
<xp:eventHandler event="onkeypress" submit="true"
refreshMode="complete">
<xp:this.script><![CDATA[//if we have a enter, launch the search
if (thisEvent.keyCode==13) {
var qryField = document.getElementById("#{id:inputSearch}");
if(doSearch(qryField)) {
showStandBy();
return true;
} else {
return false;
}
}else{
return false;
}]]></xp:this.script>
<xp:this.action><![CDATA[#{javascript:launchSearch();}]]></xp:this.action>
</xp:eventHandler>
</xp:inputText>
<xp:button id="button1" icon="/search.png"
styleClass="searchButtonSmall">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.onStart>
StandbyDialog_Started();
</xp:this.onStart>
<xp:this.action><![CDATA[#{javascript:launchSearch()}]]>
</xp:this.action>
<xp:this.script><![CDATA[ var qryField = document.getElementById("#{id:inputSearch}");
if(doSearch(qryField)) {
showStandBy();
return true;
} else {
return false;
}]]></xp:this.script>
</xp:eventHandler>
</xp:button>
<xp:br />
</xp:panel>
<!--
This event handler makes sure the search box has the focus once the
page is loaded
<xp:eventHandler event="onClientLoad" submit="false">
<xp:this.onStart>
StandbyDialog_Started();
</xp:this.onStart>
<xp:this.script><![CDATA[var edit = dojo.byId("#{id:inputSearch}");
if (edit) {
edit.focus();
}]]>
</xp:this.script>
</xp:eventHandler>
-->
<xp:eventHandler event="onClientLoad" submit="false">
<xp:this.script><![CDATA[var edit = dojo.byId("#{id:inputSearch}");
if (edit) {
edit.focus();
}]]></xp:this.script>
</xp:eventHandler></xp:view>

XPages: image onCclick needs 2 clicks to do what is expected

I have a custom control that contains 2 images: add and remove from favorites.
There is some code on the onCLick event of the image, and both images use a SSJS function to see if the current document is already in the favorites or not, in the visible property of each image.
All works well, execpt that I need to click twice on the image in order to see the changes in the UI. Both onClick events are set to FullUpdate (also tried partial update with the panel that contains the images).
I could move all the favorites logic into session scope variables, but I think this should work as is. I just don't understand why I need to click twice, as if the partial refresh doesn't do anything (though it is, as I see the reload Arrow in the browser!).
Can it be that the code takes too long to execute and the refresh doesn'T get the updated info???
Here's the custom control code:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xe="http://www.ibm.com/xsp/coreex">
<xp:this.resources>
<xp:script src="/AppUtils.jss" clientSide="false"></xp:script>
</xp:this.resources>
<xp:image url="/favorites-add.png" id="image1"
alt="Add to Favorites" title="Add to Favorites">
<xp:this.rendered><![CDATA[#{javascript:!isInFavorites(document1.getDocument().getUniversalID(), userBean.canonicalName);
}]]></xp:this.rendered>
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:addToFavorites(document1.getDocument().getUniversalID(),userBean.canonicalName);}]]></xp:this.action>
</xp:eventHandler>
</xp:image>
<xp:image url="/favorites-remove.png" id="image2"
alt="Remove from Favorites" title="Remove from Favorites">
<xp:this.rendered><![CDATA[#{javascript:isInFavorites(document1.getDocument().getUniversalID(),userBean.canonicalName);
}]]></xp:this.rendered>
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:removeFromFavorites(document1.getDocument().getUniversalID(),userBean.canonicalName);}]]></xp:this.action>
</xp:eventHandler>
</xp:image>
</xp:view>
And here's the SSJS:
function addToFavorites(unid, userName) {
var newDoc:NotesDocument = database.createDocument();
newDoc.appendItemValue("Form","Favorite");
newDoc.appendItemValue("UserName", userName);
newDoc.appendItemValue("DocUNID", unid);
newDoc.save();
return;
}
function removeFromFavorites(unid, userName) {
var notesView:NotesView = database.getView("(lkpFavorites)");
var keys = new java.util.Vector();
keys.addElement(userName);
keys.addElement(unid);
var coll:NotesDocumentCollection = notesView.getAllDocumentsByKey(keys, true);
if(coll.getCount()==1) {
coll.getFirstDocument().remove(true);
}
return;
}
function isInFavorites(unid, userName) {
var notesView:NotesView = database.getView("(lkpFavorites)");
var keys = new java.util.Vector();
keys.addElement(userName);
keys.addElement(unid);
var coll:NotesDocumentCollection = notesView.getAllDocumentsByKey(keys, true);
if(coll.getCount()>0) {
return true;
} else {
return false;
}
}
I'd suggest you to put an xp:link around your image to cast the event code instead of using the evennts of the image directly.
OK, not sure what happened there but I manually edited the custom control's source to see wheter I had empty eventHandler as suggested by Oliver, and it started to work as expected. I am totally unsure of what I changed: to my knowledge, all I did was to add extra "returns" in the source view, to make it more readable... Christmas gift I guess.
All is good now. Thanks to all :)

xpages validation on field having onChange script

There is a required field:
<xp:this.validators>
<xp:validateRequired
message="Required field. Please add some text.">
</xp:validateRequired>
</xp:this.validators>
Also, the value from this field is copied ( using the onChange event ) to other fields:
<xp:eventHandler event="onchange" submit="true"refreshMode="norefresh">
<xp:this.action><![CDATA[#{javascript:Cdoc.setValue("dlg_Localitate",Cdoc.getValue("txt_LocalitateCompanie"));
Cdoc.setValue("dlg_Localitate_1",Cdoc.getValue("txt_LocalitateCompanie"))}]]>
</xp:this.action>
</xp:eventHandler>
An inconvenient issue appears when I just click the field to fill it: the validation message appears. Is because the field initially is empty and the code I added is into the onChange event?
I'd like to use this field as required before users can save the doc.
I tried set the values by CSJS, but without a result...
var string = XSP.getElementById("#{id:inputText1}").value
XSP.getElementById("#{id:txt_LocalitateS}").value = string
XSP.getElementById("#{id:txt_LocalitateP}").value = string
Also, let say I enter a value for inputText1 and later on I enter a new value... How can I update automatically the other 2 fields with the new value?
I tried something like this:
<xp:inputText id="inputText1" value="#{Cdoc.txt_LocalitateCompanie}"
style="height:20.0px;width:122.0px;font-weight:bold;font-size:10pt;font-family:verdana"
required="true">
<xp:this.validators>
<xp:validateRequired message="Completarea localitatii este obligatorie.">
</xp:validateRequired>
</xp:this.validators>
<xp:typeAhead mode="full" minChars="1" ignoreCase="true"
id="typeAhead1">
<xp:this.valueList><![CDATA[#{javascript:#DbLookup(#DbName(),"vwLocalitati",Cdoc.txt_LocalitateCompanie,1,"[PARTIALMATCH]");}]]></xp:this.valueList>
</xp:typeAhead>
<xp:eventHandler event="onchange" submit="true"
refreshMode="norefresh">
<xp:this.action><![CDATA[#{javascript:Cdoc.setValue("dlg_Localitate",Cdoc.getValue("txt_LocalitateCompanie"));
Cdoc.setValue("dlg_Localitate_1",Cdoc.getValue("txt_LocalitateCompanie"))}]]></xp:this.action>
<xp:this.script><![CDATA[XSP.partialRefreshGet("#{id:txt_LocalitateS}", {
onComplete: function() {
XSP.partialRefreshGet("#{id:txt_LocalitateP}", {
onComplete: function(){ }
});
}
});]]></xp:this.script>
</xp:eventHandler>
</xp:inputText>
Thanks in advance
Two things here. First, you should disable validators for onChange event, therefore it won't display the validation error.
Second, when you use a CSJS script together with a SSJS, it will fire the CSJS one and if it returns true, proceed with the SSJS. So if you want your CSJS code run after SSJS, you can place it into oncomplete.
If I understood your question correctly, the following code would solve it.
<xp:inputText
id="inputText1"
value="#{Cdoc.txt_LocalitateCompanie}"
style="height:20.0px;width:122.0px;font-weight:bold;font-size:10pt;font-family:verdana"
required="true">
<xp:this.validators>
<xp:validateRequired
message="Completarea localitatii este obligatorie.">
</xp:validateRequired>
</xp:this.validators>
<xp:typeAhead
mode="full"
minChars="1"
ignoreCase="true"
id="typeAhead1">
<xp:this.valueList><![CDATA[#{javascript:#DbLookup(#DbName(),"vwLocalitati",Cdoc.txt_LocalitateCompanie,1,"[PARTIALMATCH]");}]]></xp:this.valueList>
</xp:typeAhead>
<xp:eventHandler
event="onchange"
submit="true"
refreshMode="norefresh"
disableValidators="true">
<xp:this.action><![CDATA[#{javascript:Cdoc.setValue("dlg_Localitate",Cdoc.getValue("txt_LocalitateCompanie"));
Cdoc.setValue("dlg_Localitate_1",Cdoc.getValue("txt_LocalitateCompanie"))}]]></xp:this.action>
<xp:this.onComplete><![CDATA[if(dojo.byId("#{id:txt_LocalitateP}")) {
XSP.partialRefreshGet("#{id:txt_LocalitateP}", {
onComplete: function() {
XSP.partialRefreshGet("#{id:txt_LocalitateS}", {
onComplete: function(){ }
});
}
});
}]]></xp:this.onComplete>
</xp:eventHandler>
</xp:inputText>
UPDATE: In your case, the field you want to refresh is on the second tab with partialRefresh="true". It means that at the time of partialRefreshGet, the target fields might not exist in the DOM. I have added a check now.
this is taken from my comments and put into an answer:
onChange events are generally frowned upon due to performance and user experience. If, however, the field is a listed control ie combobox it is not so dramatic. The following options/ideas are available
Take out the onChange() to test whether that makes a difference. If so, move your code.
Use an update button to change all the fields en masse also preventing information that is already inputted from being deleted unwanted-ly
create your own validation method and show/hide a label manually (hack-y)
Research how to manually put text into an errors control
If the field is in a dialog box, move the onChange() to the open/close methods of the dialog
FURTHER EDIT
An idea that I might suggest is using the xspDoc.getDocument(true) method to push all changes from the xpage to the background document. Something tells me that this might make a difference with the server reading the changes to the document and realizing that it is not empty.
ADDITIONAL IDEAS
I did not mention this because it is a bit more advanced, but should also get the job done assuming the refreshes are done. Even that is not that big of a deal. You could read all of your data from the document into a java bean. This bean is then the "data source" for your page and you bind all of your controls to the properties of this bean. You will then use EL to bind your controls to the bean. In the setters for those variables that trigger changes in other fields, change those values. So,
public PageBean(){
//read connection information out of the URL and get the correct information out of the document
//set all variables
firstName=doc.getItemValueString("firstName");
}
private String firstName;
public String getFirstName(){
return firstName;
}
public void setFirstName(String firstName){
this.firstName = firstName;
setLastName("Schmidt");
}
....
Once you register your bean with faces-config.xml, you can then use EL to access the data
#{PageBean.firstName}
#{PageBean.lastName}
Then you can get your document again in save and reset the values, save and release.

Resources