I'm currently working on a custom field type, more specifically on the template content associated with it. Maybe it's best to first show you what I have, what I get, and what I expected to see instead.
custom/Espo/Custom/Resources/metadata/fields/contactDetails.json
client/custom/src/views/fields/contact-details.js
What I see:
const raw = this.model.get(this.name) || '{}';
The data doesn't seem to be availble in some cases, so that raw is initiated to {}.
So I guess my question is: What is the best place to call model.get()?
custom/Espo/Custom/Resources/metadata/fields/contactDetails.json
Code:
{ "params": [], "view": "custom:views/fields/contact-details" }
Code:
define(['views/fields/base'], (BaseFieldView) => { return class extends BaseFieldView { type = 'contactDetails'; editTemplateContent = ` <div> <input type="text" class="form-control" data-field="contact-name" value="{{name}}" placeholder="{{contactNamePlaceholder}}" /><br> <input type="text" class="form-control" data-field="contact-phone" value="{{phone}}" placeholder="{{contactPhonePlaceholder}}" /><br> <input type="email" class="form-control" data-field="contact-email" value="{{email}}" placeholder="{{contactEmailPlaceholer}}" /> </div> `; detailTemplateContent = ` <div> <strong>Name:</strong> {{name}}<br> <strong>Phone:</strong> <a href="tel:{{phone}}">{{phone}}</a><br> <strong>Email:</strong> <a href="mailto:{{email}}">{{email}}</a> </div> `; listTemplateContent = ` {{name}} <{{email}}> {{phone}} `; data() { const formData = this.formData || { name: '', phone: '', email: '' }; return { ...formData, contactNamePlaceholder: this.placeholderName, contactPhonePlaceholder: this.placeholderPhone, contactEmailPlaceholer: this.placeholderEmail, }; } setup() { // Calling the parent `setup` method, can be omitted. super.setup(); const raw = this.model.get(this.name) || '{}'; console.log(raw); try { const parsed = JSON.parse(raw); this.formData = { name: parsed.name || '', phone: parsed.phone || '', email: parsed.email || '' }; } catch (e) { this.formData = { name: '', phone: '', email: '' }; } // Add translations to be used in the template this.placeholderName = this.translate('contactDetailsName', "labels", "Fields"); this.placeholderPhone = this.translate('contactDetailsPhone', "labels", "Fields"); this.placeholderEmail = this.translate('contactDetailsEmail', "labels", "Fields"); } fetch() { const contactData = { name: this.$el.find('[data-field="contact-name"]').val().trim(), phone: this.$el.find('[data-field="contact-phone"]').val().trim(), email: this.$el.find('[data-field="contact-email"]').val().trim() }; return { [this.name]: JSON.stringify(contactData) }; } }; });
- When I create a field with this type and add it to the entity layout, it does show with the expected placeholders. So, this part of the template data works fine.
- When I save the form, the information on the detail page is shown correctly. So, here the data values for name, phone, and email work fine.
- When I refresh the page and I click on the newly created entry, THE FIRST TIME the template data for name, phone, and email are not available.
- When I go back and click on the newly created entry again, it works just fine.
const raw = this.model.get(this.name) || '{}';
The data doesn't seem to be availble in some cases, so that raw is initiated to {}.
So I guess my question is: What is the best place to call model.get()?
Comment