User Support
Ticket system for communicating with users
Ticket Submit Component
The supportTicketSubmit component displays a form that lets the signed-in user submit a new ticket, of a type they pick or that the page forces.
| Property | Description |
|---|---|
| ticketType | The code of a ticket type to give every ticket from this page, even a hidden type. Leave it empty to let the user pick a type. See Forcing a Type. |
| redirect | The page to open after a ticket is submitted, with the new ticket's ID as the id URL parameter. This is usually the page with the Ticket component. |
Basic Usage
The component only accepts tickets from a signed-in user, so restrict the page to signed-in users with the RainLab.User session component.
title = "Submit Ticket"
url = "/support/submit"
layout = "default"
[session]
security = "user"
redirect = "account/login"
[supportTicketSubmit]
redirect = "support/ticket"
==
{% component "supportTicketSubmit" %}
The default form asks for a ticket type first. When the user picks one, it shows the type's description with the subject, content and attachment fields.
Page Variables
The ticketTypes method of the component returns the ticket types that users can pick, sorted by name. Hidden types are left out.
{% set ticketTypes = supportTicketSubmit.ticketTypes %}
The component also sets these page variables.
| Variable | Description |
|---|---|
ticketTypeCode |
The ticketType property value. |
ticketType |
The forced ticket type. Without a forced type, it is the visible type posted as type_id, or null. |
The following page submits a ticket with its own markup.
title = "Submit Ticket"
url = "/support/submit"
layout = "default"
[session]
security = "user"
redirect = "account/login"
[supportTicketSubmit]
redirect = "support/ticket"
==
{{ form_ajax('onSubmitTicket', { files: true, flash: true, validate: true }) }}
<label for="ticketType">
Ticket type
</label>
<select name="type_id" id="ticketType">
<option value="">
Select a ticket type
</option>
{% for type in supportTicketSubmit.ticketTypes %}
<option value="{{ type.id }}">
{{ type.name }}
</option>
{% endfor %}
</select>
<div data-validate-for="type_id"></div>
<label for="subject">
Subject
</label>
<input name="subject" id="subject" type="text" maxlength="255" />
<div data-validate-for="subject"></div>
<label for="content">
Message
</label>
<textarea name="content" id="content" rows="8"></textarea>
<div data-validate-for="content"></div>
<input name="files[]" type="file" multiple />
<div data-validate-for="files"></div>
<button type="submit" data-attach-loading>
Submit ticket
</button>
{{ form_close() }}
AJAX Handlers
The component provides the following AJAX handlers.
| Handler | Description |
|---|---|
| onSubmitTicket | Validates and saves the new ticket with its attachments, then redirects. |
| onUpdateTicketType | Loads the posted ticket type into the ticketType page variable, so the form can show its description. |
Submitting a Ticket
The onSubmitTicket handler accepts the following fields.
| Field | Description |
|---|---|
subject |
The subject. Required, and at most 255 characters. |
content |
The ticket text, in Markdown. Required, and at most 50,000 characters. |
type_id |
The ID of a ticket type from ticketTypes. Optional, and ignored when the ticketType property is set. |
files[] |
Files to attach. See Attachments. |
redirect |
Optional. A page name, or a path on this site, that replaces the redirect property. |
The handler saves the ticket for the signed-in user with the New status, and staff receive the new-ticket mail. Then it sets the flash message The ticket has been posted successfully. and redirects to the redirect page with the new ticket's ID. When no redirect is set, it redirects back to the same page, which clears the form.
A posted redirect that is not a page name is treated as a path on this site, so the scheme and host of a full URL are dropped.
Showing the Type Description
The default form calls the onUpdateTicketType handler when the user picks a type, and updates the message-form partial with the type's description and the remaining fields.
<select
name="type_id"
data-request="onUpdateTicketType"
data-request-update="{ '@message-form': '#partialMessageForm' }">
<option value="">
Select a ticket type
</option>
{% for type in ticketTypes %}
<option value="{{ type.id }}">
{{ type.name }}
</option>
{% endfor %}
</select>
<div id="partialMessageForm">
{% partial '@message-form' %}
</div>
The handler refuses a hidden or unknown type with Ticket type not found. An empty type_id clears the type, and the form asks for one again.
Forcing a Type
Set the ticketType property to a type code to give every ticket from the page that type, even when the type is hidden. The handler ignores any posted type_id, and the default form leaves out the type select.
[supportTicketSubmit] ticketType = "technical" redirect = "support/ticket"
When no type has that code, the default form shows a notice in place of the fields, and the handler refuses every submission with the message This ticket type is not available. A warning is also written to the log. To show the same notice in your own markup, check the page variables.
{% if ticketTypeCode and not ticketType %}
<p>
This ticket type is not available.
</p>
{% else %}
{{ form_ajax('onSubmitTicket', { files: true, flash: true, validate: true }) }}
<!-- Subject, content and attachment fields -->
{{ form_close() }}
{% endif %}
See Ticket Types for hidden types and type codes.
Partials
The component renders the following partials.
| Partial | Description |
|---|---|
| default | Wraps the form in the responsiv-support element, with the ticket type select when no type is forced. |
| message-form | The type description with the subject, content and attachment fields, or a notice asking for a type. |
| flash-messages | Shared. Shows the flash messages. |
To change one of them, copy it into the partials/supportTicketSubmit folder of your theme. See Overriding Partials.
Rules
- Signed-in users. The handler refuses a guest with You should be logged in. The new ticket always belongs to the signed-in user.
- Posted values. Only the subject, content, type and files are taken from the form. Other posted values, such as a status or an assignee, are ignored.
- Ticket types. A posted
type_idmust be one of the types inticketTypes. Otherwise the handler refuses it with Please select a valid ticket type. under thetype_idfield. - Validation. Errors are reported under the
subjectandcontentfields. - Attachments. Every file is checked against the attachment rules before the ticket is saved, and errors are reported under the
filesfield.
Previous: Ticket Next: Ticket Update