Widget Definitions (Editor)

The editor uses a similar form capability which allows one to create a form without having to write all the HTML tags needed to handle each widget. Actually, one widget may include many tags and it can be so complicated that attempting to rewrite those tags by hand each time would be really tedious.

The core system offers the basic widgets such as a simple text edit and image drag and drop area. We already support one widget extension called locale allowing the user to select a timezone. This is an external extension to the editor.

Each widget needs at least one attribute defining their type. These are defined in the <widget> tag. The <snap-editor> also includes other tags defining the first widget which should be given the focus first, the tab order, and a few other form wide choices.

The S column below gives you the current status:

  • 'I' -- implemented
  • 'P' -- partially available
  • '-' -- still just an idea
  • '?' -- what the heck was I thinking?
Tag Parent Attributes Comments & Example S
<snap-editor> root owner
content-modified
The root tag defining forms using the Snap! editor plugin.

* owner -- define the owner of the form, the name of the plugin; it is often set to "output" although if you want to properly fail when your plugin gets uninstalled, you may want to use the name of your plugin.
* content-modified -- the date when the data in the form was last modified (the format must use: YYYY-MM-DD HH:MM:SS)
I
<auto-reset> <snap-editor> minutes The amount of time the user has to fill out the form before it automatically gets cleared. This is especially useful for forms with sensitive data (i.e. passwords, credit card numbers, etc.)

Note that all forms timeout after a while. In that case, attempting to submit the form fails, but we may not want to prevent the submission (i.e. we may want to ask the user to re-login, and redirect the user to the form so he can submit it properly, which is different from the auto-reset feature.)

TBD: The tag includes a list of comma separated REFID that limit the widgets that get cleared to those listed. If the list is empty, clear the entire form.

  <snap-editor>
    <auto-clear minutes="15">secret</auto-clear>
    <widget id="secret" type="password">
      ...
    </widget>
  </snap-editor>

The minutes attribute defines the number of minutes before the the form gets cleared. Using the editor (typing a key or clicking a button) resets the timeout counter to zero. The minutes attribute represents the number of minutes of inactivity before the form gets cleared.
-
<focus> <snap-editor> refid Define which widget should be given focuson startup. The widget to be focused is referenced by the refid attribute. It references the identifier as defined by the id attribute of the widget tag. The focus tag is expected to always be an empty tag.

  <focus refid="login"/>

The focus may be forced to a different widget under two conditions:

* focus=<widget> query string (highest priority) -- someone defined the focus query string with a widget idenfitier
* error -- when a form is submitted, the editor may generate a validation error, error that will reference the widget with the error and as a result the first such widget may instead be given focus on reload
P
<taborder> <snap-editor>   A list of identifiers giving the order in which widgets should be selected when the tab key is used. The list of identifiers is defined using the <tabindex> tags.

  <taborder>
    <tabindex refid="login"/>
    <tabindex refid="password"/>
  </taborder>

Note 1: some widgets do not yet support the tab key properly (i.e. timezone widget, radio button group).
Note 2: the final HTML tabindex number is not currently correct when the page includes multiple forms. Especially, if we want to dynamically add widgets to a form, the tabindex parameter needs to be recalculated for the entire page.
P
<tabindex> <taborder> refid Defines the widget identifier at that position. The list of tab indexes is used to define the tabindex attribute of the different HTML input tags generated by Snap! for your form. The HTML tabindex numbers are automatically generated for you. The refid attribute references the id of a widget. There can be only one <tabindex> that reference a given refid or your table is considered invalid.

  <tabindex refid="widget-identifier"/>

You can safely reference disabled widgets. It is not required for widgets that will always remain disabled.
P
<drop> <snap-editor>   Mark all widgets as accepting drops of files. It is also possible to mark a specific widget as accepting drops using the drop attribute of that <widget> tag.

By default, if this tag is not defined, widgets will refuse dropped files.
I
<accesskeys> <snap-editor>   The list of accesskeys. It is made in its own block to make it easy to see which key is used for what widget in a single place.

  <accesskeys>
    <key refid="email">e</key>
  </accesskeys>
-
<key> <accesskeys> refid Defines the key that activates the specified widget. The widget is referenced by refid which should match one of the widget id attributes.

  <key refid="email">e</key>
-
<widget> <snap-editor> id
type
field
path
duplicate-of
secret
mode
auto-save
drop
Define a widget with all of its parameters. This tag is what is used to add widgets to a form. All widgets are defined within a widget tag. Widgets are named using the id attribute. Each widget must have a unique id.

