Options
All
  • Public
  • Public/Protected
  • All
Menu

Module Form

JMap.Form

Here you'll find all form related methods

Index

Functions

addDisplayedFormPhoto

  • JMap.Form.addDisplayedFormPhoto

    Adds a photo to the currently displayed form.

    example
    
    if (JMap.Form.hasDisplayedForm() && JMap.Form.hasDisplayedFormAPhotoField()) {
     // returns the photos of the currently displayed form
     const newPhoto = JMap.Form.addDisplayedFormPhoto({
       url: "https://your-url/myphoto.jpeg",
       title: "My photo",
       fileName: "myphoto.jpeg",
       comment: undefined,
       metadata: {
         projectionType: "none"
       },
       imageBase64: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABEAYAAABPhRjKAAABhWlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw1AUhU9TpSIVhVYQcchQnSyISnHUKhShQqgVWnUweekfNGlIUlwcBdeCgz+LVQcXZ10dXAVB8AfE0clJ0UVKvK8ptIjxwuN9nHfP4b37AKFeZprVNQFoum2mEnExk10VA6/wIYRBxDAgM8uYk6QkPOvrnrqp7qI8y7vvz+pTcxYDfCLxLDNMm3iDOLZpG5z3icOsKKvE58TjJl2Q+JHristvnAtNFnhm2Eyn5onDxGKhg5UOZkVTI54mjqiaTvlCxmWV8xZnrVxlrXvyFwZz+soy12mNIIFFLEGCCAVVlFCGjSjtOikWUnQe9/APN/0SuRRylcDIsYAKNMhNP/gf/J6tlZ+adJOCcaD7xXE+RoHALtCoOc73seM0TgD/M3Clt/2VOjDzSXqtrUWOgP5t4OK6rSl7wOUOMPRkyKbclPy0hHweeD+jb8oCoVugd82dW+scpw9AmmaVvAEODoGxAmWve7y7p3Nu//a05vcDhJpyruvcgbwAAAAGYktHRAD/AP8A/6C9p5MAAAAJcEhZcwAALiMAAC4jAXilP3YAAAAHdElNRQfmARsTORZSgY7TAAAAGXRFWHRDb21tZW50AENyZWF0ZWQgd2l0aCBHSU1QV4EOFwAAAAtJREFUCNdjYIACAAAJAAFjKhYNAAAAAElFTkSuQmCC"
     })
     ...
    }

    Parameters

    • photo: JPhoto

      the photo to add

    Returns JId

    the new photo id

canCreateElementOnForm

  • canCreateElementOnForm(params: JFormId): boolean
  • JMap.Form.canCreateElementOnForm

    Returns true if current user can create element on the given form.

    example
    
    // returns true if current user can create element on form id=1 of layer id=3.
    JMap.Form.canCreateElementOnForm({
     layerId: 3,
     formId: 1
    })

    Parameters

    • params: JFormId

      parameters needed to identify the form

    Returns boolean

canDeleteElementOnForm

  • canDeleteElementOnForm(params: JFormId): boolean
  • JMap.Form.canDeleteElementOnForm

    Returns true if current user can delete element on the given form.

    example
    
    // returns true if current user can delete element on form id=1 of layer id=3.
    JMap.Form.canDeleteElementOnForm({
     layerId: 3,
     formId: 1
    })

    Parameters

    • params: JFormId

      parameters needed to identify the form

    Returns boolean

canUpdateElementOnForm

  • canUpdateElementOnForm(params: JFormId): boolean
  • JMap.Form.canUpdateElementOnForm

    Returns true if current user can update element on the given form.

    example
    
    // returns true if current user can udpate element on form id=1 of layer id=3.
    JMap.Form.canUpdateElementOnForm({
     layerId: 3,
     formId: 1
    })

    Parameters

    • params: JFormId

      parameters needed to identify the form

    Returns boolean

checkAndCorrectSchemas

  • JMap.Form.checkAndCorrectSchemas

    Checks if the schemas are valid, corrects them when possible, throws for non-repairable errors

    example
    
    const schema = ...
    const uiSchema = ...
    // checks the schemas, corrects them when possible, throws for non-repairable errors
    JMap.Form.checkAndCorrectSchemas(schema, uiSchema)

    Parameters

    Returns void

