OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

User not filtering on VirtualSelect option

  • Thread starter Thread starter xenxen101219
  • Start date Start date
X

xenxen101219

Guest
So i have this livewire component for Approval Configurations, In this page a user selects the Level of Approvals, once the user select the numbes of approvals it generate VirtualSelect, like if a user select 3 levels it generates 3 VirtualSelect.

Now the problem is it does not filter the ones the are already selected. but it works for some.. Here is the bug explanation

Example User options: Felix K. Bean, Howard G. Sanford, Holly C. Beck Example: I selected 3 levels of approvals

Level 1 Approver selected: Felix K. Bean -other options- Howard G. Sanford Holly C. Beck

Level 2 Approver selected: Howard G. Sanford -other options- Holly C. Beck

Level 3 Approver selected: Holly C. Beck -other options- None

So when i click the Level 1 Approver again it still shows the users that are already selected, And when i check on Level 2 approver the user "Holly C. Beck" still in options even though already seleced on Level 3 approver. But it level 3 Approver the filtering works when i check the options are none.

Can anyone check the code why is it not filtering, but only filters on the higher levels?

Here is my Livewire controller


Code:
class CreateHelpTopic extends Component
{
    use Utils, BasicModelQueries;

    public $approvalLevels = [1, 2, 3, 4, 5];
    public $level1Approvers = [];
    public $level2Approvers = [];
    public $level3Approvers = [];
    public $level4Approvers = [];
    public $level5Approvers = [];
    public $approvalLevelSelected;
    public $buDepartment;

    public function cancel()
    {
        $this->reset();
        $this->resetValidation();
        $this->dispatchBrowserEvent('close-modal');
        $this->hideSpecialProjectContainer();
    }

    public function updatedApprovalLevelSelected()
    {
        $this->resetLevels();
        $this->getFilteredApprovers(1);
    }

    public function updatedLevel1Approvers()
    {
        $this->getFilteredApprovers(2);
    }

    public function updatedLevel2Approvers()
    {
        $this->getFilteredApprovers(3);
    }

    public function updatedLevel3Approvers()
    {
        $this->getFilteredApprovers(4);
    }

    public function updatedLevel4Approvers()
    {
        $this->getFilteredApprovers(5);
    }

    public function getFilteredApprovers($level)
    {
        $selectedApprovers = array_merge(
            (array)$this->level1Approvers,
            (array)$this->level2Approvers,
            (array)$this->level3Approvers,
            (array)$this->level4Approvers,
            (array)$this->level5Approvers
        );

        $filteredApprovers = User::with(['profile', 'roles'])
            ->role([Role::APPROVER, Role::SERVICE_DEPARTMENT_ADMIN])
            ->whereNotIn('id', $selectedApprovers)
            ->orderByDesc('created_at')
            ->get();

        $this->dispatchBrowserEvent('load-approvers', ['approvers' => $filteredApprovers, 'level' => $level]);
    }

    protected $listeners = [
        'approver-level-changed' => 'handleApproverLevelChanged',
        'approval-level-selected' => 'updatedApprovalLevelSelected'
    ];

    public function handleApproverLevelChanged($event)
    {
        $level = $event['level'] + 1;
        $this->getFilteredApprovers($level);
    }

    private function resetLevels()
    {
        $this->level1Approvers = [];
        $this->level2Approvers = [];
        $this->level3Approvers = [];
        $this->level4Approvers = [];
        $this->level5Approvers = [];
    }

    public function render()
    {
        return view('livewire.staff.help-topic.create-help-topic', [
            'serviceLevelAgreements' => $this->queryServiceLevelAgreements(),
            'serviceDepartments' => $this->queryServiceDepartments(),
            'buDepartments' => $this->queryBUDepartments(),
        ]);
    }
}

And here is my Blade file