The different types of widgets are defined using the type attribute (see table below.) There is no default type.

  <widget id="email" type="edit-line">
    <default>contact@m2osw.com</default>
    <state>disabled</state>
  </widget>

When a widget corresponds to a field in the database, you can name it in the field attribute. This allows the editor to read the data before sending the form to the client and to write the data directly to the database when saving the form. The auto-save attribute is also needed for that purpose.

The widgets are transformed into HTML tags and added to your XML document that will later be parsed by your body parser. The path attribute is used to define the path in that XML document. The path is always relative. The widgets are always added in the /snap/page/body tag.

When defining a password field and you want to have a duplicate for verification (when you change your password) then you should define the identifier (id) of the duplicate widget. This is done using the duplicate-of attribute.

The secret attribute can be set to "public" or "secret". "secret" means that the value in that field has to be kept secret. As a result, it is never shown in an error or a log file that is considered public. Also, when the field gets auto-saved, it gets saved in the secret table instead of the revision table (note that this means there is no revision for secret fields.)

The dropdown widget uses the mode attribute. This widget can be defined as "select-only" or "editable". When marked as editable, one can enter his her own value to the widget. (There is only partial support for that feature; also it should be a widget sub-tag instead.)

The editor knows how to directly load and save the data of your forms in the database. The auto-save attribute defines the type of data to load and save. The currently supported types are:

* no -- this special value can be used to prevent the auto-load and auto-save feature for this widget
* double or float64 -- a 64 bit floating point value
* html -- HTML data, formatting tags are expected in this text (i.e. <i> or <strong>); other tags are not allowed (i.e. <html> or <title>); the <img> tag is give special treatment: if defined inline, the image gets saved as an attachment and the tag replaced by an href
* int8 -- an integer of 8 bits
* ms-date-us -- very simple US date (MM/DD/YYYY)
* plain -- plain text, like string, only we make sure to remove all possible tags
* string -- plain text, managed as is

The difference between html, string, and plain is not always easy to grasp. In general, a text-edit widget is said to use html and a line-edit will be setup as using string. We also support a text-html type which is clearly HTML. However, the line-edit may end up with a tag and string will keep that tag intact. It may not be a problem for you, but in some situation you may want to not have the tag. In that case you want to use plain. How does this happen? Copy & Paste is probably the main offender in a line-edit. It could also be the browser that decides to transform an email into a mailto: anchor (Internet Exporer does that by default).

WARNING: changing the type of data of a widget means that any existing data is lost. The database has no information about the type of data from the old type so the edit cannot read the old data properly. If you need to change the type, it is safer to rename the field (see field attribute) and write an upgrade path which will load the old data, convert it, and save it back to the new field.

The drop attribute is used with image-box widgets. It tells the editor that drag and drop is allowed over image-box widgets. The only supported value is drop (drop="drop").
I
<label> <widget> lang The label of the widget is used to name a widget. By default this is the few words appearing just before an input widget. The lang attribute defines the language of the label. If undefined, the default language for that website is used. If the website has no default, "en" is assumed.

  <label lang="fr">Votre nom :</label>

Note: many times the widget label is not used, instead we write a label in the XSLT parser. However, it is a good idea to have a label because that appears to the end user whenever an error occurs with that data entry.
I
<background-value> <widget>   The value appearing in the background of the widget when it is empty.

This value is often the name of the widget (i.e. username, password, email, address, zip code, etc.) so the user knows what to enter even if no label or description was given for that field.

  <background-value>enter email</background-value>
I
<sizes> <widget>   This tag includes a set of sizes / limits as defined below.

  <sizes>
    <!-- text fields      image fields -->
    <min>10</min>  or  <min>10x10</min>
    <max>60</max>  or  <max>1024x768</max>
    <min-lines>3</min-lines>
    <max-lines>30</max-lines>
  </sizes>
I
<max> <sizes>   Defines the maximum length (in characters) that this field accepts. If not defined, an inferred 256 characters is enforced by the core system in order to prevent potential problems (The inferred maximum is not implemented yet.)

You may use the <max-lines> tag to enforce a maximum number of lines.

For images, the parameter is parsed as a <width>x<height> string and the dimensions of the image are checked using these dimensions.

  <max>60</max>
  <max>1024x768</max>
I
<min> <sizes>   Defines the minimum length (in characters) that this field can be. In most cases this is not defined. The default is zero (0) which means empty values are accepted. A minimum of 1 makes the field mandatory, although you probably want to use the <require> tag instead. The system may represent mandatory fields with a little red start (*) at the end of the label or after the field or with a different field color or shape. Note that the filters may also impose a minimum, but if not defined here, then no required flag appears.