closeCurrentDisplayedDialog

  • closeCurrentDisplayedDialog(): void
  • JMap.Form.closeCurrentDisplayedDialog

    Closes the currently displayed form.

    Do nothing if no form displayed.

    example
    
     // closes currently displayed form
     JMap.Form.closeCurrentDisplayedDialog()

    Returns void

createAttributeFormElement

  • JMap.Form.createAttributeFormElement

    Creates an attribute form element.

    Works only for attribute form.

    throws

    if layer not found, if form not found, or form is not an attribute form, or invalid parameter

    example
    
    // returns the new created feature
    JMap.Form
     .createAttributeFormElement({
       layerId: 3,
       formId: 4,
       attributeValueByName: {
         color: "green",
         type: "tree"
       },
       geometry: {
         type: "Point",
         coordinates: [43.55843, 6.55121]
       }
     })
     .then(feature => console.log("New feature created:", feature))
     .catch(error => console.error("An error occurred while creating new feature", error))

    Parameters

    Returns Promise<Feature>

createDatabaseFormEntry

  • JMap.Form.createDatabaseFormEntry

    Creates an external or sub form entry.

    Works only for external or sub forms.

    throws

    if layer not found, if form not found, or form is not an external or sub form, or invalid parameter

    example
    
    // returns the new created entries
    JMap.Form
     .createDatabaseFormEntry({
       layerId: 3,
       formId: 5,
       parentId: 3,
       parentAttributeValueByName: {
         jmap_id: 3,
         color: "green",
         type: "tree"
       },
       attributeValueByName: {
         name: "bird",
         type: "nest"
       },
       elementId: 3
     })
     .then(entry => console.log("New entry created:", entry))
     .catch(error => console.error("An error occurred while creating new entry", error))

    Parameters

    Returns Promise<JFormElement>

deleteDatabaseFormEntries

  • JMap.Form.deleteDatabaseFormEntries

    Deletes entries of an attribute form.

    Works only for attribute form.

    throws

    if layer not found, if form not found, or form is not an attribute form, or invalid parameter

    example
    
    // returns delete result
    JMap.Form
     .deleteDatabaseFormEntries({
       layerId: 3,
       formId: 4,
       elements: [{
         id: 3,
         parentId: 3,
         elementId: 3,
         attributeValueByName: {
           name: "bee",
           type: "nest"
         },
         parentAttributeValueByName: {
           jmap_id: 3,
           color: "red",
           type: "tree"
         }
       }]
     })
     .then(result => console.log("Deleted entries result:", result))
     .catch(error => console.error("An error occurred while deleting entries", error))

    Parameters

    Returns Promise<JDeleteEntriesResult>

getActiveTabIndex

  • getActiveTabIndex(): number
  • JMap.Form.getActiveTabIndex

    Returns the active tab index.

    If no form, or sub form is displayed, returns 0.

    example
    
    if (JMap.Form.hasDisplayedForm()) {
     // reset currently displayed form values
     const currentTabIndex = JMap.Form.getActiveTabIndex()
     ...
    }

    Returns number

getAllFormsMetaDataForCurrentLayer

  • JMap.Form.getAllFormsMetaDataForCurrentLayer

    Returns the current layer forms metadata.

    If no layer form displayed, returns an empty array.

    example
    
     // returns the current layer forms metadata
     const formsMetadata = JMap.Form.getAllFormsMetaDataForCurrentLayer()
    }

    Returns JFormMetaData[]

getAttributeForm

  • getAttributeForm(): JForm
  • JMap.Form.getAttributeForm

    Returns attribute form of currently displayed layer.

    throws

    if layer has no attribute form

    example
    
     // returns attribute form of currently displayed layer
     const attributeForm = JMap.Form.getAttributeForm()
    }

    Returns JForm

getDefaultValues

  • JMap.Form.getDefaultValues

    Returns the default data values of the form.

    The result is an object where :

    • key is the attribute id
    • value the default value
    example
    
    const form = ...
    const defaultValues = JMap.Form.getDefaultValues(form)

    Parameters

    Returns JAttributeValueByName

    a key/value object

