From 7d46575d28e64d4c4ca47a6ec7dc426664d1bec3 Mon Sep 17 00:00:00 2001 From: Matthew Kobs Date: Fri, 4 Mar 2016 09:03:54 -0600 Subject: [PATCH] [skip] Updated attributesFromForm to support nested objects (7m) --- .../javascripts/neat/model_editor.coffee | 50 ++++++++++++------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/vendor/assets/javascripts/neat/model_editor.coffee b/vendor/assets/javascripts/neat/model_editor.coffee index 87c1128..54b5cb8 100644 --- a/vendor/assets/javascripts/neat/model_editor.coffee +++ b/vendor/assets/javascripts/neat/model_editor.coffee @@ -94,26 +94,42 @@ class window.Neat.ModelEditor extends Backbone.View okToSave: (attributes)-> true - attributesFromForm: ($el)-> + attributesFromForm: ($el) -> attrs = {} $el.find('input, select, textarea').each -> - elem = $(this) + elem = $(@) name = elem.attr('name') - if name - elemType = elem.attr('type') - value = elem.val() - - if name.substr(-2) == '[]' - name = name.substring(0, name.length - 2) - attrs[name] = attrs[name] || [] - attrs[name].push elem.val() - - else if elemType == 'checkbox' || elemType == 'radio' - attrs[name] = '' if typeof(attrs[name]) == 'undefined' - attrs[name] = value if elem.prop('checked') - - else - attrs[name] = value + elemType = elem.attr('type') + value = elem.val() + return true unless name + + # Parse out nested objects as represented in names + # person[address][zip]=63303 should be serialized to: + # person: + # address: + # zip: 63303 + parts = _.without(name.split(/\[([^\]]+)\]/), '') + name = parts.pop() + isArray = false + while name is '[]' + isArray = true + name = parts.pop() + context = attrs + for part in parts + context = context[part] or (context[part] = {}) + + if (elemType == 'checkbox' || elemType == 'radio') && !elem.prop('checked') + return true + + if isArray + # select with multiple=true will return + # an array of selected values, so we don't + # need to nest that array in another array + value = [value] unless _.isArray(value) + value = (context[name] || []).concat(value) + + context[name] = value + true # Don't break out of the loop attrs destroy: (e)->