Skip to content

Commit

Permalink
Add Options component (#962)
Browse files Browse the repository at this point in the history
* Add Options component

* Add Options component - Fix style issues

* Add Options component - Add test case

* Add Options component - Make test case compatible with L7

* [Components/Options]: Add code improvements and support to handle disabled options.

* [Component/Options]: Add support for empty option.

* [Components/Options]: Add support to empty option and placeholder.

Co-authored-by: Diego Smania <[email protected]>
  • Loading branch information
adwiv and dfsmania authored Aug 20, 2021
1 parent c0ce527 commit 8155808
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 0 deletions.
26 changes: 26 additions & 0 deletions resources/views/components/form/options.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{{-- Empty option --}}
@if(isset($emptyOption))

<option value>
{{ is_string($emptyOption) ? $emptyOption : '' }}
</option>

{{-- Placeholder option --}}
@elseif(isset($placeholder))

<option class="d-none" value>
{{ is_string($placeholder) ? $placeholder : '' }}
</option>

@endif

{{-- Other options --}}
@foreach($options as $key => $value)

<option value="{{ $key }}"
@if($isSelected($key)) selected @endif
@if($isDisabled($key)) disabled @endif>
{{ $value }}
</option>

@endforeach
1 change: 1 addition & 0 deletions src/AdminLteServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class AdminLteServiceProvider extends BaseServiceProvider
Components\Form\InputFile::class,
Components\Form\InputSlider::class,
Components\Form\InputSwitch::class,
Components\Form\Options::class,
Components\Form\Select::class,
Components\Form\Select2::class,
Components\Form\SelectBs::class,
Expand Down
103 changes: 103 additions & 0 deletions src/Components/Form/Options.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<?php

namespace JeroenNoten\LaravelAdminLte\Components\Form;

use Illuminate\Support\Arr;
use Illuminate\View\Component;

class Options extends Component
{
/**
* The list of options as key value pairs.
*
* @var array
*/
public $options;

/**
* The list of selected option keys.
*
* @var array
*/
public $selected;

/**
* The list of disabled option keys.
*
* @var array
*/
public $disabled;

/**
* Whether to use strict comparison between the option keys and the keys of
* the selected/disabled options.
*
* @var bool
*/
public $strict;

/**
* Whether to add a selectable empty option to the list of options. If the
* value is a string, it will be used as the option label, otherwise no
* label will be available for the empty option.
*
* @var bool|string
*/
public $emptyOption;

/**
* Whether to add a placeholder (non-selectable option) to the list of
* options. If the value is a string, it will be used as the placeholder
* label, otherwise no label will be available for the placeholder.
*
* @var bool|string
*/
public $placeholder;

/**
* Create a new component instance.
*/
public function __construct(
$options, $selected = null, $disabled = null,
$strict = null, $emptyOption = null, $placeholder = null
) {
$this->options = Arr::wrap($options);
$this->selected = Arr::wrap($selected);
$this->disabled = Arr::wrap($disabled);
$this->strict = isset($strict);
$this->emptyOption = $emptyOption;
$this->placeholder = $placeholder;
}

/**
* Determines if an option's key is on selected state.
*
* @param string $key The option's key.
* @return bool
*/
public function isSelected($key)
{
return in_array($key, $this->selected, $this->strict);
}

/**
* Determines if an option's key is on disabled state.
*
* @param string $key The option's key.
* @return bool
*/
public function isDisabled($key)
{
return in_array($key, $this->disabled, $this->strict);
}

/**
* Get the view / contents that represent the component.
*
* @return \Illuminate\View\View|string
*/
public function render()
{
return view('adminlte::components.form.options');
}
}
59 changes: 59 additions & 0 deletions tests/Components/FormComponentsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ protected function getComponents()
"{$base}.select-bs" => new Components\Form\SelectBs('name'),
"{$base}.textarea" => new Components\Form\Textarea('name'),
"{$base}.text-editor" => new Components\Form\TextEditor('name'),
"{$base}.options" => new Components\Form\Options(['o1, o2']),
];
}

Expand Down Expand Up @@ -141,6 +142,64 @@ public function testInputSwitchComponent()
$this->assertStringContainsString('is-invalid', $iClass);
}

public function testOptionsComponent()
{
$options = ['m' => 'Male', 'f' => 'Female', 'o' => 'Other'];
$component = new Components\Form\Options($options, 'f', 'o');

// Test selected / disabled options.

$this->assertFalse($component->isSelected('m'));
$this->assertTrue($component->isSelected('f'));
$this->assertFalse($component->isDisabled('m'));
$this->assertTrue($component->isDisabled('o'));

// Test rendered HTML.

$html = $component->resolveView()->with($component->data());
$format = '%A<option%avalue="m"%A>%AMale%A</option>%A';
$format .= '<option%avalue="f"%Aselected%A>%AFemale%A</option>%A';
$format .= '<option%avalue="o"%Adisabled%A>%AOther%A</option>%A';

$this->assertStringMatchesFormat($format, $html);

// Test rendered HTML with empty option (no label).

$component = new Components\Form\Options($options, 'f', 'o', null, true);

$html = $component->resolveView()->with($component->data());
$format = '%A<option%Avalue%A>%A</option>%A';
$format .= '%A<option%avalue="m"%A>%AMale%A</option>%A';
$format .= '<option%avalue="f"%Aselected%A>%AFemale%A</option>%A';
$format .= '<option%avalue="o"%Adisabled%A>%AOther%A</option>%A';

$this->assertStringMatchesFormat($format, $html);

// Test rendered HTML with empty option (and label).

$component = new Components\Form\Options($options, 'f', 'o', null, 'Label');

$html = $component->resolveView()->with($component->data());
$format = '%A<option%Avalue%A>%ALabel%A</option>%A';
$format .= '%A<option%avalue="m"%A>%AMale%A</option>%A';
$format .= '<option%avalue="f"%Aselected%A>%AFemale%A</option>%A';
$format .= '<option%avalue="o"%Adisabled%A>%AOther%A</option>%A';

$this->assertStringMatchesFormat($format, $html);

// Test rendered HTML with placeholder.

$component = new Components\Form\Options($options, 'f', 'o', null, null, 'Placeholder');

$html = $component->resolveView()->with($component->data());
$format = '%A<option%Aclass="d-none"%Avalue%A>%APlaceholder%A</option>%A';
$format .= '%A<option%avalue="m"%A>%AMale%A</option>%A';
$format .= '<option%avalue="f"%Aselected%A>%AFemale%A</option>%A';
$format .= '<option%avalue="o"%Adisabled%A>%AOther%A</option>%A';

$this->assertStringMatchesFormat($format, $html);
}

public function testSelectComponent()
{
$component = new Components\Form\Select('name');
Expand Down

0 comments on commit 8155808

Please sign in to comment.