Fixes for select2 rendering, ensuring the radius is set and unset in the right places

This commit is contained in:
Deon George 2025-07-07 10:07:35 +08:00
parent f5fe35c740
commit 7cf81c14d3
7 changed files with 155 additions and 157 deletions

31
public/css/custom.css vendored
View File

@ -1,9 +1,18 @@
/** ensure our userpassword has select is next to the password input */ /* ensure our password type select box shrinks and has the full boarder */
attribute#userpassword .select2-container--bootstrap-5 .select2-selection { attribute#userpassword .input-group > .form-select {
font-size: inherit; flex-grow: 0;
width: 9em; width: 9em;
border: var(--bs-gray-500) 1px solid; border: var(--bs-gray-500) 1px solid;
background-color: #f0f0f0; z-index: 2;
}
attribute#userpassword .input-group .select2-container--bootstrap-5 {
flex-grow: 0;
margin-bottom: 0.25em !important;
}
attribute#userpassword .input-group > .select2-container--bootstrap-5 .select2-selection {
background-color: #eef2f4;
} }
/* render the structural inside the input box */ /* render the structural inside the input box */
@ -14,20 +23,6 @@ attribute#objectclass .input-group-end:not(input.form-control) {
z-index: 5; z-index: 5;
} }
/* select forms that have nothing next to them */
.select-group:first-child .select2-container--bootstrap-5 .select2-selection {
border-radius: 4px !important;
}
.input-group:first-child:not(.select-group):not(:last-child) .select2-container--bootstrap-5 .select2-selection {
border-bottom-right-radius: unset;
border-top-right-radius: unset;
}
.select2-container .select2-selection--single .select2-selection__rendered {
font-size: 0.88em;
}
input.form-control.input-group-end { input.form-control.input-group-end {
border-bottom-right-radius: 4px !important; border-bottom-right-radius: 4px !important;
border-top-right-radius: 4px !important; border-top-right-radius: 4px !important;

20
public/css/fixes.css vendored
View File

@ -215,9 +215,17 @@ pre code .line::before {
} }
/** select2 rendering fixes */ /** select2 rendering fixes */
.select2-container--bootstrap-5 .select2-selection {
border: var(--bs-gray-500) 1px solid;
}
/* Selection rendered size */
.select2-container .select2-selection--single .select2-selection__rendered {
font-size: 95%;
}
/* The opened input box */ /* The opened input box */
.select2-container--bootstrap-5 .select2-dropdown .select2-search .select2-search__field { .select2-container--bootstrap-5 .select2-dropdown .select2-search .select2-search__field {
line-height: 1.0;
border: 1px solid #aaa; border: 1px solid #aaa;
} }
@ -226,23 +234,21 @@ pre code .line::before {
font-size: 95%; font-size: 95%;
} }
select2-container--bootstrap-5 .select2-selection--multiple .select2-selection__clear, .select2-container--bootstrap-5 .select2-selection--single .select2-selection__clear { /* Place holder text */
width: 0.5rem;
height: 0.5rem;
}
.select2-container--bootstrap-5 .select2-selection--single .select2-selection__rendered .select2-selection__placeholder { .select2-container--bootstrap-5 .select2-selection--single .select2-selection__rendered .select2-selection__placeholder {
line-height: 1.0;
font-size: 90%; font-size: 90%;
} }
/* Group options title rendering */
.select2-container--bootstrap-5 .select2-dropdown .select2-results__options .select2-results__option[role=group] .select2-results__group { .select2-container--bootstrap-5 .select2-dropdown .select2-results__options .select2-results__option[role=group] .select2-results__group {
color: #212529; color: #212529;
font-weight: 800; font-weight: 800;
} }
/* Multiple selected items rendering */
.select2-container--bootstrap-5 .select2-selection--multiple .select2-selection__rendered .select2-selection__choice { .select2-container--bootstrap-5 .select2-selection--multiple .select2-selection__rendered .select2-selection__choice {
padding: 0.25em 0.45em; padding: 0.25em 0.45em;
font-size: 90%;
} }
/* Remove the shadow outline on an opened box */ /* Remove the shadow outline on an opened box */

View File

