diff --git a/packages/vulcan-forms/lib/components/Form.jsx b/packages/vulcan-forms/lib/components/Form.jsx index d1de4c560..e394b3f7d 100644 --- a/packages/vulcan-forms/lib/components/Form.jsx +++ b/packages/vulcan-forms/lib/components/Form.jsx @@ -352,10 +352,9 @@ class SmartForm extends Component { */ getLabel = fieldName => { - return this.context.intl.formatMessage({ - id: this.getCollection()._name + '.' + fieldName, - defaultMessage: this.state.flatSchema[fieldName].label, - }); + const id = `${this.getCollection().options.collectionName.toLowerCase()}.${fieldName}`; + const defaultMessage = this.state.flatSchema[fieldName] && this.state.flatSchema[fieldName].label; + return this.context.intl.formatMessage({ id, defaultMessage }); }; // --------------------------------------------------------------------- // diff --git a/packages/vulcan-forms/lib/components/FormError.jsx b/packages/vulcan-forms/lib/components/FormError.jsx index ab9cb2ffe..5c2cd8811 100644 --- a/packages/vulcan-forms/lib/components/FormError.jsx +++ b/packages/vulcan-forms/lib/components/FormError.jsx @@ -11,6 +11,7 @@ const FormError = ({ error, errorContext, getLabel }) => error.message || ( errorContext, label: error.properties.name && getLabel(error.properties.name), ...error.data, // backwards compatibility + // note: for intl fields, the error's label property will overwrite the getLabel label ...error.properties, }} defaultMessage={JSON.stringify(error)} diff --git a/packages/vulcan-lib/lib/modules/collections.js b/packages/vulcan-lib/lib/modules/collections.js index 1e5a8ded9..649e477e3 100644 --- a/packages/vulcan-lib/lib/modules/collections.js +++ b/packages/vulcan-lib/lib/modules/collections.js @@ -6,7 +6,7 @@ import { runCallbacks } from './callbacks.js'; import { getSetting, registerSetting } from './settings.js'; import { registerFragment, getDefaultFragmentText } from './fragments.js'; import escapeStringRegexp from 'escape-string-regexp'; -import { Locales, getIntlString } from './intl'; +import { validateIntlField, getIntlString } from './intl'; const wrapAsync = (Meteor.wrapAsync)? Meteor.wrapAsync : Meteor._wrapAsync; // import { debug } from './debug.js'; @@ -119,33 +119,6 @@ Mongo.Collection.prototype.helpers = function(helpers) { }); }; -/* - -Custom validation function to check for required locales - -See https://github.com/aldeed/simple-schema-js#custom-field-validation - -*/ -const validateIntlField = function () { - let errors = []; - - // if field is required, go through locales to check which one are required - if (!this.definition.optional) { - const requiredLocales = Locales.filter(locale => locale.required); - - requiredLocales.forEach((locale, index) => { - const strings = this.value; - const hasString = strings.some(s => s.locale === locale.id && s.value); - if (!hasString) { - errors.push({ id: 'errors.required', path: `${this.key}.${index}`, properties: { name: `${this.key.replace('_intl', '')} (${locale.id})` }}); - } - }); - - } - // hack to work around the fact that custom validation function can only return a single string - return `intlError|${JSON.stringify(errors)}`; -} - export const createCollection = options => { const { typeName, collectionName = getCollectionName(typeName), schema, generateGraphQLSchema = true, dbCollectionName } = options; diff --git a/packages/vulcan-lib/lib/modules/intl.js b/packages/vulcan-lib/lib/modules/intl.js index 6013e815d..f981b35a6 100644 --- a/packages/vulcan-lib/lib/modules/intl.js +++ b/packages/vulcan-lib/lib/modules/intl.js @@ -44,4 +44,32 @@ export const getIntlString = () => { const IntlString = new SimpleSchema(schema); IntlString.name = 'IntlString'; return IntlString; +} + +/* + +Custom validation function to check for required locales + +See https://github.com/aldeed/simple-schema-js#custom-field-validation + +*/ +export const validateIntlField = function () { + let errors = []; + + // if field is required, go through locales to check which one are required + if (!this.definition.optional) { + const requiredLocales = Locales.filter(locale => locale.required); + + requiredLocales.forEach((locale, index) => { + const strings = this.value; + const hasString = strings.some(s => s.locale === locale.id && s.value); + const originalFieldName = this.key.replace('_intl', ''); + if (!hasString) { + errors.push({ id: 'errors.required', path: `${this.key}.${index}`, properties: { name: `${originalFieldName}_${locale.id}`, label: `${originalFieldName} (${locale.id})` }}); + } + }); + + } + // hack to work around the fact that custom validation function can only return a single string + return `intlError|${JSON.stringify(errors)}`; } \ No newline at end of file