You may use the <min-lines> tag to enforce a minimum number of lines.

For images, the parameter is parsed as a <width>x<height> string and the dimensions of the image are checked using these dimensions.

  <min>10</min>      for text
  <min>15x15</min>   for images

WARNING: the value in <min> has to be smaller than the value in <max> for the check to ever succeed.
I
<min-lines> <sizes>   The minimum number of lines that have to appear in a text based widget. Note that the way to count lines may not always be satisfactory...

  <min-lines>3</min-lines>
I
<max-lines> <sizes>   The maximum number of lines that can appear in a text based widget. Note that the way to count lines may not always be satisfactory...

  <max-lines>30</max-lines>

WARNING: the value in <min-lines> has to be smaller than the value in <max-lines>. The system enforce this case.
I
<resize> <sizes>   When an image is concerned, a resize of the image before saving it (TBD -- I think I prefer the idea of an image script so we can always keep the large version of an image) -
<state> <widget>   The state of the widget. By default widgets are enabled. The following are the different available states:

* enabled -- the widget is editable
* disabled -- the widget is visible, but grayed out; it cannot be edited nor focused
* read-only -- the widget is visible, but it cannot be edited, however, it may still receive the focus so one can use the keyboard to select the content of the widget.

  <state>disabled</state>

Spellchecking is turned off on widgets that are not enabled to avoid showing mispellings to users when they cannot do anything about them.
I
<attachment> <widget> type
owner
identification
force-filename
multiple
Widgets that accept a file (marked with the drop attribute) can define parameters about the file using the <attachment> tag.

The attachment being saved in its own page, that page has to be assigned an owner and a type. By default the owner attribute is set to the "attachment" plugin. Similarly, by default the editor uses "attachment" for the type of the page. The type attribute can be used to change the type of the page.

The identification attribute defaults to "attachment/public". It represents the permission to use for the attachment page in the database. This is expected to be a relative path that is appended to the path types/taxonomy/system/content-types/... The system defines "attachment/private" which can be used to only allow logged in users to access the content.

By default, the filename sent by the browser is used to save the attachment. If only one file is accepted in that widget, then the force-filename can be used to always give a specific name to that attachment. Note, however, that the extension of the original filename is kept. In other words, if you drop image.png and then image.jpg, you still get two distinct attachments.

The multiple attribute can be used to allow more than one file to be dropped on this one file widget. (multiple is not currently implemented.)
P
<help> <widget> lang The long description for this field. In most cases this is a small help that appears under the widget so the user knows what to enter in that field. If empty, no such box is added to the widget. The lang attribute can be used to define the language of this field text. The default is the website default language. If no defaults are defined, "en" is used.

  <help lang="en-US">Please enter your complete email address in this field. The email address must include your user name and your domain name separated by the @ character.</help>

See also the <background-value> and <tooltip> tags.
-
<filters> <widget>   Define a set of tags used to check the validity of the data entry. The filters support a regular expression, JavaScript code, and preset validations.

  <filters>
    <regex>[0-9]+</regex>
  </filters>
I
<regex> <filters> match
name
A regular expression used to match the input. If the regex is not matched then the value is refused. The match attribute can be used to inverse the result when set to "no" (the default is match="yes").

The regex tag also supports the attribute name which can be used to test values with regular expressions and code that we implement directly in the core implementation. The following names are currently supported:

* date -- the input must be a valid date
* datetime -- the input must be a valid date followed by a valid time
* decimal -- the input must be a decimal number (0-9 digits with one optional period followed by more digits)
* email(x) -- the input must be one to x valid emails, x must be a valid integer, emails must be separated by commas
* email -- the input must be a valid email (exactly one)
* emails -- the input must be at least one valid email, more emails can be added separated by commas
* float -- the input must be a valid decimal number with an optional exponent (e[+-]<number>)
* integer -- the input must be a valid integer
* time -- the input must be a valid time
* uri -- the input must be a valid domain name, with a path, query string, anchor; the protocol is optional in the test, but NOT added to the value if missing

IMPORTANT NOTE: The regular expressions, even if defined to refuse an empty string, do not prevent an empty entry (so one can use "^[0-9]+$" for an integer but that does not prevent "" to be viewed as valid in the editor. This is because the regular expressions do not get checked when the input is empty.) To force the user to have something in such a field, make sure to use the <required> tag.

  <filters>
    <regex match="no">some-bad-word</regex>
  </filters>

  <filters>
    <!-- one to three emails -->
    <regex name="email(3)"/>
  </filters>

  <filters>
    <regex name="date"/>
    <min-date>01/01/2000</min-date>
    <max-date>12/31/2999</max-date>
    <min-time>3PM</min-time>
    <max-time>23:59:59</max-time>
  </filters>
