ExtJs 6 or 7 focus treelist item into view - extjs

I have this treelist with a toolbar that I use to create new elements (it's a document list) and I want to focus the newly created item. I can select it but I don't seem to find a way of focusing it:
const selected = documents.treeStore.getAt(documents.treeStore.findExact(
"documentId", current.id
));
if (selected) {
tree.cmp.setSelection(selected);
const node = tree.cmp.getSelection();// maybe redundant
// how do I focus this node into view?
}

If by focus you mean that the element should appear in the visibility range, you can use this method
ensureVisible

const selected = documents.treeStore.getAt(documents.treeStore.findExact(
"documentId", current.id
));
if (selected) {
var path = [];
do {
path.push(selected.getId());
}while (selected = selected.getRefOwner());
tree.cmp.expandPath('/' + path.reverse().join('/'), {focus:true});
}

Related

Grid with LitTemplate not updating checkbox consistently

We are updating our Grid forms to use LitTemplates for rendering. However we have run into an issue with a checkbox state not being updated even though the underlying data for the state has been updated. The following code demonstrates the issue:
HorizontalLayout hlTest = new HorizontalLayout();
List<String> selected = new ArrayList<>();
Grid<String> testGrid =new Grid<>();
testGrid.setWidth("250px");
testGrid.setHeight("250px");
List<String> dataList = new ArrayList<>(List.of("AAAAA", "BBBBB", "CCCCC", "DDDDD", "EEEEE"));
ListDataProvider<String> dataProvider = new ListDataProvider<>(dataList);
testGrid.setItems(dataProvider);
String template = """
<vaadin-checkbox #click="${handleCheckClick}" ?checked="${item.rowSelected}"></vaadin-checkbox>
<div>${item.text}</div>
""";
LitRenderer<String> lit = LitRenderer.of(template);
lit.withProperty("rowSelected", item -> {
boolean rc = selected.contains(item);
System.out.println("Item selected: " + item + " => " + rc);
return rc;
});
lit.withProperty("text",item -> item);
lit.withFunction("handleCheckClick", (item) -> {
if(selected.contains(item))
selected.remove(item);
else
selected.add(item);
});
testGrid.addColumn(lit);
Button bSelect = new Button("Select");
bSelect.addClickListener(buttonClickEvent -> {
if(selected.size() > 0)
{
dataList.clear();
dataList.addAll(selected);
selected.clear();
dataProvider.refreshAll();
}
});
hlTest.add(testGrid, bSelect);
With the given grid, click a few checkboxes and click 'Select'. The list is reduced to the selected rows, but the checkboxes are still ticked even though 'selected' is empty. The logging within 'rowSelected' is correctly returning the state.
If I remove the column and re-add to grid, then all is displayed correctly. Also, if I select all items in the grid then the select also works correctly.
Currently using Java17 and Vaadin 22.0.6 (have also tried 23.0.0 beta3).
Thanks.
I think you need to call dataProvider refresh when you update
lit.withFunction("handleCheckClick", (item) -> {
if(selected.contains(item))
selected.remove(item);
else
selected.add(item);
testGrid().getDataProvider().refreshAll();
});

React Kendo Treeview scroll to item

I am using React Kendo Treeview UI. I want to try to scroll to the item that is selected in the tree. I found many examples for Javascript and JQuery but none for React version. I couldn't solve this problem by playing around with it.
Items in the tree are of type MyViewTreeModel. I have a selectOntree method that finds a node and set the selected to true. My problem is I want to scroll to that item.
export interface MyViewTreeModel {
text: string,
expanded: boolean,
employeeId : number,
treeId: number,
items?: MyViewTreeModel [],
selected: boolean
}
....
<TreeView
data={myData}
expandIcons={true}
onExpandChange={onExpandChange}
onItemClick={OnItemClick}
aria-multiselectable={false}
aria-label={'text'}
></TreeView>
....
const selectOnTree = (employeeId: number ) => {
let treeItem = recursivelyFindEmployeeInTree(myData[0], employeeId);
treeItem.selected = true;
forceUpdate();
}
}
myData is of type MyViewTreeModel .
One solution I tried : I added ref?: any to my model and tried treeItem.ref.current.focus(); in selectOnTree function, but ref was undefined.
Another solution I tried is adding this property to TreeView:
ref={component => treeViewRef.current = component}
Then tried this just to select the first 'li' tag in the TreeView:
if(!_.isNil(treeViewRef.current) ){
let domElement = ReactDOM.findDOMNode(treeViewRef.current);
let treeItemDom = domElement.firstChild.firstChild;
(treeItemDom as HTMLElement).focus();
}
This didn't work, it doesn't put the focus at that point.
I am thinking maybe I should define a custom itemRender that has a ref that I can find the offsetTop of it, but then there are more than one item, how can I create a different ref for each one? Or maybe a custom ItemRender that renders an input (with css I can make it look like a span) and then set autofocus to true if selected is true. Not sure if autofocus true make it scroll to that item.
This is the solution I could find to make it work:
Adding a reference to TreeView
let treeViewRef = useRef(null);
In return statement:
<TreeView
data={myData}
expandIcons={true}
onExpandChange={onExpandChange}
onItemClick={OnItemClick}
aria-multiselectable={false}
aria-label={'text'}
ref={component => treeViewRef.current = component}></TreeView>
2.Defined this function to scroll to a specific treeItem:
'k-in' is the className for each span that represent each item in the Kendo Treeview UI component.
const scrollToTreeViewItem = (treeItem: MyViewTreeModel ) => {
if(!_.isNil(treeViewRef.current)){
let domElement = ReactDOM.findDOMNode(treeViewRef.current);
let treeItemDoms = (domElement as Element).querySelectorAll('.k-in');
let domArray = [];
treeItemDoms.forEach((node) => {
domArray.push(node as HTMLElement);
});
let targetedDomElement = domArray.find((item) => {
return item.innerText === treeItem.text;
});
targetedDomElement.scrollIntoView();
}
}

