read value editbox in ssjs in a custom control - xpages

I have a custom control with an editbox in a modal:
<xp:inputText id="inputText1"></xp:inputText>
In the onclick event of a button , I would like to read the value of this editbox
var demo = getComponent("inputText1").getValue();
Of course this doesn't work in a custom control, since he doesn't has a handle to inputText1. How can this be done ?
EDIT
Herewith I'm posting my 'whole' code.
Even with a scoped variable it isn't working .... :(
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:this.resources>
<xp:styleSheet href="bootstrap-modal.css"></xp:styleSheet>
<xp:script src="/bootstrap-modalmanager.js" clientSide="true"></xp:script>
<xp:script src="/bootstrap-modal.js" clientSide="true"></xp:script>
<xp:script src="/JQueryXSnippet.js" clientSide="true"></xp:script>
</xp:this.resources>
<div id="Modal1" class="modal fade" tabindex="-1" data-focus-on="input:first" style="display: none;">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Modal One</h4>
</div>
<div class="modal-body">
<p>Modal 1 </p>
<div class="form-group">
<label for="inputText1">First Name:</label>
<xp:inputText id="inputText1" value="#{viewScope.input1}">
<xp:this.attrs>
<xp:attr name="class" value="form-control"></xp:attr>
<xp:attr name="data-tabindex" value="1"></xp:attr>
</xp:this.attrs>
</xp:inputText>
</div>
<xp:button value="Demo" id="button2">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="demoPanel">
<xp:this.action><![CDATA[#{javascript:viewScope.message = "input1 = "+viewScope.input1;}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:panel id="demoPanel">
<xp:text escape="true" id="computedField1"
value="#{viewScope.message}">
</xp:text>
</xp:panel>
</div>
<div class="modal-footer">
<button type="button" data-dismiss="modal" class="btn btn-primary">Close</button>
</div>
</div>
<xp:scriptBlock id="scriptBlock1">
<xp:this.value><![CDATA[
$(document).ready(function(){
x$("#{id:button1}").click(function(){
x$("#{id:Modal1}").modal(
{backdrop: true,
keyboard: false,
show: true
}
);
});
});
]]></xp:this.value>
</xp:scriptBlock>
<xp:button value="Login" id="button1" styleClass="btn btn-info btn-lg">
</xp:button>
</xp:view>

The advice from Tim Tripcony was to go to the model layer, not the component. As ever, he was spot on. Bind the Edit Box to something, probably in this scenario a viewScope variable. Then retrieve the value from that. It's likely to be more efficient than getComponent().

There are two ways that spring to mind are worth trying:
Add the button to the custom control and that way, it'll just work as is.
Set the id to be computed from a custom property of the control control-id and pass in a string e.g. my-made-up-id and then refer to it from any button out-with the custom control. Note the ${} binding is needed when computing the id.
Custom Control
<xp:inputText
id="${javascript:compositeData.control-id}">
</xp:inputText>
XPage
<xc:FieldTest control-id="my-made-up-id"></xc:FieldTest>
<xp:button
value="Get Value"
id="button1">
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:var demo = getComponent("my-made-up-id").getValue();
print("Demo: " + demo);}]]></xp:this.action>
</xp:eventHandler>
</xp:button>

Related

XPages: checkbox (groups) looses their value(s) when changing to edit mode