Code:
<div>
    <div wire:ignore.self class="modal fade help__topic__modal" id="addNewHelpTopicModal" tabindex="-1"
        aria-labelledby="addNewHelpTopicModalLabel" aria-hidden="true">
        <div class="modal-dialog modal-lg modal-dialog-centered">
            <div class="modal-content modal__content">
                <div class="modal-header modal__header p-0 border-0">
                    <h1 class="modal-title modal__title" id="addNewHelpTopicModalLabel">Add new help topic</h1>
                    <button class="btn btn-sm btn__x" data-bs-dismiss="modal">
                        <i class="fa-sharp fa-solid fa-xmark"></i>
                    </button>
                </div>
                <div class="modal-body modal__body">
                    <!-- Approval Configurations -->
                    <hr>
                    <div class="row">
                        <h6 class="fw-semibold mb-4" style="font-size: 0.89rem;">Approval Configurations</h6>
                        <div class="col-md-6">
                            <div class="mb-2">
                                <label for="department" class="form-label form__field__label">
                                    Level of Approval
                                </label>
                                <div>
                                    <div id="select-help-topic-approval-level" wire:ignore></div>
                                </div>
                                @error('bu_department')
                                    <span class="error__message">
                                        <i class="fa-solid fa-triangle-exclamation"></i>
                                        {{ $message }}
                                    </span>
                                @enderror
                            </div>
                        </div>
                        <div wire:ignore class="row" id="dynamic-approval-container"></div>
                    </div>
                    <!-- Modal Footer -->
                    <div class="modal-footer modal__footer p-0 justify-content-between border-0 gap-2">
                        <div class="d-flex align-items-center gap-2">
                            <button type="submit"
                                class="btn d-flex align-items-center justify-content-center gap-2 m-0 btn__modal__footer btn__send">
                                <span wire:loading wire:target="saveHelpTopic" class="spinner-border spinner-border-sm"
                                    role="status" aria-hidden="true">
                                </span>
                                Add New
                            </button>
                            <button type="button" class="btn m-0 btn__modal__footer btn__cancel" id="btnCloseModal"
                                data-bs-dismiss="modal" wire:click="cancel">
                                Cancel
                            </button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

@push('livewire-select')
    <script>
        document.addEventListener('DOMContentLoaded', () => {
            const approvalLevelSelect = document.querySelector('#select-help-topic-approval-level');


            const approvalLevels = @json($approvalLevels);
            const approvalLevelOption = approvalLevels.map(approvalLevel => ({
                label: `${approvalLevel} ${approvalLevel >= 2 ? 'Levels' : 'Level'}`,
                value: approvalLevel
            }));


            VirtualSelect.init({
                ele: approvalLevelSelect,
                options: approvalLevelOption,
                search: true,
                markSearchResults: true,
            });

            approvalLevelSelect.addEventListener('change', () => {
                @this.set('approvalLevelSelected', approvalLevelSelect.value);
            });

            const dynamicApprovalLevelContainer = document.querySelector('#dynamic-approval-container');
            const approvers = {};
            let selectedApprovers = [];

            const initializeApproverSelect = (level) => {
                approvers[`level${level}`] = document.querySelector(
                    `#select-help-topic-approval-level-${level}`);
                VirtualSelect.init({
                    ele: approvers[`level${level}`],
                    search: true,
                    multiple: false,
                    showValueAsTags: false,
                    markSearchResults: true,
                    hasOptionDescription: true
                });

                approvers[`level${level}`].addEventListener('change', () => {
                    selectedApprovers[level - 1] = approvers[`level${level}`].value;
                    @this.set(`level${level}Approvers`, approvers[`level${level}`].value);
                    window.dispatchEvent(new CustomEvent('approver-level-changed', {
                        detail: {
                            level
                        }
                    }));
                });

                approvers[`level${level}`].addEventListener('virtual-select:option-click', () => {
                    @this.call('getFilteredApprovers', level);
                });
            };

            approvalLevelSelect.addEventListener('change', () => {
                dynamicApprovalLevelContainer.innerHTML = '';
                selectedApprovers = [];

                for (let i = 1; i <= approvalLevelSelect.value; i++) {
                    const approverFieldWrapper = document.createElement('div');
                    approverFieldWrapper.className = 'col-md-6';
                    approverFieldWrapper.innerHTML = `
                        <div class="mb-2">
                            <label for="department" class="form-label form__field__label">Level ${i} Approver</label>
                            <div>
                                <div id="select-help-topic-approval-level-${i}" wire:ignore></div>
                            </div>
                        </div>`;
                    dynamicApprovalLevelContainer.appendChild(approverFieldWrapper);
                    initializeApproverSelect(i);
                }
                window.dispatchEvent(new CustomEvent('approval-level-selected'));
            });

            window.addEventListener('load-approvers', (event) => {
                const level = event.detail.level;
                const approverSelect = approvers[`level${level}`];
                if (approverSelect) {
                    const approverOptions = event.detail.approvers.filter(approver => {
                        return !selectedApprovers.flat().includes(approver.id);
                    }).map(approver => ({
                        label: `${approver.profile.first_name} ${approver.profile.middle_name ? approver.profile.middle_name[0] + '.' : ''} ${approver.profile.last_name}`,
                        value: approver.id,
                        description: approver.roles.map(role => role.name).join(', ')
                    }));
                    approverSelect.setOptions(approverOptions);
                }
            });

            approvalLevelSelect.addEventListener('change', () => {
                window.dispatchEvent(new CustomEvent('approval-level-selected'));
            });
        });
    </script>