I
<min> <filters> mode Minimum value allowed. The mode attribute defines the type of check: string, integer, float are allowed.

  <filters>
    <!-- positive only -->
    <min mode="float">0.0</min>
  </filters>
-
<max> <filters> mode Maximum value allowed, the field is expected to be numeric. The mode attribute defines the type of check: string, integer, float are allowed.

  <filters>
    <max mode="integer">100</max>
  </filters>
-
<min-date> <filters>   Minimum date allowed, the field is expected to be a valid date, although it is not required (if the field is an invalid date, this filter is ignored.)

See the <max-date> tag for additional detail.
I
<max-date> <filters>   Maximum date allowed, the field is expected to be a valid date, although it is not required (if the field is an invalid date, this filter is ignored.)

The date can be written as a regular date or as now +/- an adjustment. The adjustment can be written as follow:

  now +<count> <type> ...
  now -<count> <type> ...

The <count> must be an integer ([0-9]+). The spaces are all optional. The <type> must be one of:

  year, month, day, hour, minute, second

Or plurial of these words. For example, to allow a date within the last 6 months and the next 6 months:

  <min-date>now-6months</min-date>
  <max-date>now +6 month</min-date>
I
<min-time> <filters>   Minimum time allowed, the field is expected to be a valid time, although it is not required (if the field is an invalid time, this filter is ignored.)

See the <max-time> tag for additional detail.
I
<max-time> <filters>   Maximum time allowed, the field is expected to be a valid time, although it is not required (if the field is an invalid time, this filter is ignored.)

The time can be written as a regular time or as now +/- an adjustment. The adjustment can be written as follow:

  now +<count> <type> ...
  now -<count> <type> ...

The <count> must be an integer ([0-9]+). The spaces are all optional. The <type> must be one of:

  hour, minute, second

Or plurial of these words. For example, to allow a time within the last 3 hours and the next 3 hours:

  <min-date>now-3hours</min-date>
  <max-date>now +3 hour</min-date>
I
<uri> <filters> match Check whether the input is a valid URI. The check allows the URI to be entered without a protocol, the test prepends "http://" and tries again if the test of the value as is fails.

The text inside the <uri> tag is a list of top level domain (TLD) names. By default only the extensions included here are allowed. You may use the match attribute to inverse the test (match="no") to forbid certain extensions:

  <filters>
    <uri match="no">xxx</uri>
  </filters>
I
<validate> <filters>   Run the validate JavaScript code and if it returns true, it is considered valid. The code is JavaScript and it has access to all the fields in the form (NOT IMPLEMENTED, you can only access the current value right now.)

The following example accepts odd numbers only.

  <filters>
    <validate>
      <[DATA[return (plugins.editor.value % 2 == 1);]]>
    <validate>
  </filters>

Note: you may also want to use parseInt() to first transform the value in an integer and parseFloat() to make it a double if such value they are expected to be. Test with isNaN() to make sure the parseFloat() worked.
P
<extensions> <filters>   Specify a list of allowed file extensions for a dropdown / file widget.

Note: this does not work very well at this point.

  <filters>
    <extensions>.jpg,.png,.gif</extensions>
  </filters>
P
<tooltip> <widget>   Define a small description shown when the widget is hovered and/or focused.

The editor makes use of jQuery to display the tooltip giving us a lot of flexibility over the title attribute of HTML tags. For example, our tooltip text can include HTML tags and they can appear forever in a specific location including a separate area created for that purpose.

  <tooltip>Please enter your phone #</tooltip>
-
<value> <widget> default The current value of the widget (current in the database.) This value appears as the default value and can be used by the Reset button to restore the form to the way it was loaded. Note that the Reset to Default button would use the <default> value instead.

  <value>Current Value</value>

The default attribute can be used to specify a dynamic type of default. At this time we only support "today" in text fields:

  <value default="today"/>

Note: We are actually planning to change that to make use of the <default> tag instead because it should be there instead...
I
<item>
or
<item>
<value>

<preset>
default
class
value
Define a sub-item within a <value> or a <preset> tag. These are used for widgets such as dropdown widgets to define each possible entry in the dropdown.

The default attribute can be defined to mark that specific item as the default.