Crazy effect: I open a (previously saved) doc in read mode: Everthing is ok. When I change it into edit mode: All checkboxes are emptied. The other items (inputText, inputTextarea) on the xpage keep their values.
The effect doesn¨t occur when I open the page for the first time (of my browser session), but after that it happens every time.
code snippet:
<xp:panel id="pNewDoc" styleClass="panel panel-default">
<xp:this.data>
<xp:dominoDocument var="dshare" formName="dshare"
action="openDocument"
databaseName="webapp/peoplesearch/dshare.nsf">
<xp:this.documentId><![CDATA[#{javascript:viewScope.myUnid}]]></xp:this.documentId>
</xp:dominoDocument>
</xp:this.data>
<xp:this.rendered><![CDATA[#{javascript:viewScope.ShowDoc == "1"}]]></xp:this.rendered>
<div class="panel-heading">
<xp:label value="Desk Sharing Freigabe" id="label7"
for="inputText1" styleClass="panel-title">
</xp:label>
</div>
<xp:div styleClass="panel-body">
<div class="row hvrow">
<xp:label value="Owner" id="label2"
styleClass="col-sm-2 col-md-2">
</xp:label>
<xp:div styleClass="col-sm-4 col-md-4">
<xp:inputText id="inputText4"
value="#{dshare.anOwner}"
defaultValue="#{javascript:#UserName()}" disabled="true">
</xp:inputText>
</xp:div>
<xp:label value="Tel." id="label6"
styleClass="col-sm-2 col-md-2">
</xp:label>
<xp:div styleClass="col-sm-4 col-md-4">
<xp:inputText id="inputText5"
value="#{dshare.dsPhoneNumber}">
<xp:this.defaultValue><![CDATA[#{javascript:var
dbArray = [""];
dbArray.push("webapp/peoplesearch/psuser_20160610.nsf")
#DbLookup(dbArray,"lookupFullname",#UserName(),"OfficePhone")}]]></xp:this.defaultValue>
</xp:inputText>
</xp:div>
</div>
<div class="row">
<xp:label value="Von bis" id="label1"
styleClass="col-sm-2 col-md-2">
</xp:label>
<xp:div
styleClass="col-sm-4 col-md-4 form-inline">
<xp:inputText id="inputText1"
value="#{dshare.dsFrom}" style="width:45%">
<xp:dateTimeHelper id="dateTimeHelper3">
</xp:dateTimeHelper>
<xp:this.converter>
<xp:convertDateTime type="date"
dateStyle="short">
</xp:convertDateTime>
</xp:this.converter>
</xp:inputText>
 - 
<xp:inputText id="inputText2"
value="#{dshare.dsTo}" style="width:45%">
<xp:dateTimeHelper id="dateTimeHelper4">
</xp:dateTimeHelper>
<xp:this.converter>
<xp:convertDateTime type="date"
dateStyle="short">
</xp:convertDateTime>
</xp:this.converter>
</xp:inputText>
</xp:div>
<xp:label value="Zeitspanne" id="label3"
styleClass="col-sm-2 col-md-2">
</xp:label>
<xp:div styleClass="col-sm-4 col-md-4">
<xp:checkBoxGroup id="checkBoxGroup1"
value="#{dshare.dsPeriod}">
<xp:selectItem itemLabel="Vormittag"
itemValue="V">
</xp:selectItem>
<xp:selectItem itemLabel="Nachmittag"
itemValue="N">
</xp:selectItem>
</xp:checkBoxGroup>
</xp:div>
</div>
<div class="row">
<xp:label value="Details" id="label9"
styleClass="col-sm-2 col-md-2">
</xp:label>
<xp:div styleClass="col-sm-10 col-md-10">
<xp:inputTextarea id="inputTextarea1"
style="width:100%" rows="5" value="#{dshare.dsDetails}">
</xp:inputTextarea>
</xp:div>
<xp:label value="Status" id="label10"
styleClass="col-sm-2 col-md-2">
</xp:label>
<xp:div styleClass="col-sm-4 col-md-4">
<xp:checkBox text="aktiv" id="checkBox1"
value="#{dshare.dsStatus}" checkedValue="activ"
uncheckedValue="inactiv" defaultChecked="true">
</xp:checkBox>
</xp:div>
</div>
</xp:div>
<div class="panel-footer" style="text-align:right">
<xp:button value="Bearbeiten" id="btEdit" type="submit"
rendered="#{javascript:!dshare.isEditable()}">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" immediate="false" save="false"
refreshId="pNewDoc" execMode="partial" execId="pNewDoc">
<xp:this.action>
<xp:changeDocumentMode mode="edit"></xp:changeDocumentMode>
</xp:this.action>
</xp:eventHandler>
</xp:button>
<xp:button value="Speichern" id="btSave" type="submit"
rendered="#{javascript:dshare.isEditable()}">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" immediate="false" save="false"
refreshId="pDSall" execMode="partial" execId="pDSall">
<xp:this.action><![CDATA[#{javascript:viewScope.ShowDoc = "0"
qsave(dshare);}]]></xp:this.action>
</xp:eventHandler>
</xp:button>
</div>
</xp:panel>
Your button has the property type="submit":
<xp:button
value="Bearbeiten"
id="button2"
type="submit"
rendered="#{javascript:!dshare.isEditable()}">
...
It is responsible for your issue.
Just delete type="submit" and your check boxes will work with setting edit mode by partial refresh:
<xp:button
value="Bearbeiten"
id="btEdit"
rendered="#{javascript:!dshare.isEditable()}">
<xp:eventHandler
event="onclick"
submit="true"
refreshMode="partial"
immediate="false"
save="false"
refreshId="pNewDoc"
execMode="partial"
execId="pNewDoc">
<xp:this.action>
<xp:changeDocumentMode mode="edit"></xp:changeDocumentMode>
</xp:this.action>
</xp:eventHandler>
</xp:button>

Visibility property not working as expected on XPage

Based upon the value/selection in a radiobutton group control I want to display another div containing an edit box control.
The code does not work as expected. Although the scope variable is set, the div never appears again when the visibility is set to false and I change the radiobutton selected value to Yes.
What am I doing incorrect?
<div class="form-group">
<label class="control-label col-sm-4">Membership</label>
<div class="col-sm-8">
<xp:radioGroup value="#{employeeBean.employee.stafMember}" binding="#{stafMember}"
id="stafMember">
<xp:selectItem itemLabel="Yes" />
<xp:selectItem itemLabel="No" />
<xp:eventHandler event="onchange" submit="true"
refreshMode="partial" refreshId="stafMemberDept" disableValidators="true">
<xp:this.action><![CDATA[#{javascript:var thisVal = getComponent("stafMember").getValue();
viewScope.put("stafMember", thisVal);}]]></xp:this.action>
</xp:eventHandler>
</xp:radioGroup>
</div>
</div>
<xp:div styleClass="form-group"
id="stafMemberDept">
<xp:this.rendered><![CDATA[#{javascript:var thisVal = viewScope.get("stafMember");
if(thisVal=="Yes"){
return false;
}
else if (thisVal == "No"){
return true;
}
else{
return false;
}}]]></xp:this.rendered>
<!-- just some fields to test the value of the radio group -->
<xp:text escape="true" id="computedField1"
value="#{javascript:stafMember.getValue()}">
</xp:text>
<xp:text escape="true" id="computedField2">
<xp:this.value><![CDATA[#{javascript:getComponent("stafMember").getValue()}]]></xp:this.value>
</xp:text>
<xp:text escape="true" id="computedField3">
<xp:this.value><![CDATA[#{javascript:"v" + viewScope.get("stafMember") + "v"}]]></xp:this.value>
</xp:text>
<label class="control-label col-sm-4"
style="font-size: 75%">
Department:
</label>
<div class="col-sm-8">
<xp:inputText id="inputText1"></xp:inputText>
</div>
</xp:div>
You need to refresh a component that stays in the component tree in order to show/hide components. So surround your stafMemberDept div with annother div that you then refresh:
<xp:div id="divToBeRefreshed">
<xp:div styleClass="form-group" id="stafMemberDept">
<xp:this.rendered>
<![CDATA[#{javascript:var thisVal = viewScope.get("stafMember");
if(thisVal=="Yes"){
return false;
}
else if (thisVal == "No"){
return true;
}
else{
return false;
}}]]>
</xp:this.rendered>
<!-- just some fields to test the value of the radio group -->
<xp:text escape="true" id="computedField1" value="#{javascript:stafMember.getValue()}">
</xp:text>
<xp:text escape="true" id="computedField2">
<xp:this.value>
<![CDATA[#{javascript:getComponent("stafMember").getValue()}]]>
</xp:this.value>
</xp:text>
<xp:text escape="true" id="computedField3">
<xp:this.value>
<![CDATA[#{javascript:"v" + viewScope.get("stafMember") + "v"}]]>
</xp:this.value>
</xp:text>
<label class="control-label col-sm-4" style="font-size: 75%">
Department:
</label>
<div class="col-sm-8">
<xp:inputText id="inputText1"></xp:inputText>
</div>
</xp:div>
</xp:div>

Using Bootstrap Accordion Panels

Been struggling with jQuery syntax. I am trying to setup some JS code to expand/collapse an accordion panel (http://www.w3schools.com/Bootstrap/bootstrap_collapse.asp). I can get it to expand and collapse with x$("#{id:collapsePanel2}").collapse("toggle"); That works fine but does not collapse the other panels. You can see this at https://www.netexperts.com/xpages1.nsf/collapse.xsp. There is a "parent" parameter which says it takes the selector. I have tried "#view:_id1:accordion" (the generated id of the parent panel), I have tried parent="#view:_id1:accordion" and a few other combinations. The docs at http://www.w3schools.com/Bootstrap/bootstrap_ref_js_collapse.asp under the .collapse options say the parent is a parameter that takes the parent selector but I can't seem to pass this in without throwing a JS error.
<?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">
<xe:navbar
id="navbar1"
headingText="Collapse Panel"
pageWidth="full">
</xe:navbar>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:panel
styleClass="panel-group"
id="accordion">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<xp:link
escape="true"
id="link1">
Collapsible panel
<xp:eventHandler
event="onclick"
submit="false">
<xp:this.script><![CDATA[
//function is called using x$("#{id:inputText1}", " parameters").
x$("#{id:collapsePanel}").collapse( "toggle");
function x$(idTag, param){ //Updated 18 Feb 2012
idTag=idTag.replace(/:/gi, "\\:")+(param ? param : "");
return($("#"+idTag));
}
]]></xp:this.script>
</xp:eventHandler>
</xp:link>
</h4>
</div>
<xp:panel
id="collapsePanel"
styleClass="panel-collapse collapse">
<div class="panel-body">Panel Body</div>
<div class="panel-footer">Panel Footer</div>
</xp:panel>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<xp:link
escape="true"
id="link2">
Collapsible panel
<xp:eventHandler
event="onclick"
submit="false">
<xp:this.script><![CDATA[
//function is called using x$("#{id:inputText1}", " parameters").
x$("#{id:collapsePanel2}").collapse("toggle");
function x$(idTag, param){ //Updated 18 Feb 2012
idTag=idTag.replace(/:/gi, "\\:")+(param ? param : "");
return($("#"+idTag));
}
]]></xp:this.script>
</xp:eventHandler>
</xp:link>
</h4>
</div>
<xp:panel
id="collapsePanel2"
styleClass="panel-collapse collapse">
<div class="panel-body">Panel Body</div>
<div class="panel-footer">Panel Footer</div>
</xp:panel>
</div>
</xp:panel>
</xp:view>
You need to update the jquery something like this
$( "#link" ).on( "click", function(event) {
event.preventDefault();
$('#accordion .panel-collapse').collapse('hide');
$('#collapseTwo').collapse('toggle');
});
Working example http://bootsbin.com/bin/view/46/

Xpages: Dynamic View Panel - Sorting

In my dynamic view panel, I need to have sortable columns. Problem is when sorting a column it resubmits the XPage and whole content is refreshed. Is there a way to achieve sorting only on the dynamic view panel without submitting whole page? Also, I want to hide this control if selected view is empty.
Here is my code:
<xp:panel id="searchPanel">
<xp:table styleClass="table table-condensed" style="width:auto">
<xp:tr>
<xp:td style="border-top:0px" styleClass="text-nowrap" id="searchColumn">
<xp:inputText id="inputText1" value="#{viewScope.searchterm}" styleClass="form-control"></xp:inputText>
<xp:link escape="true" text="" id="searchLink">
<i class="fa fa-search" style="margin-left:5px"></i>
<xp:eventHandler event="onclick" refreshMode="partial" immediate="false" submit="true" refreshId="ddPanel">
<xp:this.action><![CDATA[#{javascript:var pager:com.ibm.xsp.component.xp.XspPager = getComponent("pager");
pager.gotoFirst();}]]></xp:this.action>
</xp:eventHandler>
</xp:link>
<xp:link escape="true" text="" id="clearSearchLink">
<i class="fa fa-times" style="margin-left:5px"></i>
<xp:eventHandler event="onclick" submit="true" refreshMode="partial" refreshId="ddPanel" onComplete="showHideTableToggle()">
<xp:this.action><![CDATA[#{javascript:viewScope.remove("searchterm");}]]></xp:this.action>
<xp:this.script><![CDATA[dojo.byId(getID("inputText1")).value=""]]></xp:this.script>
</xp:eventHandler>
</xp:link>
</xp:td>
<xp:td style="border-top:0px;padding-left:20px">
<xp:link escape="true" id="addButton" onclick="return false;" styleClass="btn btn-primary" style="color:rgb(255,255,255)" text="Add">
<i class="fa fa-plus" style="margin-right:5px"></i>
<xp:eventHandler event="onclick" submit="false" refreshMode="complete">
<xp:this.script><![CDATA[XSP.openDialog(getID('contentDialog'),'',{"docID":"","newDoc":"false"});]]></xp:this.script>
</xp:eventHandler>
</xp:link>
</xp:td>
</xp:tr>
</xp:table>
<xp:panel id="ddPanel">
<xe:dynamicViewPanel id="mainView" width="100%" dataTableStyleClass="table table-bordered table-condensed table-hover" rows="10" var="myView"
showColumnHeader="true" customizerBean="com.hcl.igdm.PickerViewBeanMainViews" partialRefresh="true" refreshId="ddPanel"
>
<xe:this.data>
<xp:dominoView var="mainDataView" dataCache="nodata">
<xp:this.viewName><![CDATA[#{javascript:sessionScope.showView.split("~")[0]}]]></xp:this.viewName>
</xp:dominoView>
</xe:this.data>
<xe:this.rowAttrs>
<xp:attr name="onClick">
<xp:this.value><![CDATA[#{javascript:return "javascript:myJSFunction();"}]]></xp:this.value>
</xp:attr>
</xe:this.rowAttrs>
</xe:dynamicViewPanel>
<xp:pager layout="Previous Group Next" partialRefresh="true" id="pager" for="mainView" title="Pager"></xp:pager>
</xp:panel>
It's a long time ago this question was placed... but maybe the answer can help other people.
You can put the dynamicViewPanel into a 'dynamic content' container (from ExtLib) with partial events attribute set to true. This will convert the full update events into partial refresh events.
<xe:dynamicContent partialEvents="true">
...
</xe:dynamicContent>

Required Date Time Picker has always "aria-invalid=false"

I'm not sure if I am missing out a very simple thing. Normally, XPages maintain "aria-required" and "aria-invalid" attributes for validation.
However, for DateTime Picker (standard one), it's always aria-invalid="false".
Here is a simple test I have used in Domino 9.0.1:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:this.data>
<xp:dominoDocument var="document1" formName="TestForm"></xp:dominoDocument>
</xp:this.data>
<xp:button value="Label" id="button1">
<xp:eventHandler event="onclick" submit="true"
refreshMode="partial" refreshId="panel1">
</xp:eventHandler>
</xp:button>
<xp:panel id="panel1">
<xp:inputText id="inputText1" required="true">
<xp:dateTimeHelper id="dateTimeHelper1"></xp:dateTimeHelper>
<xp:this.converter>
<xp:convertDateTime type="date"></xp:convertDateTime>
</xp:this.converter>
</xp:inputText>
<xp:messages id="messages1"></xp:messages>
</xp:panel>
</xp:view>
Generated HTML before the button clicked contains:
<input type="text" aria-haspopup="true" role="textbox" data-dojo-attach-point="textbox,focusNode" autocomplete="off" class="dijitReset dijitInputInner" aria-invalid="false" tabindex="0" aria-required="true" id="view:_id1:inputText1" value="">
After clicking, I can see Messages component has been aggregated but aria-invalid is false.
<input type="text" aria-haspopup="true" role="textbox" data-dojo-attach-point="textbox,focusNode" autocomplete="off" class="dijitReset dijitInputInner" aria-invalid="false" tabindex="0" aria-required="true" id="view:_id1:inputText1" value="">
(I removed dojo stuff wrapping the input)
After some digging, I found that this problem is not related to XPages.
XPages provides the aria-invalid attribute correctly if validation fails. However, dojo controls automatically change it during rendering. So it's not possible unless you inject a correction into Dojo component rendering code.

Resources