@endpush

<p>So i have this livewire component for Approval Configurations, In this page a user selects the Level of Approvals, once the user select the numbes of approvals
it generate VirtualSelect, like if a user select 3 levels it generates 3 VirtualSelect.</p>
<p>Now the problem is it does not filter the ones the are already selected. but it works for some..
Here is the bug explanation</p>
<p>Example User options: Felix K. Bean, Howard G. Sanford, Holly C. Beck
Example:
I selected 3 levels of approvals</p>
<p>Level 1 Approver selected: Felix K. Bean
-other options-
Howard G. Sanford
Holly C. Beck</p>
<p>Level 2 Approver selected: Howard G. Sanford
-other options-
Holly C. Beck</p>
<p>Level 3 Approver selected: Holly C. Beck
-other options-
None</p>
<p>So when i click the Level 1 Approver again it still shows the users that are already selected, And when i check on Level 2 approver the user "Holly C. Beck" still in options even though already seleced on Level 3 approver. But it level 3 Approver the filtering works when i check the options are none.</p>
<p>Can anyone check the code why is it not filtering, but only filters on the higher levels?</p>
<p>Here is my Livewire controller</p>
<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-html lang-html prettyprint-override"><code>class CreateHelpTopic extends Component
{
use Utils, BasicModelQueries;

public $approvalLevels = [1, 2, 3, 4, 5];
public $level1Approvers = [];
public $level2Approvers = [];
public $level3Approvers = [];
public $level4Approvers = [];
public $level5Approvers = [];
public $approvalLevelSelected;
public $buDepartment;

public function cancel()
{
$this->reset();
$this->resetValidation();
$this->dispatchBrowserEvent('close-modal');
$this->hideSpecialProjectContainer();
}

public function updatedApprovalLevelSelected()
{
$this->resetLevels();
$this->getFilteredApprovers(1);
}

public function updatedLevel1Approvers()
{
$this->getFilteredApprovers(2);
}

public function updatedLevel2Approvers()
{
$this->getFilteredApprovers(3);
}

public function updatedLevel3Approvers()
{
$this->getFilteredApprovers(4);
}

public function updatedLevel4Approvers()
{
$this->getFilteredApprovers(5);
}

public function getFilteredApprovers($level)
{
$selectedApprovers = array_merge(
(array)$this->level1Approvers,
(array)$this->level2Approvers,
(array)$this->level3Approvers,
(array)$this->level4Approvers,
(array)$this->level5Approvers
);

$filteredApprovers = User::with(['profile', 'roles'])
->role([Role::APPROVER, Role::SERVICE_DEPARTMENT_ADMIN])
->whereNotIn('id', $selectedApprovers)
->orderByDesc('created_at')
->get();

$this->dispatchBrowserEvent('load-approvers', ['approvers' => $filteredApprovers, 'level' => $level]);
}

protected $listeners = [
'approver-level-changed' => 'handleApproverLevelChanged',
'approval-level-selected' => 'updatedApprovalLevelSelected'
];

public function handleApproverLevelChanged($event)
{
$level = $event['level'] + 1;
$this->getFilteredApprovers($level);
}

private function resetLevels()
{
$this->level1Approvers = [];
$this->level2Approvers = [];
$this->level3Approvers = [];
$this->level4Approvers = [];
$this->level5Approvers = [];
}

public function render()
{
return view('livewire.staff.help-topic.create-help-topic', [
'serviceLevelAgreements' => $this->queryServiceLevelAgreements(),
'serviceDepartments' => $this->queryServiceDepartments(),
'buDepartments' => $this->queryBUDepartments(),
]);
}
}</code></pre>
</div>
</div>
</p>
<p>And here is my Blade file</p>
<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-html lang-html prettyprint-override"><code><div>
<div wire:ignore.self class="modal fade help__topic__modal" id="addNewHelpTopicModal" tabindex="-1"
aria-labelledby="addNewHelpTopicModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content modal__content">
<div class="modal-header modal__header p-0 border-0">
<h1 class="modal-title modal__title" id="addNewHelpTopicModalLabel">Add new help topic</h1>
<button class="btn btn-sm btn__x" data-bs-dismiss="modal">
<i class="fa-sharp fa-solid fa-xmark"></i>
</button>
</div>
<div class="modal-body modal__body">
<!-- Approval Configurations -->
<hr>
<div class="row">
<h6 class="fw-semibold mb-4" style="font-size: 0.89rem;">Approval Configurations</h6>
<div class="col-md-6">
<div class="mb-2">
<label for="department" class="form-label form__field__label">
Level of Approval
</label>
<div>
<div id="select-help-topic-approval-level" wire:ignore></div>
</div>
@error('bu_department')
<span class="error__message">
<i class="fa-solid fa-triangle-exclamation"></i>
{{ $message }}
</span>
@enderror
</div>
</div>
<div wire:ignore class="row" id="dynamic-approval-container"></div>
</div>
<!-- Modal Footer -->
<div class="modal-footer modal__footer p-0 justify-content-between border-0 gap-2">
<div class="d-flex align-items-center gap-2">
<button type="submit"
class="btn d-flex align-items-center justify-content-center gap-2 m-0 btn__modal__footer btn__send">
<span wire:loading wire:target="saveHelpTopic" class="spinner-border spinner-border-sm"
role="status" aria-hidden="true">
</span>
Add New
</button>
<button type="button" class="btn m-0 btn__modal__footer btn__cancel" id="btnCloseModal"
data-bs-dismiss="modal" wire:click="cancel">
Cancel
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

