Adf Search panel with checkbox - oracle-adf

I added a checkbox to my search panel, the search is working initially in the sense if I select the check box and add a query string I am getting the expected result in the table. If I click on the column header and try to sort it my table gets reset with the filtered out result.
I figured that the executeQuery of the ViewObject is getting called each time I am clicking on sort. I added code to set the value of the viewCriteria attributes here but tat is also not working. My executeQuery method included below;
public void executeQuery() {
ViewCriteria vc = this.getViewCriteria("RegionMasterCriteria");
if (null != vc.getCurrentRow()) {
if (null != vc.getCurrentRow().getAttribute("Active") &&
vc.getCurrentRow().getAttribute("Active").equals("true")) {
setActiveVariable("Y");
} else {
setActiveVariable("N");
}
}
super.executeQuery();
}
vc.getCurrentRow() is null when I am trying to perform search. The Criteria is has Auto query set to true so that when the page loads the table has default search data. But then why will vc.getCurrentRow() become null..

Can you try using executeQueryForCollection(java.lang.Object qc, java.lang.Object[] params, int noUserParams)
instead of executeQuery()?
You will be able to find your "Active" view criteria attribute in method argument:
java.lang.Object[] params
just keep in mind 'params' is a matrix (array of arrays).

Related

Showing the new row in react-table on the current page

I have been playing with ReactTable v7 for a while and have encountered the following problem: when the table is sorted and uses paginator sometimes adding (or editing) a row causes it to be outside the current page.
You can see the problem here:
https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/material-UI-kitchen-sink
Sort the table by First Name
Press add
Enter a record with First Name "zzzzz"
The record is added but is currently hidden which confuses users.
Is there a "standard" way to fix the issue? Am I missing something?
In v6 I have done a workaround for it:
React.useEffect(() => {
if (editedElementId && reactTable) {
const { data } = reactTable.props;
if (data && data.length > 0) {
const internal = reactTable.getResolvedState();
let position = -1;
internal.sortedData.forEach((row, i) => {
if (row._original.id === editedElementId) position = i;
});
if (position >= 0) {
const pageNumber = Math.floor(position / pageSize);
setPage(pageNumber);
} else {
alert.info("Element not visible");
}
}
}
}, [editedElementId]);
...
<ReactTable
ref={(r) => {setReactTable(r);}}
...
But maybe there is a bulit-in way to achieve it?
There is not currently a way to only sort the elements which are currently being displayed, no.
React Table v7's useSortBy hook sorts the entirety of the input data array, so sorting by First Name descending (A->Z) naturally places 'ZZZZZZ' at the end of the list, which will be hidden due to pagination. The v7 way of doing it would probably be similar to what you are doing already, using the exposed properties from the useTable hook instead of reactTable.resolvedState() and etc. Another way to do it would be to write your own custom sortBy method and only sort the items [0...n] where n is the number of currently displayed items.
As a side note, since the autoResetSortBy property is true by default in the example you linked, the step of sorting on First Name is irrelevant -- since the function which adds a new user to the list mutates the data array, the sorting method is reset. That function appends the new user to the end of the list, so it will always be on a new page, even if the "Rows per page" option is set to "All". Both issues can be fixed by setting autoResetSortBy to false, and changing the pageSize in addUserHandler.

ADF Cascading Lov Search and Select popup customization

