From 8317a0c55e25f629427b212e6e696a78c0a82dd5 Mon Sep 17 00:00:00 2001 From: Josh Schneider Date: Thu, 12 Mar 2015 15:09:18 -0700 Subject: [PATCH 1/7] Fix for selects not working in IE8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://github.com/angular-ui/ui-select/issues/158, based on an observed (but maybe not well understood) code change by @careywalker. Basically, just move the ng-click/ng-mouseenter bindings from the LI (choices-row) to the contained DIV (choices-row-inner). So far, I haven't seen an affect on behavior in any browser, but this is with light manual testing. All automated tests pass with these changes in place: >gulp test [15:05:36] Using gulpfile C:\web\sites\ui-select\gulpfile.js [15:05:36] Starting 'clean'... [15:05:36] Finished 'clean' after 14 ms [15:05:36] Starting 'scripts'... [15:05:36] Starting 'styles'... [15:05:36] Finished 'styles' after 61 ms [15:05:37] Finished 'scripts' after 1.01 s [15:05:37] Starting 'build'... [15:05:37] Finished 'build' after 14 μs [15:05:37] Starting 'karma'... [15:05:38] Finished 'karma' after 880 ms [15:05:38] Starting 'test'... [15:05:38] Finished 'test' after 5.63 μs INFO [karma]: Karma v0.12.31 server started at http://localhost:9876/ INFO [launcher]: Starting browser Chrome INFO [Chrome 41.0.2272 (Windows 7)]: Connected on socket gaw3nxxZW2Omee4BBX-X with id 17666700 Chrome 41.0.2272 (Windows 7): Executed 110 of 110 SUCCESS (2.483 secs / 2.465 secs) --- src/uiSelectChoicesDirective.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/uiSelectChoicesDirective.js b/src/uiSelectChoicesDirective.js index 41d24e31b..baa3d90f8 100644 --- a/src/uiSelectChoicesDirective.js +++ b/src/uiSelectChoicesDirective.js @@ -39,14 +39,14 @@ uis.directive('uiSelectChoices', } choices.attr('ng-repeat', RepeatParser.getNgRepeatExpression($select.parserResult.itemName, '$select.items', $select.parserResult.trackByExp, groupByExp)) - .attr('ng-if', '$select.open') //Prevent unnecessary watches when dropdown is closed - .attr('ng-mouseenter', '$select.setActiveItem('+$select.parserResult.itemName +')') - .attr('ng-click', '$select.select(' + $select.parserResult.itemName + ',false,$event)'); + .attr('ng-if', '$select.open'); //Prevent unnecessary watches when dropdown is closed var rowsInner = element.querySelectorAll('.ui-select-choices-row-inner'); if (rowsInner.length !== 1) throw uiSelectMinErr('rows', "Expected 1 .ui-select-choices-row-inner but got '{0}'.", rowsInner.length); - rowsInner.attr('uis-transclude-append', ''); //Adding uisTranscludeAppend directive to row element after choices element has ngRepeat - + rowsInner.attr('uis-transclude-append', '') //Adding uisTranscludeAppend directive to row element after choices element has ngRepeat + .attr('ng-mouseenter', '$select.setActiveItem('+$select.parserResult.itemName +')') + .attr('ng-click', '$select.select(' + $select.parserResult.itemName + ',false,$event)'); + $compile(element, transcludeFn)(scope); //Passing current transcludeFn to be able to append elements correctly from uisTranscludeAppend scope.$watch('$select.search', function(newValue) { From 9510eb1eda476fe6cf8e0076901c0709db3ed353 Mon Sep 17 00:00:00 2001 From: Josh Schneider Date: Fri, 20 Mar 2015 10:14:03 -0700 Subject: [PATCH 2/7] Only change ngClick event finding for IE8. Leave ngMouseEnter binding as it is. --- src/uiSelectChoicesDirective.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/uiSelectChoicesDirective.js b/src/uiSelectChoicesDirective.js index baa3d90f8..60635d07d 100644 --- a/src/uiSelectChoicesDirective.js +++ b/src/uiSelectChoicesDirective.js @@ -39,14 +39,14 @@ uis.directive('uiSelectChoices', } choices.attr('ng-repeat', RepeatParser.getNgRepeatExpression($select.parserResult.itemName, '$select.items', $select.parserResult.trackByExp, groupByExp)) - .attr('ng-if', '$select.open'); //Prevent unnecessary watches when dropdown is closed + .attr('ng-if', '$select.open') //Prevent unnecessary watches when dropdown is closed + .attr('ng-mouseenter', '$select.setActiveItem('+$select.parserResult.itemName +')'); var rowsInner = element.querySelectorAll('.ui-select-choices-row-inner'); if (rowsInner.length !== 1) throw uiSelectMinErr('rows', "Expected 1 .ui-select-choices-row-inner but got '{0}'.", rowsInner.length); rowsInner.attr('uis-transclude-append', '') //Adding uisTranscludeAppend directive to row element after choices element has ngRepeat - .attr('ng-mouseenter', '$select.setActiveItem('+$select.parserResult.itemName +')') .attr('ng-click', '$select.select(' + $select.parserResult.itemName + ',false,$event)'); - + $compile(element, transcludeFn)(scope); //Passing current transcludeFn to be able to append elements correctly from uisTranscludeAppend scope.$watch('$select.search', function(newValue) { From fb8386583757efe43281c024f553276ce797fc18 Mon Sep 17 00:00:00 2001 From: Josh Schneider Date: Mon, 30 Mar 2015 16:10:03 -0700 Subject: [PATCH 3/7] Revert "Only change ngClick event finding for IE8. Leave ngMouseEnter binding as it is." This reverts commit 9510eb1eda476fe6cf8e0076901c0709db3ed353. --- src/uiSelectChoicesDirective.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/uiSelectChoicesDirective.js b/src/uiSelectChoicesDirective.js index 60635d07d..baa3d90f8 100644 --- a/src/uiSelectChoicesDirective.js +++ b/src/uiSelectChoicesDirective.js @@ -39,14 +39,14 @@ uis.directive('uiSelectChoices', } choices.attr('ng-repeat', RepeatParser.getNgRepeatExpression($select.parserResult.itemName, '$select.items', $select.parserResult.trackByExp, groupByExp)) - .attr('ng-if', '$select.open') //Prevent unnecessary watches when dropdown is closed - .attr('ng-mouseenter', '$select.setActiveItem('+$select.parserResult.itemName +')'); + .attr('ng-if', '$select.open'); //Prevent unnecessary watches when dropdown is closed var rowsInner = element.querySelectorAll('.ui-select-choices-row-inner'); if (rowsInner.length !== 1) throw uiSelectMinErr('rows', "Expected 1 .ui-select-choices-row-inner but got '{0}'.", rowsInner.length); rowsInner.attr('uis-transclude-append', '') //Adding uisTranscludeAppend directive to row element after choices element has ngRepeat + .attr('ng-mouseenter', '$select.setActiveItem('+$select.parserResult.itemName +')') .attr('ng-click', '$select.select(' + $select.parserResult.itemName + ',false,$event)'); - + $compile(element, transcludeFn)(scope); //Passing current transcludeFn to be able to append elements correctly from uisTranscludeAppend scope.$watch('$select.search', function(newValue) { From c1871b2cff1abd229e3b1b58421dce0d70afde83 Mon Sep 17 00:00:00 2001 From: Josh Schneider Date: Mon, 30 Mar 2015 16:10:21 -0700 Subject: [PATCH 4/7] Revert "Fix for selects not working in IE8" This reverts commit 8317a0c55e25f629427b212e6e696a78c0a82dd5. --- src/uiSelectChoicesDirective.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/uiSelectChoicesDirective.js b/src/uiSelectChoicesDirective.js index baa3d90f8..41d24e31b 100644 --- a/src/uiSelectChoicesDirective.js +++ b/src/uiSelectChoicesDirective.js @@ -39,14 +39,14 @@ uis.directive('uiSelectChoices', } choices.attr('ng-repeat', RepeatParser.getNgRepeatExpression($select.parserResult.itemName, '$select.items', $select.parserResult.trackByExp, groupByExp)) - .attr('ng-if', '$select.open'); //Prevent unnecessary watches when dropdown is closed + .attr('ng-if', '$select.open') //Prevent unnecessary watches when dropdown is closed + .attr('ng-mouseenter', '$select.setActiveItem('+$select.parserResult.itemName +')') + .attr('ng-click', '$select.select(' + $select.parserResult.itemName + ',false,$event)'); var rowsInner = element.querySelectorAll('.ui-select-choices-row-inner'); if (rowsInner.length !== 1) throw uiSelectMinErr('rows', "Expected 1 .ui-select-choices-row-inner but got '{0}'.", rowsInner.length); - rowsInner.attr('uis-transclude-append', '') //Adding uisTranscludeAppend directive to row element after choices element has ngRepeat - .attr('ng-mouseenter', '$select.setActiveItem('+$select.parserResult.itemName +')') - .attr('ng-click', '$select.select(' + $select.parserResult.itemName + ',false,$event)'); - + rowsInner.attr('uis-transclude-append', ''); //Adding uisTranscludeAppend directive to row element after choices element has ngRepeat + $compile(element, transcludeFn)(scope); //Passing current transcludeFn to be able to append elements correctly from uisTranscludeAppend scope.$watch('$select.search', function(newValue) { From fe0f109a05b146fccef23f6a8b9d5bea5cd0f252 Mon Sep 17 00:00:00 2001 From: Josh Schneider Date: Tue, 31 Mar 2015 15:52:25 -0700 Subject: [PATCH 5/7] Use test for addEventListener to put ng-click and ng-mouseenter attributes on .ui-select-choices-row-inner specifically in IE8, which cannot capture those events from the parent .ui-select-choices-row. Fixes ability to select options in IE8, at least when binding the click event. Leaves functionality as-is for modern browsers. --- src/uiSelectChoicesDirective.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/uiSelectChoicesDirective.js b/src/uiSelectChoicesDirective.js index 41d24e31b..ed8f1d60a 100644 --- a/src/uiSelectChoicesDirective.js +++ b/src/uiSelectChoicesDirective.js @@ -39,13 +39,19 @@ uis.directive('uiSelectChoices', } choices.attr('ng-repeat', RepeatParser.getNgRepeatExpression($select.parserResult.itemName, '$select.items', $select.parserResult.trackByExp, groupByExp)) - .attr('ng-if', '$select.open') //Prevent unnecessary watches when dropdown is closed - .attr('ng-mouseenter', '$select.setActiveItem('+$select.parserResult.itemName +')') - .attr('ng-click', '$select.select(' + $select.parserResult.itemName + ',false,$event)'); + .attr('ng-if', '$select.open'); //Prevent unnecessary watches when dropdown is closed + if (typeof window.document.addEventListener !== 'undefined') { //crude way to exclude IE8, specifically, which also cannot capture events + choices.attr('ng-mouseenter', '$select.setActiveItem('+$select.parserResult.itemName +')') + .attr('ng-click', '$select.select(' + $select.parserResult.itemName + ',false,$event)'); + } var rowsInner = element.querySelectorAll('.ui-select-choices-row-inner'); if (rowsInner.length !== 1) throw uiSelectMinErr('rows', "Expected 1 .ui-select-choices-row-inner but got '{0}'.", rowsInner.length); rowsInner.attr('uis-transclude-append', ''); //Adding uisTranscludeAppend directive to row element after choices element has ngRepeat + if (typeof window.document.addEventListener === 'undefined') { //crude way to target IE8, specifically, which also cannot capture events - so event bindings must be here + rowsInner.attr('ng-mouseenter', '$select.setActiveItem('+$select.parserResult.itemName +')') + .attr('ng-click', '$select.select(' + $select.parserResult.itemName + ',false,$event)'); + } $compile(element, transcludeFn)(scope); //Passing current transcludeFn to be able to append elements correctly from uisTranscludeAppend From 5f5a7174929527d0ce24ab223d36e45a1f634940 Mon Sep 17 00:00:00 2001 From: Josh Schneider Date: Fri, 1 May 2015 09:52:04 -0700 Subject: [PATCH 6/7] Update uiSelectChoicesDirective.js No need for verbose conditionals --- src/uiSelectChoicesDirective.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uiSelectChoicesDirective.js b/src/uiSelectChoicesDirective.js index ed8f1d60a..548270e82 100644 --- a/src/uiSelectChoicesDirective.js +++ b/src/uiSelectChoicesDirective.js @@ -40,7 +40,7 @@ uis.directive('uiSelectChoices', choices.attr('ng-repeat', RepeatParser.getNgRepeatExpression($select.parserResult.itemName, '$select.items', $select.parserResult.trackByExp, groupByExp)) .attr('ng-if', '$select.open'); //Prevent unnecessary watches when dropdown is closed - if (typeof window.document.addEventListener !== 'undefined') { //crude way to exclude IE8, specifically, which also cannot capture events + if (document.addEventListener) { //crude way to exclude IE8, specifically, which also cannot capture events choices.attr('ng-mouseenter', '$select.setActiveItem('+$select.parserResult.itemName +')') .attr('ng-click', '$select.select(' + $select.parserResult.itemName + ',false,$event)'); } @@ -48,7 +48,7 @@ uis.directive('uiSelectChoices', var rowsInner = element.querySelectorAll('.ui-select-choices-row-inner'); if (rowsInner.length !== 1) throw uiSelectMinErr('rows', "Expected 1 .ui-select-choices-row-inner but got '{0}'.", rowsInner.length); rowsInner.attr('uis-transclude-append', ''); //Adding uisTranscludeAppend directive to row element after choices element has ngRepeat - if (typeof window.document.addEventListener === 'undefined') { //crude way to target IE8, specifically, which also cannot capture events - so event bindings must be here + if (!document.addEventListener) { //crude way to target IE8, specifically, which also cannot capture events - so event bindings must be here rowsInner.attr('ng-mouseenter', '$select.setActiveItem('+$select.parserResult.itemName +')') .attr('ng-click', '$select.select(' + $select.parserResult.itemName + ',false,$event)'); } From aebb75dfbfcb340edbd7feecdd8c3856303e48fe Mon Sep 17 00:00:00 2001 From: Josh Schneider Date: Fri, 1 May 2015 11:21:55 -0700 Subject: [PATCH 7/7] Update uiSelectChoicesDirective.js Broke things by referencing undefined document. Add dependency on $window to reference $window.document.addEventListener. --- src/uiSelectChoicesDirective.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/uiSelectChoicesDirective.js b/src/uiSelectChoicesDirective.js index 548270e82..8a84faf8f 100644 --- a/src/uiSelectChoicesDirective.js +++ b/src/uiSelectChoicesDirective.js @@ -1,6 +1,6 @@ uis.directive('uiSelectChoices', - ['uiSelectConfig', 'uisRepeatParser', 'uiSelectMinErr', '$compile', - function(uiSelectConfig, RepeatParser, uiSelectMinErr, $compile) { + ['uiSelectConfig', 'uisRepeatParser', 'uiSelectMinErr', '$compile', '$window', + function(uiSelectConfig, RepeatParser, uiSelectMinErr, $compile, $window) { return { restrict: 'EA', @@ -40,7 +40,7 @@ uis.directive('uiSelectChoices', choices.attr('ng-repeat', RepeatParser.getNgRepeatExpression($select.parserResult.itemName, '$select.items', $select.parserResult.trackByExp, groupByExp)) .attr('ng-if', '$select.open'); //Prevent unnecessary watches when dropdown is closed - if (document.addEventListener) { //crude way to exclude IE8, specifically, which also cannot capture events + if ($window.document.addEventListener) { //crude way to exclude IE8, specifically, which also cannot capture events choices.attr('ng-mouseenter', '$select.setActiveItem('+$select.parserResult.itemName +')') .attr('ng-click', '$select.select(' + $select.parserResult.itemName + ',false,$event)'); } @@ -48,7 +48,7 @@ uis.directive('uiSelectChoices', var rowsInner = element.querySelectorAll('.ui-select-choices-row-inner'); if (rowsInner.length !== 1) throw uiSelectMinErr('rows', "Expected 1 .ui-select-choices-row-inner but got '{0}'.", rowsInner.length); rowsInner.attr('uis-transclude-append', ''); //Adding uisTranscludeAppend directive to row element after choices element has ngRepeat - if (!document.addEventListener) { //crude way to target IE8, specifically, which also cannot capture events - so event bindings must be here + if (!$window.document.addEventListener) { //crude way to target IE8, specifically, which also cannot capture events - so event bindings must be here rowsInner.attr('ng-mouseenter', '$select.setActiveItem('+$select.parserResult.itemName +')') .attr('ng-click', '$select.select(' + $select.parserResult.itemName + ',false,$event)'); }