OnChange of fields we have various validation that fires and, once that validation is completed we need to fire the parent fieldGroup's expressions.
My fields are grouped in pairs, so each fieldGroup holds two fields.
OnChange of one of the two fields I want to be able to access said field's parent fieldGroup in order to run its runExpression() function
try using $scope.$parent.model inside the onChange function
Related
In an xpage I have two select2 lists. The choice in the first select box directs the options in the second select box.
The lists are defines via List Box controls.
In order to have select2 applied to them I have a scriptblock
$(document).ready(
function(){
x$("#{id:list1}").select2();
}
)
$(document).ready(
function(){
x$("#{id:list2}").select2();
}
)
$(document).ready(
function(){
x$("#{id:list1}").on("change", function(e) {
XSP.partialRefreshPost("#{id:pnlList2}"
})
pnlList2 contains the second list box.
The problem is that the validation for the second list is triggered when the first list box changes in value.
I tried to apply as parameters:
'params': {
'disableVal':'true'
}
but that does not work as desired.
anyone has a suggestion?
There are a couple of ways to go about it, but I prefer the most performing one, that is partial execution. Partial execution should be mandatory as a best practice.
What happens with your code is that you refresh a portion of your page while validating the whole of it. By doing this the second select gets caught without value.
I would define the onchange param for the combobox - not the event handler - so that the select2 will automatically pick up the event without declaring it through JavaScript later on as you do.
Just use:
<xp:combobox onchange=“XSP.partialRefreshPost('#{id:select2Id}', { execId: '#{id:select1Id}' }”
As I said select2 will see the onchange declared in this way and honor it. When it will fire only the combobox1 will be evaluated, thus automatically skipping any other validation on the page because not included. At this point the second select will not complain and be refreshed.
An additional word of advice is to reinitialize the second combobox with select2 because the partial refresh will destroy it. Better to expand the partial refresh area to include both the combobox and the scriptBlock specific for the second select.
In JSF we can use
valueChangeListener attribute
or
<f:valueChangeListener type=""/>
to listen for ValueChange Events for Individual components.
Is there any way that i can apply the ValueChangeListner to group of
components or entire form?
Edit:
The basic idea is, There is a huge form of around 30
components[input-texts,text-areas,select-many-menu,select-one-menu.....]
and some of them will be pre-populated.
I want to notify the user whenever there is value change in any one component of this entire
form.
No. You can apply the same value change listener for multiple components, and you will need to handle it programatically
On a XPage how can I clear some fields when a certain radio button is pressed?
The fields are on a panel. Outside of that panel are some radio buttons. In the onChange of the radio buttons I change the render property of the panel via a viewScope variable and a partial refresh of the panel to make it disappear. This works. I just want to be able to also blank out the fields as well, else the values are saved when the users submits!
The SSJS equivalent of the modifyField simple action is the setValue method of the document data source; for example:
currentDocument.setValue("fieldName", null);
If someone tells you to instead call getComponent("someId").setValue(null)... don't. At first glance, that also works, but it's less efficient, fragile, and doesn't work when the target component is in a repeat control but the event component is outside the repeat. Always update the data source directly... any components bound to that data source will automatically pick up any changes you make.
Add an event that will modify the field on onchange event and refresh the area you want to change.
<xp:modifyField
var="document1"
name="FIELDNAME"
value="">
</xp:modifyField>
Use client side onChange to run whichever of these dojo's, where the < parentID > is the id of the container the RadioButton or RadioGroup is within:
dojo.query("*[type=radio]:checked",dojo.byId(parentID)).forEach(function(node, index, nodelist){
node.checked=false;
});
dojo.query("*[type=checkbox]:checked",dojo.byId(parentID)).forEach(function(node, index, nodelist){
node.checked=false;
});
dojo.query("input",parentID).
forEach(function(node, index, nodelist){
node.value = "";
})
//reset(
I have a Check box group, whose values are computed by using the selected values of another Check box group. So when I do
var check6:com.ibm.xsp.component.xp.XspSelectManyCheckbox = getComponent("check6");
ArrSelected = check6.getSelectedValues();
to get the selected values, the following exception occurs:
Error calling method 'getSelectedValues()' on java class 'com.ibm.xsp.component.xp.XspSelectManyCheckbox'
java.util.ArrayList incompatible with [Ljava.lang.Object;
Check6 gets its values from a session scope variable that is computed on beforePageLoad event and I have also set the default value.
Note that this does not happen onload of the page, but when the first partial refresh happens. Does anyone know what this exception indicates?
Thanks a lot!
Bind the value of the selectItems for the second check box group to precisely the same expression the first checkbox group's value attribute is bound to.
This article provides a lengthy description of the reason why, but here's a very quick summary: if you ask a component what its value is, it has to ask the data it's bound to. So skip the component, and ask the data yourself.
So, if your first group looks like this:
<xp:checkBoxGroup value="#{currentDocument.FirstField}">...
Then your second group should look like this:
<xp:checkBoxGroup value="#{currentDocument.SecondField}">
<xp:selectItems value="#{currentDocument.FirstField}">
</xp:checkBoxGroup>
When the user's selection in the first group is posted to the data source, the second group will reflect the changes because they're linked to the same property on that data source. Slight caveat: if your page includes any required fields, you may need to skip validation on the onchange event that triggers the second group to recalculate.
the reason is simple, this class has no method getSelectedValues() (as far as I can see it, look here for more info: http://public.dhe.ibm.com/software/dw/lotus/Domino-Designer/JavaDocs/XPagesExtAPI/8.5.2/index.html?overview-summary.html)
Maybe you could bind the control to a scoped variable and then access this variable to compute your other values?
I am struggling with the following.
On my XPage I have a viewpanel component, but it is not bound to a notesview datasource, but to a hashmap stored in viewScope. Reasons for this is beyond scope of my question.
Since the lines in my view are not actually linked to the documents I cannot use the standard checkboxes and the related getSelectedDocIds. I do however want a way to remove the selected documents. I have a column with checkboxes containing the unid of the corresponding row.
So long story short. I have an array of unids and want to perform an action that does the following:
Display a dijit.Dialog asking for confirmation
If OK clicked call a function that does the following:
Remove the documents based on the unids
Refresh the viewpanel
I am thinking of the following 2 solutions, but in doubt what would be best (maybe a third, even simpler solution?)
Have the OK button of the dojo dialog call a function that does an XmlHttpRequest to an XAgent or plain old LS agent
Have the OK button trigger an eventhandler that runs on the server as described by JeremyHodge here. But how would I pass the unids as parameter and refresh the view afterwards?
Thanks!
Cant you just make use of the extension library dialog with the dialog button control. In this button control you can then
A third option would be to add a column to your datatable/view which contains checkboxes. On the onchange event of these boxes you add an eventhander which adds the value to a viewScope variable.
A button on the bottom (or top.) of the page you add the code you need to remove the selected items from the hashmap, delete the documents associate with the selected id's. this button can be a ordinary button with a partial refresh on the viewpanel. When you run into the bug that you cant use buttons in a dialog please use the extension library dialog control because this fixes that issue for you.
If the current user does not have the correct access level to delete documents you could use the sessionAsSigner global (assuming the signer of the design element has the correct access levels).
This way you dont need to go call an xAgent by xmlthttprequest and can stay with the default xpage methodology.
I hope this helps in some way
I would second #jjbsomhorst in the use of the extension library for the dialog box - if you use one at all. Usually users don't read dialog boxes. So the approach would be add the column with the checkboxes, but don't bother with an event handler, but bind them ALL with their value to ONE scopeVariable. On submission that variable will then hold an array with the selected UNID.
Then render a page that lists these documents and have a confirm button. While the new page affords a server round-trip the likelihood, that users actually pay attention is way higher. What you can do:
Have the normal page that renders the dialog with editable checkboxes and when the user clicks "Delete" you set something like viewScope.confirmDeleteMode=true; and use that as condition for the checkboxes and make them read-only AND set the class of the selected rows to "morituri" which in your CSS would have something like .morituri { color: white; background-color : red; font-weight: bold } and a new button "Confirm Delete" (and hide the Delete button).
This way you only have one page to deal with.
I went for option 2, which has the possibility to provide the partial refresh id. I passed the unids as a submitvalue like:
function doRemove(unids){
XSP.executeOnServer(ISP.UI.removeEventID, ISP.UI.removeRefreshID, {
params: {
'$$xspsubmitvalue': unids
},
onComplete : function() {
//alert('test')
}
});
}
The ISP.UI.removeEventID performs the following code:
var unids = context.getSubmittedValue();
removeDocuments(unids); //SSJS function performing the actual delete
viewScope.reload = 'reload' //triggers the hashmap to be rebuild based on new documentcollection