I have built a cascading LOV with Group and division fields (Combo box with list of values). When I select a value for Group and click on Search and Select dialog for Division field, the SearchAndSelect popup has both Group and Division fields as search criteria(as defined in my view criteria).
Now, is there a way to populate the Group value in the popup criteria, I know the where clause uses the already entered Group value but I want to display it to the user in the SearchAndSelect popup search region.
There is no declarative way of pre setting search field values in lov popup. Although it can be done by using a custom launchPopupListener for lov component. To know more about how to use lov popup listeners refer to Building Custom Lovs
Create a launchPopupListener method for your dependent lov.
<af:inputComboboxListOfValues id="inpClv2"
popupTitle="Search and Select: #{bindings.StateProvince.hints.label}"
value="#{bindings.StateProvince.inputValue}"
label="#{bindings.StateProvince.hints.label}"
model="#{bindings.StateProvince.listOfValuesModel}"
required="#{bindings.StateProvince.hints.mandatory}"
columns="#{bindings.StateProvince.hints.displayWidth}"
shortDesc="#{bindings.StateProvince.hints.tooltip}"
partialTriggers="inpClv1"
launchPopupListener="#{backingBeanScope.lovBean.stateLaunchPopupListener}">
</af:inputComboboxListOfValues>
In launchPopupListener set the value of search criteria attribute with the value from first lov.
public void stateLaunchPopupListener(LaunchPopupEvent launchPopupEvent)
{
UIXInputPopup lovComponent = (UIXInputPopup)launchPopupEvent.getSource();
ListOfValuesModel model = lovComponent.getModel();
if (model != null)
{
QueryDescriptor queryDesc = model.getQueryDescriptor();
/** Code to pre populate a Search and Select field**/
ConjunctionCriterion conCrit = queryDesc.getConjunctionCriterion();
List<Criterion> criterionList = conCrit.getCriterionList();
for (Criterion criterion: criterionList)
{
AttributeDescriptor attrDesc = ((AttributeCriterion) criterion).getAttribute();
if (attrDesc.getName().equalsIgnoreCase("CountryId"))
{
List values = ((AttributeCriterion) criterion).getValues();
values.set(0, "US"); //use the value from first lov
}
}
}
}

How to keep "empty" selection on my combobox list in JavaFx?

In my application I hava combobox which is holding some values from databse ( some real time updated list ). This ComboBox list is updated every 1 minute.
List dosen't have null values. When I'm setting this list to ComboBox..
ComboBox box = new ComboBox(items);
.. there is one extra "empty" row, which is perfectly fine because non value is selected.
Right after I'm selecting some value my "empty" value disappears from the list.
My main question is How to keep this value on the list?
Why this is a problem..
Scenerio values is selected in database, first application start
List is loaded ( wiht selected empty value ).
Value is selected.
During first background refresh, empty values disappears, and combobox value is selected to n+1, next value is selected.
If I want to select empty values I have to all clearSelection from selection model / by some extra control.
While it is an old question, I spent quite bit of time trying to solve the same issue in my application and thought i might as well add my solution here.
One possible workaround is to create an extra list that contains null and the items you wish to be selectable.
ObservableList<String> selectableActivities = FXCollections.observableArrayList("a", "b", "c");
ObservableList<String> selectableActivitiesWithNull = FXCollections.observableArrayList();;
selectableActivitiesWithNull.add(null);
selectableActivitiesWithNull.addAll(selectableActivities);
In order to support updates of the original list you would need a ListChangeListener that updates the extra list according to changes in the original list.
selectableActivities.addListener((ListChangeListener<String>)(change -> {
while (change.next()) {
if (change.wasPermutated()) {
selectableActivitiesWithNull.sort((a, b) -> {
return Integer.compare(selectableActivities.indexOf(a), selectableActivities.indexOf(b));
});
} else if (change.wasRemoved()) {
selectableActivitiesWithNull.remove(change.getFrom()+1, change.getTo()+2);
} else if (change.wasAdded()) {
selectableActivitiesWithNull.addAll(change.getFrom()+1, selectableActivities.subList(change.getFrom(), change.getTo()));
} else if (change.wasUpdated()) {
for (int i = change.getFrom(); i < change.getTo(); ++i) {
selectableActivitiesWithNull.set(i+1, selectableActivities.get(i));
}
}
}
}));
And finally you use the extra list for the ComboBox items.
ComboBox<String> combobox = new ComboBox<String>();
combobox.setItems(selectableActivitiesWithNull);
Now you can modify the original list as usual and the ComboBox will update accordingly while also having an empty selection as the first item. And most importantly your original list will not be polluted by placeholder objects that could cause issues in other parts of the application.
This will also work with other objects, assuming that you add an apropriate StringConverter to the ComboBox. Note that the converter must also be able to handle null values if using the above approach.
StringConverter<Object> activityConverter = new StringConverter<Object>() {
#Override
public String toString(Object object) {
return object != null ? object.toString() : "";
}
#Override
public ActivityDataRow fromString(String string) {
return null;
}
};
combobox.setConverter(activityConverter);
While this approach is not exactly what you desired, I believe this is a close you can get without implementing a custom combobox.

How to get a selected object within other stuff?

