Skip to content

Commit

Permalink
Merge pull request #1
Browse files Browse the repository at this point in the history
1.x
  • Loading branch information
ringunger authored May 21, 2024
2 parents b5d3bfa + 4217599 commit abbad72
Show file tree
Hide file tree
Showing 6 changed files with 314 additions and 110 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
## v1.0.1 (2024-05-21)

### Added
* Support for grouped collections: Added support for grouping collections using the `groupBy` method.
* Support for data attributes: Added support for specifying data attributes for the selectable items using the `withDataAttribute` method.
* Support for classes: Added support for adding classes to the selectable items using the `withClass` method.

### Improved
* Performance optimization option rendering

## v1.0.0 (2024-05-20)
First release
176 changes: 122 additions & 54 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
# Laravel Selectable

[![Latest Version on Packagist](https://img.shields.io/packagist/v/ringlesoft/laravel-selectable.svg?style=flat-square)](https://packagist.org/packages/ringlesoft/laravel-selectable)
[![GitHub Tests Action Status](https://img.shields.io/github/actions/workflow/status/ringlesoft/laravel-selectable/run-tests.yml?branch=main&label=tests&style=flat-square)](https://github.com/ringlesoft/laravel-selectable/actions?query=workflow%3Arun-tests+branch%3Amain)
[![GitHub Code Style Action Status](https://img.shields.io/github/actions/workflow/status/ringlesoft/laravel-selectable/fix-php-code-style-issues.yml?branch=main&label=code%20style&style=flat-square)](https://github.com/ringlesoft/laravel-selectable/actions?query=workflow%3A"Fix+PHP+code+style+issues"+branch%3Amain)
[![Total Downloads](https://img.shields.io/packagist/dt/ringlesoft/laravel-selectable.svg?style=flat-square)](https://packagist.org/packages/ringlesoft/laravel-selectable)
<!--delete-->
---
A laravel package for generating HTML select options from laravel collections. You do not need to add any trait or extend any class.
***
Laravel Selectable is a powerful package that simplifies the process of generating HTML select options from Laravel
collections. With its flexible and intuitive syntax, you can easily create customized select options without the need
for
additional traits or class extensions.

## Features

- Generate select options from Laravel collections with ease
- Customize label and value fields using strings or closures
- Specify selected and disabled options
- Add data attributes and classes to options
- Support for grouping options
- Convert collections to an array of selectable items for AJAX responses or SPAs
- Utilize the power Laravel's collections for more advanced filtering and sorting

## Installation

Expand All @@ -16,81 +25,140 @@ You can install the package via composer:
composer require ringlesoft/laravel-selectable
```

You can publish the config file with:

```bash
php artisan vendor:publish --tag="laravel-selectable-config"
```

This is the contents of the published config file:

```php
return [
"css_library" => "tailwind",
];
```

Optionally, you can publish the views using

```bash
php artisan vendor:publish --tag="laravel-selectable-views"
```
<small> No additional configuration is required.</small>

## Usage

### 1. Basic Usage

```html
<select name="user_id" >
<select name="user_id">
{!! \\App\\Model\\User::all()->toSelectOptions(); !!}}
</select>
```
The output for this code will be as follows

This will generate a select dropdown with options for all users, using the name field as the label and the id field as
the value.

```bladehtml
<option value="{{$user->id}}">{{$user->name}}</option>
...
<select name="user_id">
<option value="{{$user->id}}">{{$user->name}}</option>
...
</select>
```

### 2. Custom text and value for options
### 2. Inline Customization

```bladehtml
<select name="user_id" >
{!! \\App\\Model\\User::all()->toSelectOptions('email', 'uuid'); !!}}
<select name="user_id">
{!! \\App\\Model\\User::all()->toSelectOptions('email', 'uuid', '6490132934f22'); !!}}
</select>
```
The output for this code will be as follows

This will generate a select dropdown with options for all users, using the `email` field as the label and the `uuid`
field
as the value. The selected option will be the user with the `uuid` 6490132934f22.

```bladehtml
<option value="{{$user->uuid}}">{{$user->email}}</option>
...
<select name="user_id">
<option value="{{$user->uuid}}" {{($user->uuid === '6490132934f22') ? 'selected' : '')}}>{{$user->email}}</option>
...
</select>
```

### 3. Advanced use
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.
#### Method parameters

- `label`: The name of the field to be used as the label for the option. If a closure is provided, the result of the
closure will be used as the label. Default is `name`.
- `value`: The name of the field to be used as the value for the option. If a closure is provided, the result of the
closure will be used as the value. Default is `id`.
- `selected`: The value of the item to be used as the selected option. Can be value, array of values or closure.
- `disabled`: The value of the item to be used as the disabled option. Can be value, array of values or closure.

### 3. Advanced Usage

This package allows building of select options from a `Selectable` object using method chaining.
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. The `toSelectOptions` method is used to
convert the `Selectable` object into html select options.

```bladehtml
<select name="user_id" multiple="multiple">
{!!
$x = \App\Models\User::all()
->toSelectable()
->withValue('id')
->withLabel(fn($user) => "{$user->first_name} {$user->last_name}")
->withSelected([4, 5])
->withDisabled(fn($item) => $item->status = 'inactive')
->toSelectOptions();
\App\Models\User::all()
->toSelectable()
->withValue('id')
->withLabel(fn($user) => "{$user->first_name} {$user->last_name}")
->withSelected([2, 3])
->withDisabled(fn($item) => $item->status = 'inactive')
->withDataAttribute('hidden', fn($item) => $item->status !== 'active')
->withClass('form-option custom')
->toSelectOptions();
!!}
</select>
```
### 4. Available methods
- `toSelectable()`: This method returns the current selectable object.
- `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.
- `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.
- `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.
- `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.

This will generate a multi-select dropdown with options for all users, using the `id` field as the `value`, and a
combination of the `first_name` and `last_name` fields as the `label`. Options with IDs `2` and `3` will be selected by
default,
and options with an '`inactive`' `status` will be disabled. A '`data-hidden`' attribute will be added to options with
a `status`
other than '`active`', and a custom class '`form-option custom`' will be applied to all options.

```bladehtml
<select name="user_id" multiple="multiple">
<option value="1" data-hidden="false" class="form-option custom">David Moore</option>
<option value="2" data-hidden="false" class="form-option custom">John Doe</option>
<option value="3" data-hidden="false" class="form-option custom">Jane Doe</option>
<option value="4" data-hidden="true" class="form-option custom" disabled>Mark Manson</option>
</select>
```

#### Available methods

- `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.
- `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.
- `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.
- `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.
- `withDataAttribute(string $attribute, mixed|callable $value)`: This method allows you to add a data attribute to each
option.
- `withClass(string $class)`: This method allows you to add a class to each option.
- `toSelectItems()`: This method converts the selectable collection to an array of selectable items. Useful for Ajax
responses or SPA.
- `toSelectOptions()`: This method converts the selectable collection to an HTML select options string.
- `toSelectItems()`: This method converts the selectable collection to an array of selectable items. Useful for Ajax responses or SPA.
-
- Some of the methods from `Illuminate\Support\Collection` are also available including `groupBy()`.

> <small><strong>Note:</strong> Writing queries within blade templates is not recommended. This is only for simplifying
> demonstration</small>
## Get Selectable Items
```php
$selectableItems = \App\Models\User::all()->toSelectable()->toSelectItems();
```
This will convert the collection of users into an array of selectable items, which can be useful for AJAX responses or
Single Page Applications (SPAs).

#### Structure of Selectable Items
```json
[
[
'label' => 'User Name',
'value' => 'user_id',
'selected' => false,
'disabled' => false,
'dataAttributes' => ['hidden' => false],
'classes' => ['form-option', 'custom'],
],
[...]
]
```

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

## Testing

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

## Credits

- [David Ringle](https://github.com/ringunger)
- [David Ringle](https://github.com/ringunger) (Author)
- [All Contributors](../../contributors)

## License
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"name": "master"
}
},
"version": "1.0.0",
"version": "1.0.1",
"minimum-stability": "dev",
"prefer-stable": true
}
10 changes: 8 additions & 2 deletions src/LaravelSelectableServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace RingleSoft\LaravelSelectable;

use Closure;
use Illuminate\Support\Collection;
use Illuminate\Support\ServiceProvider;

Expand All @@ -18,8 +19,13 @@ public function boot(): void
$this->mergeConfigFrom(
__DIR__ . '/../config/laravel_selectable.php', 'laravel_selectable'
);
Collection::macro('toSelectOptions', function ( $text = null, $value = null, $selected = null) {
return Selectable::collectionToSelectOptions($this, $text, $value, $selected);
Collection::macro('toSelectOptions', function (
string|Closure|null $label = null,
string|Closure|null $value = null,
mixed $selected = null,
mixed $disabled = null
) {
return Selectable::collectionToSelectOptions($this, $label, $value, $selected, $disabled);
});
Collection::macro('toSelectable', function () {
return Selectable::fromCollection($this);
Expand Down
Loading

0 comments on commit abbad72

Please sign in to comment.