diff --git a/dist/css/ionic.css b/dist/css/ionic.css
index 0ef9c299d9..ad7a4b8d2e 100644
--- a/dist/css/ionic.css
+++ b/dist/css/ionic.css
@@ -4884,6 +4884,13 @@ a.button {
-webkit-animation: fadeIn 0.3s;
animation: fadeIn 0.3s; }
+.fade-in-not-out.ng-enter, .fade-in-not-out .ng-enter {
+ position: relative;
+ -webkit-animation: fadeIn 0.3s;
+ animation: fadeIn 0.3s; }
+.fade-in-not-out.ng-leave, .fade-in-not-out .ng-leave {
+ display: none; }
+
@-moz-keyframes spin {
100% {
-moz-transform: rotate(360deg); } }
diff --git a/dist/js/ionic-angular.js b/dist/js/ionic-angular.js
index 531d9da694..f07eaed42a 100644
--- a/dist/js/ionic-angular.js
+++ b/dist/js/ionic-angular.js
@@ -23165,13 +23165,15 @@ angular.module('ionic.service.modal', ['ionic.service.templateLoad', 'ngAnimate'
},
// Show the modal
show: function() {
+ var _this = this;
var element = angular.element(this.el);
if(!element.parent().length) {
- $animate.enter(element, angular.element($document[0].body));
+ $animate.enter(element, angular.element($document[0].body), null, function() {
+ ionic.views.Modal.prototype.show.call(_this);
+ });
}
- $animate.addClass(element, this.animation);
-
- ionic.views.Modal.prototype.show.call(this);
+ $animate.addClass(element, this.animation, function() {
+ });
},
// Hide the modal
hide: function() {
@@ -23542,35 +23544,48 @@ angular.module('ionic.ui.checkbox', [])
restrict: 'E',
replace: true,
require: '?ngModel',
- scope: true,
- template: '
',
+ scope: {},
+ template: '',
+
link: function($scope, $element, $attr, ngModel) {
- var checkbox, handle;
+ var checkbox;
if(!ngModel) { return; }
checkbox = $element.children().eq(0);
- handle = $element.children().eq(1);
- if(!checkbox.length || !handle.length) { return; }
+ if(!checkbox.length) { return; }
- $scope.checkbox = new ionic.views.Checkbox({
- el: $element[0],
- checkbox: checkbox[0],
- handle: handle[0]
- });
-
- $element.bind('click', function(e) {
- $scope.checkbox.tap(e);
+ var tapHandler = function(e) {
+ checkbox[0].checked = !checkbox[0].checked;
$scope.$apply(function() {
ngModel.$setViewValue(checkbox[0].checked);
});
+ e.preventDefault();
+ };
+
+ var clickHandler = function(e) {
+ checkbox[0].checked = !checkbox[0].checked;
+ $scope.$apply(function() {
+ ngModel.$setViewValue(checkbox[0].checked);
+ });
+ };
+
+ $scope.$on('$destroy', function() {
+ $element.unbind('tap', tapHandler);
+ $element.unbind('click', clickHandler);
});
- ngModel.$render = function() {
- $scope.checkbox.val(ngModel.$viewValue);
- };
+ if(ngModel) {
+ $element.bind('tap', tapHandler);
+ $element.bind('click', clickHandler);
+
+ ngModel.$render = function() {
+ console.log('checkbox redern', ngModel.$viewValue);
+ checkbox[0].checked = ngModel.$viewValue;
+ };
+ }
}
};
});
@@ -24171,11 +24186,11 @@ angular.module('ionic.ui.radio', [])
},
transclude: true,
template: '',
+ \
+ \
+
\
+ \
+ ',
link: function($scope, $element, $attr, ngModel) {
var radio;
@@ -24186,20 +24201,34 @@ angular.module('ionic.ui.radio', [])
if(!radio.length) { return; }
- radio.bind('click', function(e) {
- $scope.$apply(function() {
- ngModel.$setViewValue($scope.$eval($attr.ngValue));
- });
+ var tapHandler = function(e) {
+ radio[0].checked = true;
+ ngModel.$setViewValue($scope.$eval($attr.ngValue));
+ e.preventDefault();
+ };
+
+ var clickHandler = function(e) {
+ ngModel.$setViewValue($scope.$eval($attr.ngValue));
+ };
+
+ $scope.$on('$destroy', function() {
+ $element.unbind('tap', tapHandler);
+ $element.unbind('click', clickHandler);
});
- ngModel.$render = function() {
- var val = $scope.$eval($attr.ngValue);
- if(val === ngModel.$viewValue) {
- radio.attr('checked', 'checked');
- } else {
- radio.removeAttr('checked');
- }
- };
+ if(ngModel) {
+ $element.bind('tap', tapHandler);
+ $element.bind('click', clickHandler);
+
+ ngModel.$render = function() {
+ var val = $scope.$eval($attr.ngValue);
+ if(val === ngModel.$viewValue) {
+ radio.attr('checked', 'checked');
+ } else {
+ radio.removeAttr('checked');
+ }
+ };
+ }
}
};
});
diff --git a/dist/js/ionic.js b/dist/js/ionic.js
index 2b5ff978a7..40d60c3c8d 100644
--- a/dist/js/ionic.js
+++ b/dist/js/ionic.js
@@ -1769,7 +1769,7 @@ window.ionic = {
ionic.Platform.detect();
})(window.ionic);
;
-(function(ionic) {
+(function(window, document, ionic) {
'use strict';
// From the man himself, Mr. Paul Irish.
@@ -1799,7 +1799,71 @@ window.ionic = {
}
})();
-})(window.ionic);
+
+ // polyfill use to simulate native "tap"
+ function inputTapPolyfill(ele, e) {
+ if(ele.type === "radio" || ele.type === "checkbox") {
+ console.log('RADIOPOLY');
+ ele.checked = !ele.checked;
+ } else if(ele.type === "submit" || ele.type === "button") {
+ ele.click();
+ } else {
+ ele.focus();
+ }
+ e.stopPropagation();
+ e.preventDefault();
+ return false;
+ }
+
+ function tapPolyfill(e) {
+ // if the source event wasn't from a touch event then don't use this polyfill
+ if(!e.gesture || e.gesture.pointerType !== "touch" || !e.gesture.srcEvent) return;
+
+ if(e.defaultPrevented) {
+ e.stopPropagation();
+ e.preventDefault();
+ return false;
+ }
+
+ e = e.gesture.srcEvent; // evaluate the actual source event, not the created event by gestures.js
+
+ var ele = e.target;
+
+ while(ele) {
+ if( ele.tagName === "INPUT" || ele.tagName === "TEXTAREA" || ele.tagName === "SELECT" ) {
+ return inputTapPolyfill(ele, e);
+ } else if( ele.tagName === "LABEL" ) {
+ if(ele.control) {
+ return inputTapPolyfill(ele.control, e);
+ }
+ }
+ /* Let ng-click handle this
+ else if( ele.tagName === "A" || ele.tagName === "BUTTON" ) {
+ ele.click();
+ e.stopPropagation();
+ e.preventDefault();
+ return false;
+ }
+ */
+ ele = ele.parentElement;
+ }
+
+ // they didn't tap one of the above elements
+ // if the currently active element is an input, and they tapped outside
+ // of the current input, then unset its focus (blur) so the keyboard goes away
+ var activeElement = document.activeElement;
+ if(activeElement && (activeElement.tagName === "INPUT" || activeElement.tagName === "TEXTAREA" || activeElement.tagName === "SELECT")) {
+ activeElement.blur();
+ e.stopPropagation();
+ e.preventDefault();
+ return false;
+ }
+ }
+
+ // global tap event listener polyfill for HTML elements that were "tapped" by the user
+ ionic.on("tap", tapPolyfill, window);
+
+})(this, document, ionic);
;
(function(ionic) {
@@ -2779,30 +2843,6 @@ window.ionic = {
}
});
-})(ionic);
-;
-(function(ionic) {
-'use strict';
-
- ionic.views.Checkbox = ionic.views.View.inherit({
- initialize: function(opts) {
- this.el = opts.el;
- this.checkbox = opts.checkbox;
- this.handle = opts.handle;
- },
-
- tap: function(e) {
- this.val( !this.checkbox.checked );
- },
-
- val: function(value) {
- if(value === true || value === false) {
- this.checkbox.checked = value;
- }
- return this.checkbox.checked;
- }
- });
-
})(ionic);
;
(function(ionic) {
diff --git a/js/ext/angular/src/directive/ionicCheckbox.js b/js/ext/angular/src/directive/ionicCheckbox.js
index d230b10d85..5d03b93274 100644
--- a/js/ext/angular/src/directive/ionicCheckbox.js
+++ b/js/ext/angular/src/directive/ionicCheckbox.js
@@ -9,35 +9,48 @@ angular.module('ionic.ui.checkbox', [])
restrict: 'E',
replace: true,
require: '?ngModel',
- scope: true,
- template: '',
+ scope: {},
+ template: '',
+
link: function($scope, $element, $attr, ngModel) {
- var checkbox, handle;
+ var checkbox;
if(!ngModel) { return; }
checkbox = $element.children().eq(0);
- handle = $element.children().eq(1);
- if(!checkbox.length || !handle.length) { return; }
+ if(!checkbox.length) { return; }
- $scope.checkbox = new ionic.views.Checkbox({
- el: $element[0],
- checkbox: checkbox[0],
- handle: handle[0]
- });
-
- $element.bind('click', function(e) {
- $scope.checkbox.tap(e);
+ var tapHandler = function(e) {
+ checkbox[0].checked = !checkbox[0].checked;
$scope.$apply(function() {
ngModel.$setViewValue(checkbox[0].checked);
});
+ e.preventDefault();
+ };
+
+ var clickHandler = function(e) {
+ checkbox[0].checked = !checkbox[0].checked;
+ $scope.$apply(function() {
+ ngModel.$setViewValue(checkbox[0].checked);
+ });
+ };
+
+ $scope.$on('$destroy', function() {
+ $element.unbind('tap', tapHandler);
+ $element.unbind('click', clickHandler);
});
- ngModel.$render = function() {
- $scope.checkbox.val(ngModel.$viewValue);
- };
+ if(ngModel) {
+ $element.bind('tap', tapHandler);
+ $element.bind('click', clickHandler);
+
+ ngModel.$render = function() {
+ console.log('checkbox redern', ngModel.$viewValue);
+ checkbox[0].checked = ngModel.$viewValue;
+ };
+ }
}
};
});
diff --git a/js/ext/angular/src/directive/ionicRadio.js b/js/ext/angular/src/directive/ionicRadio.js
index f4b93c20e2..49bc0c1676 100644
--- a/js/ext/angular/src/directive/ionicRadio.js
+++ b/js/ext/angular/src/directive/ionicRadio.js
@@ -15,11 +15,11 @@ angular.module('ionic.ui.radio', [])
},
transclude: true,
template: '',
+ \
+ \
+
\
+ \
+ ',
link: function($scope, $element, $attr, ngModel) {
var radio;
@@ -30,20 +30,34 @@ angular.module('ionic.ui.radio', [])
if(!radio.length) { return; }
- radio.bind('click', function(e) {
- $scope.$apply(function() {
- ngModel.$setViewValue($scope.$eval($attr.ngValue));
- });
+ var tapHandler = function(e) {
+ radio[0].checked = true;
+ ngModel.$setViewValue($scope.$eval($attr.ngValue));
+ e.preventDefault();
+ };
+
+ var clickHandler = function(e) {
+ ngModel.$setViewValue($scope.$eval($attr.ngValue));
+ };
+
+ $scope.$on('$destroy', function() {
+ $element.unbind('tap', tapHandler);
+ $element.unbind('click', clickHandler);
});
- ngModel.$render = function() {
- var val = $scope.$eval($attr.ngValue);
- if(val === ngModel.$viewValue) {
- radio.attr('checked', 'checked');
- } else {
- radio.removeAttr('checked');
- }
- };
+ if(ngModel) {
+ $element.bind('tap', tapHandler);
+ $element.bind('click', clickHandler);
+
+ ngModel.$render = function() {
+ var val = $scope.$eval($attr.ngValue);
+ if(val === ngModel.$viewValue) {
+ radio.attr('checked', 'checked');
+ } else {
+ radio.removeAttr('checked');
+ }
+ };
+ }
}
};
});
diff --git a/js/ext/angular/src/service/ionicModal.js b/js/ext/angular/src/service/ionicModal.js
index 2725aeec28..f7b544e7b0 100644
--- a/js/ext/angular/src/service/ionicModal.js
+++ b/js/ext/angular/src/service/ionicModal.js
@@ -9,13 +9,15 @@ angular.module('ionic.service.modal', ['ionic.service.templateLoad', 'ngAnimate'
},
// Show the modal
show: function() {
+ var _this = this;
var element = angular.element(this.el);
if(!element.parent().length) {
- $animate.enter(element, angular.element($document[0].body));
+ $animate.enter(element, angular.element($document[0].body), null, function() {
+ ionic.views.Modal.prototype.show.call(_this);
+ });
}
- $animate.addClass(element, this.animation);
-
- ionic.views.Modal.prototype.show.call(this);
+ $animate.addClass(element, this.animation, function() {
+ });
},
// Hide the modal
hide: function() {
diff --git a/js/ext/angular/test/checkbox.html b/js/ext/angular/test/checkbox.html
index 1324ab67e5..01655c1f1b 100644
--- a/js/ext/angular/test/checkbox.html
+++ b/js/ext/angular/test/checkbox.html
@@ -9,12 +9,14 @@
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/js/ext/angular/test/input.html b/js/ext/angular/test/input.html
new file mode 100644
index 0000000000..b069982e52
--- /dev/null
+++ b/js/ext/angular/test/input.html
@@ -0,0 +1,35 @@
+
+
+
+ Checkbox
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/js/utils/poly.js b/js/utils/poly.js
index 82a598b2b3..014e7376fa 100644
--- a/js/utils/poly.js
+++ b/js/utils/poly.js
@@ -1,4 +1,4 @@
-(function(ionic) {
+(function(window, document, ionic) {
'use strict';
// From the man himself, Mr. Paul Irish.
@@ -28,4 +28,68 @@
}
})();
-})(window.ionic);
+
+ // polyfill use to simulate native "tap"
+ function inputTapPolyfill(ele, e) {
+ if(ele.type === "radio" || ele.type === "checkbox") {
+ console.log('RADIOPOLY');
+ ele.checked = !ele.checked;
+ } else if(ele.type === "submit" || ele.type === "button") {
+ ele.click();
+ } else {
+ ele.focus();
+ }
+ e.stopPropagation();
+ e.preventDefault();
+ return false;
+ }
+
+ function tapPolyfill(e) {
+ // if the source event wasn't from a touch event then don't use this polyfill
+ if(!e.gesture || e.gesture.pointerType !== "touch" || !e.gesture.srcEvent) return;
+
+ if(e.defaultPrevented) {
+ e.stopPropagation();
+ e.preventDefault();
+ return false;
+ }
+
+ e = e.gesture.srcEvent; // evaluate the actual source event, not the created event by gestures.js
+
+ var ele = e.target;
+
+ while(ele) {
+ if( ele.tagName === "INPUT" || ele.tagName === "TEXTAREA" || ele.tagName === "SELECT" ) {
+ return inputTapPolyfill(ele, e);
+ } else if( ele.tagName === "LABEL" ) {
+ if(ele.control) {
+ return inputTapPolyfill(ele.control, e);
+ }
+ }
+ /* Let ng-click handle this
+ else if( ele.tagName === "A" || ele.tagName === "BUTTON" ) {
+ ele.click();
+ e.stopPropagation();
+ e.preventDefault();
+ return false;
+ }
+ */
+ ele = ele.parentElement;
+ }
+
+ // they didn't tap one of the above elements
+ // if the currently active element is an input, and they tapped outside
+ // of the current input, then unset its focus (blur) so the keyboard goes away
+ var activeElement = document.activeElement;
+ if(activeElement && (activeElement.tagName === "INPUT" || activeElement.tagName === "TEXTAREA" || activeElement.tagName === "SELECT")) {
+ activeElement.blur();
+ e.stopPropagation();
+ e.preventDefault();
+ return false;
+ }
+ }
+
+ // global tap event listener polyfill for HTML elements that were "tapped" by the user
+ ionic.on("tap", tapPolyfill, window);
+
+})(this, document, ionic);
diff --git a/js/views/checkboxView.js b/js/views/checkboxView.js
deleted file mode 100644
index 1328e1a6f2..0000000000
--- a/js/views/checkboxView.js
+++ /dev/null
@@ -1,23 +0,0 @@
-(function(ionic) {
-'use strict';
-
- ionic.views.Checkbox = ionic.views.View.inherit({
- initialize: function(opts) {
- this.el = opts.el;
- this.checkbox = opts.checkbox;
- this.handle = opts.handle;
- },
-
- tap: function(e) {
- this.val( !this.checkbox.checked );
- },
-
- val: function(value) {
- if(value === true || value === false) {
- this.checkbox.checked = value;
- }
- return this.checkbox.checked;
- }
- });
-
-})(ionic);
diff --git a/scss/_animations.scss b/scss/_animations.scss
index 72f4b60d03..07c97fb6de 100644
--- a/scss/_animations.scss
+++ b/scss/_animations.scss
@@ -198,6 +198,17 @@ $slide-in-up-function: cubic-bezier(.1, .7, .1, 1);
}
}
+.fade-in-not-out {
+ &.ng-enter, .ng-enter {
+ position: relative;
+ -webkit-animation: fadeIn 0.3s;
+ animation: fadeIn 0.3s;
+ }
+ &.ng-leave, .ng-leave {
+ display: none;
+ }
+}
+
@-moz-keyframes spin {
100% { -moz-transform: rotate(360deg); }
}
@@ -210,3 +221,4 @@ $slide-in-up-function: cubic-bezier(.1, .7, .1, 1);
transform:rotate(360deg);
}
}
+