Skip to content

Commit 4217599

Browse files
committed
Version 1.0.1
1 parent 60e0eef commit 4217599

File tree

5 files changed

+163
-43
lines changed

5 files changed

+163
-43
lines changed

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
## v1.0.1 (2024-05-21)
2+
3+
### Added
4+
* Support for grouped collections: Added support for grouping collections using the `groupBy` method.
5+
* Support for data attributes: Added support for specifying data attributes for the selectable items using the `withDataAttribute` method.
6+
* Support for classes: Added support for adding classes to the selectable items using the `withClass` method.
7+
8+
### Improved
9+
* Performance optimization option rendering
10+
11+
## v1.0.0 (2024-05-20)
12+
First release

README.md

Lines changed: 112 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
11
# Laravel Selectable
2-
32
[![Latest Version on Packagist](https://img.shields.io/packagist/v/ringlesoft/laravel-selectable.svg?style=flat-square)](https://packagist.org/packages/ringlesoft/laravel-selectable)
4-
[![GitHub Tests Action Status](https://img.shields.io/github/actions/workflow/status/ringlesoft/laravel-selectable/run-tests.yml?branch=master&label=tests&style=flat-square)](https://github.com/ringlesoft/laravel-selectable/actions?query=workflow%3Arun-tests+branch%3Amaster)
5-
[![GitHub Code Style Action Status](https://img.shields.io/github/actions/workflow/status/ringlesoft/laravel-selectable/fix-php-code-style-issues.yml?branch=master&label=code%20style&style=flat-square)](https://github.com/ringlesoft/laravel-selectable/actions?query=workflow%3A"Fix+PHP+code+style+issues"+branch%3Amaster)
63
[![Total Downloads](https://img.shields.io/packagist/dt/ringlesoft/laravel-selectable.svg?style=flat-square)](https://packagist.org/packages/ringlesoft/laravel-selectable)
7-
<!--delete-->
8-
---
9-
A laravel package for generating HTML select options from laravel collections. You do not need to add any trait or extend any class.
4+
***
5+
Laravel Selectable is a powerful package that simplifies the process of generating HTML select options from Laravel
6+
collections. With its flexible and intuitive syntax, you can easily create customized select options without the need
7+
for
8+
additional traits or class extensions.
9+
10+
## Features
11+
12+
- Generate select options from Laravel collections with ease
13+
- Customize label and value fields using strings or closures
14+
- Specify selected and disabled options
15+
- Add data attributes and classes to options
16+
- Support for grouping options
17+
- Convert collections to an array of selectable items for AJAX responses or SPAs
18+
- Utilize the power Laravel's collections for more advanced filtering and sorting
1019

1120
## Installation
1221

@@ -16,15 +25,20 @@ You can install the package via composer:
1625
composer require ringlesoft/laravel-selectable
1726
```
1827

28+
<small> No additional configuration is required.</small>
29+
1930
## Usage
2031

2132
### 1. Basic Usage
33+
2234
```html
2335
<select name="user_id">
2436
{!! \\App\\Model\\User::all()->toSelectOptions(); !!}}
2537
</select>
2638
```
27-
The output for this code will be as follows
39+
40+
This will generate a select dropdown with options for all users, using the name field as the label and the id field as
41+
the value.
2842

2943
```bladehtml
3044
<select name="user_id">
@@ -33,52 +47,118 @@ The output for this code will be as follows
3347
</select>
3448
```
3549

36-
### 2. Custom label and value
50+
### 2. Inline Customization
51+
3752
```bladehtml
3853
<select name="user_id">
39-
{!! \\App\\Model\\User::all()->toSelectOptions('email', 'uuid'); !!}}
54+
{!! \\App\\Model\\User::all()->toSelectOptions('email', 'uuid', '6490132934f22'); !!}}
4055
</select>
4156
```
42-
The output for this code will be as follows
57+
58+
This will generate a select dropdown with options for all users, using the `email` field as the label and the `uuid`
59+
field
60+
as the value. The selected option will be the user with the `uuid` 6490132934f22.
4361

4462
```bladehtml
4563
<select name="user_id">
46-
<option value="{{$user->uuid}}">{{$user->email}}</option>
64+
<option value="{{$user->uuid}}" {{($user->uuid === '6490132934f22') ? 'selected' : '')}}>{{$user->email}}</option>
4765
...
4866
</select>
4967
```
5068

51-
### 3. Advanced use
52-
The method `toSelectable` is used to convert the collection into a `Selectable` object. The `Selectable` object has several methods that allow you to customize the options and their properties.
69+
#### Method parameters
70+
71+
- `label`: The name of the field to be used as the label for the option. If a closure is provided, the result of the
72+
closure will be used as the label. Default is `name`.
73+
- `value`: The name of the field to be used as the value for the option. If a closure is provided, the result of the
74+
closure will be used as the value. Default is `id`.
75+
- `selected`: The value of the item to be used as the selected option. Can be value, array of values or closure.
76+
- `disabled`: The value of the item to be used as the disabled option. Can be value, array of values or closure.
77+
78+
### 3. Advanced Usage
79+
80+
This package allows building of select options from a `Selectable` object using method chaining.
81+
The method `toSelectable()` is used to convert the collection into a `Selectable` object. The `Selectable` object has
82+
several methods that allow you to customize the options and their properties. The `toSelectOptions` method is used to
83+
convert the `Selectable` object into html select options.
5384

5485
```bladehtml
5586
<select name="user_id" multiple="multiple">
5687
{!!
57-
$x = \App\Models\User::all()
58-
->toSelectable()
59-
->withValue('id')
60-
->withLabel(fn($user) => "{$user->first_name} {$user->last_name}")
61-
->withSelected([4, 5])
62-
->withDisabled(fn($item) => $item->status = 'inactive')
63-
->withDataAttribute('hidden', fn($item) => $item->status !== 'active')
64-
->withClass('form-option custom')
65-
->toSelectOptions();
66-
->toSelectOptions();
88+
\App\Models\User::all()
89+
->toSelectable()
90+
->withValue('id')
91+
->withLabel(fn($user) => "{$user->first_name} {$user->last_name}")
92+
->withSelected([2, 3])
93+
->withDisabled(fn($item) => $item->status = 'inactive')
94+
->withDataAttribute('hidden', fn($item) => $item->status !== 'active')
95+
->withClass('form-option custom')
96+
->toSelectOptions();
6797
!!}
6898
</select>
6999
```
100+
101+
This will generate a multi-select dropdown with options for all users, using the `id` field as the `value`, and a
102+
combination of the `first_name` and `last_name` fields as the `label`. Options with IDs `2` and `3` will be selected by
103+
default,
104+
and options with an '`inactive`' `status` will be disabled. A '`data-hidden`' attribute will be added to options with
105+
a `status`
106+
other than '`active`', and a custom class '`form-option custom`' will be applied to all options.
107+
108+
```bladehtml
109+
<select name="user_id" multiple="multiple">
110+
<option value="1" data-hidden="false" class="form-option custom">David Moore</option>
111+
<option value="2" data-hidden="false" class="form-option custom">John Doe</option>
112+
<option value="3" data-hidden="false" class="form-option custom">Jane Doe</option>
113+
<option value="4" data-hidden="true" class="form-option custom" disabled>Mark Manson</option>
114+
</select>
115+
```
116+
70117
#### Available methods
71-
- `withLabel(string|callable $label)`: This method allows you to customize the label for each option. A string will be used as the collection field from which the label will be generated, while a callable will be used to generate the label.
72-
- `withValue(string|callable $value)`: This method allows you to customize the value for each option. A string will be used as the collection field from which the value will be generated, while a callable will be used to generate the value.
73-
- `withSelected(mixed|callable $selected)`: This method allows you to customize the selected options. Can be a `string`, `int`, an array of `string`/`int`, a `model` or a callable that returns a boolean value.
74-
- `withDisabled(mixed|callable $disabled)`: This method allows you to customize the disabled options. Can be a `string`, `int`, an array of `string`/`int`, a `model` or a callable that returns a boolean value.
75-
- `withDataAttribute(string $attribute, mixed|callable $value)`: This method allows you to add a data attribute to each option.
118+
119+
- `withLabel(string|callable $label)`: This method allows you to customize the label for each option. A string will be
120+
used as the collection field from which the label will be generated, while a callable will be used to generate the
121+
label.
122+
- `withValue(string|callable $value)`: This method allows you to customize the value for each option. A string will be
123+
used as the collection field from which the value will be generated, while a callable will be used to generate the
124+
value.
125+
- `withSelected(mixed|callable $selected)`: This method allows you to customize the selected options. Can be
126+
a `string`, `int`, an array of `string`/`int`, a `model` or a callable that returns a boolean value.
127+
- `withDisabled(mixed|callable $disabled)`: This method allows you to customize the disabled options. Can be
128+
a `string`, `int`, an array of `string`/`int`, a `model` or a callable that returns a boolean value.
129+
- `withDataAttribute(string $attribute, mixed|callable $value)`: This method allows you to add a data attribute to each
130+
option.
76131
- `withClass(string $class)`: This method allows you to add a class to each option.
77-
- `toSelectItems()`: This method converts the selectable collection to an array of selectable items. Useful for Ajax responses or SPA.
132+
- `toSelectItems()`: This method converts the selectable collection to an array of selectable items. Useful for Ajax
133+
responses or SPA.
78134
- `toSelectOptions()`: This method converts the selectable collection to an HTML select options string.
79-
-
135+
- Some of the methods from `Illuminate\Support\Collection` are also available including `groupBy()`.
136+
137+
> <small><strong>Note:</strong> Writing queries within blade templates is not recommended. This is only for simplifying
138+
> demonstration</small>
139+
140+
## Get Selectable Items
141+
```php
142+
$selectableItems = \App\Models\User::all()->toSelectable()->toSelectItems();
143+
```
144+
This will convert the collection of users into an array of selectable items, which can be useful for AJAX responses or
145+
Single Page Applications (SPAs).
146+
147+
#### Structure of Selectable Items
148+
```json
149+
[
150+
[
151+
'label' => 'User Name',
152+
'value' => 'user_id',
153+
'selected' => false,
154+
'disabled' => false,
155+
'dataAttributes' => ['hidden' => false],
156+
'classes' => ['form-option', 'custom'],
157+
],
158+
[...]
159+
]
160+
```
80161

81-
> <small><strong>Note:</strong> Writing queries within blade templates is not recommended. This is only for simplifying demonstration</small>
82162

83163
## Testing
84164

@@ -100,7 +180,7 @@ Please review [our security policy](../../security/policy) on how to report secu
100180

101181
## Credits
102182

103-
- [David Ringle](https://github.com/ringunger)
183+
- [David Ringle](https://github.com/ringunger) (Author)
104184
- [All Contributors](../../contributors)
105185

106186
## License

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
"name": "master"
5252
}
5353
},
54-
"version": "1.0.0",
54+
"version": "1.0.1",
5555
"minimum-stability": "dev",
5656
"prefer-stable": true
5757
}

src/LaravelSelectableServiceProvider.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,13 @@ public function boot(): void
1919
$this->mergeConfigFrom(
2020
__DIR__ . '/../config/laravel_selectable.php', 'laravel_selectable'
2121
);
22-
Collection::macro('toSelectOptions', function ( string|Closure|null $label = null, string|Closure|null $value = null, mixed $selected = null) {
23-
return Selectable::collectionToSelectOptions($this, $label, $value, $selected);
22+
Collection::macro('toSelectOptions', function (
23+
string|Closure|null $label = null,
24+
string|Closure|null $value = null,
25+
mixed $selected = null,
26+
mixed $disabled = null
27+
) {
28+
return Selectable::collectionToSelectOptions($this, $label, $value, $selected, $disabled);
2429
});
2530
Collection::macro('toSelectable', function () {
2631
return Selectable::fromCollection($this);

src/Selectable.php

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,12 @@ private function _shouldDisable(object $item, int|null $index = null): bool
106106
return false;
107107
}
108108

109+
/**
110+
* Prepare data attributes
111+
* @param mixed $item
112+
* @param int|null $index
113+
* @return array
114+
*/
109115
private function _getDataAttributes(mixed $item, int|null $index = null): array
110116
{
111117
$dataAttributes = [];
@@ -117,6 +123,11 @@ private function _getDataAttributes(mixed $item, int|null $index = null): array
117123
return $dataAttributes;
118124
}
119125

126+
/**
127+
* Generate select options from a Collection instance
128+
* @param Collection $collection
129+
* @return string
130+
*/
120131
private function _generateOptions(Collection $collection): string
121132
{
122133
$html = "";
@@ -152,18 +163,18 @@ private function _generateOptions(Collection $collection): string
152163
/**
153164
* Generate select options from a Collection instance
154165
* @param Collection $collection the collection instance to be used
155-
* @param string|null $label the field to be used as the main text of the option (default is 'name')
156-
* @param string|null $value the field to be used as value of the option (default is 'id')
166+
* @param string|Closure|null $label the field to be used as the label for the option (default is 'name')
167+
* @param string|Closure|null $value the field to be used as value of the option (default is 'id')
157168
* @param mixed $selected selected value/values
158169
* @param mixed|null $disabled
159170
* @return string
160171
*/
161172
public static function collectionToSelectOptions(
162-
Collection $collection,
173+
Collection $collection,
163174
string|Closure|null $label = null,
164175
string|Closure|null $value = null,
165-
mixed $selected = null,
166-
mixed $disabled = null,
176+
mixed $selected = null,
177+
mixed $disabled = null,
167178
): string
168179
{
169180
return (new self($collection, $label, $value, $selected, $disabled))->toSelectOptions();
@@ -277,14 +288,26 @@ public function toCollection(): Collection
277288
return $this->_collection;
278289
}
279290

291+
/**
292+
* Call a method on the collection
293+
* @param string $name
294+
* @param array $arguments
295+
* @return $this
296+
*/
280297
public function __call(string $name, array $arguments)
281298
{
282299
$allowedMethods = [
283-
'groupBy', 'add', 'zip', 'unique', 'range',
300+
'groupBy', 'add', 'zip', 'unique', 'range', 'merge',
284301
'diff', 'diffUsing', 'diffAssoc', 'diffAssocUsing',
285-
'diffKeys', 'diffKeysUsing', 'forget'
302+
'diffKeys', 'diffKeysUsing', 'forget', 'merge', 'mergeRecursive', 'combine',
303+
'union', 'nth', 'only', 'select', 'prepend', 'push', 'concat', 'put', 'random',
304+
'replace', 'replaceRecursive', 'reverse', 'shuffle', 'sliding', 'skip',
305+
'skipUntil', 'skipWhile', 'slice', 'split', 'splitIn', 'chunk', 'chunkWhile',
306+
'sort', 'sortDesc', 'sortBy', 'sortByMany', 'sortByDesc', 'sortKeys',
307+
'sortKeysDesc', 'sortKeysUsing', 'splice', 'take', 'takeUntil', 'takeWhile',
308+
'transform', 'dot', 'undot', 'unique', 'values', 'zip', 'pad', 'getIterator',
309+
'countBy', 'add', 'toBase',
286310
];
287-
288311
if (in_array($name, $allowedMethods) && method_exists($this->_collection, $name)) {
289312
$res = $this->_collection->{$name}(...$arguments);
290313
if ($res instanceof Collection) {

0 commit comments

Comments
 (0)