Skip to content
This repository has been archived by the owner on Apr 30, 2018. It is now read-only.

Commit

Permalink
feat(formly-field): Adds parser for keys that contain arrays (#709)
Browse files Browse the repository at this point in the history
angular. does not (and will not angular/angular.js#9850) properly
handle arrays in keys unless they have already been created in the model. This fix/feature adds a
separate parser for these circumstances and a formlyConfig.extras flag to control its use. The flag
is in place to minimize impact on current functionality of the setter.

This is in support of #706
  • Loading branch information
Phil Jolly authored and Kent C. Dodds committed Sep 6, 2016
1 parent 2073a91 commit fc45fb3
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 1 deletion.
22 changes: 21 additions & 1 deletion src/directives/formly-field.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ function formlyField($http, $q, $compile, $templateCache, $interpolate, formlyCo

// @ngInject
function FormlyFieldController($scope, $timeout, $parse, $controller, formlyValidationMessages) {
/* eslint max-statements:[2, 34] */
/* eslint max-statements:[2, 37] */
if ($scope.options.fieldGroup) {
setupFieldGroup()
return
Expand Down Expand Up @@ -109,6 +109,24 @@ function formlyField($http, $q, $compile, $templateCache, $interpolate, formlyCo
return angular.isNumber(key) || !formlyUtil.containsSelector(key)
}

function keyContainsArrays(key) {
return /\[\d{1,}\]/.test(key)
}

function deepAssign(obj, prop, value) {
if (angular.isString(prop)) {
prop = prop.replace(/\[(\w+)\]/g, '.$1').split('.')
}

if (prop.length > 1) {
const e = prop.shift()
obj[e] = obj[e] || (isNaN(prop[0])) ? {} : []
deepAssign(obj[e], prop, value)
} else {
obj[prop[0]] = value
}
}

function parseSet(key, model, newVal) {
// If either of these are null/undefined then just return undefined
if ((!key && key !== 0) || !model) {
Expand All @@ -118,6 +136,8 @@ function formlyField($http, $q, $compile, $templateCache, $interpolate, formlyCo
if (shouldNotUseParseKey(key)) {
// TODO: Fix this so we can get several levels instead of just one with properties that are numeric
model[key] = newVal
} else if (formlyConfig.extras.parseKeyArrays && keyContainsArrays(key)) {
deepAssign($scope.model, key, newVal)
} else {
const setter = $parse($scope.options.key).assign
if (setter) {
Expand Down
14 changes: 14 additions & 0 deletions src/directives/formly-field.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,20 @@ describe('formly-field', function() {
expect(scope.model[key]).to.eq(defaultValue)
})

it('should handle arrays properly when formlyConfig.extras.parseKeyArrays is set', () => {
const key = 'foo[0]'
const defaultValue = 'bar'

formlyConfig.extras.parseKeyArrays = true
scope.fields = [
{template: input, key, defaultValue},
]
scope.model = {}

compileAndDigest()
expect(scope.model.foo).to.be.instanceof(Array)
})

it('should get and set values when key is alpha numeric with alpha first', () => {
const key = 'A1'
const defaultValue = 'bar'
Expand Down
1 change: 1 addition & 0 deletions src/providers/formlyApiCheck.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ const formOptionsApi = apiCheck.shape({
resetModel: apiCheck.func.optional,
updateInitialValue: apiCheck.func.optional,
removeChromeAutoComplete: apiCheck.bool.optional,
parseKeyArrays: apiCheck.bool.optional,
templateManipulators: templateManipulators.optional,
manualModelWatcher: apiCheck.oneOfType([apiCheck.bool, apiCheck.func]).optional,
watchAllExpressions: apiCheck.bool.optional,
Expand Down
1 change: 1 addition & 0 deletions src/providers/formlyConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ function formlyConfig(formlyUsabilityProvider, formlyErrorAndWarningsUrlPrefix,
fieldTransform: [],
ngModelAttrsManipulatorPreferUnbound: false,
removeChromeAutoComplete: false,
parseKeyArrays: false,
defaultHideDirective: 'ng-if',
getFieldId: null,
},
Expand Down

0 comments on commit fc45fb3

Please sign in to comment.