@push('livewire-select')
<script>
document.addEventListener('DOMContentLoaded', () => {
const approvalLevelSelect = document.querySelector('#select-help-topic-approval-level');


const approvalLevels = @json($approvalLevels);
const approvalLevelOption = approvalLevels.map(approvalLevel => ({
label: `${approvalLevel} ${approvalLevel >= 2 ? 'Levels' : 'Level'}`,
value: approvalLevel
}));


VirtualSelect.init({
ele: approvalLevelSelect,
options: approvalLevelOption,
search: true,
markSearchResults: true,
});

approvalLevelSelect.addEventListener('change', () => {
@this.set('approvalLevelSelected', approvalLevelSelect.value);
});

const dynamicApprovalLevelContainer = document.querySelector('#dynamic-approval-container');
const approvers = {};
let selectedApprovers = [];

const initializeApproverSelect = (level) => {
approvers[`level${level}`] = document.querySelector(
`#select-help-topic-approval-level-${level}`);
VirtualSelect.init({
ele: approvers[`level${level}`],
search: true,
multiple: false,
showValueAsTags: false,
markSearchResults: true,
hasOptionDescription: true
});

approvers[`level${level}`].addEventListener('change', () => {
selectedApprovers[level - 1] = approvers[`level${level}`].value;
@this.set(`level${level}Approvers`, approvers[`level${level}`].value);
window.dispatchEvent(new CustomEvent('approver-level-changed', {
detail: {
level
}
}));
});

approvers[`level${level}`].addEventListener('virtual-select:option-click', () => {
@this.call('getFilteredApprovers', level);
});
};

approvalLevelSelect.addEventListener('change', () => {
dynamicApprovalLevelContainer.innerHTML = '';
selectedApprovers = [];

for (let i = 1; i <= approvalLevelSelect.value; i++) {
const approverFieldWrapper = document.createElement('div');
approverFieldWrapper.className = 'col-md-6';
approverFieldWrapper.innerHTML = `
<div class="mb-2">
<label for="department" class="form-label form__field__label">Level ${i} Approver</label>
<div>
<div id="select-help-topic-approval-level-${i}" wire:ignore></div>
</div>
</div>`;
dynamicApprovalLevelContainer.appendChild(approverFieldWrapper);
initializeApproverSelect(i);
}
window.dispatchEvent(new CustomEvent('approval-level-selected'));
});

window.addEventListener('load-approvers', (event) => {
const level = event.detail.level;
const approverSelect = approvers[`level${level}`];
if (approverSelect) {
const approverOptions = event.detail.approvers.filter(approver => {
return !selectedApprovers.flat().includes(approver.id);
}).map(approver => ({
label: `${approver.profile.first_name} ${approver.profile.middle_name ? approver.profile.middle_name[0] + '.' : ''} ${approver.profile.last_name}`,
value: approver.id,
description: approver.roles.map(role => role.name).join(', ')
}));
approverSelect.setOptions(approverOptions);
}
});

approvalLevelSelect.addEventListener('change', () => {
window.dispatchEvent(new CustomEvent('approval-level-selected'));
});
});
</script>
@endpush</code></pre>
</div>
</div>
</p>
 

Latest posts

D
Replies
0
Views
1
Dhanushka Amarakoon
D
S
Replies
0
Views
1
Shikhar Ambashta
S
Top