working on select but not on blur - EXTJS

I am newbie to ExtJS I have the following lines of code that is working fine on select event and now I am planning to add on blur event too.
autoResolve.on("select" || "blur", function (component, record, index) {
var fieldSet = utils.getComponentFromMngr(component.id.split("~")[0]);
if(autoResolveData.CURRSEL){ //Set previous selection property
var xmlElem = fieldSet.DomainXML.documentElement.childNodes[1];
xmlElem.setAttribute("PR_DOMAINTYPE",autoResolveData.FILL_SUBTYP);
xmlElem.setAttribute("PR_DOMAINID", record.get("ITEMID"));
xmlElem.setAttribute("PR_DOMAINVALUE", record.data.TITLE);
fieldSet.DomainObj.push({PRDomainType:autoResolveData.FILL_SUBTYP,PRDomainID:record.get("ITEMID"),PRDomainValue:record.data.TITLE});
}
it is still working fine on select event but not on blur event where am I going wrong please suggest
"select" || "blur" will return select, as you can find out if you type the following in browser console:
console.log("select" || "blur");
Furthermore, "blur" event does not have record as the second parameter. You would have to look how to get record and call the function with a valid record parameter.
What you want to achieve is roughly the following:
var myFunction = function (component, record, index) {
var fieldSet = utils.getComponentFromMngr(component.id.split("~")[0]);
if(autoResolveData.CURRSEL){ //Set previous selection property
var xmlElem = fieldSet.DomainXML.documentElement.childNodes[1];
xmlElem.setAttribute("PR_DOMAINTYPE",autoResolveData.FILL_SUBTYP);
xmlElem.setAttribute("PR_DOMAINID", record.get("ITEMID"));
xmlElem.setAttribute("PR_DOMAINVALUE", record.data.TITLE);
fieldSet.DomainObj.push({PRDomainType:autoResolveData.FILL_SUBTYP,PRDomainID:record.get("ITEMID"),PRDomainValue:record.data.TITLE});
}
};
autoResolve.on({
select:myFunction,
blur:function(component) {
var record = ... // your special magic here
return myFunction(component,record);
}
});

How do I reset all filters in Extjs Grids?

How do I reset my ExtJS filters in my grids. More specifically, how do I get the header to honour the changes to the filtering.
ie. This works fine :
grid.store.clearFilter();
But the header rendering is all wrong. I need to get into all the menu objects and unselect the checkboxes.
I am getting pretty lost. I am pretty sure this gives me the filterItems :
var filterItems = grid.filters.filters.items;
And from each of these filter items, i can get to menu items like so :
var menuItems = filter.menu.items;
But that's as far as I can get. I am expecting some kind of checkbox object inside menu items, and then I can uncheck that checkbox, and hopefully the header rendering will then change.
UPDATE :
I now have this code. The grid store has its filter cleared. Next I get the filterItems from grid.filters.filters.items and iterate over them. Then I call a function on each of the menu items.
grid.store.clearFilter();
var filterItems = grid.filters.filters.items;
for (var i = 0; i<filterItems.length; i++){
var filter = filterItems[i];
filter.menu.items.each(function(checkbox) {
if (checkbox.setChecked)
checkbox.setChecked(false, true);
});
}
The checkboxes do get called, but still nothing is happening :(
Try this code:
grid.filters.clearFilters();
This should take care of both the grid and its underlying store.
When you do
grid.store.clearFilter();
it can only clear the filters on the store but the grid's view doesn't get updated with that call. Hence to handle it automatically for both the grid's view as well as the grid's store, just use
grid.filters.clearFilters();
Hope it helps!
Cheers!
Your update help me but you forget the case where you have input text instead of checkbox.
So this is my addition of your solution:
grid.filters.clearFilters();
var filterItems = grid.filters.filters.items;
for (var i = 0; i<filterItems.length; i++){
var filter = filterItems[i];
filter.menu.items.each(function(element) {
if (element.setChecked) {
element.setChecked(false, true);
}
if(typeof element.getValue !== "undefined" && element.getValue() !== "") {
element.setValue("");
}
});
}
When you use grid wiht gridfilters plugin
and inovoke
grid.filters.clearFilters();
it reset applyed filters, but it don't clean value in textfield inside menu.
For clean textfield text you can try this:
grid.filters.clearFilters();
const plugin = grid.getPlugin('gridfilters');
let activeFilter;
if('activeFilterMenuItem' in plugin) {
activeFilter = plugin.activeFilterMenuItem.activeFilter
}
if (activeFilter && activeFilter.type === "string") {
activeFilter.setValue("");
}

How to set an item selected in extjs tree panel by default?

I have a tree panel with some items. Whenever I render the treepanel an item should be selected by default.
Please refer this code. This will work
Ext.each(Nodes, function(item, index, allNodes)
{
var rec = TreePanelObj.getView().getRecord(item);
if() //any condition
{
TreePanelObj.getSelectionModel().select(index);
}
});

Resources