This is a Web Component you can use in any web framework as well as plain HTML sites.
Your will need to have a running Cartona Survey server you can connect to.
The current version is 0.0.1, meaning the project is still under development. It cannot be used in production.
Further documentation is available from the developers upon request.
Install the component itself:
npm install @cartona/survey-component
If you also need to invoke the Survey API directly in your code (only in Angular), you can also install the client module:
npm install @cartona/cform
In your angular.json
file, add the following to your scripts under "build" under "architect":
"styles": [ ...
{
"input": "node_modules/@cartona/survey-component/styles.css"
}
],
"scripts": [ ...
{ "input": "node_modules/@cartona/survey-component/elements.js"
}
]
This allows Angular to load the component at startup and make it available.
In your component file (where you need to use the survey component) add the following import:
import "@cartona/survey-component";
In the owner module file, make sure to have the following:
schemas: [ CUSTOM_ELEMENTS_SCHEMA ],
Now you can embed the web component in your html:
<cform-mat-survey id="survey"
api_url="http://<your host>:<port>"
user_id="<unique user identifier>"
incident="<unique event identifier>"
survey_id="<id the survey to show>"
data="<initial data to merge>"
options='<see later>'
i18n-json='<localizations>'
(close)="exit()"
(done)="success($event)"
(error)="onError(kind)">
</cform-mat-survey>
Data can be bound directly as attributes of the component or passed all at once by an options
attribute.
The required attributes are survey_id
, user_id
, and api_url
. The rest are optional.
The incident
attribute is required in a survey of type incidence
.
The lang
attribute can be either en
or ar
.
The dir
attribute can be either ltr
or rtl
.
The data
attribute is a json object containing data known by your app, so it can be provided as part of the user input.
The i18n_json
is a valid json object containing translations for keywords used in the interface.
The i18n_file
points to a local or absolute path where a suitable i18n.json file can be found.
The survey component emits the following events that can be handled by your app.
-
edit
Emitted whenever the user changes the input data on any field. Current data is passed as a parameter.
-
done
Emitted when the user submits the form successfully. Submitted data is passed as a parameter.
-
close
Emitted when the user decides to close the form (usually without completing it). Current data is passed as a parameter.
-
error
Emitted when an error occurs. The possible errors (passed as a parameter) are:
- 'no-server' (Failed connection to the
api_url
) - 'no-survey' (Missing survey)
- 'not-allowed' (The survey is not published or the
user_id
is not allowed.) - 'not-submitted' (An error occurred on submitting the form.)
- 'no-server' (Failed connection to the
This has 2 benefits:
- The size and loading time of your app is unaffected. The code is only loaded when a survey is opened for the first time.
- Updates to the survey user interface will not require a rebuild or redistribution of your app.
To do this you need to install cordova-plugin-inappbrowser
and follow the instructions given here:
https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-inappbrowser/index.html
Now you can use cordova.InAppBrowser.open()
and pass the url provided by the control-cp
application. Remember to add the recommended parameter embed=y
and provide your own values for other url parameters.
We use cordova instead of capacitor to be able to listen to messages posted by the survey.
The messages passed will be JSON (stringified) in the following format:
{
“event”: “<done, edit, close, or error>”,
“error”: “<no-server, no-survey, not-allowed, or not-submitted>”,
”data”: “<current data to be submitted, if any>”
}
You can handle these messages and provide your own user feedback or custom handling since the embed=y
parameter keeps the embedded page silent.
Surveys are styled by css and can be customized to the look and feel of your application.
Your applied styles need to override the built-in styling, so a good idea is to wrap your component in a container with an id and use that id as a prefix to selectors:
#myid <selector> { color: yellow; }
These are the most likely entry points to the internal css.
-
.wizard-header
Use this to style the title bar of the wizard.
-
.wizard-footer
Use this to style the navigation bar at the bottom of the wizard.
-
.wizard-welcome
Use this to style the first page of the wizard.
-
.wizard-thank-you
Use this to style the last page of the wizard.
-
.mat-tab-body
Use this to style pages of the wizard.
-
.mat-card
Use this to style form sections.
-
.mat-button
Use this to style all buttons.
To select only buttons inside a component, precede this class by a suitable selector:
#mysurvey .wizard-footer .mat-button { ... }
-
.mat-form-field
Use this to apply styles to the entire area of an input field, including the label.
-
.mat-form-field-label
Use this to apply a style to the label of an input field.
-
.mat-form-field-underline
Use this to apply a style to the underlining line beneath a field.
For example, you can change the
background-color
orheight
. -
.mat-form-field.mat-focused
Use this to apply styles to fields that have keyboard focus
The ripple can be styled by
.mat-form-field.mat-focused .mat-form-field-ripple
-
.mat-form-field input
Use this to apply styles to the input text of a field.
-
.mat-form-field[data-key=]
Use this to apply styles to a specific input field if the relevant key is known.
#mysurvey .mat-form-field[data-key=firstname] { ... }
-
.mat-form-field[data-type=]
Use this to apply styles to a specific type of input fields.
#mysurvey .mat-form-field[data-type=string] { ... }
Possible types are: ‘string’, ‘number’, ‘date’, ‘time’, ‘choice’, ‘boolean’, ‘camera’, or ‘label’.
-
.rating
Use this to style a rating component.
-
.rating .stars
Use this to style the stars inside a rating component.
-
.scale
Use this to style a scale (usually 1-10) component.
-
.scale .labels
Use this to style the labels that appear above the boxes.
-
.scale .levels .level
Use this to style individual number boxes.
-
.camera
Use this to style a camera component.
-
.camera .preview
Use this to apply styles to the preview image in a camera component.
-
.camera .tools
Use this to apply styles to the toolbar in a camera component.
-
.chips
Use this to apply styles to chips (as in multi-select combo boxes). You can style a single chip by extending the selector:
#mysurvey .chips .mat-chip { … }
Surveys use 2 sets of strings: Those defined by the form and those defined by the system.
Each string in the form can be translated inside the designer.
To translate the system strings used by the interface (such as next and previous buttons, error messages, etc.) you can provide a custom file defined in json using the format below:
```json
{
"survey": {
"wizard": {
"start": {"en": "Start", "ar": "بدء"},
"next": {"en": "Next", "ar": "التالي"},
"back": {"en": "Back", "ar": "السابق"},
"done": {"en": "Done", "ar": "انتهاء"},
"restart": {"en": "Restart", "ar": "اعادة"},
"cancel": {"en": "Cancel", "ar": "الغاء"},
"close": {"en": "Close", "ar": "خروج"}
},
"camera": {
"take_photo": {"en": "Take Photo", "ar": "التقاط صورة"},
"gallery": {"en": "Gallery", "ar": "فتح صورة"},
"clear": {"en": "Clear", "ar": "مسح"}
},
"msg": {
"submitted": {"en": "Your input has been submitted."},
"not-submitted": {"en": "Your data could not be submitted. Please try again or contact your administrator."},
"not-allowed": {"en": "The Survey has not been made available to you. Please contact your administrator."},
"no-server": {"en": "Failed to reach the Survey server. Please check your internet connection and if the problem persists, contact your administrator."},
"no-survey": {"en": "Survey not available. It may no longer be published or you may not be allowed."}
}
}
}
```
You can even add a new language and specify it when calling the survey.