Support for "$" syntax to indicate where the serialization logic should collect values into arrays.
Use a dollar sign to indicate where tp-form should collect values as an array. For example `myfield.$list.value` collects { myfield: { list: [ { value: '...' } ] } }
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@tp/tp-form",
|
||||
"version": "1.1.1",
|
||||
"version": "1.2.0",
|
||||
"description": "",
|
||||
"main": "tp-form.js",
|
||||
"scripts": {
|
||||
|
84
tp-form.js
84
tp-form.js
@ -184,12 +184,86 @@ class TpForm extends LitElement {
|
||||
// Check if the object syntax is used in the elements name.
|
||||
if (el.name.indexOf('.') > -1) {
|
||||
const parts = el.name.split('.');
|
||||
parts.reduce((json, field, idx) => {
|
||||
if (idx < parts.length - 1) {
|
||||
json[field] = json[field] || {};
|
||||
return json[field];
|
||||
|
||||
// Check if any part has a $ prefix to indicate array collection
|
||||
const arrayIndex = parts.findIndex(part => part.startsWith('$'));
|
||||
|
||||
if (arrayIndex !== -1) {
|
||||
// Remove the $ from the part name
|
||||
parts[arrayIndex] = parts[arrayIndex].substring(1);
|
||||
|
||||
// Build the path to the array location
|
||||
let current = json;
|
||||
for (let i = 0; i < arrayIndex; i++) {
|
||||
current[parts[i]] = current[parts[i]] || {};
|
||||
current = current[parts[i]];
|
||||
}
|
||||
|
||||
// The key where we want the array
|
||||
const arrayKey = parts[arrayIndex];
|
||||
|
||||
// Initialize as array if needed
|
||||
if (!current[arrayKey]) {
|
||||
current[arrayKey] = [];
|
||||
} else if (!Array.isArray(current[arrayKey])) {
|
||||
// If it was previously a non-array, convert it
|
||||
current[arrayKey] = [current[arrayKey]];
|
||||
}
|
||||
|
||||
// Create the path for the remaining parts
|
||||
const remainingParts = parts.slice(arrayIndex + 1);
|
||||
|
||||
// Find an object in the array that doesn't have this value set yet
|
||||
// or create a new one
|
||||
let targetObj = current[arrayKey].find(item => {
|
||||
if (remainingParts.length === 0) {
|
||||
// If no remaining parts, we're adding directly to the array
|
||||
return false; // Always add a new item
|
||||
}
|
||||
|
||||
// Check if this object doesn't have the property yet
|
||||
let obj = item;
|
||||
for (let i = 0; i < remainingParts.length - 1; i++) {
|
||||
if (!obj[remainingParts[i]]) {
|
||||
return true; // This object doesn't have the path, use it
|
||||
}
|
||||
obj = obj[remainingParts[i]];
|
||||
}
|
||||
|
||||
return !obj[remainingParts[remainingParts.length - 1]];
|
||||
});
|
||||
|
||||
// If no suitable object found, create a new one
|
||||
if (!targetObj) {
|
||||
targetObj = {};
|
||||
current[arrayKey].push(targetObj);
|
||||
}
|
||||
|
||||
// Add the value to the target object
|
||||
if (remainingParts.length === 0) {
|
||||
// Direct array of values
|
||||
// Just push the value (we already created a new entry above)
|
||||
current[arrayKey][current[arrayKey].length - 1] = el.value !== null && el.value !== undefined ? el.value : '';
|
||||
} else {
|
||||
this._addToJson(field, el.value, json);
|
||||
// Add the value at the nested path
|
||||
let objCursor = targetObj;
|
||||
for (let i = 0; i < remainingParts.length - 1; i++) {
|
||||
objCursor[remainingParts[i]] = objCursor[remainingParts[i]] || {};
|
||||
objCursor = objCursor[remainingParts[i]];
|
||||
}
|
||||
objCursor[remainingParts[remainingParts.length - 1]] = el.value !== null && el.value !== undefined ? el.value : '';
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Default behavior (no $ in the path)
|
||||
parts.reduce((currentJson, field, idx) => {
|
||||
if (idx < parts.length - 1) {
|
||||
currentJson[field] = currentJson[field] || {};
|
||||
return currentJson[field];
|
||||
} else {
|
||||
this._addToJson(field, el.value, currentJson);
|
||||
}
|
||||
}, json);
|
||||
|
||||
|
Reference in New Issue
Block a user