If I have two separate mule flows that would run synchronously
<flow name="GatherDDICollection" doc:name= "GatherDDICollection" processingStrategy="synchronous" >
<poll doc:name= "Poll" frequency ="5000">
<invoke object-ref="numberInformationCollectionFlow" method="popWaiting" doc:name="PopPending"/>
</poll>
<expression-filter expression="#[payload != null && ((payload instanceof org. mule.transport. NullPayload) == false) && payload.size() > 0 ]" doc:name ="HasRequest"/>
<logger message= "Collection request - #[payload]" level= "INFO" doc:name="Logger" />
</flow >
<flow name= "ProvisionDDI" doc:name ="ProvisionDDI" processingStrategy="synchronous" >
<poll doc:name="Poll" frequency="5000" >
<invoke object-ref="numberInformationCollectionFlow" method="getParentDdis" doc:name= "DataToProvision"/>
</poll>
<expression-filter expression="#[payload != null && ((payload instanceof org. mule.transport. NullPayload) == false) && payload > 0]" doc:name="HasDataToProvision" />
<logger message= "DDI to provision- #[payload]" level="INFO" doc:name= "Logger"/>
</flow >
Would the payload get confused which flow it belongs to?
I ask because I am confuse with the current scenario:
The first flow (GatherDDICollection) will not show "Collection request -.." because method "popWaiting" returns null.
The second flow (ProvisionDDI) should show "DDI to provision .." because te method "getParentDdis" returns a list of objects but it doesn't (I know this because if I remove the expression-filter on the second flow, the logger shows the message . Is this because it is getting confused with the payload from the first flow?
Related
I'm using Apache Camel 2.17 and using the simple language to catch a null exchange. It is not working and I've tried several formatting approaches, but it doesn't catch a null. I believe it is the format/syntax of how I'm using it. please instruct where I'm going wrong. thank you!
<process id="_process18" ref="csvMarshallerProcessor"/>
<process id="toReOrgCSV" ref="reOrgCSVData"/>
<choice id="_choice13">
<when id="_when13">
<simple>"${body}" == null</simple>
<log id="_log22" message="body is NULL, do not send NULL body!"/>
<stop id="_stop7"/>
</when>
<otherwise id="_otherwise1">
I've tried
<simple>"${body} == null"</simple>
<simple>"${body}" == null</simple>
<simple>${body} == null</simple>
<simple>${body} == 'null'</simple>
I set the exchange to null in a previous process IF the data is filtered out and ineligiable to send out. I'd like to just use Camel Spring XML.
???
Don't set the exchange as null, as that is not valid, set the message body to null or empty string etc.
exchange.getIn().setBody(null);
And then you can use simple to test its null,
${body} == null
Or if you set it as empty text
${body} == ''
thank you Claus!
this is what I ended up with, ..
...
line.append(System.lineSeparator());
if ( lookup ) {
if ( validate(fleetName, line.toString()) ) {
baos.write(line.toString().getBytes());
}
} else {
baos.write(line.toString().getBytes());
}
}
List<String> serviceRecords = new ArrayList<String>(Arrays.asList(baos.toString().split(System.lineSeparator())));
if ( serviceRecords.size() > 1 ) { //has more than a header
byte[] ba = baos.toByteArray();
exchange.getIn().setBody(ba);
} else {
exchange.getIn().setBody(null); //empty message, only header, no data
}
Camel Context
<process id="_process18" ref="csvMarshallerProcessor"/>
<choice id="_choice13">
<when id="_when13">
<simple trim="true">"${body}" == "" || ${body} == null</simple>
<log id="_log22" message="body is NULL, do not send NULL body!"/>
<stop id="_stop7"/>
</when>
<otherwise id="_otherwise1">
<process id="toReOrgCSV" ref="reOrgCSVData"/>
<to id="_to7" uri="{{DDFEndpoint}}?fileName={{APMLoaderPath}}/${header.aircraftMetadata.shipNumber}-${header.enginePosition}_${header.messageDateTime}.csv"/>
<log id="_log23" message="Sending data packet: ${header.aircraftMetadata.outputPath}/${header.aircraftMetadata.shipNumber}-${header.enginePosition}_${header.messageDateTime}.csv"/>
</otherwise>
</choice>
</aggregate>
I have a program that contains some for-loops. The idea of the program is to log into a website using multiple accounts and retrieve a list (each login brings a different list). So the way I have it setup is with an enhanced for loop:
loginsList.put( "firstUsername", "firstPassword" );
loginsList.put( "secondUsername", "secondPassword" );
loginsList.put( "thirdUsername", "thirdPassword" );
loginsList.put( "fourthUsername", "fourthPassword" );
loginsList.put( "fifthUsername", "fifthPassword" );
for ( Entry<String, String> nextLogin : logins.entrySet() ) {
String nextUser = nextLogin.getKey();
String nextPass = nextLogin.getValue();
Response authenticateUserResponse = Jsoup.connect( WEBSITE_I_NEED_TO_LOGIN_TO )
.data( "username", nextUser )
.data( "password", nextPass )
.execute();
Basically here is what i want the flow to be:
read()--> obtain list----> send list to write() method to write it to the database--> loop back around and get the next login-->read()--> obtain list-->send it to the write()....etc..
however the issue I'm having is that my loop runs in the read method and does not go to the write method until all the lists have been traversed in all the accounts. Essentially the write is only being called once at the end, so what I have right now is something like this(this is the flawed design):
read()--->obtain list-->next account--->obtain list---next account--->obtain list--->write()
How can I organize the chunk processing in Spring to write after I read a chunk only?
for ( Entry<String, String> nextLogin : logins.entrySet() ) {
String nextUser = nextLogin.getKey();
String nextPass = nextLogin.getValue();
//do something
......
//call write function
writeValues(x, y, z);
}
Is this all you want?
Otherwise it seems like a traditional SpringBatch: Read > Process > Proceeed case.
You will have your reader = gets a record
Procesor > saves a record
Spring batch moves you to next record if the was no error.
<step id="processUpdates">
<tasklet task-executor="batchThreadPoolTaskExecutor" throttle-limit="${batch.cviscoreupdate.threadcount}">
<chunk reader="Reader" processor="ItemProcessor" writer="ItemWriter" commit-interval="${batch.commit.interval}" skip-limit="${batch.skip.limit}" >
<skippable-exception-classes>
<include class="batch.support.SkipRecordException" />
</skippable-exception-classes>
</chunk>
</tasklet>
<next on="FAILED" to="errorExit"/>
<next on="*" to="moveFilesFromWorkToDone" />
<listeners>
<listener ref="UpdateSkipListener"/>
</listeners>
</step>
<bean id="CVIScoreUpdateItemProcessor" class="com.batch.MyUpdateItemProcessor" scope="step" init-method="init" />
I'm building an application where I have mainDoc which can have one or more related notes Documents. In the mainDoc there is a repeat control that is bound to Payments.getAllItems(WFSMainDoc.getValue("LinkKey")); The java class Payments has methods that manipulate and ArrayList of PaymentItems. The getAllItems method grabs all of the related NotesDocuments and loads them into an ArrayList. If the ArrayList already exists it just returns the previously built ArrayList. The button in the Repeat sets viewScope.vsRIndex = rIndex; and viewScope.vsShowPayment = true; which now displays the panelPaymentDetail and the custom control that has a custom property of type java.lang.Object and load pItem using pItem = Payments.getItem(rIndex); return pItem;
all of the above works and I have a couple sample controls below. I have two issues:
1. The compositeData.pItem is computed over and over again and as far as I can tell keeps returning the original values from the Payments.getAllItems() even though I'm editing them in the payment input 'form' -- the question then is how can I block this repeated calculation?
The save button in the Payment Input custom control does not appear to fire (none of the print statements occur when clicked) I think the reloading of the Object pItem gets in the way.
Test Main Document Control:
<?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">
<xp:this.data>
<xp:dominoDocument var="WFSMainDoc" formName="frmMainDoc"
computeWithForm="onsave" ignoreRequestParams="false">
<xp:this.documentId><![CDATA[${javascript:var UNID:String = sessionScope.get("ssUNID");
(UNID == null || UNID == "") ? "" : UNID}]]></xp:this.documentId>
<xp:this.action><![CDATA[${javascript:if (sessionScope.containsKey("ssUNID")){
if(sessionScope.get('ssUNID').length){
sessionScope.get('ssAction') == 'edit' ? 'editDocument':'openDocument'
} else {
return 'createDocument'
break;
}
}else{
return "createDocument";
break;
}}]]></xp:this.action>
<xp:this.databaseName><![CDATA[${appProps[sessionScope.ssApplication].appFilePath}]]></xp:this.databaseName>
</xp:dominoDocument>
</xp:this.data>
Main document
<xp:br></xp:br>
<xp:inputText id="inputText1" value="#{WFSMainDoc.LinkKey}"
defaultValue="#{javascript:#Unique}">
</xp:inputText>
<xp:br></xp:br>
Other Fields and controls
<xp:br></xp:br>
<xp:panel id="panelPaymentContainer">
<xp:repeat id="repeatData" rows="10" var="pItem"
indexVar="rIndex">
<xp:this.value><![CDATA[#{javascript:Payments.getAllItems(WFSMainDoc.getValue("LinkKey"));}]]></xp:this.value>
<xp:button id="buttonEditPayment"
rendered="#{javascript:(WFSMainDoc.isEditable())}">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="panelPaymentsContainer">
<xp:this.action><![CDATA[#{javascript:try{
viewScope.vsRIndex = rIndex;
viewScope.vsShowPayment = true;
break;
}catch(e){
WFSUtils.sysOut("Error in calling dialogPayment " + e.tostring)
}}]]>
</xp:this.action>
</xp:eventHandler>
</xp:button>
<br />
</xp:repeat>
<xp:panel id="panelPaymentInput">
<xp:this.styleClass><![CDATA[#{javascript:(viewScope.vsShowPayment) ? "" : "display=none";}]]></xp:this.styleClass>
<xc:ccTestPaymentInput rendered="#{javascript:(viewScope.vsShowPayment)}">
<xc:this.pItem><![CDATA[#{javascript:try{
var debug:Boolean = true;
if (debug) WFSUtils.sysOut("Open existing row = " + viewScope.vsRIndex)
rIndex = parseInt(viewScope.vsRIndex.toString());
if (debug) WFSUtils.sysOut("rIndex = " + rIndex);
pItem = Payments.getItem(rIndex);
return pItem;
}catch(e){
WFSUtils.sysOut("Failure in Custom Prop of add item " + e.toString());
return null;
}}]]></xc:this.pItem>
</xc:ccTestPaymentInput>
</xp:panel>
</xp:panel><!-- panelPaymentContainer -->
<xp:br></xp:br>
<xp:br></xp:br>
</xp:view>
payment Input Control
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:br></xp:br>
Actual Pay Date:
<xp:inputText id="actualPayDate"
value="#{compositeData.pItem.actualPayDate}">
<xp:dateTimeHelper id="dateTimeHelper1"></xp:dateTimeHelper>
<xp:this.converter>
<xp:convertDateTime type="date"></xp:convertDateTime>
</xp:this.converter>
</xp:inputText>
<br /> <br />
<xp:button value="Save" id="button1">
<xp:eventHandler event="onclick"
submit="true" refreshMode="partial" refreshId="panelPayments">
<xp:this.action><![CDATA[#{javascript:try{
var debug:Boolean = true;
if (debug) print("Start Payment save");
var pos:Integer = parseInt(viewScope.vsRIndex.toString());
if (debug) print("Working with pos = " + pos + " Call saveThisItem");
if (Payments.saveThisItem(compositeData.pItem , pos)){
if (debug) print("save Payments Worked ");
}else{
if (debug) print("save Payments FAILED ");
}
}catch(e){
print("payment save Error " + e.tostring);
}finally{
viewScope.vsExpPayDate = "";
viewScope.remove("vsShowPayment");
viewScope.remove("vsRIndex");
viewScope.remove("vsGotItem")
}}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
</xp:view>
This is all very complicated, and I'm far from understanding what you're trying to achieve here. But at least I found a few oddities in your code:
ad 1: there is a panel with id="panelPaymentContainer" containing a repeat. Inside that repeat is a button doing a partialRefresh on an id="panelPaymentsContainer" >> is this a typo (plural vs. singular forms in "Payment(s))? Should the button be refreshing the panel?
Assuming that this assumption is true: every time you click the button the panel is refreshed together with all its contents, thus also refreshing the repeat's datasource. And so pItem will always be pushed from "outside in" into the content of your repeat. - If the refreshId thing is NOT a typo, then what should it be? I tried hard to read the entire code, but there's a lot of it, so I might have missed something
ad 2: similar thing here: the save button tries to refresh something with an id="panelPayments", but I cannot see anything with this id. So no wonder it doesn't appear to do anything useful.
My recommendation for complicated tasks like these: try to strip everything down to the bare essentials; the more complicated your code is the harder it is to find its mistakes. Start with a panel, a repeat and a few simple controls like a button and a bunch of computed fields to display some test values. Then as soon as this very simple model is working you can start to add to it. - Simplifying also helps others to find mistakes in you concept, btw.
I've been stuck on this one the last couple of days to no avail and after a lot of googling and trial and error I'm back at the beginning with no luck.
I'm currently working on a Java Application which connects to a third party via JAX-WS. They provide a WSDL which we run in using the jaxws-maven-plugin to generate the services. Implemented via Spring, HTTPConduit is then used to change the endpoints and provide relevant config (e.g. keystores) for connecting to various environments (e.g. SysTest, UAT, Production etc).
The issue is, I haven't set any logging (in fact removing the two interceptors there previously), however the xml message being sent to the third party is appearing in the logs. This is a major issue as we're sending credit card information to the third parties which can no way be logged for obvious reasons. I can change the log4j properties in order to prevent the logging that way, but that's no way a fix.
Here is some code:
This is our beans file.
<jaxws:client id="client1"
xmlns:hsn="http://example.com"
serviceClass="com.example.Service1"
address="${service1.url}"
endpointName="hsn:service1"/>
<jaxws:client id="client2"
xmlns:hsn="http://example.com"
serviceClass="com.example.Service2"
address="${service2.url}"
endpointName="hsn:service2"/>
<jaxws:client id="client3"
xmlns:hsn="http://example.com"
serviceClass="com.example.Service3"
address="${service3.url}"
endpointName="hsn:service3"/>
<http:conduit name="https://*/.*">
<http:tlsClientParameters disableCNCheck="${service.disable-cn-check}">
<sec:keyManagers keyPassword="${service.keystore.password}">
<sec:keyStore type="JKS" password="${service.keystore.password}"
resource="${service.keystore.name}"/>
</sec:keyManagers>
<sec:trustManagers>
<sec:keyStore type="JKS" password="${service.truststore.password}"
resource="${service.truststore.name}"/>
</sec:trustManagers>
<sec:cipherSuitesFilter>
<sec:include>.*_EXPORT_.*</sec:include>
<sec:include>.*_EXPORT1024_.*</sec:include>
<sec:include>.*_WITH_DES_.*</sec:include>
<sec:include>.*_WITH_AES_.*</sec:include>
<sec:include>.*_WITH_NULL_.*</sec:include>
<sec:exclude>.*_DH_anon_.*</sec:exclude>
</sec:cipherSuitesFilter>
</http:tlsClientParameters>
<http:client AutoRedirect="true" Connection="Keep-Alive"
ConnectionTimeout="${service.max-response-time}"
ReceiveTimeout="${service.max-response-time}"/>
</http:conduit>
<http:conduit name="http://*/.*">
<http:client AutoRedirect="true" Connection="Keep-Alive"
ConnectionTimeout="${service.max-response-time}"
ReceiveTimeout="${service.max-response-time}"/>
</http:conduit>
As you can see there are no logging interceptors or logging explicitly turned on using:
<cxf:bus>
<cxf:features>
<cxf:logging/>
</cxf:features>
</cxf:bus>
The only other related file I can think of is META-INF/cxf/org.apache.cxf.Logger which contains:
org.apache.cxf.common.logging.Slf4jLogger
Which even without the file present doesn't make any changes.
Just so you can see, here is a sample from the logs as well:
15:05:45.742 DEBUG | org.apache.cxf.phase.PhaseInterceptorChain - Invoking handleMessage on interceptor org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor#5e62b59d
15:05:45.742 DEBUG | org.apache.cxf.transport.http.Headers - Accept: */*
15:05:45.743 DEBUG | org.apache.cxf.transport.http.Headers - Connection: Keep-Alive
15:05:45.743 DEBUG | org.apache.cxf.transport.http.Headers - SOAPAction: ""
15:05:45.744 DEBUG | org.apache.cxf.transport.http.HTTPConduit - No Trust Decider for Conduit '{http://example.com}service1.http-conduit'. An afirmative Trust Decision is assumed.
15:05:45.746 DEBUG | org.apache.cxf.transport.http.HTTPConduit - Sending POST Message with Headers to http://localhost:8080/stubs/Service1 Conduit :{http://example.com}service1.http-conduit
15:05:45.746 DEBUG | org.apache.cxf.transport.http.HTTPConduit - Conduit "{http://example.com}service1.http-conduit" Transmit cached message to: http://localhost:8080/stubs/Service1: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body>********************HERE LIES THE XML MESSAGE*********************</soap:Body></soap:Envelope>
15:05:45.766 DEBUG | org.apache.cxf.endpoint.ClientImpl - Interceptors contributed by bus: [org.apache.cxf.ws.policy.PolicyInInterceptor#24ec87dc]
15:05:45.767 DEBUG | org.apache.cxf.endpoint.ClientImpl - Interceptors contributed by client: []
15:05:45.767 DEBUG | org.apache.cxf.endpoint.ClientImpl - Interceptors contributed by endpoint: [org.apache.cxf.jaxws.interceptors.WrapperClassInInterceptor#52d1f1fb, org.apache.cxf.jaxws.interceptors.HolderInInterceptor#5565c037, org.apache.cxf.jaxws.interceptors.SwAInInterceptor#b2e86ae, org.apache.cxf.frontend.WSDLGetInterceptor#1ca801a2]
15:05:45.768 DEBUG | org.apache.cxf.endpoint.ClientImpl - Interceptors contributed by binding: [org.apache.cxf.interceptor.AttachmentInInterceptor#1b8c0f3e, org.apache.cxf.interceptor.StaxInInterceptor#83cbd93, org.apache.cxf.binding.soap.interceptor.SoapActionInInterceptor#4bc2021e, org.apache.cxf.interceptor.DocLiteralInInterceptor#2e19266d, org.apache.cxf.binding.soap.interceptor.SoapHeaderInterceptor#7529d5bf, org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor#d902ab1, org.apache.cxf.binding.soap.interceptor.StartBodyInterceptor#73e2d16b, org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor#3023033d, org.apache.cxf.binding.soap.interceptor.MustUnderstandInterceptor#4aa9b27b]
15:05:45.768 DEBUG | org.apache.cxf.endpoint.ClientImpl - Interceptors contributed by databinging: [org.apache.cxf.jaxb.attachment.JAXBAttachmentSchemaValidationHack#331fef77]
15:05:45.769 DEBUG | org.apache.cxf.phase.PhaseInterceptorChain - Chain org.apache.cxf.phase.PhaseInterceptorChain#273221e was created. Current flow:
receive [PolicyInInterceptor, AttachmentInInterceptor]
post-stream [StaxInInterceptor]
read [WSDLGetInterceptor, ReadHeadersInterceptor, SoapActionInInterceptor, StartBodyInterceptor]
pre-protocol [MustUnderstandInterceptor]
post-protocol [CheckFaultInterceptor, JAXBAttachmentSchemaValidationHack]
unmarshal [DocLiteralInInterceptor, SoapHeaderInterceptor]
post-logical [WrapperClassInInterceptor]
pre-invoke [SwAInInterceptor, HolderInInterceptor]
15:05:45.769 DEBUG | org.apache.cxf.phase.PhaseInterceptorChain - Invoking handleMessage on interceptor org.apache.cxf.ws.policy.PolicyInInterceptor#24ec87dc
Few months back I had come across similar problem, where I needed to mask few fields of my xml
The CustomLoginInterceptor
import org.apache.commons.lang3.StringUtils;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingMessage;
public class KPLogInInterceptor extends LoggingInInterceptor {
#Override
protected String formatLoggingMessage(LoggingMessage loggingMessage) {
String str = loggingMessage.toString();
String output = maskPasswords(str);
//output = maskRestPasswords(output);
return(output);
}
private String maskPasswords(String str) {
// String str =
// "<password1>asdasdad</password1><Password3></Password3><Password5/><PassWord6>fdsfsf</PassWord6>";
final String[] keys = { "password", "authpass", "accountnumber", "authphrase" };
for (String key : keys) {
int beginIndex = 0;
int lastIndex = -1;
boolean emptyPass = false;
boolean multiline = false;
if(key.equals("authphrase") || key.equals("authpass"))
{
//when lines are in multiplelines say <name>authphrase</name><value>vals</value>
multiline = true;
}
while (beginIndex != -1
&& (beginIndex = StringUtils.indexOfIgnoreCase(str, key,
beginIndex)) > 0) {
if(multiline){
beginIndex = StringUtils.indexOfIgnoreCase(str, "value", beginIndex);
}
beginIndex = StringUtils.indexOf(str, ">", beginIndex);
if (beginIndex != -1) {
char ch = str.charAt(beginIndex - 1);
if (ch == '/') {
emptyPass = true;
}
if (!emptyPass) {
lastIndex = StringUtils.indexOf(str, "<", beginIndex);
if (lastIndex != -1) {
String overlay = "*";
String str2 = StringUtils.substring(str,
beginIndex + 1, lastIndex);
if (str2 != null && str2.length() > 1) {
overlay = StringUtils.rightPad(overlay,
str2.length(), "*");
str = StringUtils.overlay(str, overlay,
beginIndex + 1, lastIndex);
}
}
}
if (emptyPass) {
emptyPass = false;
lastIndex = beginIndex + 1;
} else {
if (lastIndex != -1) {
lastIndex = StringUtils
.indexOf(str, ">", lastIndex);
}
}
}
beginIndex = lastIndex;
}
}
return str;
}
}
And the cxf config xml
<bean id="kpInInterceptor" class="com.kp.swasthik.KPLogInInterceptor"></bean>
<bean id="kpOutInterceptor" class="com.kp.swasthik.KPLogOutInterceptor"></bean>
<cxf:bus>
<cxf:inInterceptors>
<ref bean="kpInInterceptor" />
</cxf:inInterceptors>
<cxf:outInterceptors>
<ref bean="kpOutInterceptor" />
</cxf:outInterceptors>
<cxf:outFaultInterceptors>
<ref bean="kpOutInterceptor" />
</cxf:outFaultInterceptors>
<cxf:inFaultInterceptors>
<ref bean="kpInInterceptor" />
</cxf:inFaultInterceptors>
</cxf:bus>
You need to create one more class that extends LogOutInterceptor
EDIT
Create class the sets the loglevel to INFO for
public class KPLogicSupresser {
public void kpinit(){
LogManager.getLogger(HTTPConduit.class).setLevel(Level.INFO);
}
}
And create a bean in CXF configuration file
<bean id="kpLog4Jsupresser" class="com.kp.swasthik.KPLogicSupresser" init-method="kpinit" ></bean>
Just add logback.xml file in your class path with logger level INFO, it will disable all output from CXF DEBUGS.
Sample File
Filename: logback.xml
Location: src/main/resources (In my project its resources, you can place the file accordingly in your project classpath)
File Content:
<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
<resetJUL>true</resetJUL>
</contextListener>
<!-- To enable JMX Management -->
<jmxConfigurator/>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<logger name="com.mycompany.subpackage" level="INFO"/>
<root level="INFO">
<appender-ref ref="console"/>
</root>
I try to recover the answer of the user but i can't.
I have a dropdownbutton, I recover the list and the value by default by a java class.
It's ok about this.
But when I try to push another text of the list : nothing append...
<xe:dropDownButton id="dropdownEtatDoc">
<xe:this.treeNodes>
<xe:basicContainerNode>
<!-- Affiche l'état du document par défaut-->
<xe:this.label id="labelEtatDoc">
<![CDATA[#{javascript:
etatDoc.nomEtatDoc;
}]]>
</xe:this.label>
<!-- affiche la liste des états du document-->
<xe:repeatTreeNode var="index" value="#{etatDoc.listEtatDoc}">
<xe:this.children>
<xe:basicLeafNode label="#{index}" submitValue="#{index}" />
</xe:this.children>
</xe:repeatTreeNode>
</xe:basicContainerNode>
</xe:this.treeNodes>
<!-- actualise la chaine sélectionnée-->
<xp:eventHandler event="onItemClick" submit="true"
refreshMode="complete">
<xp:this.action>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:
var montest = getComponent("dropdownEtatDoc").submittedValue();
etatDoc.nomEtatDoc = montest;
}]]></xp:this.script>
</xp:executeScript>
</xp:this.action>
</xp:eventHandler>
</xe:dropDownButton>
An idea ? Thanks !
I use a combobox and it's ok, I don't know why...
My code for anyone has the same problem :
<xp:this.beforePageLoad>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:
viewScope.etat = etatDoc.listEtatDoc;
viewScope.grdFam = chapitre.listChapitre1;
}]]></xp:this.script>
</xp:executeScript>
</xp:this.beforePageLoad>
<xp:div>
<!--**************** DEBUT CBXETATDOC *************************************************************-->
<xp:label value="Etat : " id="label1"></xp:label>
<xp:comboBox id="cbxEtat">
<xp:selectItem itemLabel="Tout" itemValue="" />
<xp:selectItems value="#{viewScope.etat}" />
<xp:eventHandler event="onchange" submit="true" refreshMode="complete" immediate="true">
<xp:this.action>
<xp:executeScript>
<xp:this.script>
<![CDATA[#{javascript:
var etat = getComponent("cbxEtat").submittedValue;
}]]>
</xp:this.script>
</xp:executeScript>
</xp:this.action>
</xp:eventHandler>
</xp:comboBox>
Assuming "etatDoc" is a NotesXspDocument and not a bean.
1) If you are having trouble getting the submitted value, get it via the context:
var submitted = context.getSubmittedValue();
print("submitted: " + submitted); //check if it is there, delete afterward
switch(submitted){
case("btn1")
//doSomething(submitted);
break;
}
Since you are using the repeater node, it would not be practical to use the switch for all of it, but you could make a default where you do what ever you need to with the index value.
2) then I do not think you are setting the value properly. Try:
var montest = submitted;
etatDoc.replaceItemValue("nomEtatDoc", etatDoc.getItemValue("nomEtatDoc").add(montest))
//gets the current list (java.util.Vector) from the document
//add a value to the list
//replace the value with the new list
I am assuming that you are not using a self-made-bean for this.