While Domma Models store flat key-value pairs, you can work with nested data structures by
combining Models with utility functions. This enables dot notation in forms through _.get() and
_.set() utilities.
// Create model with nested object values
const userModel = M.create({
profile: { type: 'object', default: {} },
address: { type: 'object', default: {} }
});
// Set nested data
userModel.set('profile', {
firstName: 'John',
lastName: 'Doe',
bio: 'Software developer'
});
userModel.set('address', {
street: '123 Main St',
city: 'New York',
zip: '10001'
});
// Access nested properties using utilities
const city = _.get(userModel.get('address'), 'city');
console.log('City:', city); // 'New York'
// Update nested property
const address = userModel.get('address');
_.set(address, 'city', 'Boston');
userModel.set('address', address); // Trigger change events
// Helper function for binding nested properties
function bindNested(model, field, path, selector, options = {}) {
M.bind(model, field, selector, {
...options,
format: (data) => _.get(data, path, ''),
parse: (value) => {
const data = _.cloneDeep(model.get(field) || {});
_.set(data, path, value);
return data;
}
});
}
// Create form model
const formModel = M.create({
userData: { type: 'object', default: {} }
});
// Bind form inputs with dot notation paths
bindNested(formModel, 'userData', 'user.name', '#user-name', { twoWay: true });
bindNested(formModel, 'userData', 'user.email', '#user-email', { twoWay: true });
bindNested(formModel, 'userData', 'address.city', '#address-city', { twoWay: true });
// Utility to serialize form with dot notation support
function serializeFormWithDotNotation(formSelector) {
const data = {};
$(formSelector).find('input, select, textarea').each(function() {
const element = $(this);
const name = element.attr('name');
if (!name) return;
let value;
if (element.attr('type') === 'checkbox') {
value = element.prop('checked');
} else if (element.attr('type') === 'radio') {
if (element.prop('checked')) {
value = element.val();
} else {
return; // Skip unchecked radio
}
} else {
value = element.val();
}
// Use _.set to handle dot notation
_.set(data, name, value);
});
return data;
}
// Usage
const formData = serializeFormWithDotNotation('#my-form');
// Returns nested object: { user: { name: '...', email: '...' }, address: { ... } }
section.field
throughout your forms
_.get()bindNested() for common
patterns
persist option
for localStorage
_.get() to
avoid errors
set() the parent
object to trigger model change events