melk/mjr-box-select-bundle
A PHP bundle that adds reusable box-selection UI components to Laravel applications, letting developers render grouped, selectable boxes for forms and filters with minimal configuration. Includes flexible markup, styling hooks, and simple integration for quick setup.
This is not a Laravel package. melk/mjr-box-select-bundle is a Symfony-style bundle whose only job is to register and ship Ext.ux.form.field.BoxSelect (a Sencha ExtJS "tag/multi-select" field) inside an MJR application. There is no service provider, no config/ file, no facade, no Blade directives. If your stack is Laravel-only, the honest answer is: don't install this bundle — vendor the ExtJS component directly (see below). Use the bundle only if you are maintaining an MJR/ExtJS admin panel alongside Laravel.
Minimal steps if you are in that situation:
composer require melk/mjr-box-select-bundle in the MJR app (not the Laravel app).bootstrap/providers.php. MJR predates the modern Symfony bundle autodiscovery conventions, so expect to add it to the app's bundle list manually.ux component, not ExtJS. ExtJS is separately licensed and must be vendored or loaded from your Sencha build.Resources/public/js for the Ext.ux.form.field.BoxSelect source, the bundle's DI extension class for what it registers, and any view helper that exposes the boxselect xtype. That is roughly 90% of the package's surface area.combobox with multiSelect: true for a boxselect on a belongsToMany-style relationship — tags, categories, users-on-a-project.{
xtype: 'boxselect',
name: 'tags[]',
displayField: 'name',
valueField: 'id',
queryMode: 'remote',
forceSelection: true,
store: Ext.create('Ext.data.Store', {
fields: ['id', 'name'],
proxy: { type: 'ajax', url: '/api/tags', reader: 'json' }
})
}
Treat this as a front-end asset, not a backend integration. The bundle's day-to-day value is one JS class plus an xtype registration. Everything else — persistence, validation, search endpoints — is your application's work.
{id, name} pairs with a q/query param. ExtJS sends queryParam (default query) on remote stores, so map it explicitly rather than assuming q. Keep the response shape flat; BoxSelect's default reader expects an array or {data: [...]}.'tags' => ['array'], 'tags.*' => ['integer', 'exists:tags,id'] and sync() on the pivot. Watch for the classic trailing-empty-string ("1,2,") when delimiter/forceSelection is misconfigured.Ext.create it in a Vite/asset entry. Don't try to make MJR's asset manager and Laravel's pipeline both own the same file.Ext.data.Store per entity type on the page and point multiple boxselects at it (store: 'Tags') — remote stores are the most common source of duplicate AJAX traffic.value after the store loads (store.on('load', ...) → field.setValue(ids)), otherwise forceSelection silently drops labels and you get raw ids rendered as tags.displayTpl/listConfig override for anything beyond plain string labels; that is where you customise the tag rendering (colours, avatars, secondary text).symfony/* constraints. If you only want the JS, git clone the repo and copy Resources/public/js into resources/js/vendor/ — that is the entire useful payload.ux namespace must be loaded before any xtype is used. If you get Cannot create instance of unrecognized alias: widget.boxselect, it's a Sencha Cmd build ordering / requires problem, not a PHP problem. Add requires: ['Ext.ux.form.field.BoxSelect'] in your viewport class.<script> order in the page source first; then Ext.ClassManager.getByAlias('widget.boxselect') in the console. If it's undefined, stop looking at Laravel.setValue with ids before the store loads throws no error — it just renders blank tags. Always bind to store.load or use addValue(record) explicitly.onTypeAhead, createPicker, filterPickList, displayTpl, and listConfig. There is no PHP-side extension point worth mentioning.search endpoint, or Livewire + wire:model for the multi-select — a fraction of the weight, MIT-licensed, and it composes with Laravel's validation and Eloquent sync() without an assets-management argument. Reach for boxselect only when you must match an existing ExtJS UI.How can I help you explore Laravel packages today?