dile-crud
The dile-crud
component is the primary tool for building the CRUD system, combining various components from this library to implement the full functionality of a create, read, update, and delete (CRUD) system.
Additionally, dile-crud
also offers batch operation management through the definition of action components.
Installation
npm i @dile/crud
Usage
Import the dile-crud component.
import '@dile/crud/components/crud/crud.js';
Use the component.
<dile-crud
.config=${this.config}
></dile-crud>
Properties
- title: String, title for the crud component. Optional.
- config: Object, the configuration object that customizes the behavior and functionality of the CRUD system.
- actionIds: Array, the list of IDs for the items selected for batch operations.
- keyword: String, the search keyword used to filter the items in the CRUD system.
- belongsTo: String, indicates the name of the resource to which the records managed by the
dile-crud
component belong in this instance. - relationId: String, is the identifier that uniquely identifies the specific resource.
- language: String, the feedback messages language. Available 'en', 'es'. Fallback to 'en'.
Methods
- openInsert(): Opens the form or interface for inserting a new item into the CRUD system.
- editItem(id): Opens the form or interface to edit the item with the specified
id
. - setKeyword(keyword): Sets the search keyword used to filter the items within the list system based on the provided
keyword
. - attachActionId(id): Adds the specified
id
to the list of IDs selected for batch actions. - detachActionId(id): Removes the specified
id
from the list of IDs selected for batch actions. - removeActionItems(idsArray): Removes the items with the specified IDs in
idsArray
from the CRUD system. - refresh(): Refreshes the data or content of the CRUD system, reloading the items from the server.
Events
This component is based on elements such as dile-crud-list
, dile-crud-insert
, dile-crud-update
, dile-crud-item-delete
, and many others. Therefore, all events documented in those components can be listened to in dile-crud
. Please refer to the mentioned components for information on those events.
Eventos específicos de dile-crud
:
- crud-item-insert: Dispatched when the system shows the insert form.
- crud-action-success: Dispached when an action succeed. The detail of this event includes the properties
msg
with a message from the server response,action
with the name of the action being responded to, anddata
with any additional data that the backend may have sent as a response. Of course, the backend shoul be developed to send all this data.
Configuration
Please refer to the general documentation on the CRUD library to find the established mechanisms for configuring the dile-crud
component.
belongTo and relationId configuration
These fields facilitate the implementation of a type of filtering on the items that a dile-crud
component will allow you to manage. For example, if you are trying to view invoices for the customer with id=10
, belongsTo
would be set to "customer" and relationId
would be set to "10."
This is useful, for example, for managing a specific record on an admin page, like those that can be created using the dile-crud-single
component. For instance, when viewing the details of a country, you could use a dile-crud
component configured with belongsTo
and relationId
to manage all the states within that country directly from the dile-crud-single
component.
Note that these configurations must be supported by the backend. The listing component will handle sending the necessary query strings to the backend, ensuring that the records delivered for the listings in this
dile-crud
component are properly filtered.
Unpaginated Crud Example
For the correct functioning of the dile-crud
component, a configuration object is required. Depending on the functionalities requested through the configuration object, various additional components from the CRUD library may also be needed.
Configuration object
Find the guides for creating the configuration object on the resource configuration page.
<script type="module">
import { html } from 'lit';
import { CrudConfigBuilder } from '@dile/crud/lib/CrudConfigBuilder';
import '@dile/ui/components/pages/pages';
// For the correct functioning of this declaration in the demo system, we have defined the variable with the configuration object globally. Normally, it would be created in a module and exported.
window.countryConfig = new CrudConfigBuilder('https://timer.escuelait.com/api/countries', {
templates: {
item: (country) => html`<demo-country-item .country=${country}></demo-country-item>`,
insertForm: () => html`<demo-country-form id="insertform"></demo-country-form>`,
updateForm: () => html`<demo-country-form id="updateform"></demo-country-form>`,
help: () => html`<p>This is the help provided to the countries resource.</p>`,
detail: (country) => html`<demo-country-detail .country="${country}"></demo-country-detail>`,
relations: (country) => html`<demo-country-relations .country=${country}></demo-country-relations>`,
formSingleActions: (actionName, country) => html`
<dile-pages attrForSelected="action" selected="${actionName}">
<demo-set-europe-as-continent-action action="SetEurope" .country=${country}></demo-set-europe-as-continent-action>
<demo-set-asia-as-continent-action action="SetAsia" .country=${country}></demo-set-asia-as-continent-action>
</dile-pages>
`,
},
customization: {
disablePagination: true,
disableHelp: false,
disableKeywordSearch: false,
disableSort: false,
disableFilter: false,
},
actions: {
single: [
{
name: "SetEurope",
label: "Set Europe as continent"
},
{
name: "SetAsia",
label: "Set Asia as continent"
},
]
},
labels: {
helpTitle: 'Country help',
},
sort: {
options: [
{
name: 'name',
label: 'Name',
direction: 'desc'
},
],
initialSortField: 'name',
},
availableFilters: [
{
name: 'continent',
label: 'Continent',
active: false,
value: false,
type: 'select',
options: [
{
name: 'Europe',
label: 'Europe'
},
{
name: 'Africa',
label: 'Africa'
},
{
name: 'Asia',
label: 'Asia'
},
]
},
],
});
</script>
Item component
The item component serves as a template to display each of the elements in the list.
<script type="module">
import { LitElement, html, css } from 'lit';
export class DemoCountryItem extends LitElement {
static styles = [
css`
:host {
display: block;
color: #303030;
}
span {
font-style: italic;
font-size: 0.9rem;
}
`
];
static get properties() {
return {
country: { type: Object }
};
}
render() {
return html`
${this.country.name} -
<span @click=${this.dispatchContinent}>${this.country.continent}</span>
`;
}
dispatchContinent() {
this.dispatchEvent(new CustomEvent('continent-event', {
bubbles: true,
composed: true,
detail: this.country
}));
}
}
customElements.define('demo-country-item', DemoCountryItem);
</script>
Resource form component
The resource form provides the necessary fields for adding new elements to the resource. In this example, the same form is used for both insertions and edits, but it is possible to have a different form for each operation.
Instructions on how to create these forms can be found in the dile-crud-insert
and dile-ajax-form
component documentation.
<script type="module">
import { LitElement, html, css } from 'lit';
import '@dile/ui/components/input/input.js';
import '@dile/ui/components/select/select.js';
import { DileForm } from '@dile/ui/mixins/form'
export class DemoCountryForm extends DileForm(LitElement) {
static styles = [
css`
:host {
display: block;
}
`
];
render() {
return html`
<dile-input label="Country name" name="name" id="name" hideErrorOnInput></dile-input>
<dile-input label="Slug" name="slug" id="slug" hideErrorOnInput></dile-input>
<dile-select name="continent" id="continent" label="Continent" hideErrorOnInput>
<select slot="select">
<option value="">Select...</option>
<option value="Europe">Europa</option>
<option value="South America">América del Sur</option>
<option value="North America">Norte América</option>
<option value="Asia">Asia</option>
<option value="Africa">Africa</option>
<option value="Oceania">Oceania</option>
</select>
</dile-select>
`;
}
}
customElements.define('demo-country-form', DemoCountryForm);
</script>
<demo-country-form></demo-country-form>
Crud component
<script type="module">
import { LitElement, html, css } from 'lit';
import '@dile/crud/components/crud/crud';
export class DemoCountryCrud extends LitElement {
static styles = [
css`
:host {
display: block;
}
`
];
static get properties() {
return {
config: { type: Object },
};
}
constructor() {
super();
this.config = window.countryConfig.getConfig();
}
render() {
return html`
<dile-crud
.config="${this.config}"
></dile-crud>
`;
}
}
customElements.define('demo-country-crud', DemoCountryCrud);
</script>
<demo-country-crud></demo-country-crud>
Paginated Crud Example
Configuration object
Find the guides for creating the configuration object on the resource configuration page.
<script type="module">
import { html } from 'lit';
import { CrudConfigBuilder } from '@dile/crud/lib/CrudConfigBuilder';
import { ResponseApiAdapter } from '@dile/crud/lib/ResponseApiAdapter';
class BoardGameResponseApiAdapter extends ResponseApiAdapter {
getElementList() {
return this.response.data.result.data;
}
}
// For the correct functioning of this declaration in the demo system, we have defined the variable with the configuration object globally. Normally, it would be created in a module and exported.
window.boardGameConfig = new CrudConfigBuilder('https://timer.escuelait.com/api/board-games', {
customization: {
hideCountSummary: false,
hideCheckboxSelection: false,
disablePagination: false,
disableHelp: true,
disableKeywordSearch: false,
disableSort: false,
disableFilter: false,
},
sort: {
options: [
{
name: 'name',
label: 'Name',
direction: 'asc'
},
{
name: 'year',
label: 'Year',
direction: 'desc'
},
],
initialSortField: 'year',
},
availableFilters: [
{
name: 'essential',
label: 'Is essential',
active: false,
value: false,
type: 'boolean',
},
],
responseAdapter: new BoardGameResponseApiAdapter(),
actions: {
list: [
{
label: 'Delete board games',
name: 'DeleteAction'
},
{
label: 'Change Essential',
name: 'DemoChangeEssentialAction'
},
],
},
templates: {
item: (boardGame) => html`<demo-board-game-item .boardGame=${boardGame}></demo-board-game-item>`,
insertForm: (belongsTo, relationId) => html`<demo-board-game-form id="insertform" belongsTo="${belongsTo}" relationId="${relationId}"></demo-board-game-form>`,
updateForm: () => html`<demo-board-game-form id="updateform"></demo-board-game-form>`,
formActions: (actionName, actionIds) => html`
<dile-pages attrForSelected="action" selected="${actionName}">
<dile-crud-delete-action action="DeleteAction"></dile-crud-delete-action>
<demo-change-essential-action action="DemoChangeEssentialAction" .actionIds=${actionIds}></demo-change-essential-action>
</dile-pages>
`,
},
});
</script>
Item component
The item component serves as a template to display each of the elements in the list.
<script type="module">
import { LitElement, html, css } from 'lit';
export class DemoBoardGameItem extends LitElement {
static styles = [
css`
:host {
display: block;
color: #303030;
}
`
];
static get properties() {
return {
boardGame: { type: Object }
};
}
render() {
return html`
${this.boardGame.name} - (${this.boardGame.year})
`;
}
}
customElements.define('demo-board-game-item', DemoBoardGameItem);
</script>
Resource form component
The resource form provides the necessary fields for adding new elements to the resource. In this case, the same form is used for both insertions and edits, but it is possible to have a different form for each operation.
Instructions on how to create these forms can be found in the dile-crud-insert
component documentation and dile-ajax-form
.
<script type="module">
import { LitElement, html, css } from 'lit';
import '@dile/ui/components/input/input.js';
import '@dile/ui/components/input/input-integer.js';
import '@dile/ui/components/checkbox/checkbox.js';
import '@dile/crud/components/ajax-select-crud/ajax-select-crud';
import { DileForm } from '@dile/ui/mixins/form'
export class DemoBoardGamesForm extends DileForm(LitElement) {
static styles = [
css`
:host {
display: block;
}
`
];
static get properties() {
return {
belongsTo: { type: String },
relationId: { type: String },
};
}
firstUpdated() {
if(this.belongsTo == "country" && this.relationId) {
this.shadowRoot.getElementById('countryselect').value = this.relationId;
}
}
render() {
return html`
<dile-input label="Nombre" name="name" id="name" hideErrorOnInput></dile-input>
<dile-input label="Slug" name="slug" id="slug" hideErrorOnInput></dile-input>
<dile-input-integer name="year" label="Year" hideErrorOnInput id="year"></dile-input-integer>
<dile-ajax-select-crud
id="countryselect"
idProperty="id"
name="country_id"
label="País"
endpoint="https://timer.escuelait.com/api/countries"
queryStringVariable="keyword"
placeholder="Buscar país"
resultDataProperty="data"
displayProperty="name"
selectDefaultPlaceholder="Seleccionar país..."
></dile-ajax-select-crud>
<p><dile-checkbox name="essential">Essential</dile-checkbox></p>
`;
}
}
customElements.define('demo-board-game-form', DemoBoardGamesForm);
</script>
<demo-board-game-form></demo-board-game-form>
Action component
For the purposes of this CRUD component demo, we will include a custom batch action.
You can find more information about actions in the actions section of the CRUD documentation.
<script type="module">
import { LitElement, html, css } from 'lit';
import { DileForm } from '@dile/ui/mixins/form';
import '@dile/ui/components/select/select.js';
export class DemoChangeEssentialAction extends DileForm(LitElement) {
static styles = [
css`
:host {
display: block;
}
`
];
static get properties() {
return {
actionIds: { type: Array }
};
}
constructor() {
super();
this.actionIds = [];
}
render() {
return html`
<p>Change essential game state of ${this.actionIds.length} elements.</p>
<dile-select name="essential">
<select slot="select">
<option value="0">Not Essential</option>
<option value="1">Essential</option>
</select>
</dile-select>
`;
}
}
customElements.define('demo-change-essential-action', DemoChangeEssentialAction);
</script>
Crud component
<script type="module">
import { LitElement, html, css } from 'lit';
class DemoBoardGameCrud extends LitElement {
static styles = [
css`
:host {
display: block;
}
`
];
static get properties() {
return {
config: { type: Object },
};
}
constructor() {
super();
this.config = window.boardGameConfig.getConfig();
this.config.customization.hideCheckboxSelection = false;
}
render() {
return html`
<dile-crud
.config="${this.config}"
></dile-crud>
`;
}
}
customElements.define('demo-board-game-crud', DemoBoardGameCrud);
</script>
<demo-board-game-crud></demo-board-game-crud>