getDisplayedForm

  • getDisplayedForm(): JForm
  • JMap.Form.getDisplayedForm

    Returns the currently displayed form.

    Use [[JMap.Form.hasDisplayedForm()]] to know if a form is currently displayed.

    throws

    if no layer is displayed

    example
    
    if (JMap.Form.hasDisplayedForm()) {
     // returns the currently displayed form
     const form = JMap.Form.getDisplayedForm()
     ...
    }

    Returns JForm

getDisplayedFormPhotos

  • getDisplayedFormPhotos(): JPhoto[]
  • JMap.Form.getDisplayedFormPhotos

    Returns the photo of the currently displayed form.

    example
    
    if (JMap.Form.hasDisplayedForm() && JMap.Form.hasDisplayedFormAPhotoField()) {
     // returns the photos of the currently displayed form
     const photos = JMap.Form.getDisplayedFormPhotos()
     ...
    }

    Returns JPhoto[]

getElement

  • JMap.Form.getElement

    Returns form data of an element from given parameters.

    Works only for attribute forms.

    throws

    if layer not found, if form not found, or form is not an attribute form

    example
    
    // returns element form data for layer id=3, form id=2, and element id=245
    JMap.Form
     .getElement({
       layerId: 3,
       formId: 2,
       elementId: 245
     })
     .then(element => console.log("Element:", element))
     .catch(error => console.error("An error occurred when getting element data", error))

    Parameters

    Returns Promise<JFormElement | undefined>

getElements

  • JMap.Form.getElements

    Returns form data of multiple elements from given parameters.

    Works only for attribute forms.

    throws

    if layer not found, if form not found, or form is not an attribute form

    example
    
    // returns elements form data for layer id=3, form id=2, and elements id=245,236
    JMap.Form
     .getElements({
       layerId: 3,
       formId: 2,
       elementIds: [245, 236]
     })
     .then(elements => console.log("Elements:", elements))
     .catch(error => console.error("An error occurred when getting elements data", error))

    Parameters

    Returns Promise<JFormElement[]>

getEntries

  • JMap.Form.getEntries

    Returns form data of multiple entries from given parameters.

    Works only for external and sub forms.

    throws

    if layer not found, if form not found, or form is not an external or sub form

    example
    
    // returns entries form data for layer id=3, form id=4, and elements id=5
    JMap.Form
     .getEntries({
       layerId: 3,
       formId: 4,
       elementId: 5,
       parentId: 2,
       parentFormAttributesValuesByName: { jmap_id: 2, name: "Yellow" },
     })
     .then(entries => console.log("Entries:", entries))
     .catch(error => console.error("An error occurred when getting entries data", error))

    Parameters

    Returns Promise<JFormElement[]>

getExternalForms

  • getExternalForms(): JForm[]
  • JMap.Form.getExternalForms

    Returns external forms of currently displayed layer.

    example
    
     // returns external forms of currently displayed layer
     const externalForms = JMap.Form.getExternalForms()
    }

    Returns JForm[]

    an empty array if layer has no external forms

getFormMetaDataByIdForCurrentLayer

  • JMap.Form.getAllFormsMetaDataForCurrentLayer

    Returns form metadata of the currently displayed layer and given form id.

    throws

    if form not found

    example
    
     // returns the form metadata of currently displayed layer and form id=2
     const formMetadata = JMap.Form.getAllFormsMetaDataForCurrentLayer(2)
    }

    Parameters

    • formId: JId

      the JMap form id

    Returns JFormMetaData

getFormValues

  • JMap.Form.getFormValues

    Returns default values if form has not been edited, else form values.

    This is a technical method used by JMap App, you should never have to use this function

    example
    
     const form = ...
     // returns the form values
     JMap.Form.getFormValues(form)

    Parameters

    Returns JAttributeValueByName

getFormsMetaDataByLayerId

  • JMap.Form.getFormsMetaDataByLayerId

    Returns all forms metadata for a given layer id.

    Fecthes data from server first time, then keeps it in cache for the next time.

    throws

    if layer not found

    example
    
    // returns all forms metadata for layer id=3
    JMap.Form
     .getFormsMetaDataByLayerId(3)
     .then(formsMetadata => console.log("Forms metatada of layer 3", formsMetadata))
     .catch(error => console.error("An error occurred when getting form metadata", error))

    Parameters

    • layerId: JId

      the JMap layer id

    Returns Promise<JFormMetaData[]>