@ -1,49 +1,47 @@
<!-- $o=Attribute::class --> <!-- $o=Attribute::class -->
<x-attribute.layout :edit="$edit=($edit ?? FALSE)" :new="$new=($new ?? FALSE)" :o="$o" :template="$template"> <x-attribute.layout :edit="$edit=($edit ?? FALSE)" :new="$new=($new ?? FALSE)" :o="$o" :template="$template">
<div class="col-12"> <div class="tab-content">
<div class="tab-content"> @foreach($o->langtags as $langtag)
@foreach($o->langtags as $langtag) <span @class(['tab-pane','active'=>$loop->index === 0]) id="langtag-{{ $o->name_lc }}-{{ $langtag }}" role="tabpanel">
<span @class(['tab-pane','active'=>$loop->index === 0]) id="langtag-{{ $o->name_lc }}-{{ $langtag }}" role="tabpanel"> @foreach(Arr::get(old($o->name_lc,[$langtag=>$new ? [NULL] : $o->tagValues($langtag)]),$langtag,[]) as $key => $value)
@foreach(Arr::get(old($o->name_lc,[$langtag=>$new ? [NULL] : $o->tagValues($langtag)]),$langtag,[]) as $key => $value) <!-- AutoValue Lock -->
<!-- AutoValue Lock --> @if($new && $template && ($av=$template->attributeValue($o->name_lc)))
@if($new && $template && ($av=$template->attributeValue($o->name_lc))) <input type="hidden" name="_auto_value[{{ $o->name_lc }}]" value="{{ $av }}">
<input type="hidden" name="_auto_value[{{ $o->name_lc }}]" value="{{ $av }}"> @endif
@endif
<div class="input-group has-validation"> <div class="input-group has-validation">
<input type="text" <input type="text"
@class([ @class([
'form-control', 'form-control',
'noedit'=>(! $edit) || ($o->is_rdn), 'noedit'=>(! $edit) || ($o->is_rdn),
'is-invalid'=>($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index)) || ($e=$errors->get('_auto_value.'.$o->name_lc)), 'is-invalid'=>($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index)) || ($e=$errors->get('_auto_value.'.$o->name_lc)),
'mb-1', 'mb-1',
'border-focus'=>! ($tv=$o->tagValuesOld($langtag))->contains($value), 'border-focus'=>! ($tv=$o->tagValuesOld($langtag))->contains($value),
'bg-success-subtle'=>$updated]) 'bg-success-subtle'=>$updated])
name="{{ $o->name_lc }}[{{ $langtag }}][]" name="{{ $o->name_lc }}[{{ $langtag }}][]"
value="{{ $value ?: ($av ?? '') }}" value="{{ $value ?: ($av ?? '') }}"
placeholder="{{ ! is_null($x=$tv->get($loop->index)) ? $x : '['.__('NEW').']' }}" placeholder="{{ ! is_null($x=$tv->get($loop->index)) ? $x : '['.__('NEW').']' }}"
@readonly(! $new) @readonly(! $new)
@disabled($o->isDynamic())> @disabled($o->isDynamic())>
<div class="invalid-feedback pb-2"> <div class="invalid-feedback pb-2">
@if($e) @if($e)
{{ join('|',$e) }} {{ join('|',$e) }}
@endif @endif
</div>
</div> </div>
@endforeach </div>
</span> @endforeach
@endforeach </span>
@endforeach
@if($edit && (! $o->is_rdn)) @if($edit && (! $o->is_rdn))
<span @class(['tab-pane']) id="langtag-{{ $o->name_lc }}-+" role="tabpanel"> <span @class(['tab-pane']) id="langtag-{{ $o->name_lc }}-+" role="tabpanel">
<span class="d-flex font-size-sm alert alert-warning p-2"> <span class="d-flex font-size-sm alert alert-warning p-2">
It is not possible to create new language tags at the moment. This functionality should come soon.<br> It is not possible to create new language tags at the moment. This functionality should come soon.<br>
You can create them with an LDIF import though. You can create them with an LDIF import though.
</span>
</span> </span>
@endif </span>
</div> @endif
</div> </div>
</x-attribute.layout> </x-attribute.layout>

View File

