I need to access the old value of ADF viewObject - oracle-adf

I have ADF page fragement (.jsff), which conatins ADF form based on ViewObject, I need to get the old value of af:RichInputField using EL expression, when I use:
#{bindings.fieldName.inputValue}, it gets the new submitted value, but what I need is the value before submission...

You can use the valueChangeListener attribute (https://docs.oracle.com/cd/E21043_01/apirefs.1111/e12046/oracle/adf/view/js/event/AdfValueChangeEvent.html) of your af:RichInputField to trigger a java function in a bean that will get the new value and the old value for you to do whatever you want.
Here is a quick example with an inputText (It would work in a similar way with any ADF Faces input) :
//In your jsff
<af:inputText value="#{bindings.YOUR_VO_BINDING_VALUE.inputValue}"
valueChangeListener="#{YOUR_BEAN_SCOPE.YOUR_BEAN.itChange}"
id="it">
<f:validator binding="#{bindings.YOUR_VO_BINDING_VALUE.validator}"/>
</af:inputText>
//In your YOUR_BEAN_SCOPE.YOUR_BEAN
public void itChange(ValueChangeEvent valueChangeEvent) {
String oldValue = valueChangeEvent.getOldValue();
String newValue = valueChangeEvent.getNewValue();
//do whatever you want with those values
}
If you need to set a binding value in the [//do whatever you want with those values] please read https://cedricleruth.com/how-to-set-jsf-binding-attribute-programmatically-in-oracle-adf/ :
JSFUtils.setExpressionValue("#{bindings.YOUR_VO_ATTRIBUTE.inputValue}",oldValue);

Related

How to check if records related to fields in custom metadata are changed

I have a scenario where I need to check in opportunity update if particular field values of opportunity which are mentioned in metadata are changed or not, if these values are changed meaning that that record would be considered for update. I have done this with field sets but not sure how we can achieve the same using custom metadata. Attaching the code used for field sets here
Public static boolean isValuesChanged(List<Opportunity> newOpportunitiesList, Map<id,Opportunity> oldOpportunityMap)
{
for(Opportunity oppRecord : newOpportunitiesList)
{
for(Schema.FieldSetMember fieldSetMemberObj : SObjectType.Opportunity.FieldSets.Opportunity_Comparision_FieldSet.getFields())
{
if(oppRecord.get(fieldSetMemberObj.getFieldPath()) != oldOpportunityMap.get(oppRecord.id).get(fieldSetMemberObj.getFieldPath()) && oppRecord.Amount > 0)
{
return true;
}
}
}
return false;
}
This is what I have done when I used field sets. The same I want to do using custom metadata.How can I check changes in Apex ?
Thanks in Advance
Cut it into 2 problems.
Given a set of strings with field api names - how to detect changes
Set<String> fields = new Set<String>{'Name', 'CloseDate', 'StageName'};
Set<Id> oppsToProcess = new Set<Id>();
for(Opportunity opp: newList){
Opportunity old = oldMap.get(opp.Id);
for(String field : fields){
if(opp.get(field) != old.get(field)){
oppsToProcess.add(opp.Id);
break;
}
}
}
Given a custom metadata with field names - how do I make a set of strings out of it.
Solution for this one depends what exactly you have in custom meta:
list with multiple records, each with single field's name?
1 record with field names saved in columns like Field1__c, Field2__c, Field3__c
1 record with list of fields stored comma-separated, like Fields__c = 'Name,CloseDate,StageName'
You'll have to do it yourself, query and loop through first one or call String.split(','); on the last one or...

Fetch Id from SelectOneChoice in ADF 12c

I am using Oracle ADF12C, I have a table which has an strong textselect One Choice>(Customized Query) as a column, on change of the value I need to open a popup, I have tried using value Change Listener to fetch the ID but not able to find. Any Suggestions….
I have tried using the JavaScript to fetch the ID, still it did not work
<af:selectOneChoice value="#{row.bindings.ProfileId.inputValue}"
label="#{row.bindings.ProfileId.label}"
required="#{bindings.Assets1.hints.ProfileId.mandatory}"
shortDesc="#{bindings.Assets1.hints.ProfileId.tooltip}"
id="soc7"
binding="#{GenericListenerBean.assetprofileBV}">
<f:selectItems value="#{row.bindings.ProfileId.items}"
id="si8"/>
<f:validator binding="#{row.bindings.ProfileId.validator}"/>
<af:clientListener method="profileLovValue"
type="valueChange"/>
</af:selectOneChoice>
function profileLovValue() {
alert("function called");
var lov_value = document.getElementById('soc8');
alert("Executedd ======"+lov_value);
var strUser = lov_value.options[lov_value.selectedIndex].value;
alert("value ======"+strUser);
}
There is a couple issues in your code. you are doing a :
var lov_value = document.getElementById('soc8');
when your af:selectOneChoice Html DOM ID will be something like "p1::pc2::soc7".
If you want to get the real Html DOM ID of an element from your browser, you need to right-click it in your browser and click Inspect to check the real ID in your console.
Since you are using the oracle ADF framework, you should also avoid JavaScript and use Java with built-in java ADF fonction.
—If you want to get the value of this #{row.bindings.ProfileId.inputValue} use resolveExpression as describe here https://cedricleruth.com/how-to-retreive-the-value-of-an-iterator-binding-variable-programmatically-in-adf/
//Here is how to simply retreive the value of and ADF Binding from the view El Expression :
//Below is a view example with values taken from an ADF View Object
<af:inputText id="it1" autoSubmit="true" value="#{bindings.YOUR_VO.YOUR_VO_ATTRIBUTE.inputValue}" />
<af:table value="#{bindings.YOUR_VO.collectionModel}" var="row">
<af:column sortProperty="#{bindings.YOUR_VO.hints.YOUR_VO_ATTRIBUTE.name}"
id="c1">
<af:outputText value="#{row.YOUR_VO_ATTRIBUTE}" id="ot1"/>
</af:column>
</af:table>
//Using below function you can easily get any of those value in your ADF Bean as follow :
//Note: replace String by the correct type
String inputTextValue= (String)resolveExpression("#{bindings.YOUR_VO.YOUR_VO_ATTRIBUTE.inputValue}");
String currentRowValue= (String)resolveExpression("#{row.YOUR_VO_ATTRIBUTE}");
/**
* Method for taking a reference to a JSF binding expression and returning
* the matching object (or creating it).
* #param expression EL expression
* #return Managed object
* #author : Duncan Mills, Steve Muench and Ric Smith's JSFUtils class
*/
public static Object resolveExpression(String expression) {
FacesContext facesContext = getFacesContext();
Application app = facesContext.getApplication();
ExpressionFactory elFactory = app.getExpressionFactory();
ELContext elContext = facesContext.getELContext();
ValueExpression valueExp = elFactory.createValueExpression(elContext, expression, Object.class);
return valueExp.getValue(elContext);
}
—If you want to get the ID of the element that trigger an event :
public void yourValueChangeEvent(ValueChangeEvent valueChangeEvent) {
String IdOfTheObjectTriggeringTheEvent = valueChangeEvent.getComponent().getId();
}
I think you need change your design to avoid using JavaScript. Oracle ADF run java code on server side.
In the code, you bound the selectOneChoice to assetprofileBV
binding="#{GenericListenerBean.assetprofileBV}">
You can get value of this selectOneChoice by assetprofileBV.getValue() .You can use valueChangeListener attribute to listen when value change and get value

How to avoid page refresh while using selectOneChoice

I am working on JDeveloper 11g Release 2. I am having af:input text elements and af:selectonechoice elements in my form. The problem is with af:selectonechoice element. After selecting a value from this choice list, it refreshes the values of other elements. I mean the values of af:inputtext are lost or the fields becomes empty.
The code for af:selectonechoice is as follows:
<af:selectOneChoice label="User Permission" id="soc"
value="#{row.bindings.UserPermission.inputValue}"
autoSubmit="true" valueChangeListener="#{SomeBean.setSomeValue}">
<af:selectItem label="Administrator" value="ADMIN" id="si1"/>
<af:selectItem label="Manager" value="MANAGER" id="si2"/>
<af:selectItem label="Employee" value="EMPLOYEE" id="si3"/>
</af:selectOneChoice>
Below is the code for input text:
<af:inputText value="XXX" label="XXX" id="id3" readOnly="true" partialTriggers="soc" >
</af:inputText>
Only the above inputText has partialtriggers. This works fine. Also I am sure that other input elements not having any partial triggers. Why the other input elements also being updated. Any ideas regarding this.
EDIT:
<af:column sortProperty="#{bindings.TasksView1.hints.TaskNo.name}"
sortable="true" headerText="Task No" id="c2">
<af:inputText value="#{row.bindings.TaskNo.inputValue}"
label="#{bindings.TasksView1.hints.TaskNo.label}" id="id3"
partialTriggers="soc">
</af:inputText>
</af:column>
And Code for ValueChangeLister is:
public void generateTaskNo(ValueChangeEvent valueChangeEvent){
DCBindingContainer dcBindings = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
DCIteratorBinding iterBind = (DCIteratorBinding)dcBindings.get("TasksView1Iterator");
valueChangeEvent.getComponent().processUpdates(FacesContext.getCurrentInstance());
String task_code = (String)iterBind.getCurrentRow().getAttribute("USERPERMISSION");
task_code = task_code +'-';
String task_no = (String)iterBind.getCurrentRow().getAttribute("TaskNo");
task_code = task_code + task_no;
iterBind.getCurrentRow().setAttribute("TaskNo", task_code );
}
Here i am getting the SelectOneChoice value and Input text value[with id 'id3' ]. Based on the selected choice's value[Admin,manager,employee] i will set the value[TaskNo] in that input text. This should not affect other input fields in the form. But the problem is all other input fields are also updating and losing their previous values. I am sure those input fields don't have any partial triggers.
Your select one choice (SOC) set as auto submit = true. Then any element had partial triggers for SOC, Then that elements get refreshed. element SOC submit his value to server and other elements listen that value. listening elements needs to refreshed for update his value for SOC
The solution for this is if you use select one choice component with list of values you want store the id in database. For suppose your storage "ID" datatype consist integer but in database storage column datatype consist Varchar then soc components automatically refreshed when click save.so let you check the db column and list of values(lov) store value.

Setting Model id With id Property

http://documentcloud.github.io/backbone/#Model-id indicates that the id property of a model is special because if my_model.set("id", <new_id>) is called, my_model.id will have that new value. This property is not commutative, however. Calling my_model.id = 4 followed by my_model.get("id") will not result in 4.
Is there a way to have my_model.id=4 set the value of my_model.attributes.id so that my_model.get("id") will result in 4?
To achieve what you want, you can override the get method of Backbone.Model, but that is not a very good proposition cause there is a reason why model id and id property of attribute are separated from each other, id of model is something local to backbone and id property of the attribute is something that might be used by the remote servers when you sync your model.
So in usual cases, overriding the get function of Model can cause trouble in future.
You can achieves what you want like this :
Backbone.Model.prototype.get = function(attr) {
if (attr == 'id' && this.attributes[attr] != this.id) {
this.attributes[attr] = this.id;
}
return this.attributes[attr];
};

How to validate a pair of values from the same Model?

Use case
My use case is that I need to validate a Table Tennis score.
Form
<input name="data[MatchesPlayer][1][score]" type="number" id="MatchesPlayer1Score">
<input name="data[MatchesPlayer][2][score]" type="number" id="MatchesPlayer2Score">
Constraints
One score must be bigger than 11.
One score must be 2 points or greater than the other if the score is higher than 11.
Problem
When cake validates multiple rows from the same model, the model data is set to that record. This means that it's not possible to compare the two values as they aren't both available in $this->data. As I am using saveAll() each record is set to the model and then validated before it's saved.
Question
I'd like to know if there is a good way to validate this pair of data without resorting to saving it into the session or similar before I can validate it.
What I normally do here is I create a wrapper for the save method. This allows me to perform custom manipulation that would otherwise not be possible with model callbacks, or even use custom transactions etc.
In your case, it would be something like:
class MatchesPlayer extends Model {
protected $_saveData = null;
public function updateScore($data) {
$this->_saveData = $data;
try {
// You can use saveAll to validate
// only, and not actually save
$saved = $this->saveAll($data, array('validate' => 'only'));
} catch (Exception $e) {
// Catch exceptions here in case the
// saveAll is instead something that throws Exceptions
// Or your database uses exceptions
$saved = false;
}
$this->_saveData = null;
return $saved
}
}
You could then use $this->_saveData across the model. If you want to be clever with this, you could detect all sub-models that are being saved in the $data and then set the $this->_saveData on those as well - I would make this an AppModel method of course.
Note that you may want to throw exceptions from this updateScore() method when validation fails. Throwing an exception if validation fails - vs save - would allow you to set a custom flash message for the user as well, or even have an api that responds with a different status code.
Use custom validation rules in MatchesPlayer model, please check
http://book.cakephp.org/2.0/en/models/data-validation.html#adding-your-own-validation-methods

Resources