getNextViewId

  • getNextViewId(): number
  • JMap.Form.getNextViewId

    Returns the next view id.

    This is a technical method that you should never have to use.

    example
    
    // returns the next view id
    JMap.Form.getNextViewId()

    Returns number

getPreparedData

  • JMap.Form.getPreparedData

    This function prepare the data, it returns a copy object containing the values formatted in a way that fit the server needs.

    It's not mandatory to use this function but it's highly recommended to use it before :

    • sending them to the server ()
    • validating them using JMap.Form.getPreparedData (change values to fit the )

    It returns another object without modifing the passed object.

    Use to set the correct type (number if a string number is passed), and many other things.

    example
    
    const data = ...
    const form = ...
    const preparedData = JMap.Form.getPreparedData(form, data)
    const errors = JMap.Form.validateData(form, preparedData)

    Parameters

    Returns JAttributeValueByName

    the prepared data

getSubForms

  • JMap.Form.getSubForms

    Returns sub forms of currently displayed layer.

    example
    
     // returns sub forms of currently displayed layer
     const subForms = JMap.Form.getSubForms()
    }

    Returns JForm[]

    an empty array if layer has no sub forms

hasAttributeForm

  • hasAttributeForm(): boolean
  • JMap.Form.hasAttributeForm

    Returns true if the currently displayed layer has an attribute form.

    example
    
     // returns true if the currently displayed layer has an attribute form
     JMap.Form.hasAttributeForm()
    }

    Returns boolean

    If no form is displayed, return false.

hasDisplayedForm

  • hasDisplayedForm(): boolean
  • JMap.Form.hasDisplayedForm

    Returns true if a form is currently displayed.

    example
    
    // returns true if a form is currently displayed, else false
    JMap.Form.hasDisplayedForm()

    Returns boolean

hasDisplayedFormAPhotoField

  • hasDisplayedFormAPhotoField(): boolean
  • JMap.Form.hasDisplayedFormAPhotoField

    Returns true if currently displayed form has a photo field.

    example
    
    // returns true if currently displayed form has a photo field
    JMap.Form.hasDisplayedFormAPhotoField()

    Returns boolean

hasEditOwnRightsForAllElements

  • JMap.Form.hasEditOwnRightsForAllElements

    Returns true if current user has the right to edit all given elements.

    example
    
    // returns true if current user has the right to edit all given elements
    JMap.Form.hasEditOwnRightsForAllElements({
     layerId: 3,
     formId: 1,
     elements: [{
       id: 3,
       attributeValueByName: {
         author: "administrator",
         jmap_id: 3,
         color: "white",
         type: "tree"
       }
     }, {
       id: 4,
       attributeValueByName: {
         author: "administrator",
         jmap_id: 4,
         color: "red",
         type: "tree"
       }
     }]
    })

    Parameters

    Returns boolean

incrementNextViewId

  • incrementNextViewId(): void
  • JMap.Form.incrementNextViewId

    Increments the next view id.

    This is a technical method that you should never have to use.

    example
    
    // increments the next view id
    JMap.Form.incrementNextViewId()

    Returns void

isOwnPermissionRespectedForAllElements

  • isOwnPermissionRespectedForAllElements(layerId: JId, elements: JFormElement[]): boolean
  • JMap.Form.isOwnPermissionRespectedForAllElements

    Returns true if all given elements respect edit own permission.

    Works only for attribute form elements, edit own permission are not supported for external or sub forms.

    example
    
    const formElements = ... // get attribute form elements
    // returns true if all elements respect edit own permission
    JMap.Form.isOwnPermissionRespectedForAllElements(3, elements)

    Parameters

    Returns boolean

openCreationDialogForLayer

  • openCreationDialogForLayer(layerId: JId, geometry: GeoJSON.Geometry): Promise<JFormMetaData[]>
  • JMap.Form.openCreationDialogForLayer

    Opens the form creation dialog.

    throws

    if layer not found, or invalid geometry, or layer has no form

    example
    
     // opens the form creation dialog for layer id=3
     JMap.Form
       .openCreationDialogForLayer(
         3,
         {
           type: "Point",
           coordinates: [43.55843, 6.55121]
         }
       )
       .then(formsMetadata => console.log("Creation form dialog opened", formsMetadata))
       .catch(error => console.error(error))

    Parameters

    • layerId: JId

      the JMap layer id

    • geometry: GeoJSON.Geometry

      the feature geometry

    Returns Promise<JFormMetaData[]>

