Support wrapping selection index with keyboard
diff --git a/bundles/org.eclipse.rap.addons.dropdown/js/rwt/dropdown/DropDown.js b/bundles/org.eclipse.rap.addons.dropdown/js/rwt/dropdown/DropDown.js
index 8dd8b89..1c5cc54 100644
--- a/bundles/org.eclipse.rap.addons.dropdown/js/rwt/dropdown/DropDown.js
+++ b/bundles/org.eclipse.rap.addons.dropdown/js/rwt/dropdown/DropDown.js
@@ -107,12 +107,19 @@
if( index < -1 || index >= this.getItemCount() || isNaN( index ) ) {
throw new Error( "Can not select item: Index " + index + " not valid" );
}
+ // This is more than optimization, it prevents too early rendering that can crash the client:
+ this._.viewer._inServerResponse = rwt.util.Functions.returnTrue;
this._.viewer.deselectAll();
if( index > -1 ) {
var item = this._.viewer.getRootItem().getChild( index );
this._.viewer.selectItem( item );
this._.viewer.setFocusItem( item );
+ this._.viewer._scrollIntoView( index, item );
+ } else {
+ this._.viewer.setFocusItem( null );
+ this._.viewer.setTopItemIndex( 0 );
}
+ delete this._.viewer._inServerResponse;
this._.viewer._sendSelectionChange(); // Not called for selection changes by API/Server
},
@@ -305,12 +312,14 @@
var renderGridItems = function() {
var rootItem = this._.viewer.getRootItem();
var items = this._.items;
+ this._.viewer._inServerResponse = rwt.util.Functions.returnTrue;
rootItem.setItemCount( 0 );
rootItem.setItemCount( items.length );
for( var i = 0; i < items.length; i++ ) {
var gridItem = new rwt.widgets.GridItem( rootItem, i, false );
gridItem.setTexts( [ items[ i ] ] );
}
+ delete this._.viewer._inServerResponse;
};
var onTextAppear = function() {
@@ -325,6 +334,12 @@
event.preventDefault();
if( key === "Down" && this.getSelectionIndex() === -1 && this.getItemCount() > 0 ) {
this.setSelectionIndex( 0 );
+ } else if( key === "Up" && this.getSelectionIndex() === 0 ) {
+ this.setSelectionIndex( -1 );
+ } else if( key === "Down" && this.getSelectionIndex() === this.getItemCount() - 1 ) {
+ this.setSelectionIndex( -1 );
+ } else if( key === "Up" && this.getSelectionIndex() === -1 && this.getItemCount() > 0 ) {
+ this.setSelectionIndex( this.getItemCount() - 1 );
} else {
this._.viewer.dispatchEvent( event );
}
diff --git a/tests/org.eclipse.rap.addons.dropdown.test/js/rwt/dropdown/DropDown_Test.js b/tests/org.eclipse.rap.addons.dropdown.test/js/rwt/dropdown/DropDown_Test.js
index 17411ff..a579054 100644
--- a/tests/org.eclipse.rap.addons.dropdown.test/js/rwt/dropdown/DropDown_Test.js
+++ b/tests/org.eclipse.rap.addons.dropdown.test/js/rwt/dropdown/DropDown_Test.js
@@ -676,6 +676,27 @@
assertEquals( 1, dropdown.getSelectionIndex() );
},
+ testSetSelectionIndex_ScrollToSelection : function() {
+ dropdown.setVisibleItemCount( 3 );
+ showDropDown();
+ dropdown.setItems( [ "a", "b", "c", "d", "e", "f" ] );
+
+ dropdown.setSelectionIndex( 5 );
+
+ assertEquals( 3, viewer.getTopItemIndex() );
+ },
+
+ testResetSelectionIndex_ResetScrollPosition : function() {
+ dropdown.setVisibleItemCount( 3 );
+ showDropDown();
+ dropdown.setItems( [ "a", "b", "c", "d", "e", "f" ] );
+ dropdown.setSelectionIndex( 5 );
+
+ dropdown.setSelectionIndex( -1 );
+
+ assertEquals( 0, viewer.getTopItemIndex() );
+ },
+
testSetSelectionIndex_RemoteSet : function() {
dropdown.setItems( [ "a", "b", "c" ] );
@@ -754,6 +775,8 @@
},
testKeyEventForwarding_Down : function() {
+ dropdown.setItems( [ "a", "b", "c" ] );
+ dropdown.setSelectionIndex( 1 );
showDropDown();
var logger = TestUtil.getLogger();
@@ -766,6 +789,8 @@
},
testKeyEventForwarding_PageUp : function() {
+ dropdown.setItems( [ "a", "b", "c" ] );
+ dropdown.setSelectionIndex( 1 );
showDropDown();
var logger = TestUtil.getLogger();
@@ -778,6 +803,8 @@
},
testKeyEventForwarding_PageDown : function() {
+ dropdown.setItems( [ "a", "b", "c" ] );
+ dropdown.setSelectionIndex( 1 );
showDropDown();
var logger = TestUtil.getLogger();
@@ -815,6 +842,54 @@
assertTrue( viewer.isFocusItem( viewer.getRootItem().getChild( 0 ) ) );
},
+ testPressUpAfterSelectionResetsSelectsLastItem : function() {
+ dropdown.setItems( [ "a", "b", "c" ] );
+ showDropDown();
+ dropdown.setSelectionIndex( -1 );
+ TestUtil.flush();
+
+ widget.focus();
+ TestUtil.pressOnce( widget, "Up" );
+
+ assertEquals( 2, dropdown.getSelectionIndex() );
+ },
+
+ testPressUpAfterSelectionFirstItemResetsFocus : function() {
+ dropdown.setItems( [ "a", "b", "c" ] );
+ showDropDown();
+ TestUtil.flush();
+
+ widget.focus();
+ TestUtil.pressOnce( widget, "Down" );
+ TestUtil.pressOnce( widget, "Up" );
+
+ assertFalse( viewer.isFocusItem( viewer.getRootItem().getChild( 0 ) ) );
+ },
+
+ testPressUpOnFirstItemResetsSelection : function() {
+ dropdown.setItems( [ "a", "b", "c" ] );
+ dropdown.setSelectionIndex( 0 );
+ showDropDown();
+ TestUtil.flush();
+
+ widget.focus();
+ TestUtil.pressOnce( widget, "Up" );
+
+ assertEquals( -1, dropdown.getSelectionIndex() );
+ },
+
+ testPressDownOnLastItemResetsSelection : function() {
+ dropdown.setItems( [ "a", "b", "c" ] );
+ dropdown.setSelectionIndex( 2 );
+ showDropDown();
+ TestUtil.flush();
+
+ widget.focus();
+ TestUtil.pressOnce( widget, "Down" );
+
+ assertEquals( -1, dropdown.getSelectionIndex() );
+ },
+
testSelectionResetResetsLeadItem : function() {
dropdown.setItems( [ "a", "b", "c" ] );
showDropDown();