Перейти к содержимому
PHP Ecosystem
Explore

Usage examples

Это содержимое пока не доступно на вашем языке.

Each snippet renders in a fresh view, so widget id values start at w0. Long inline SVG icons are shortened to <svg class="..." ...>...</svg>, and asset URLs are shown as /assets/<hash>/....

The same accordion built with value objects renders the same markup:

Content between begin() and end() is not encoded:

The same trail built with value objects renders the same markup:

A split button renders the action button and a separate toggle inside .btn-group:

The plugin is always created:

import("/assets/<hash>/bootstrap.bundle.js").then((bootstrap) => { bootstrap.Carousel.getOrCreateInstance(document.getElementById("w0"), {}); });

The same slides as value objects render the same markup:

The widget keeps the hidden input in sync with the plugin:

document.getElementById("w0-chips").addEventListener("change.bs.chips", (event) => { document.getElementById("w0-value").value = event.values.join(","); });

The fluent methods chain on the value returned by begin(). A toggler method enables the toggle button, and a class added to it replaces the default btn-solid theme-primary:

multiple, search, and check add data-bs-multiple="true", data-bs-search="true", the .combobox-search field, the .combobox-no-results element, and a .menu-item-check icon in every item.

In input mode the field submits the locale-formatted text shown to the user, so parse it with the same locale on the server. Inline mode keeps the YYYY-MM-DD values in a hidden input:

The same dialog configured with the fluent methods, which chain on the value returned by begin(); the dialog class is still added while rendering:

Sizes, responsive fullscreen, and backdrop behavior:

'responsive' => Breakpoint::LG renders class="lg:drawer drawer-start": the content is a drawer below lg and inline from lg up.

Use it in every grid and list view through the DI container: add the definition to container.definitions in config/web.php, or set it at runtime:

Menu renders only the panel; place it after your own toggle:

The same panel built with value objects renders the same markup:

The Menu plugin binds to the toggle, so clientOptions and clientEvents set on a standalone Menu target the panel and have no effect on the toggle. Put the options on the toggle as data-bs-* attributes, or use ButtonMenu.

The same nav built with value objects renders the same markup; leave active as null to detect it from the route:

'drawerOptions' => false renders the content inline without toggler and drawer, and 'expand' => null renders navbar-expand for every width.

Stacked segments size the .progress elements:

The same segments as value objects render the same markup:

A responsive horizontal stepper with a description and a link:

The same stepper built with value objects renders the same markup:

messages are passed to the plugin constructor:

import("/assets/<hash>/bootstrap.bundle.js").then((bootstrap) => { bootstrap.Strength.getOrCreateInstance(document.getElementById("w0"), {"messages":{"weak":"Too weak","strong":"Great"}}); });

The same tabs built with value objects render the same markup:

The widget creates the plugin instance but does not show the toast. Show it from the view with the bundle helper:

Set dateTime to render a relative time such as <small>2 minutes ago</small> in the header.

With target, the matching elements carry their own data-bs-value and data-bs-attribute attributes.

The examples use this model, validated with an invalid email so the forms show the error state; the CSRF input rendered after <form> is omitted from the output.

With an error on email:

<div class="row mb-3 field-signupform-email required">
<label class="sm:col-2 col-form-label" for="signupform-email">Email</label>
<div class="sm:col-10">
<input type="text" id="signupform-email" class="form-control is-invalid" name="SignupForm[email]" value="not-an-email" aria-required="true" aria-invalid="true">
<div class="invalid-feedback">Email is not a valid email address.</div>
</div>
</div>
<div class="row mb-3 field-signupform-remember">
<div class="sm:col-10 sm:offset-2">
<div class="form-field">
<input type="hidden" name="SignupForm[remember]" value="0"><input type="checkbox" id="signupform-remember" class="check" name="SignupForm[remember]" value="1" checked>
<label for="signupform-remember">Remember</label>
<div class="invalid-feedback"></div>
</div>
</div>
</div>

Change the grid through fieldConfig:

The label comes before the control inside .form-floating; the hint and the error follow the wrapper. The wrapper receives is-invalid on the server so the sibling feedback is displayed. On the client, a :has() rule registered once per form displays the feedback when the control carries is-invalid, so client validation needs no jQuery:

Select, range, static control, and input group

Section titled “Select, range, static control, and input group”

Bootstrap 6 uses .form-control for <select> elements too; rangeInput() registers the plugin bundle that initializes the range.

Client-side validation styling and error summary

Section titled “Client-side validation styling and error summary”

Input widgets work with ActiveField::widget() (the tags, fruit, and birthday attributes of SignupForm):

The widget registers, at the end of the body:

import("/assets/<hash>/bootstrap.bundle.js").then((bootstrap) => { bootstrap.Toast.getOrCreateInstance(document.getElementById("w0"), {"autohide":false}); });
document.getElementById("w0").addEventListener("hidden.bs.toast", function (event) { console.log(event.type); });

The bundle is an ES module without globals. Import the same URL the page loaded, so the browser reuses the evaluated module; BootstrapPluginAsset::importJs() builds the call from PHP:

In your own module scripts, read the URL with $bundle->moduleUrl($this) and import it:

const { Dialog } = await import(moduleUrl);
Dialog.getOrCreateInstance(document.getElementById("confirm")).show();

Accessing plugin instances through window.bootstrap

Section titled “Accessing plugin instances through window.bootstrap”

Enable exposeGlobal (see the installation guide) for scripts written against the Bootstrap 5 global. The assignment happens when the module import resolves, so wait for the load event:

window.addEventListener("load", () => {
bootstrap.Toast.getOrCreateInstance(document.getElementById("w0")).show();
});