openCreationDialogForSubForm

  • JMap.Form.openCreationDialogForSubForm

    Opens the sub form creation dialog.

    throws

    if no form dialog currently opened, or sub form not found, or no sub form table field in currently displayed form, or invalid parameters

    example
    
     // opens the form creation dialog for layer id=3
     JMap.Form
       .openCreationDialogForSubForm(
         4,
         [
           id: 3,
           attributeValueByName: {
             jmap_id: 3,
             color: "red",
             type: "tree"
           }
         ]
       )
       .then(formMetadata => console.log("Creation sub form dialog opened", formMetadata))
       .catch(error => console.error(error))

    Parameters

    Returns JFormMetaData

openUpdateDialogForLayer

  • JMap.Form.openUpdateDialogForLayer

    Opens the form update dialog.

    throws

    if layer not found, or layer has no form

    example
    
     const layerId = 3
     const featureId = 4
     // in this exemple we fetch the feature from the server, but we could get from the map
     // with the following method <a href="jmap.map.html#getrenderedfeatures">JMap.Map.getRenderedFeatures</a>
     const feature = await JMap.Feature.getById(layerId, featureId)
     // opens form update dialog for one element of layer id=3
     JMap.Form
       .openUpdateDialogForLayer(
         layerId,
         [{
           id: featureId,
           attributeValueByName: feature.properties
         }]
       )
       .then(formsMetadata => console.log("Update form dialog opened", formsMetadata))
       .catch(error => console.error(error))

    Parameters

    • layerId: JId

      the JMap layer id

    • elements: JFormElement[]

      the elements to update

    Returns Promise<JFormMetaData[]>

openUpdateDialogForSubForm

  • JMap.Form.openCreationDialogForSubForm

    Opens the sub form creation dialog.

    throws

    if no form dialog currently opened, or sub form not found, or no sub form table field in currently displayed form, or invalid parameters

    example
    
     // opens the form creation dialog for layer id=3
     JMap.Form
       .openCreationDialogForSubForm(
         4,
         [
           id: 4,
           parentId: 3,
           elementId: 3,
           parentAttributeValueByName: {
             jmap_id: 3,
             color: "red",
             type: "tree"
           },
           attributeValueByName: {
             id: 4,
             name: "bee",
             type: "nest"
           }
         ]
       )
       .then(formMetadata => console.log("Update sub form dialog opened", formMetadata))
       .catch(error => console.error(error))

    Parameters

    Returns JFormMetaData

processRule

  • processRule(rule: any, data: any): any
  • JMap.Form.processRule

    Processes a JSON Logic rule and returns the result, or undefined if rules are not correct.

    https://github.com/jwadhams/json-logic-js#readme

    example
    
    // returns "banana"
    JMap.Form.processRule({"var" : 1 }, [ "apple", "banana", "carrot" ])

    Parameters

    • rule: any

      the json logic rule

    • data: any

      the data

    Returns any

removeDisplayedFormPhotoById

  • removeDisplayedFormPhotoById(photoId: JId): void
  • JMap.Form.removeDisplayedFormPhotoById

    Deletes a photo on the currently displayed form, for a given photo id.

    throws

    if invalid id passed, or photo not found

    example
    
    if (JMap.Form.hasDisplayedForm() && JMap.Form.hasDisplayedFormAPhotoField()) {
     const photos = getDisplayedFormPhotos()
     if (photos.length > 0) {
       JMap.Form.removeDisplayedFormPhotoById(photos[0].id)
     }
    }

    Parameters

    • photoId: JId

      the photo to delete

    Returns void

resetDisplayedForm

  • resetDisplayedForm(): void
  • JMap.Form.resetDisplayedForm

    Resets the currently displayed form.

    Use [[JMap.Form.hasDisplayedForm()]] to know if a form is currently displayed.

    throws

    if no layer is displayed

    example
    
    if (JMap.Form.hasDisplayedForm()) {
     // reset currently displayed form values
     JMap.Form.resetDisplayedForm()
     ...
    }

    Returns void

