@@ -16,7 +16,7 @@ var DATETIMELOCAL_REGEXP = /^(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d)$/;
16
16
var WEEK_REGEXP = / ^ ( \d { 4 } ) - W ( \d \d ) $ / ;
17
17
var MONTH_REGEXP = / ^ ( \d { 4 } ) - ( \d \d ) $ / ;
18
18
var TIME_REGEXP = / ^ ( \d \d ) : ( \d \d ) $ / ;
19
- var DEFAULT_REGEXP = / ( \b | ^ ) d e f a u l t ( \b | $ ) / ;
19
+ var DEFAULT_REGEXP = / ( \s + | ^ ) d e f a u l t ( \s + | $ ) / ;
20
20
21
21
var inputType = {
22
22
@@ -878,6 +878,25 @@ function addNativeHtml5Validators(ctrl, validatorName, element) {
878
878
}
879
879
}
880
880
881
+ function addUpdateOnListeners ( scope , element , options , listener ) {
882
+ if ( options ) {
883
+ if ( options . updateOn ) {
884
+ element . on ( options . updateOn , function ( ev ) {
885
+ scope . $apply ( function ( ) {
886
+ listener ( ev ) ;
887
+ } ) ;
888
+ } ) ;
889
+ }
890
+
891
+ scope . $on ( '$updateInputModels' , function ( scopeEvent , ev ) {
892
+ // Since this event can be triggered manually, we pass a dummy submit event
893
+ // in case no 'ev' argument is passed. This is important since $setViewValue
894
+ // will never debounce stuff that come from 'submit' trigger.
895
+ listener ( ev || { type : 'submit' } ) ;
896
+ } ) ;
897
+ }
898
+ }
899
+
881
900
function textInputType ( scope , element , attr , ctrl , $sniffer , $browser ) {
882
901
var validity = element . prop ( 'validity' ) ;
883
902
@@ -924,11 +943,7 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
924
943
}
925
944
} ;
926
945
927
- // Allow adding/overriding bound events
928
- if ( ctrl . $options && ctrl . $options . updateOn ) {
929
- // bind to user-defined events
930
- element . on ( ctrl . $options . updateOn , listener ) ;
931
- }
946
+ addUpdateOnListeners ( scope , element , ctrl . $options , listener ) ;
932
947
933
948
// setup default events if requested
934
949
if ( ! ctrl . $options || ctrl . $options . updateOnDefault ) {
@@ -1205,20 +1220,18 @@ function radioInputType(scope, element, attr, ctrl) {
1205
1220
1206
1221
var listener = function ( ev ) {
1207
1222
if ( element [ 0 ] . checked ) {
1208
- scope . $apply ( function ( ) {
1209
- ctrl . $setViewValue ( attr . value , ev && ev . type ) ;
1210
- } ) ;
1223
+ ctrl . $setViewValue ( attr . value , ev && ev . type ) ;
1211
1224
}
1212
1225
} ;
1213
1226
1214
- // Allow adding/overriding bound events
1215
- if ( ctrl . $options && ctrl . $options . updateOn ) {
1216
- // bind to user-defined events
1217
- element . on ( ctrl . $options . updateOn , listener ) ;
1218
- }
1227
+ addUpdateOnListeners ( scope , element , ctrl . $options , listener ) ;
1219
1228
1220
1229
if ( ! ctrl . $options || ctrl . $options . updateOnDefault ) {
1221
- element . on ( 'click' , listener ) ;
1230
+ element . on ( 'click' , function ( ev ) {
1231
+ scope . $apply ( function ( ) {
1232
+ listener ( ev ) ;
1233
+ } ) ;
1234
+ } ) ;
1222
1235
}
1223
1236
1224
1237
ctrl . $render = function ( ) {
@@ -1237,19 +1250,17 @@ function checkboxInputType(scope, element, attr, ctrl) {
1237
1250
if ( ! isString ( falseValue ) ) falseValue = false ;
1238
1251
1239
1252
var listener = function ( ev ) {
1240
- scope . $apply ( function ( ) {
1241
- ctrl . $setViewValue ( element [ 0 ] . checked , ev && ev . type ) ;
1242
- } ) ;
1253
+ ctrl . $setViewValue ( element [ 0 ] . checked , ev && ev . type ) ;
1243
1254
} ;
1244
1255
1245
- // Allow adding/overriding bound events
1246
- if ( ctrl . $options && ctrl . $options . updateOn ) {
1247
- // bind to user-defined events
1248
- element . on ( ctrl . $options . updateOn , listener ) ;
1249
- }
1256
+ addUpdateOnListeners ( scope , element , ctrl . $options , listener ) ;
1250
1257
1251
1258
if ( ! ctrl . $options || ctrl . $options . updateOnDefault ) {
1252
- element . on ( 'click' , listener ) ;
1259
+ element . on ( 'click' , function ( ev ) {
1260
+ scope . $apply ( function ( ) {
1261
+ listener ( ev ) ;
1262
+ } ) ;
1263
+ } ) ;
1253
1264
}
1254
1265
1255
1266
ctrl . $render = function ( ) {
@@ -1817,7 +1828,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
1817
1828
: ctrl . $options . debounce ) || 0 ;
1818
1829
1819
1830
$timeout . cancel ( pendingDebounce ) ;
1820
- if ( debounceDelay ) {
1831
+ if ( debounceDelay && trigger !== 'submit' ) {
1821
1832
pendingDebounce = $timeout ( function ( ) {
1822
1833
ctrl . $$realSetViewValue ( value ) ;
1823
1834
} , debounceDelay ) ;
@@ -2264,6 +2275,11 @@ var ngValueDirective = function() {
2264
2275
* important because `form` controllers are published to the related scope under the name in their
2265
2276
* `name` attribute.
2266
2277
*
2278
+ * Any pending changes will take place immediately when an enclosing form is submitted via the
2279
+ * `submit` event. Note that `ngClick` events will occur before the model is updated. Use `ngSubmit`
2280
+ * to have access to the updated model. It is possible to flush the pending changes manually by
2281
+ * triggering a scope event with name `$updateInputModels`.
2282
+ *
2267
2283
* @param {Object } ngModelOptions options to apply to the current model. Valid keys are:
2268
2284
* - `updateOn`: string specifying which event should be the input bound to. You can set several
2269
2285
* events using an space delimited list. There is a special event called `default` that
@@ -2358,13 +2374,13 @@ var ngModelOptionsDirective = function() {
2358
2374
var that = this ;
2359
2375
this . $options = $scope . $eval ( $attrs . ngModelOptions ) ;
2360
2376
// Allow adding/overriding bound events
2361
- if ( this . $options . updateOn ) {
2377
+ if ( this . $options . updateOn !== undefined ) {
2362
2378
this . $options . updateOnDefault = false ;
2363
2379
// extract "default" pseudo-event from list of events that can trigger a model update
2364
- this . $options . updateOn = this . $options . updateOn . replace ( DEFAULT_REGEXP , function ( ) {
2380
+ this . $options . updateOn = trim ( this . $options . updateOn . replace ( DEFAULT_REGEXP , function ( ) {
2365
2381
that . $options . updateOnDefault = true ;
2366
2382
return ' ' ;
2367
- } ) ;
2383
+ } ) ) ;
2368
2384
} else {
2369
2385
this . $options . updateOnDefault = true ;
2370
2386
}
0 commit comments