Form with a Dialog
Build a form that relies on HTML dialogs for parts of its input.
In this example we wil build a form that uses an HTML dialog to enter or edit data. We will build an expense report application.
The form consists of general input fields: description, cost center, manager and payment method. These are regular input fields and select controls which are rendered in the table lines 5 to 39 of the following code.
Besides these fields, the form contains an empty DIALOG
element (line 49) with id linedialog
and classes dialog-modal
and onclose-restore
. The dialog-modal
class tells Sircl to open the dialog in modal way (blocking access to the underlying page). The onclose-restore
class tells Sircl to restore the content of the DIALOG
element when the dialog is closed, which in this case basically means to clear the dialog when it is closed. We'll see later why.
Furthermore, the initial form contains two buttons: an Add new line button (line 42) and a Submit button (line 46). Both are regular form submit buttons where the Add new line button has a formaction
attribute to perform a LineNew action.
The whole form lays inside a DIV
element with target
class: when the form is submitted, the surrounding DIV
element is the inline target and the server is expected to return new content for that DIV
element. The target also contains an overlay (line 2) that will show up whenever the form is submitted:
<div class="target">
<div class="overlay" hidden></div>
<form action="/Expense/Submit" method="post" class="onsubmit-disable">
<table>
<tbody>
<tr>
<td>Description:</td>
<td>
<input type="text" name="Item.Description" />
</td>
</tr>
<tr>
<td>Cost center:</td>
<td>
<select name="Item.CostCenter">
<option value=""></option>
<option value="...">...</option>
</select>
</td>
</tr>
<tr>
<td>Manager:</td>
<td>
<select name="Item.Manager">
<option value=""></option>
<option value="...">...</option>
</select>
</td>
</tr>
<tr>
<td>Payment method:</td>
<td>
<label><input type="radio" name="Item.PaymentMethod" value="0" checked="chekced" /> By crediting credit card</label><br />
<label><input type="radio" name="Item.PaymentMethod" value="1" /> By bank transfer</label>
</td>
</tr>
</tbody>
</table>
<div>
<button type="submit" formaction="/Expense/LineNew">+ Add new line</button>
</div>
<div>
<button type="submit">Submit</button>
</div>
<dialog id="linedialog" class="dialog-modal onclose-restore"></dialog>
</form>
</div>
Clicking the Submit button will submit the form and, unless valid data was entered, result in the form being returned with information about validation errors: a new version of the form (including validation information) is returned by the server and replaces the content of the inline target. This is normal behaviour with Sircl.
Clicking the Add new line button is also expected to return new content for the inline target. And that is why clicking this button will trigger the overlay of the target.
But the invoked LineNew action will only return content of the DIALOG
element. And to tell the client it does provide content for the dialog only, it sets the following response header:
X-Sircl-Target: #linedialog
In other words, the server decides it will provide content for the dialog only, not for the whole form. This is the same as having a target="#linedialog"
attribute on the Add new line button element (except the overlay would not be triggered).
The following HTML code is then returned by the LineNew action:
<h3>New line</h3>
<div>
<label>Description</label><br />
<input type="text" name="CurrentLine.Description" />
</div>
<div>
<label>Date</label><br />
<input type="date" name="CurrentLine.Date" />
</div>
<div>
<label>Cateogry:</label><br />
<select name="CurrentLine.Category">
<option value=""></option>
<option value="...">...</option>
</select>
</div>
<div>
<label>Amount:</label><br />
<input type="text" name="CurrentLine.Amount" />
</div>
<div>
<button type="button" class="onclick-closedialog">Cancel</button>
<button type="submit" formaction="/Expense/LineSubmit">Add</button>
</div>
Since the NewLine action returns content to be embedded in a DIALOG
element, Sircl will make sure the dialog is opened. And since the DIALOG
element has the dialog-modal
class, the HTML dialog will be opened in modal mode.
The DIALOG
element is part of the surrounding form. As a consequence, the input elements and submit buttons inside the dialog are part of the surrounding form.
Pressing the Add button in the dialog will therefore submit the whole form to the LineSubmit action. If entered data is valid, new content will be provided for the regular inline target (the DIV
element surrounding the form): a new version of the form with information of the added expense report line (with hidden fields to include the content in subsequent submits).
If the LineSubmit action estimates the submitted content is not valid, it will return a new version of the dialog content (including validation information) as well as the following response header to instruct Sircl to display the returned content inside the DIALOG
element instead of inside the target surrounding the form:
X-Sircl-Target: #linedialog
The dialog content also includes a Cancel button to close the dialog. This button does not submit the form, it simply closes the dialog by means of the onclick-closedialog
event-action attribute. When closing the dialog this way, it would still contain its fields which may interfer with the (validation of the) main form. Therefore, the onclose-restore
class on the dialog was added: it removes all content of the dialog when it is closed using the Cancel button.
Working demo
Requirements
This example requires following Sircl library files to be loaded:
or:
Or their non-minified counterparts.
See the Get Started section about how to set up your project to use the Sircl library.