The class attribute are additional HTML classes to be added to the final widget HTML.

The value attribute defines the value to be saved in the database. This can be completely different from the display string of the dropdown (which by default would be saved in the database if no value attribute is defined.) It is especially useful when you are to translate the content of the widgets.

  <preset>
    <item default="default" value="1">One</item>
    <item class="two" value="2">Two</item>
    <item value="3">Three</item>
  </preset>
I
<default> <widget>   The default value of the widget. This is what you would have by default at the start. If undefined, the empty string is used as the default. This value is used when a user clicks on a Reset to Defaults button.

  <default>Default Value</default>

Note: at this time only the dropdown widget supports this tag. All widgets should use it though.
P
<preset> <widget>   The <preset> tag is used by the dropdown to define the default (preset) items of the dropdown. The value repsents one of the items of the preset and as such it cannot define these values.

  <preset>
    <item>US</item>
    <item>Canada</item>
  </select>
I
<require> <widget>   Whether content in this widget is required. The text in that tag must be "required" too. We may add support for other texts at a later time.

  <required>required</required>
I
<classes> <widget>   A widget can be assigned additional HTML classes. This tag includes those classes each separated by a space as they would otherwise appear in the class attribute of an HTML document.

  <classes>color</classes>
I
<immediate> <snap-editor>   Make the form editable immediately instead of having to click on the Edit button. I
<mode> <snap-editor> action This tag forces the action set to "edit". This is most often used for plugin setting forms.

The action can be set to "view" (default), "edit", or "auto".
I
<on-save> <snap-editor> redirect
target
allow-edit
auto-save
What happens when the Save command is received by the server.

The <on-save> tag uses the redirect attribute to define the destination URI. On a successful save the user is redirected to that page.

The target attribute is the same as the HTML anchor target attribute. Only we support _top, _parent, and _self for now. The meaning is the same.

The allow-edit attribute can be set to "no" in which case the editor darkens the whole screen while saving the data of this form. It is usually safer to set this flag to "no" although it defaults to "yes" since by default we expect the user to be able to further edit their data while saving.

The auto-save attribute can be set to "no" to prevent the automatic saving of the data to the database. This is particularly useful for pages where you have a form that is expected to be filled by many users (i.e. a survey, contact form, etc.) The default is "yes" meaning that the data is automatically saved in the database.
I
<no-toolbar> <snap-editor>   Mark the form as having no need for a toolbar. By default a toolbar is added for widgets such as text-edit widgets. That allows the user to change formatting and other similar things. I

The different types of widgets are defined in the following table. This is defined in the type attribute of the <widget> tag. The type attribute is mandatory and it has no default.

Type Comments
dropped-file-with-preview An area where the user can drop files to upload to the server. This specific version will accept files as it goes and add a preview of the file as available (i.e. an image representing the content of the file.)
image-box An area where the user can drop image files. Files that do not represent an image are refused immediately.
dropdown A list of item on can choose in a dropdown popup. Some dropdowns may allow the user to type an entry.

The dropdown popup will always open in the top most window. This allows the dropdown to appear as if it were leaking from IFRAMEs.

Dropdown popups that are too large to be displayed on the current viewport (browser window too small) will be changed to use multiple columns or include a sliderbar. Which to use can be defined by declaring the algorithm tag for that widget.
checkmark One checkmark widget. It can be unselected or selected.
radio Two or more radio buttons (it should be at least 2 entries, but can be just one.)
text-edit A widget allowing users to write formatted text. The format is of course defined using HTML tags and the editor is used to set those up.
line-edit A widget allowing users to write one line of text, in most cases, plain text.
button Define a button although at this time we generally directly define an anchor in the parser instead of using these buttons. We may ameliorate the use of the button at some point to make it much more useful to have buttons in the widget definition files.
custom The special type "custom" is used with widgets that are dynamically defined. The editor does not really do much with those other than output the data (i.e. <value> tag) defined by the dynamic code.
silent A silent widget is similar to a hidden widget except that it is never sent back to the server. These are generally used to send the client data that will be useful to the JavaScript handling that form.
hidden A hidden widget is similar to a line-edit except that it is always sent back to the server when we save the form (contrary to the silent widget that does not get sent back.) It is always sent back because it will never change otherwise.

The Locale plugin (locale_widgets to be precise) offers an extension which are two dropdown widgets merged in one widget (i.e. a composite widget.)

See Also: Locale feature (Date, Time, numbers, currency, etc.) [core]

Snap! Websites
An Open Source CMS System in C++

Contact Us Directly