Am using PrimeFaces 3.5 and a Tree Table in single select mode. The single node selection is working fine in the following situation:
1- user clicks on different nodes (there is only one node selected at any time)
2- user clicks on different nodes with Ctrl key down (there is only one node selected at any time)
both 1 and 2 from above are working correctly, except when the user uses the keyboard shift key. Even though the selection mode is single, the user is managing to select multiple nodes using the shift key, this causes an error because my back bean selection method is expecting one TreeNode and not TreeNode[] array.
Any idea how can I disable the shift key on this tree table?
<p:treeTable value="#{bean.obj.root}" var="somthing" id="myTreeTable"
selectionMode="single" selection="#{bean.selectedNode}">
</p:treeTable>
Thanks,
I found the problem and fixed it. The problem is in Primefaces 3.5 source code. inside the tree table onRowClick event, the shift key was handled correctly but right underneath there was a wrong if statement that triggered the re selection of the nodes. here is the right code that fix this problem:
The problem:
if(this.isMultipleSelection && shiftKey)
The fix
if(this.isMultipleSelection() && shiftKey)
It was comparing the existing of a function and not the return value of the function.
onRowClick : function(event, node) {
if($(event.target).is('td,span:not(.ui-c)')) {
var selected = node.hasClass('ui-state-highlight'),
metaKey = event.metaKey||event.ctrlKey,
shiftKey = event.shiftKey;
if(this.isCheckboxSelection()) {
this.toggleCheckboxNode(node);
}
else {
if(selected && metaKey) {
this.unselectNode(node);
}
else {
if(this.isSingleSelection()||(this.isMultipleSelection() && !metaKey)) {
this.unselectAllNodes();
}
if(this.isMultipleSelection() && shiftKey) {
this.selectNodesInRange(node);
}
else {
this.selectNode(node);
this.cursorNode = node;
}
}
}
PrimeFaces.clearSelection();
}
};
Related
Ive got a working grid, using in-line editing thanks to this example
https://www.telerik.com/kendo-angular-ui/components/grid/editing/editing-row-click/
What I need to do now, is force the saving upon a user hitting the enter key, instead of clicking away onto another row or away from the current row. I suppose I could add a "save" button in the header?
You could probably use cellClose event in your html (cellClose)="cellCloseHandler($event)" - API Documentation
You could then write your own code (in typescript) in cellCloseHandler() to modify and save the updated items accordingly.
From Kendo UI for Angular Documentation:
In-Cell Editing
You could capture the Enter key hits and force executing cellCloseHandler() like that:
#HostListener('keydown', ['$event'])
public keydown(event: any): void {
console.log("keydown event", event);
if (event.keyCode === 13) {
this.cellCloseHandler();
}
}
Similar to Giannis answer but with small modifications:
Add keydown event to kendo-grid tag.
Call grid.closeCell() instead of calling the closeHander directly.
Template
<kendo-grid #grid
[data]="data$ | async"
(cellClose)="cellCloseHandler($event)"
(keydown)="onKeydown(grid, $event)"
>
Class
onKeydown(grid: GridComponent, e: KeyboardEvent) {
if (e.key === 'Enter') {
grid.closeCell();
}
}
cellCloseHandler(args: CellCloseEvent) {
const { formGroup, dataItem } = args;
// save to backend etc
}
Calling grid.closeCell(); will make the grid to call cellCloseHandler
You dont have to implement a HostListener for Keydown by yourself. If you set the input navigable to true, the cellClose event will get triggered when pressing Enter while editing a cell or row. This way you get the data of the row in your cellCloseHandler aswell for saving it.
<kendo-grid [navigable]="true" (cellClose)="cellCloseHandler($event)"></kendo-grid>
I am working on web application. In which i am stuck with some issue.
When i call some server function it will take time to get response. When response have high number of data. It will get data, process on that data and update GUI in background.
Upto that my application GUI freeze. I can not click on any part. I see some where that ActionScript support multithreading. I found some tutorial for that which is here. But, it is for desktop application only.
Is there any way i can handle this freezing of application/GUI in web application. It will decrease my application performance and looks very bad.
Example:
If i have list of data with checkbox and on checkbox click there is some process. Now, there is one button called "Select All". Now, if i click on "select all" then all check box selected and process on check selection is going and freeze the application upto process done.
like: I have following list
<s:List id="tempList" itemRenderer="CustomItemRenderer"
dataProvider="{someList}" useVirtualLayout="false"/>
ItemRenderer have label and checkbox as following.
<s:CheckBox id="cCheckId" selected="{data.selected}"
change="onChangeHandler(event)" />
<s:Label id="lblTest" />
protected function onChangeHandler(event:Event):void
{
data.selected = !data.selected;
}
Now, on button Select all will select all check box.
<s:Button id="btnSelectAll" label="Select All" click="selectAllHandler(event)" />
protected function selectAllHandler(event:MouseEvent):void
{
for(var i:int = 0;i<someList.length;i++)
{
someList[i].selected = true;
}
}
Now, if someList have lots of data then it will freeze the screen.
Any help is greatly appreciated.
The main idea behind the list and itemrenderers that you have a list (or datagrid) that displays like 30 items and then you can scroll to see the rest. Then you will only have 30 Itemrenderers that would be updated at once.
If you don't want to scroll you will need to distribute your item selection over several frames, something like that (untested, but you get the idea)
private static const ITEMS_AT_ONCE:int = 5000;
private var _currentIndex:int;
protected function selectAllHandler(event:MouseEvent):void
{
_currentIndex = 0;
addEventListener(Event.ENTER_FRAME, onEnterFrame); // this will call the onEnterFrame method on each frame rendered
}
private function onEnterFrame(e:Event):void
{
// make sure we don't run out of bounds of the dataprovider's length
var maxIndex:int = Math.min(_currentIndex + ITEMS_AT_ONCE, someList.length);
// set selection for the current bunch
for (var i:int = _currentIndex; i < maxIndex; i++)
{
someList[i].selected = true;
}
if (maxIndex == someList.length)
{
// We are done, remove enterframe listener
removeEventListener(Event.ENTER_FRAME, onEnterFrame);
// I'm not sure but don't you need to refresh the dataprovider to reflect the changes in the ItemRenderers ?
// (someList.dataProvider as ArrayCollection).refresh();
}
else
{
// update the _currentindex so we continue after this item on the next frame
_currentIndex = maxIndex;
}
Another possible solution - if you display all of them anyways - you might try to switch to a VGroup that will hold custom UIComponents (without MXML) for the items - this should speed up the rendering.
I am trying to use md-autocomplete in Angular Material as a multi selector. The idea is, that the selected element from the autocomplete will be added to an object array after selection and then the selection will be removed from the md-autocomplete. I was able to clear the md-autocomplete, but the focus stays on the md-autocomplete input and so the autocomplete suggestions are still visible.
Example:
http://cdpn.io/QjQGVQ
Code:
function selectedItemChange(item) {
$log.info('Item changed to ' + JSON.stringify(item));
if(item)
{
//check if item is already selected
if($filter('filter')(vm.contactsSelected, function (d) {return d.id === item.id;})[0])
{
$log.info('Item already selected. Will not add it again.');
}
else
{
//add id to object
vm.contactsSelected.push(item);
}
// clear search field
vm.searchText = '';
vm.selectedItem = undefined;
//somehow blur the autocomplete focus
//$mdAutocompleteCtrl.blur();
}
}
PS: I am aware I could use the contact chips of Angular Material instead, but I was still wondering how the blur could be achieved.
If you set md-no-cache="true" property inside your the list will dissapear, but input field will not be cleared. I think is better solution than clearing input field but leaving the list visible, but is up to you.
I received a ConcurrentNodificationException when I implemented a rich:tree with dynamic loading of the nodes.
I'm using JSF1.2, Tomcat 6.0, RichFaces 3.3.3, and Java 6u31.
in JSF page I have this rich tree component
<rich:tree id="treeAreas" value="#{areaArmazenamento.treeAreas}"
var="node"
adviseNodeOpened="#{storageArea.adviseNodeOpenedTreeAreas}"
adviseNodeSelected="#{storageArea.adviseNodeSelectedTreeAreas}"
ajaxSubmitSelection="true"
componentState="#{storageArea.treeAreasState}"
nodeSelectListener="#{storageArea.selectNodeArea}"
nodeFace="#{node.type}" similarityGroupingId="true"
ondragstart="hideContextMenu();" disableKeyboardNavigation="true"
rightClickSelection="true" toggleOnClick="true" requestDelay="150"
changeExpandListener="#{storageArea.expandNodeListener}">
In Managed Bean storageArea I'have the code that load nodes, and on first time the method is called the first level of nodes is loaded, when a click in a node the substructure of this node is loaded.
On load the first level is validated the user's permissions, and this validation use the iterator of list that stores the tree nodes, this validation remove nodes that the user access is denied. some like this:
List<AreaArmazenamento> areas = root.getPastas();
synchronized (areas) {
Iterator<AreaArmazenamento> it = areas.iterator();
while(it.hasNext())
{
area = it.next();
boolean havePermission = ControllerPermission.havePermission(null, area, Permissions.VIEW, false);
if(!havePermission)
{
it.remove();
}
}
}
When I click on any node, I select the sub nodes of database and add the substructure in selected node, this working but sometimes on select node is throwed a ConcurrentNodificationException on Hashtable which is in TreeDataModule of Rich Tree.
This is a trace of exception:
Caused by: java.util.ConcurrentModificationException
at java.util.Hashtable$Enumerator.next(Hashtable.java:1031)
at org.richfaces.model.TreeDataModel.doWalk(TreeDataModel.java:136)
at org.richfaces.model.TreeDataModel.doWalk(TreeDataModel.java:154)
at org.richfaces.model.TreeDataModel.doWalk(TreeDataModel.java:154)
at org.richfaces.model.TreeDataModel.walk(TreeDataModel.java:178)
at org.richfaces.component.UITree.walk(UITree.java:422)
at org.richfaces.renderkit.TreeRendererBase.writeContent(TreeRendererBase.java:683)
anything about it may be causing this error? and why?
I Found the problem...
while(it.hasNext())
{
area = it.next();
boolean havePermission = ControllerPermission.havePermission(null, area, Permissions.VIEW, false);
if(!havePermission)
{
it.remove(); //problem here
}
}
I was removing items from the list on iteration...
Have you tried using a4j:queue ?
In the application I'm building I have Tabs and a list in for each Tab. the behavior I want is when I press the Left/Right Nav Key the selected Tab will change. when I press the Up/Down Nav Key the List will change selection index.
I used LWUIT GUI builder to generate StateMachine/StateMachineBase class.
I've been trying to fix this all day. please help.
Pheromix's answer is correct but he didn't account for the UIBuilder. To override the Form creation in the UIBuilder override the method:
protected Component createComponentInstance(String componentType, Class cls) {
if(cls == com.sun.lwuit.Form.class) {
return new MyFormSubclass();
}
return super.createComponentInstance(componentType, cls);
}
There is an option to override the Tab selection behavior but to get the most accurate behavior this might be the best approach.
Why do you complicate your life ? Just use keyReleased method implementation in your class. Make a test :
if (display.getGameAction(keyCode) == Display.GAME_LEFT || display.getGameAction(keyCode) == Display.GAME_RIGHT)
{
if (tab.getSelectedIndex == 0)
tab.setSelectedIndex(1);
else
tab.setSelectedIndex(0);
}
else if (display.getGameAction(keyCode) == Display.GAME_UP || display.getGameAction(keyCode) == Display.GAME_DOWN)
{
if (list.hasFocus())
super.keyReleased(keyCode);
}