Clear dependent attribute values on changing parent attribute - oracle-adf

I have a parent attribute OrganizationId and attributes- ProjectId which is dependent on OrganizationId . So on clearing/updating OrganizationId ProjectId should be removed.In current scenarion on clearing OrganizationId we aren't able to select any ProjectId from though the existing ProjectId value still shows on page.
<af:inputComboboxListOfValues id="OrganizationCode"
popupTitle="#{ResourcesGenBundle['Header.SearchandSelect.Searchandselectanobjectusingad']}: #{bindings.OrganizationCode.hints.label}"
value="#{bindings.OrganizationCode.inputValue}"
label="#{bindings.OrganizationCode.hints.label}"
model="#{bindings.OrganizationCode.listOfValuesModel}"
required="#{bindings.OrganizationCode.hints.mandatory}"
columns="#{bindings.OrganizationCode.hints.displayWidth}"
shortDesc="#{bindings.OrganizationCode.hints.tooltip}"
searchDesc="#{bindings.OrganizationCode.hints.tooltip}"
autoSubmit="true"
partialTriggers="DeliveryName"
valueChangeListener="#{CreatePickWaveBean.onOrganizationCodeChange}"
binding="#{CreatePickWaveBean.organizationCode}">
<af:inputListOfValues id="projCostingProjectNumberId"
popupTitle="#{ResourcesGenBundle['Header.SearchandSelect.Searchandselectanobjectusingad']}: #{bindings.ProjCostingProjectNumber.hints.label}"
value="#{bindings.ProjCostingProjectNumber.inputValue}"
label="#{wshpickreleaseuiBundle['ColAttr.ProjectCostingProjectNumber.ProjectPVO.ProjectCostingProjectNumber']}"
model="#{bindings.ProjCostingProjectNumber.listOfValuesModel}"
required="#{bindings.ProjCostingProjectNumber.hints.mandatory}"
columns="#{bindings.ProjCostingProjectNumber.hints.displayWidth}"
shortDesc="#{bindings.ProjCostingProjectNumber.hints.tooltip}"
autoSubmit="true"
binding="#{CreatePickWaveBean.pjcProjectNumber}"
valueChangeListener="#{CreatePickWaveBean.onPjcNumberChange}">
public void onOrganizationCodeChange(ValueChangeEvent valueChangeEvent) {
updateEVH(getOrganizationCode());
private void updateEVH(EditableValueHolder evh) {
if (evh != null)
evh.setSubmittedValue(null);
}

Try to reset the value or to set value null for inputListOfValues OrganizationId changed
You already set the binding for projectId component to
"#{CreatePickWaveBean.pjcProjectNumber}"
So you can use the following code in The Value change listener method for ProjectId
this.getPjcProjectNumber().setValue(null);
or
this.getPjcProjectNumber().resetValue();

Related

Default value gets stored in another column based on value selected from LOV

Table-Items
Columns-Order_Type
(Sales,
Return,
Defective)
Order_Type_Id(1,2,3)
i.e 1-Sales,
2-Return,
3-Defective
VO has Transient attribute-OrderType which has an LOV showing Order_Type.
Based on selected Order_Type, Order_Type_Id should get stored in Order_Type_Id column
public Number getOrder_Type_Id() {
String orderType = null;
Number orderNumber = null;
if (getOrderType() != null) {
orderType = getOrderType();
if (orderType.equals("Sales")) {
orderNumber = new oracle.jbo.domain.Number(2);
} else if (orderType.equals("Return")) {
orderNumber = new oracle.jbo.domain.Number(3);
} else if (orderType.equals("Defective")) {
orderNumber = new oracle.jbo.domain.Number(4);
}
this.setOrder_Type_Id(orderNumber);
}
Following code worked.
Writing following code in Order_Type_Id:
public Number Order_Type_Id()
{
String orderType=null;
Number orderNumber=null;
if(getOrder_Type()!=null){
orderType=getOrder_Type();
if(orderType.equals("Sales")){
orderNumber=new oracle.jbo.domain.Number(2);
}
else if(orderType.equals("Defective")){
orderNumber=new oracle.jbo.domain.Number(3);
return orderNumber;
}
else
{
return (Number)getAttributeInternal(Order_Type_Id);}
}
}
In Order_Type_Id attribute add dependency or Order_Type
Assuming LOV VO is also from Query not from static list :
It is developed in ADF 11g
OrderTypeLOVVO :
order_type_id - back-end stored column
order_type_desc - display column
BaseOrderVO
OrderTypeId - transient attribute - LOV - OrderTypeLOVVO
OrderTypeDesc - transient attribute - OutputText column with default value - 1
orderTypeId
- Make autoSubmit property true in both places in VO and in jsff page ( drop it as select one choice) .
- OrderTypeId value will be bindings.orderTypeId.inputValue
- Shuffle the dependent attribute Order_type_desc from left to right in dependecies component of VO.
OrderTypeDesc
Make default value as 1 and in jsff page set partial trigger dependent of orderTypeId after dropping it as output label.
Make OrderTypeDesc value attribute as bindings.orderTypeId.attributeValue
We need to make OrderTypeDesc value as orderTypeId.attributeValue because when you select OrderTypeId as sales (this is inputValue), so backend value (id) is 1. so attributeValue will get the id of the selected value in LOV.
Same works with static list VO too.
As per your requirement, In programatically,
I have created a method on value change listener of LOV,
changeValue() is the method in bean class.
public void changeValue(ValueChangeEvent valueChangeEvent) {
AppModuleImpl module = getApp(); // creating appModuleImpl class object
//definition for getApp() is given below.
item_desc = module.assignValue(valueChangeEvent.getNewValue().toString());
// This item_desc value is declared globally.
//assignValue method of AppModuleClass is given below
bind_item_desc.setValue(item_desc);
AdfFacesContext adfFacesContext = AdfFacesContext.getCurrentInstance();
adfFacesContext.addPartialTarget(bind_item_desc);
// bind_item_desc is the binding attribute of output label which needs to be refreshed.
// Add event code here...
}
public static AppModuleImpl getApp() {
return (AppModuleImpl)Configuration.
createRootApplicationModule(
"Model.AppModule", // where your module is stored
"AppModuleShared"); // chosen configuration
}
Here Model.AppModule is the location of AppModule.
assingValue() of AppModuleClass where it will assign the value according to the selected value in LOV.
public String assignValue(String value)
{
String item_desc=null;
System.out.println("Changed value " + value);
if(value.equals("Sales"))
{
item_desc="14";
}
return item_desc;
}
In assignValue, Parameter is value which will be input from bean class (a selected value from LOV) and returning the String parameter which you will be needed back again in bean class.
So when you select a value in LOV, it will trigger the value change listener method (changeValue()) and will navigate to AppModule . In AppModule , value will be assigned and come back to Bean class.
But it will not reflect untill, you will not refresh the page component.
<af:selectOneChoice value="#{bindings.item_id_lov.inputValue}"
label="item for lov"
required="#{bindings.item_id_lov.hints.mandatory}"
shortDesc="#{bindings.item_id_lov.hints.tooltip}"
id="soc4" autoSubmit="true"
valueChangeListener="#{bean1.changeValue}">
<f:selectItems value="#{bindings.item_id_lov.items}" id="si4"/>
</af:selectOneChoice>
Here value change listener is called in SelectOneChoice and autoSubmit is true.
<af:panelLabelAndMessage label="item description"
id="plam1" partialTriggers="soc4">
<af:outputFormatted value="#{bean1.item_desc}" binding="#{bean1.bind_item_desc}"
id="of1"/>
</af:panelLabelAndMessage>
Here , in value attribute item_desc is assigned (which is declared in bean). Also binding got created for the output label. PartialTrigger is assigned of LOV as outputLabel is dependent on LOV.

Linq search database considering duplicates

I've got the problem with searching database through duplicate list values.
First I search all occurrences by given string.
var parentIdList = await _context.ECATEGORIES
.Where(a => a.NAME.ToLower().Contains(partOfName.ToLower()))
.ToListAsync(ct);
then
I retrieve all names when given PARENTID of parentIdList equals database ID
var mainName = await _context.ECATEGORIES
.Where(a=> parentIdList.Any(p=>p.PARENTID==a.ID) )
.Select(s => s.NAME)
.ToListAsync(ct);
My problem is that, sometimes property PARENTID is duplicated.
For example PARENTID = {1,1,2,2,4,5,6}
then result is mainName = {"a","b","c","d","e"}
But I want mainName = {"a", "a","b","b","c","d","e"}
So you have a sequence of Categories, where every Category has an Id, a ParentId and a Name. You also have a string partOfName
You want the Names of Categories. All Categories? No. only those Categories that have a Parent which has a Name that looks like partOfName (looks like is represented by the use of the function contains in your code)
I'm not sure if you use entity framework. Your use of _context seems a hint to this. In that case, It would be easier to use the virtual parent properties. See later.
If you do not use entity framework, I'd advise to fetch your data in one query: join the elements with their parents, and keep only the join results where the parent meets your contains predicate:
string lowerCasePartOfName = partOfName.ToLower(); // for efficiency: do this only once
IQueryable<Category> categories = myDbContext.Categories;
IQueryable<Category> validParents = myDbContext.Categories
.Where(category => category.Name.ToLower().Contains(lowerCasePartOfName))
Now join every Category with the validParentIds on Category.ParentId = Parent.Id
var query = Categories.Join(validParents, // join categories with validParents
category => category.ParentId, // from each category take the ParentId
parent => parent.Id, // from each valid parent take the Id
(category, parent) => new // when they match make one new object
{
CategoryName = category.Name,
});
Note, until now the query has been made, it has not been executed yet. If you want you can concatenate them into one big LINQ query. I'm not sure if that would increase performance very much; however, it would decrease readability.
var result = query.ToListAsync();
Entity Framework Solution
If you use entity framework, your Category class would be like:
class Category
{
public int Id {get; set;}
public string Name {get; set;}
// every Category has zero or one Parent category:
public int? ParentId {get; set;}
public Category Parent {get; set;}
// every Category has zero or more Children, each of them has this Category as Parent
public virtual ICollection<Category> Children {get; set;}
}
You query will be much simpler:
Give me all names of Categories whose Parents have a name that looks like partOfName
string lowerCasePartOfName = partOfName.ToLower();
var result = myDbContext.Categories
// keep only the Categories whose name looks like:
.Where(category => category.Parent.Name.ToLower().Contains(lowerCasePartOfName))
.Select(category => category.Name);

Dapper multi-mapping not returning null object when splitOn column is not in child object

I'm using dapper 1.50.2 with MySQL and running into a problem trying to map a left outer join child object to its parent. If I split on a column alias that doesn't actually exist in the child object, Dapper always creates a child object with default properties, even when there is nothing in the left join.
I created a simple example to demonstrate this:
public class ParentRecord
{
public string MemberID { get; set; }
public ChildRecord Child { get; set; }
}
public class ChildRecord
{
//public string Split { get; set; }
public string SomeField { get; set; }
}
using (MySqlConnection connection = new MySqlConnection(connectionString))
{
ParentRecord result = connection.Query<ParentRecord, ChildRecord, ParentRecord>(
#"SELECT 'FakeID' AS MemberID, NULL AS Split, NULL AS SomeField",
(mt, crt) =>
{
mt.Child = crt;
return mt;
},
splitOn: "Split").Single();
}
I would expect this to result a ParentRecord with the Child property set to null, but the Child property is set to a ChildRecord with all default fields.
If I uncomment the Split property in ChildRecord, or if I split on SomeField, this works as I'd expect.
Are there any good workarounds for this?
In the actual query I'm dealing with, there are multiple primary key and foreign key fields with the same names and I'd rather not change the property names in the POCOs to be unique. I'd prefer to be able to use column aliases that are just there to split on. I know this isn't normally how Dapper is set to up to work.
Any help would be appreciated, thanks.
This happen because the object Child initialize for default when you attribute the ctr param. Then the solution that I did implement was:
ParentRecord result = connection.Query<ParentRecord, ChildRecord, ParentRecord>(
#"SELECT 'FakeID' AS MemberID, NULL AS Split, NULL AS SomeField",
(mt, crt) =>
{
if (crt.SomeField != null){ mt.Child = crt; }
return mt;
},
splitOn: "Split").Single();

praogramatically fetch any particular object's related objects from its related list

I am pretty new to SFDC. I am trying to implement a clone functionality of a custom object by which when I am cloning an object, the object as well as all the object in its related list are to be cloned. I have implemented the part of cloning a object but stuck how to get the object list associated with a object's related list. pls let me know , how to implement this.
Thanks
You can try this...
public class PurchaseOrderCloneWithItemsController {
//added an instance varaible for the standard controller
private ApexPages.StandardController controller {get; set;}
// add the instance for the variables being passed by id on the url
private Purchase_Order__c po {get;set;}
// set the id of the record that is created -- ONLY USED BY THE TEST CLASS
public ID newRecordId {get;set;}
// initialize the controller
public PurchaseOrderCloneWithItemsController(ApexPages.StandardController controller) {
//initialize the stanrdard controller
this.controller = controller;
// load the current record
po = (Purchase_Order__c)controller.getRecord();
}
// method called from the VF's action attribute to clone the po
public PageReference cloneWithItems() {
// setup the save point for rollback
Savepoint sp = Database.setSavepoint();
Purchase_Order__c newPO;
try {
//copy the purchase order - ONLY INCLUDE THE FIELDS YOU WANT TO CLONE
po = [select Id, Name, Ship_To__c, PO_Number__c, Supplier__c, Supplier_Contact__c, Date_Needed__c, Status__c, Type_of_Purchase__c, Terms__c, Shipping__c, Discount__c from Purchase_Order__c where id = :po.id];
newPO = po.clone(false);
insert newPO;
// set the id of the new po created for testing
newRecordId = newPO.id;
// copy over the line items - ONLY INCLUDE THE FIELDS YOU WANT TO CLONE
List<Purchased_Item__c> items = new List<Purchased_Item__c>();
for (Purchased_Item__c pi : [Select p.Id, p.Unit_Price__c, p.Quantity__c, p.Memo__c, p.Description__c From Purchased_Item__c p where Purchase_Order__c = :po.id]) {
Purchased_Item__c newPI = pi.clone(false);
newPI.Purchase_Order__c = newPO.id;
items.add(newPI);
}
insert items;
} catch (Exception e){
// roll everything back in case of error
Database.rollback(sp);
ApexPages.addMessages(e);
return null;
}
return new PageReference('/'+newPO.id+'/e?retURL=%2F'+newPO.id);
}
Sounds like you need to "Deep Clone" - check out the links below for reference:
https://salesforce.stackexchange.com/questions/8493/deep-clone-parent-child-grand-child
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_System_List_deepClone.htm

HasMany: Empty list instead of null

I am using CastleProject ActiveRecord.
I have the following property in my class:
[HasMany(typeof(Order), Table = "Orders", ColumnKey = "OrderId")]
internal IList<Order> Orders
{
get;
set;
}
In case Orders table does not contain any orders, Orders property is null. Can I somehow point ActiveRecord that it should create empty list instead of returning null, without giving up autoproperty?
Not exactly what you want, but couldn't you instantiate an empty list in the constructor:
public MyClass()
{
Orders = new List<Order>();
}

Resources