Repository navigation
RML Forms
A form is a collection of input elements inside a <form> element - when the form is "submitted", the value of each named input element inside it is passed to the form's submit event.
You don't need a <form> to use the controls. <input>, <textarea>, <select> and <dataselect> work anywhere in a document, and SCPUI never uses <form>: it reacts to each control's change event and reads values from Lua instead. A <form> is only needed for submit buttons and for grouping radio buttons.
- onsubmit - Lua code to run when the form is submitted, like any other
on*attribute (see Events). The values of the form's controls are inevent.parameters, keyed by each control'sname.
<form onsubmit="controller:login(event)">
<input type="text" name="callsign"/>
<input type="password" name="password"/>
<input type="submit" name="action" value="login">Log in</input>
</form>function Controller:login(event)
local callsign = event.parameters.callsign
local action = event.parameters.action -- "login"
endWhat gets submitted:
- Every named control in the form that isn't disabled. Controls without a
nameare skipped. - Checkboxes and radio buttons only if they are checked.
- The submit button that was clicked, under its
name(or undersubmitif it has no name), with itsvalue. - If several controls share a name, their values are joined with
", ".
There are four elements that function as children to a <form> element: the <input>, <textarea>, <select> and <dataselect> elements. These have many common attributes which are listed below. Any specific attributes are listed afterwards under their own headings.
The name of the input element. This is used to look up the element's value when the form is submitted. For types of radio it is used to group together radio buttons so that only one with the same name can be checked at once.
For types of text, password and range, this is used as the initial value of the element. For the radio and checkbox types this is used as the value that is submitted (and sent with change) if the input is checked. For <option> elements, this is the value that is submitted by the parent <select>, if it is the selected option.
If this attribute is set, then the input element is unable to be changed by user input, and it is left out when the form is submitted. Disabled controls have the :disabled pseudo-class for styling.
Cast the element to its control type to get at its value and other properties. element.value on a plain element is not the control's value.
local input = Element.As.ElementFormControlInput(document:GetElementById("chat_input"))
local text = input.value
input.value = ""The control's change event also carries the new value as event.parameters.value. See Events.
The type of the input field. Must be one of the types below. Without a type the input is a text field. The input also gets a class with the same name as its type (text, range, checkbox and so on), so input.range selects range inputs in RCSS.
Known issue: changing an input's
typefrom Lua works for every type except back totext; settingtypetotexton an input that is currently another type does nothing. Create a new input instead.
A one-line text-entry field.
Like text, but replaces the entered text with asterisks.
A radio button.
A checkbox.
A slider bar.
A button for submitting the form. Clicking it submits the enclosing <form>; outside a form it does nothing.
A plain button. It does nothing by itself and isn't submitted with the form; use its onclick. A disabled button doesn't send click events.
For types of text and password, defines the length (in characters) of the element. The default is 20.
For types of text and password, defines the maximum length (in characters) that the element will accept.
For types of radio and checkbox, if this attribute is set then the element is "on". Checked inputs have the :checked pseudo-class.
From Lua, use the checked property of the cast element:
local box = Element.As.ElementFormControlInput(element)
if box.checked then ... endRadio buttons are only grouped by name inside a <form>. Outside a form, checking one radio button doesn't uncheck the others; you have to do that yourself from Lua.
For the range type, defines the value at the lowest (left or top) end of the slider. The default is 0.
For the range type, defines the value at the highest (right or bottom) end of the slider. The default is 100.
For the range type, defines the increment that the slider will move by. The default is 1.
For the range type, specifies if it is a vertical or horizontal slider. Values can be horizontal or vertical.
The change event of a range input reports the slider's position from 0 to 1 in event.parameters.value, not a value between min and max. Read the cast element's value if you need the actual value. SCPUI's sliders use min="0" max="1", so the two are the same.
The width of the visible area of the textarea, as a number of columns of text. The default is 20.
The height of the visible area of the textarea, as a number of text rows. The default is 2.
If set nowrap, the textarea will not wrap unbroken lines to a new row.
The maximum length (in characters) that the element will accept.
<select> is a drop-down list of <option> elements. It has no additional attributes.
<select id="difficulty" onchange="controller:difficulty_changed(event)">
<option value="easy">Easy</option>
<option value="medium" selected>Medium</option>
<option value="hard">Hard</option>
</select>From Lua, cast it with Element.As.ElementFormControlSelect. Note the mixed indexing: selection is 1-based (and -1 when nothing is selected), but options[] is 0-based, so the selected option is options[selection - 1]:
local select_el = Element.As.ElementFormControlSelect(element)
local option = select_el.options[select_el.selection - 1]If set, then the option is selected when the <select> element is first loaded.
If set, then the option is not selectable by the user. Useful for labelling groups of options.
A <dataselect> is a <select> whose options come from a data source instead of <option> elements. SCPUI uses it for the drop-downs in the options screen.
The data source and table to read the options from, written source_name.table_name. The source must exist when the dataselect is first updated; you can also set it later from Lua with SetDataSource.
A comma-separated list of fields to fetch from the data source and to display for each option (or optionally to be sent through the data formatter). Without a formatter, only the first field is shown.
The field from the data source to use as the option's value. If not set, then the first field in the fields attribute is used.
The name of the data formatter to use to process the raw fields information into RML. If not set, then the first field is displayed as raw text.
Data sources and formatters are created in Lua with DataSource.new and DataFormatter.new. A data source needs two functions: GetNumRows(table_name) returns the number of rows, and GetRow(table_name, index, columns) returns a table of strings, one per requested column, in the same order. index is 1-based.
This is how SCPUI's options screen feeds its drop-downs:
<dataselect class="dropdown_dataselect_el" fields="display" valuefield="serialized"></dataselect>local values = { { Display = "Low", Serialized = "0" }, { Display = "High", Serialized = "1" } }
local source = DataSource.new("Graphics_Detail")
source.GetNumRows = function(table_name)
return #values
end
source.GetRow = function(table_name, index, columns)
local val = values[index]
local out = {}
for _, column in ipairs(columns) do
if column == "serialized" then
table.insert(out, val.Serialized)
elseif column == "display" then
table.insert(out, val.Display)
else
table.insert(out, "")
end
end
return out
end
local select_el = Element.As.ElementFormControlDataSelect(element)
select_el:SetDataSource("Graphics_Detail.Default")The table name ("Default" here) is passed to your functions; a single-table source can ignore it. When the data changes, call source:NotifyRowChange("Default") and the dataselect rebuilds its options. Keep a reference to the data source for as long as it is in use.
See Data Display for data formatters.