I have a multiselect grid where I can get schools.getSelectionModel().getSelection();
there is an object called data, I want to get a field within the data; lets say school_name
How I'll do it?
I've tried
schools.getSelectionModel().getSelection().data
schools.getSelectionModel().getSelection(data)
schools.datagetSelectionModel().getSelection()
they did not work.
You have to use Ext.each to iterate over the array of records..
Ext.each(schools.getSelectionModel().getSelection(), function(record, index, allRecords) {
console.log(record.get('school_name');
});
This:
schools.getSelectionModel().getSelection()[0].get('school_name')
should give you a 'school_name' field from first row selected (which is also a first record in selection).
To iterate over all selected rows do:
var selectedSchools = schools.getSelectionModel().getSelection();
for (i in selectedSchools) {
console.log(schools[i].get('school_name')); //this will log school name to firebug console - you can do whatever you need
}

ExtJS: Added grid rows wont de-highlight

When adding a rows to a grid, and then clicking on it, it gets selected (and highlighted). Then, clicking elsewhere but the new row remains highlighted (so now there are to highlighted rows).
Please, does anyone know what the problem could be? How to make it behave normally, i.e. clicking a row deselects (de-highlights) the other one?
After I reload the page (so the new row is not new anymore), everything works as expected.
Edit: Here's the code for adding rows:
var rec = new store.recordType({
test: 'test'
});
store.add(rec);
Edit 2: The problem seems to be listful: true. If false, it works! But I need it to be true so I'm looking at this further... It looks like as if the IDs went somehow wrong... If the ID would change (I first create the record and then the server returns proper ID, that would also confuse the row selector, no?)
(Note, correct as ExtJS 3.3.1)
First of all, this is my quick and dirty hack. Coincidentally I have my CheckboxSelectionModel extended in my system:-
Kore.ux.grid.CheckboxSelectionModel = Ext.extend(Ext.grid.CheckboxSelectionModel, {
clearSelections : function(fast){
if(this.isLocked()){
return;
}
if(fast !== true){
var ds = this.grid.store,
s = this.selections;
s.each(function(r){
//Hack, ds.indexOfId(r.id) is not correct.
//Inherited problem from Store.reader.realize function
this.deselectRow(ds.indexOf(r));
//this.deselectRow(ds.indexOfId(r.id));
}, this);
s.clear();
}else{
this.selections.clear();
}
this.last = false;
}
});
And this is the place where the clearSelections fails. They try to deselect rows by using ds.indexOfId(r.id) and it will returns -1 because we do not have the index defined remapped.
And this is why we can't find the id:-
http://imageshack.us/photo/my-images/864/ssstore.gif/
Note that the first item in the image is not properly "remapped". This is because we have a problem in the "reMap" function in our Ext.data.Store, read as follow:-
// remap record ids in MixedCollection after records have been realized. #see Store#onCreateRecords, #see DataReader#realize
reMap : function(record) {
if (Ext.isArray(record)) {
for (var i = 0, len = record.length; i < len; i++) {
this.reMap(record[i]);
}
} else {
delete this.data.map[record._phid];
this.data.map[record.id] = record;
var index = this.data.keys.indexOf(record._phid);
this.data.keys.splice(index, 1, record.id);
delete record._phid;
}
}
Apparently, this method fails to get fired (or buggy). Traced further up, this method is called by Ext.data.Store.onCreateRecords
....
this.reader.realize(rs, data);
this.reMap(rs);
....
It does look fine on the first look, but when I trace rs and data, these data magically set to undefined after this.reader.realize function, and hence reMap could not map the phantom record back to the normal record.
I don't know what is wrong with this function, and I don't know how should I overwrite this function in my JsonReader. If any of you happen to be free, do help us trace up further for the culprit that causes this problem
Cheers
Lionel
Looks like to have multi select enabled for you grid. You can configure the selection model of the grid by using the Ext.grid.RowSelectionModel.
Set your selection model to single select by configuring the sm (selection model) in grid panel as show below:
sm: new Ext.grid.RowSelectionModel({singleSelect:true})
Update:
Try reloading the grid using the load method or loadData method of the grid's store. Are you updating the grid on the client side? then maybe you can use loadData method. If you are using to get data from remote.. you can use load method. I use load method to update my grid with new records (after some user actions like add,refresh etc). Or you could simply reload as follows:
grid.getStore().reload();

Resources