@ -4,7 +4,7 @@
@foreach(($o->tagValues($langtag)->count() ? $o->tagValues($langtag) : [$langtag => NULL]) as $key => $value) @foreach(($o->tagValues($langtag)->count() ? $o->tagValues($langtag) : [$langtag => NULL]) as $key => $value)
@if($edit) @if($edit)
<div class="input-group has-validation"> <div class="input-group has-validation">
<x-form.select id="userpassword_hash_{{$loop->index}}{{$template?->name ?: ''}}" name="_userpassword_hash[{{ $langtag }}][]" :value="old('_userpassword_hash.'.$langtag.'.0',$o->hash($new ? '' : ($value ?? ''))->id())" :options="$helpers" allowclear="false" :disabled="! $new"/> <x-select class="mb-1" id="userpassword_hash_{{$loop->index}}{{$template?->name ?: ''}}" name="_userpassword_hash[{{ $langtag }}][]" :value="old('_userpassword_hash.'.$langtag.'.0',$o->hash($new ? '' : ($value ?? ''))->id())" :options="$helpers" allowclear="false" :disabled="! $new"/>
<input type="password" @class(['form-control','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index)),'mb-1','border-focus'=>! $o->tagValuesOld($langtag)->contains($value),'bg-success-subtle'=>$updated]) name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ Arr::get(old($o->name_lc),$langtag.'.'.$loop->index,$value ? md5($value) : '') }}" @readonly(! $new)> <input type="password" @class(['form-control','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index)),'mb-1','border-focus'=>! $o->tagValuesOld($langtag)->contains($value),'bg-success-subtle'=>$updated]) name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ Arr::get(old($o->name_lc),$langtag.'.'.$loop->index,$value ? md5($value) : '') }}" @readonly(! $new)>
<div class="invalid-feedback pb-2"> <div class="invalid-feedback pb-2">

View File

@ -3,22 +3,20 @@
@foreach($o->langtags as $langtag) @foreach($o->langtags as $langtag)
@foreach(($o->tagValues($langtag)->count() ? $o->tagValues($langtag) : [$langtag => NULL]) as $key => $value) @foreach(($o->tagValues($langtag)->count() ? $o->tagValues($langtag) : [$langtag => NULL]) as $key => $value)
@if($edit) @if($edit)
<div class="select-group"> <x-form.select
<x-form.select @class(['is-invalid'=>($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index)),'mb-1','border-focus'=>! $o->tagValuesOld($langtag)->contains($value)])
@class(['is-invalid'=>($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index)),'mb-1','border-focus'=>! $o->tagValuesOld($langtag)->contains($value)]) id="{{ $o->name_lc }}_{{$loop->index}}{{$template?->name ?: ''}}"
id="{{ $o->name_lc }}_{{$loop->index}}{{$template?->name ?: ''}}" name="{{ $o->name_lc }}[{{ $langtag }}][]"
name="{{ $o->name_lc }}[{{ $langtag }}][]" :value="$value"
:value="$value" :options="$template->attributeOptions($o->name_lc)"
:options="$template->attributeOptions($o->name_lc)" allowclear="true"
allowclear="true" :disabled="! $new"
:disabled="! $new" :readonly="false"/>
:readonly="false"/>
<div class="invalid-feedback pb-2"> <div class="invalid-feedback pb-2">
@if($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index)) @if($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index))
{{ join('|',$e) }} {{ join('|',$e) }}
@endif @endif
</div>
</div> </div>
@else @else
{{ $o->render_item_old($langtag.'.'.$key) }} {{ $o->render_item_old($langtag.'.'.$key) }}

View File

