I'm trying to do a partial update on an Edit Box ("Room") on the server onChange event of a dojo filteringselect control ("From_Name") on an xpage.
So, I use a simple Modify Field action with the computed value:
nm = getComponent("From_Name").value;
#DbLookup("names.nsf", "Full Name", nm, 10);
The onChange event also does a Partial Update to the "Room" element.
The problem is that there are a couple of more filteringselect controls on the form, and as I try to do the partial update to do the lookup into the address book to get the person's room number, it gives me the yellow exclamation point error for the other filteringselects on the xpage. If all the other filteringselect controls on the page are filled out first, then the partial update works. How do I get around this and update the Room field when, the From_Name is changed?
The code for my control:
<xe:djFilteringSelect id="From_Name" value="#{document1.From_Name}"
readOnly="# {javascript:!document1.isNewNote()}">
<xe:this.defaultValue><![CDATA[#{javascript:
#Name("[CN]", #UserName())}]]>
</xe:this.defaultValue>
<xp:selectItems>
<xp:this.value><![CDATA[#{javascript:
db = new Array("SERVER", "names.nsf");
#Unique(#DbColumn(db, "Full Name", 1))
}]]></xp:this.value>
</xp:selectItems>
<xp:eventHandler event="onChange" submit="true"
refreshMode="partial" refreshId="Room">
<xe:this.action>
<xp:modifyField name="Room">
<xp:this.value><![CDATA[#{javascript:
nm = getComponent("From_Name").value;
#DbLookup("names.nsf", "Full Name", nm, 10);
}]]></xp:this.value>
</xp:modifyField>
</xe:this.action>
</xp:eventHandler>
</xe:djFilteringSelect>
Add a Dojo attribute required with value false to the other djFilteringSelect controls:
<xe:this.dojoAttributes>
<xp:dojoAttribute
name="required"
value="false">
</xp:dojoAttribute>
</xe:this.dojoAttributes>
With this additional client side attribute you won't get the yellow exclamation point errors anymore.
Related
in an Xpage , I'm looking for a message box like p.notify that gives a personalised message that fade's in and out automatically in my onclick of a button event.
in client side I put : $.pnotify({ pnotify_title: 'Test',pnotify_text: 'personalised message'});
Which works , but how do I put a personalised text in it from for example a viewScope
in server side I put : view.postScript("$.pnotify({ pnotify_title: 'Test',pnotify_text: 'personalised message'});"); Which gives an error : Uncaught TypeError: Cannot read property 'top' of undefined
at Function.pnotify (jquery.pnotify.min.js:37)
at demo.xsp:306
So my question : How can I put a personlised message (from for example a viewScope into the client side script , or is there a way to make my server side script to work or is there another way to get the same result ( I don't think there's a way to autoclose xpages dialogs after some time?)
In the a clientside event of any XPages control you can add serverside code, for example:
<xp:button
value="Show message"
id="button1">
<xp:eventHandler
event="onclick"
submit="false">
<xp:this.script><![CDATA[
$.pnotify({
pnotify_title: 'Test',
pnotify_text: '#{javascript:viewScope.yourVar}'
});]]></xp:this.script>
</xp:eventHandler>
</xp:button>
Does that work in your situation?
I have the following requirement in an xpages application:
I have a radio button group with two options.
I have a combobox whose values will be calculated from the option chosen in the radio button group. The options will be calculated from the partial refresh of the combobox associated with the onChange event of the radio button.
My problem is that I could not get the value selected on the radio button to mount the combobox options. As I'm doing the assembly through SSJS I have to get the value selected on the radio button also in SSJS. Is there any component / method on xpages that I can get the selected value from?
I know that via RPC component or jquery coould get via CSJS the selected value, but I was only wanting to use SSJS.
Grateful
Knut,
I made an example based on your suggestion, according to the code below, but it did not work. Because?
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:radioGroup id="radioGroup2">
<xp:selectItem itemLabel="a"></xp:selectItem>
<xp:selectItem itemLabel="b"></xp:selectItem>
<xp:selectItem itemLabel="c"></xp:selectItem>
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="partial" refreshId="computedField2" execMode="partial" execId="radioGroup2">
</xp:eventHandler></xp:radioGroup>
<xp:text
escape="true"
id="computedField2"
value="#{javascript:getComponent('radioGroup2').getValue()}">
</xp:text><xp:br></xp:br><xp:br></xp:br>
</xp:view>
Use
getComponent('radioGroup1').getValue()
Replace "radioGroup1" with your radio button group's id.
Here is an example:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view
xmlns:xp="http://www.ibm.com/xsp/core">
<xp:radioGroup
id="radioGroup1"
value="#{viewScope.radio}">
<xp:selectItem itemLabel="a" />
<xp:selectItem itemLabel="b" />
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="partial"
refreshId="checkBoxGroup1" execMode="partial" execId="radioGroup1">
</xp:eventHandler>
</xp:radioGroup>
<xp:br></xp:br>
<xp:checkBoxGroup
id="checkBoxGroup1"
value="#{viewScope.check}">
<xp:selectItems>
<xp:this.value><![CDATA[#{javascript:
if (!getComponent('radioGroup1').getValue()) {
return [];
}
if (getComponent('radioGroup1').getValue() == 'a') {
return ['A1', 'A2'];
}
return ['B1', 'B2'];
}]]></xp:this.value>
</xp:selectItems>
</xp:checkBoxGroup>
</xp:view>
Instead of getComponent('radioGroup1').getValue()you could use viewScope.radio as radio's value gets stored in view scope variable in this example.
I've done similiar by either using a getComponent("RadioButtonGroup1").getValue() in the computed values for the combobox. Or you could use this:
this.getParent().getValue()
in the onChange to populate a scoped variable that you base your combobox with.
I have a dojoFilteringSelect field which I want to put a dojo tootltip for. If the user hovers over the field (or I could put an icon next to the field) I want the contents of a computed field to show up.
Looked around and saw various examples but what I cannot find is how to connect the tool tip to the hover action? I am running this in the Lotus client.
My code is below.
<xe:djFilteringSelect id="djFilteringSelect3"
rendered="true" value="#{document1.loc}" tabIndex="1">
<xe:this.defaultValue><![CDATA[""]]></xe:this.defaultValue>
<xp:selectItems>
<xp:this.value><![CDATA[#{javascript:getComponent("lookupLocs").getValue();}]]></xp:this.value>
</xp:selectItems>
<xp:eventHandler event="onClick" submit="false">
<xe:this.script><![CDATA[XSP.openTooltipDialog("#{id:tooltipDialog1}", "#{id:label1}")]]></xe:this.script>
</xp:eventHandler></xe:djFilteringSelect>
<xe:valuePicker dialogTitle="Locs with Loc Manager"
for="djFilteringSelect1">
<xe:this.dataProvider>
<xe:simpleValuePicker>
<xe:this.valueList><![CDATA[#{javascript:getComponent("lookupLocs2").getValue();}]]></xe:this.valueList>
</xe:simpleValuePicker>
</xe:this.dataProvider>
</xe:valuePicker>
<xe:tooltipDialog id="tooltipDialog1"></xe:tooltipDialog></xp:td>
<xp:scriptBlock id="scriptBlock1">
<xp:this.value><![CDATA[XSP.addOnLoad(function(){
XSP.getElementById("#{id:djFilteringSelect1}").focus();
});]]></xp:this.value>
</xp:scriptBlock>
<xp:td style="width:229.0px">
<xp:message id="message1" for="loc"></xp:message>
</xp:td>
</xp:tr>
<xp:tr>
<xp:td>
<xp:label id="label3" value="Work Category" style="font-weight:bold"></xp:label>
</xp:td>
<xp:td>
<xe:djFilteringSelect id="djFilteringSelect2"
rendered="true" value="#{document1.workCategory}" tabIndex="2">
<xe:this.defaultValue><![CDATA[""]]></xe:this.defaultValue>
<xp:selectItems>
<xp:this.value><![CDATA[#{javascript:var db = new Array(#DbName()[0], 'TSCTT.nsf');
#DbColumn(db, "workCategoryView", 1)
}]]></xp:this.value>
</xp:selectItems>
</xe:djFilteringSelect>
You are very close to the solution you are looking for.
It is not really useful to set the hover tooltip function on dojoFilteringSelect field itself as it is then impossible to select a value there. Instead, like you suggested already, let the tooltip work on an icon or the field's label.
This is an example for a tooltip dialog appearing on hovering over label:
<xp:label value="Label" id="label1">
<xp:eventHandler event="onmouseover" submit="false">
<xp:this.script><![CDATA[
XSP.openTooltipDialog("#{id:tooltipDialog1}", "#{id:label1}")
]]></xp:this.script>
</xp:eventHandler>
<xp:eventHandler event="onmouseout" submit="false">
<xp:this.script><![CDATA[
XSP.closeTooltipDialog("#{id:tooltipDialog1}")
]]></xp:this.script>
</xp:eventHandler>
</xp:label>
<xe:djFilteringSelect id="djFilteringSelect1" rendered="true"
value="#{document1.loc}">
<xp:selectItems>
<xp:this.value><![CDATA[#{javascript:
["abc","def","xyz"]
}]]></xp:this.value>
</xp:selectItems>
</xe:djFilteringSelect>
<xe:tooltipDialog id="tooltipDialog1" title="This is the dialog title">
<xp:text escape="true" id="computedField1">
<xp:this.value><![CDATA[#{javascript:
"This is the computed value"
}]]></xp:this.value>
</xp:text>
</xe:tooltipDialog>
Label's event "onmouseover" (not "onMouseOver"!) opens the tooltip dialog box. This event works only if you don't use the parameter for="djFilteringSelect1" ( I don't know why).
I added an event "onmouseout" which closes the tooltip dialog when mouse no longer hovering over label.
Instead of event "onmouseout", you can add same CSJS code to a close button inside tooltip dialog box. This is useful if you have things on tooltip dialog box you want to click on like links or editable fields.
If you use the tooltip and not the tooltipdialog than just use the for property and it will happen automatically, no code needed. Very simple.
In your code above you are using the onclick event, that will not work onMouseOver (which would be the event you need?)
Howard
In one of my XPages I got a radio button. If I choose value of the radio button, a partial refresh is called.
Value 1 of the radio button only displays a new button in the same line
Value 2 adds some more fields beneath the radio button group
Beneath this new fields there is a Dojo filtering select field to choose from a list of employees.
If I select value 1, the filtering select works fine.
If I select value 2, the filtering select still starts at the "old" position, without recognizing the space, the new fields need
How can I update the position of the filtering select list? The partial refresh is for the complete content of the page, but does not seem to work here.
Here is the code of the radio group, which does the partial refresh on change:
<xp:radioGroup id="rbgSelectEducationType" layout="pageDirection"
value="#{docApplication.EducationType}">
<xp:this.readonly>
<![CDATA[#{javascript:docApplication.getItemValueString("ZwfStepName") != "Start"}]]></xp:this.readonly>
<xp:selectItem itemLabel="ESG Veranstaltung aus dem Katalog"
itemValue="ESG-Veranstaltung">
</xp:selectItem>
<xp:selectItem itemLabel="Externe Veranstaltung"
itemValue="Externe-Veranstaltung">
</xp:selectItem>
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="wcEventDetails">
</xp:eventHandler>
</xp:radioGroup>
And here is the code of the filtering select dropdown:
<xe:djFilteringSelect id="Approver" value="#{docApplication.Approver}" ignoreCase="true">
<xe:this.rendered><![CDATA[#javascript:docApplication.getItemValueString("ZwfStepName")=="Start"}]]></xe:this.rendered>
<xp:selectItems id="selectItems2">
<xp:this.value><![CDATA[#{javascript:if(docApplication.isEditable()){
getComponent("AllUsersLastFirst").getValue().split("#");
}}]]></xp:this.value>
</xp:selectItems>
<xp:eventHandler event="onChange" submit="true" refreshMode="partial" refreshId="panelBody" id="eventHandler2">
<xp:this.action><![CDATA[#{javascript:var dbPR = new Array(applicationScope.srv, applicationScope.pathPR);
var Approver:com.ibm.xsp.extlib.component.dojo.form.UIDojoFilteringSelect = getComponent("Approver");
var lookup=#DbLookup(dbPR,applicationScope.xpPersonByLastNameFirstName,Approver.getValue(),2);
lookup=#If(#IsError(lookup),"error",lookup);
if (lookup=="error") {
errormsg = valstrings.getString("ccEsgDocWflContentApprover.lookup1");
globalScriptErrors.add(errormsg);
requestScope.put("scriptErrors", globalScriptErrors);
}
#SetField("NotesNameApprover", lookup);}]]></xp:this.action>
</xp:eventHandler>
</xe:djFilteringSelect>
The filtering select is composed of a number of HTML elements (Firebug is your friend here). When you do a partial refresh that doesn't include the select itself, it isn't drawn again, thus the dropdown stays at the same position. The short answer: include the dropdown in the partial refresh.
I have a name picker attached to the input but also want to allow type-ahead in a second field attached to the name picker, and then add the selected entry in the type-ahead control to the dojo name text box control.
In the typeahead onchange event, I can get the value of it and I can get the values in the Name Text Box control, but each entry in the NameTextBox is a spanned link like this:
<SPAN tabIndex=0 val="**abbreviatedNotesName**"><A class=lotusFilter tabIndex=-1 href="javascript:;">**commonNotesName**<SPAN class=lotusClose>x</SPAN></A></SPAN>
Do I need to re-write the innerHTML of the NameTextBox, and guess at the commonname from the typeahead result? Or, is there a better way? Thanks for any help/suggestions.
Here's the code:
<div id="copyToRow">
<div class="namePickerContainer">
<xe:namePicker id="namePicker1" for="fld_copyto_recipients">
<xe:this.dataProvider>
<xe:namePickerAggregator>
<xe:this.dataProviders>
<xe:dominoNABNamePicker addressBookSel="all"
nameList="peopleAndGroups">
</xe:dominoNABNamePicker>
<xe:dominoViewNamePicker labelColumn="$1"
viewName="($VIMPeople)" databaseName="#{javascript:viewScope.personalNAB;}"
label="#{javascript:viewScope.personalNABTitle;}">
</xe:dominoViewNamePicker>
</xe:this.dataProviders>
</xe:namePickerAggregator>
</xe:this.dataProvider>
</xe:namePicker>
<xp:div id="copyToContainer" styleClass="addresseeContainer">
<xe:djextNameTextBox id="fld_copyto_recipients"
value="#{sendFilesDoc.file_CopyToRecipients}" multipleSeparator=","
style="min-height:1.5em;" multipleTrim="true">
</xe:djextNameTextBox>
<xp:inputTextarea id="copyto_typeahead">
<xp:typeAhead mode="partial" minChars="1"
preventFiltering="true">
<xp:this.valueList><![CDATA[#{javascript:getComponent("namePicker1").getTypeAheadValue(this)}]]></xp:this.valueList>
</xp:typeAhead>
<xp:eventHandler event="onchange" submit="true"
refreshMode="partial" refreshId="copyToRow">
<xp:this.script><![CDATA[var copyTo = XSP.getElementById("#{id:copyto_typeahead}");
var result = XSP.getElementById("#{id:copyToTA}");
var newEntry = '<SPAN tabIndex=0 val="' + copyTo.value + '"><A class=lotusFilter tabIndex=-1 href="javascript:;">' + copyTo.value + '<SPAN class=lotusClose>x</SPAN></A></SPAN>';
//Format: <SPAN tabIndex=0 val="<abbreviated NotesName>"><A class=lotusFilter tabIndex=-1 href="javascript:;">common NotesName<SPAN class=lotusClose>x</SPAN></A></SPAN>
result.value = copyTo.value;
var copyToRecipients = XSP.getElementById("#{id:fld_copyto_recipients}");
//<INPUT style="MIN-HEIGHT: 1.5em" id=view:_id1:include1:fld_copyto_recipients type=text name=view:_id1:include1:fld_copyto_recipients dojoType="extlib.dijit.NameTextBox">
var copyToValue = copyToRecipients.innerHTML;
alert('copytorecipients innerHTML = ' + copyToValue);
alert('copytorecipients value = ' + document.getElementById("#{id:fld_copyto_recipients}").value); <-- undefined
var copyToArray = new Array();
var a = document.getElementsByName("#{id:fld_copyto_recipients}");
copyToArray = (a[0].value.split(','));
copyToArray.push(result.value);
//copyToRecipients.value = copyToArray.join(','); <-- this does not work
alert('copyToArray value = ' + copyToArray.join(','));
result.value = copyToArray.join(',');
copyTo.value = "";
return;]]></xp:this.script>
</xp:eventHandler>
</xp:inputTextarea>
</xp:div>
<xp:inputText id="copyToTA">
</xp:inputText>
</div></div>
What I think was tripping me up was required validation on the NameTextBox seemed to prevent the onchange event in the typeahead from firing. Who knows? Went through a lot of iterations ... I ended up adding Tommy Valand's JS function to control when validation is triggered & that seemed to fix things.
Bound the NameTextBox to the datasource field. Bound the typeahead to a requestScope variable. The typeahead onchange event code below also does a partial refresh on a container panel that wraps the 2 inputs.
/* append the typeahead name to those already selected */
var curVals:java.util.Vector = sendFilesDoc.getItemValue("file_SendToRecipients");
curVals.addElement(requestScope.sendToTypeAhead);
sendFilesDoc.replaceItemValue("file_SendToRecipients",curVals);
requestScope.sendToTypeAhead = null;
Then in the NameTextBox onChange event that also partial refreshes the container panel:
/*
remove duplicates that can be picked if the format of the displayed name in the right panel of the
name picker dialog doesn't match the column returned from the picker -- for instance, this will
happen on internet-style names stored in the user's personal names.nsf
e.g. FName LName <user#somecompany.com>
*/
var thisField:javax.faces.component.UIInput = getComponent("fld_sendto_recipients");
var theNames = #Unique(thisField.getValue());
thisField.value = theNames;
So you end up with something similar to how MSN hotmail works. Just have one final issue to try to resolve and that's how to get the cursor to return to the typeahead field after either using the namepicker or making a typeahead choice. Added this code as per this post on the client onchange event of the NameTextBox but the cursor just jumps into the typeahead field but then immediately jumps out:
/* set focus back on the typeahead input -- the input is a child of the typeahead dojo widget */
/* matches any <input> that is a child of the .dijitInputField class of the <div> for the typeahead */
var el = dojo.query('div[widgetid*="sendto_typeahead"] .dijitInputField > input').at(-1)[0].focus();
Any help??? Or, suggestions for solution improvement??