setActiveTabIndex

  • setActiveTabIndex(tabIndex: number): void
  • JMap.Form.setActiveTabIndex

    Set the active tab index.

    Works only for attribute form that have at least one external form.

    Index starts at 0 (attribute form), 1 (first external form), etc...

    Use [[JMap.Form.hasDisplayedForm()]] to know if a form is currently displayed.

    throws

    if no layer is displayed, if index is invalid.

    example
    
    if (JMap.Form.hasDisplayedForm()) {
     // reset currently displayed form values
     JMap.Form.setActiveTabIndex(1)
     ...
    }

    Parameters

    • tabIndex: number

      the tab index

    Returns void

setFormValues

  • JMap.Form.setFormValues

    Set form values of the given form.

    example
    
     const form = JMap.Form.getAttributeForm()
     // set values of the attribute form
     JMap.Form.setFormValues(form, {
       color: "white",
       type: "tree"
     })

    Parameters

    Returns JFormErrors

submit

  • JMap.Form.submit

    Submit the currently displayed form.

    throws

    if no form displayed

    example
    
     const layerId = 3
     const featureId = 4
     const feature = await JMap.Feature.getById(layerId, featureId)
     // opens form update dialog for one element of layer id=3
     await JMap.Form.openUpdateDialogForLayer(
       layerId,
       [{
         id: featureId,
         attributeValueByName: feature.properties
       }]
     )
     const form = JMap.Form.getAttributeForm()
     // change some values of the attribute form
     JMap.Form.setFormValues(form, {
       color: "white",
       type: "tree"
     })
     JMap.Form
       .submit()
       .then(result => console.log("Submit result", result))
       .catch(error => console.error(error))

    Parameters

    Returns Promise<JFormSubmitResult>

updateAttributeFormElements

  • JMap.Form.updateAttributeFormElements

    Updates an attribute form element.

    Works only for attribute form.

    throws

    if layer not found, if form not found, or form is not an attribute form, or invalid parameter

    example
    
    // returns update result
    JMap.Form
     .updateAttributeFormElements({
       layerId: 3,
       formId: 4,
       elements: [{
         id: 3,
         attributeValueByName: {
           color: "red",
           type: "tree"
         },
         parentAttributeValueByName: {}
       }]
     })
     .then(result => console.log("Element updated:", result))
     .catch(error => console.error("An error occurred while updating elements", error))

    Parameters

    Returns Promise<JFormResult[]>

updateDatabaseFormEntries

  • JMap.Form.updateDatabaseFormEntries

    Updates an external or sub form entry.

    Works only for external or sub form.

    throws

    if layer not found, if form not found, or form is not an external or sub form, or invalid parameter

    example
    
    // returns update result
    JMap.Form
     .updateDatabaseFormEntries({
       layerId: 3,
       formId: 4,
       elements: [{
         id: 3,
         parentId: 3,
         elementId: 3,
         attributeValueByName: {
           name: "bee",
           type: "nest"
         },
         parentAttributeValueByName: {
           jmap_id: 3,
           color: "red",
           type: "tree"
         }
       }]
     })
     .then(entries => console.log("Updated entries:", entries))
     .catch(error => console.error("An error occurred while updating entries", error))

    Parameters

    Returns Promise<JFormElement[]>

updateDisplayedFormPhoto

  • JMap.Form.updateDisplayedFormPhoto

    Updates a photo to the currently displayed form.

    throws

    if invalid params passed, or if title AND comments are not or empty string

    example
    
    if (JMap.Form.hasDisplayedForm() && JMap.Form.hasDisplayedFormAPhotoField()) {
     const photos = getDisplayedFormPhotos()
     if (photos.length > 0) {
       JMap.Form.updateDisplayedFormPhoto({
         photoId: photos[0].id,
         title: "My new title !",
         comment: "My new comment"
       })
     ...
     }
    }

    Parameters

    Returns void

validateData

  • JMap.Form.validateData

    Returns errors for the given form id and data.

    If no error validation, it returns an empty object.

    The result is an object where :

    • key is the attribute id
    • value is the validation error message, translated in the user locale
    example
    
    const form = ...
     const data = {
      name: "Jack"
    }
    // returns {} if no error, else could returns { age: "required field" }
    const errors = JMap.Form.validateData(form, data)

    Parameters

    Returns JFormErrors

    an empty object if no validation error, else an object containing error messages grouped by attribute id.