@ -1,78 +1,7 @@
<x-form.base {{ $attributes }}> @isset($name)
@isset($name) <input type="hidden" id="{{ $id ?? $name }}_disabled" name="{{ $name }}" value="" disabled>
<input type="hidden" id="{{ $id ?? $name }}_disabled" name="{{ $name }}" value="" disabled> @endisset
@endisset
<select class="form-select @error($old ?? $id ?? $name) is-invalid @enderror" id="{{ $id ?? $name}}" @isset($name)name="{{ $name }}"@endisset @required($required ?? FALSE) @disabled($disabled ?? FALSE)> <div class="input-group">
@if((empty($value) && ! empty($options)) || isset($addnew)) <x-select :id="$id ?? NULL" :name="$name ?? NULL" :options="$options ?? []" :value="$value ?? NULL" :class="$class ?? NULL"/>
<option value=""></option> </div>
@isset($addnew)
<option value="new">{{ $addnew ?: 'Add New' }}</option>
@endisset
@endif
@isset($options)
@empty($groupby)
@foreach($options as $option)
@continue(! Arr::get($option,'value'))
<option value="{{ Arr::get($option,'id') }}" @selected(Arr::get($option,'id') == collect(old())->dot()->get(isset($old) ? $old.'.0' : ($id ?? $name),$value ?? ''))>{{ Arr::get($option,'value') }}</option>
@endforeach
@else
@foreach($options->groupBy($groupby) as $group)
<optgroup label="{{ Arr::get($group->first(),$groupby) }}">
@foreach($group as $option)
@continue(! Arr::get($option,'value'))
<option value="{{ Arr::get($option,'id') }}" @selected(Arr::get($option,'id') == collect(old())->dot()->get(isset($old) ? $old.'.0' : ($id ?? $name),$value ?? ''))>{{ Arr::get($option,'value') }}</option>
@endforeach
</optgroup>
@endforeach
@endempty
@endisset
</select>
</x-form.base>
@section('page-scripts')
<script type="text/javascript">
// Select doesnt support read only so we'll use disable and a new field
@isset($name)
function {{$id ?? $name}}_readonly(on) {
if (on) {
$('#{{ $name }}').prop('disabled',true);
$('#{{ $name }}_disabled').prop('disabled',false).val($('#{{ $name }}').val());
} else {
$('#{{ $name }}').prop('disabled',false);
$('#{{ $name }}_disabled').prop('disabled',true);
}
}
@endisset
$(document).ready(function() {
$('#{{ $id ?? $name }}').select2({
theme: 'bootstrap-5',
dropdownAutoWidth: true,
width: 'style',
allowClear: {{ $allowclear ?? 'false' }},
placeholder: '{{ $placeholder ?? '' }}',
multiple: {{ $multiple ?? 'false' }},
@isset($addvalues)
tags: true,
@endisset
});
@if(isset($multiple) && (! $multiple))
$('#{{ $id ?? $name }}').val(' ');
$('#{{ $id ?? $name }}').trigger('change');
@endif
@isset($options)
@if(($autoselect ?? FALSE) && $options->count() === 1)
$('#{{ $id ?? $name }}')
.val('{{ $options->first()['id'] }}')
.trigger("change")
@endif
@endisset
});
</script>
@append

View File

@ -0,0 +1,72 @@
<select class="form-select {{ $class }} @error($old ?? $id ?? $name) is-invalid @enderror" id="{{ $id ?? $name}}" @isset($name)name="{{ $name }}"@endisset @required($required ?? FALSE) @disabled($disabled ?? FALSE)>
@if((empty($value) && ! empty($options)) || isset($addnew))
<option value=""></option>
@isset($addnew)
<option value="new">{{ $addnew ?: 'Add New' }}</option>
@endisset
@endif
@isset($options)
@empty($groupby)
@foreach($options as $option)
@continue(! Arr::get($option,'value'))
<option value="{{ Arr::get($option,'id') }}" @selected(Arr::get($option,'id') == collect(old())->dot()->get(isset($old) ? $old.'.0' : ($id ?? $name),$value ?? ''))>{{ Arr::get($option,'value') }}</option>
@endforeach
@else
@foreach($options->groupBy($groupby) as $group)
<optgroup label="{{ Arr::get($group->first(),$groupby) }}">
@foreach($group as $option)
@continue(! Arr::get($option,'value'))
<option value="{{ Arr::get($option,'id') }}" @selected(Arr::get($option,'id') == collect(old())->dot()->get(isset($old) ? $old.'.0' : ($id ?? $name),$value ?? ''))>{{ Arr::get($option,'value') }}</option>
@endforeach
</optgroup>
@endforeach
@endempty
@endisset
</select>
@section('page-scripts')
<script type="text/javascript">
// Select doesnt support read only so we'll use disable and a new field
@isset($name)
function {{$id ?? $name}}_readonly(on) {
if (on) {
$('#{{ $name }}').prop('disabled',true);
$('#{{ $name }}_disabled').prop('disabled',false).val($('#{{ $name }}').val());
} else {
$('#{{ $name }}').prop('disabled',false);
$('#{{ $name }}_disabled').prop('disabled',true);
}
}
@endisset
$(document).ready(function() {
$('#{{ $id ?? $name }}').select2({
theme: 'bootstrap-5',
dropdownAutoWidth: false,
width: 'style',
allowClear: {{ $allowclear ?? 'false' }},
placeholder: '{{ $placeholder ?? '' }}',
multiple: {{ $multiple ?? 'false' }},
@isset($addvalues)
tags: true,
@endisset
});
@if(isset($multiple) && (! $multiple))
$('#{{ $id ?? $name }}').val(' ');
$('#{{ $id ?? $name }}').trigger('change');
@endif
@isset($options)
@if(($autoselect ?? FALSE) && $options->count() === 1)
$('#{{ $id ?? $name }}')
.val('{{ $options->first()['id'] }}')
.trigger("change")
@endif
@endisset
});
</script>
@append