File manager - Edit - /var/www/payraty/hris/resources/views/appraisal_reviews/edit.blade.php
Back
{{ Form::model($appraisalReview, [ 'route' => ['appraisal_reviews.update', $appraisalReview->id], 'method' => 'PUT', 'class' => 'needs-validation', 'novalidate', 'id' => 'appraisal-review-form' ]) }} <div class="modal-body"> <div class="row"> {{-- Employee --}} <div class="col-12"> <div class="form-group"> {{ Form::label('employee', __('Employee'), ['class' => 'form-label']) }} <div class="form-control-plaintext"> {{ $appraisalReview->employee->name ?? __('N/A') }} </div> {{ Form::hidden('employee_id', $appraisalReview->employee_id) }} </div> </div> {{-- Rating Type --}} <div class="col-12"> <div class="form-group"> {{ Form::label('rating_type_id', __('Rating Type'), ['class' => 'form-label']) }} <div class="form-icon-user"> {{ Form::select('rating_type_id', $ratingTypes, null, [ 'class' => 'form-control', 'required' => true, 'placeholder' => __('Choose Rating Type'), // Disable if $isEmployee OR if allowEditAfterFinalScore is false ($isEmployee || !$allowEditAfterFinalScore || $isPeer) ? 'disabled' : null ]) }} </div> </div> </div> {{-- Review Type --}} <div class="col-12 mb-3"> <div class="form-group"> {{ Form::label('review_type', __('Review Type'), ['class' => 'form-label']) }} {{ Form::select('review_type', [ '90' => '90 Degree (Manager Only)', '180' => '180 Degree (Manager + Self)', '360' => '360 Degree (Manager + Self + Peers)' ], $appraisalReview->review_type, [ 'class' => 'form-control', 'required' => true, // Disable if $isEmployee OR if allowEditAfterFinalScore is false ($isEmployee || !$allowEditAfterFinalScore || $isPeer) ? 'disabled' : null ]) }} </div> </div> {{-- Goal selector (dropdown + tag list) --}} @if ($allowEditAfterFinalScore) <div class="col-12"> <div class="form-group"> {{ Form::label('goal_ids', __('Select Goals'), ['class' => 'form-label']) }} <div class="goal-select-container {{ (!$allowEditAfterFinalScore) ? 'disabled-selection-mode' : '' }}"> <div id="selected-goals-display" class="selected-goals-display"> <div id="selected-goals-list" class="selected-goals-list"></div> </div> <div class="dropdown"> <button class="btn btn-outline-secondary dropdown-toggle w-100 text-start" type="button" id="goal-dropdown-btn" data-bs-toggle="dropdown" aria-expanded="false" @if (!$allowEditAfterFinalScore || $isPeer) disabled @endif> <i class="fas fa-target me-2"></i>{{ __('Select Goals') }} </button> <ul class="dropdown-menu w-100" id="goal-dropdown-menu" style="max-height:300px;overflow-y:auto;"> <li><span class="dropdown-item-text text-muted">{{ __('No goals available') }}</span></li> </ul> </div> </div> </div> </div> @endif {{-- Competency selector (dropdown + tag list) --}} @if ($allowEditAfterFinalScore) <div class="col-12 mt-3"> <div class="form-group"> {{ Form::label('competency_ids', __('Select Competencies'), ['class' => 'form-label']) }} <div class="competency-select-container {{ (!$allowEditAfterFinalScore) ? 'disabled-selection-mode' : '' }}"> <div id="selected-competencies-display" class="selected-competencies-display"> <div id="selected-competencies-list" class="selected-competencies-list"></div> </div> <div class="dropdown" style="margin-top: 10px; padding:0px 10px"> <button class="btn btn-outline-secondary dropdown-toggle w-100 text-start" type="button" id="competency-dropdown-btn" data-bs-toggle="dropdown" aria-expanded="false" @if (!$allowEditAfterFinalScore || $isPeer) disabled @endif> {{ __('Select Competencies') }} </button> <ul class="dropdown-menu w-100" id="competency-dropdown-menu" style="max-height:300px;overflow-y:auto;"> <li><span class="dropdown-item-text text-muted">{{ __('No competencies available') }}</span></li> </ul> </div> </div> </div> </div> @endif {{-- Status --}} <div class="col-12"> <div class="form-group"> {{ Form::label('status', __('Status'), ['class' => 'form-label']) }} <div class="form-icon-user"> {{ Form::select('status', [ 'on_going' => __('On-going'), 'closed' => __('Closed'), ], null, [ 'class' => 'form-control', 'required', // Disable if allowEditAfterFinalScore is false (meaning final score exists) (!$allowEditAfterFinalScore || $isPeer) ? 'disabled' : '' ]) }} </div> </div> </div> {{-- Admin Flagging Checkbox (Visible only to Admin) --}} @if ($userIsAdmin) <div class="col-12 mt-3"> <div class="form-group"> {{ Form::label('is_flagged', __('Flag Appraisal'), ['class' => 'form-label']) }} <div class="form-check custom-checkbox"> {{ Form::checkbox('is_flagged', 1, $appraisalReview->is_flagged, [ 'class' => 'form-check-input custom-checkbox-input', 'id' => 'is_flagged', ]) }} <span class="checkmark"></span> <span class="label-text">{{ __('Flag this appraisal for review') }}</span> </div> </div> </div> @endif {{-- Admin Comment (Visible to all, readonly for non-admins) --}} <div class="col-12 mt-2"> <div class="form-group"> {{ Form::label('admin_flag_comment', __('Admin Comment'), ['class' => 'form-label']) }} {{ Form::textarea('admin_flag_comment', null, [ 'class' => 'form-control', 'rows' => 3, 'placeholder' => __('Admin comments'), // Add readonly attribute if user is not an admin !$userIsAdmin ? 'readonly' : null ]) }} </div> </div> {{-- Allow goal-update toggle --}} <div class="col-12 mt-2 mb-3"> {{ Form::hidden('allow_goal_update', 0) }} <div class="form-check custom-checkbox"> {{ Form::checkbox('allow_goal_update', 1, $appraisalReview->allow_goal_update, [ 'class' => 'form-check-input custom-checkbox-input', 'id' => 'allow_goal_update', ($isEmployee || !$allowEditAfterFinalScore || $isPeer) ? 'disabled' : null ]) }} <span class="checkmark"></span> <span class="label-text">{{ __('Allow employee to update goals during appraisal') }}</span> </div> </div> {{-- Conditionally Render Review Table --}} <div class="col-12"> <div class="table-responsive"> @if ($appraisalReview->review_type === '360' && $isPeer) {{-- New: Simple Peer Feedback Card --}} <div class="card mt-4 p-4"> <div class="card-body"> <h5 class="card-title">{{ __('Your General Peer Feedback') }}</h5> <p class="card-text">{{ __('Please provide your overall rating and comment for this appraisal.') }}</p> <div class="row"> <div class="col-md-6"> <div class="form-group"> {{ Form::label('peer_rating', __('Peer Rating'), ['class' => 'form-label']) }} <input type="text" name="peer_rating" id="peer_rating" class="form-control form-control-sm" value="{{ $peerFeedback->rating_value ?? '' }}" {{ !$isPeer || !$allowEditAfterFinalScore ? 'readonly' : '' }}> </div> </div> <div class="col-md-6"> <div class="form-group"> {{ Form::label('peer_comment', __('Peer Comment'), ['class' => 'form-label']) }} <input type="text" name="peer_comment" id="peer_comment" class="form-control form-control-sm" value="{{ $peerFeedback->comment ?? '' }}" {{ !$isPeer || !$allowEditAfterFinalScore ? 'readonly' : '' }}> </div> </div> </div> </div> </div> @else {{-- Standard Review Accordion --}} <div class="accordion" id="standard-review-accordion"> {{-- Accordion items will be dynamically populated by JavaScript --}} </div> @endif </div> </div> {{-- Peer Selection Section (Visible only for Admins/Managers on 360 reviews) --}} @if (($userIsAdmin || $isManager) && $appraisalReview->review_type === '360') <div class="card bg-base-100 shadow-md my-4"> <div class="card-body"> <h2 class="card-title text-xl font-bold mb-4">Select Peers for 360-Degree Review</h2> <div class="form-control"> <div class="form-group"> <label for="peerSelect">Select Peers</label> <select name="peer_ids[]" class="form-control select2" id="peerSelect" multiple="multiple" {{ $appraisalReview->final_score ? 'disabled' : '' }}> @foreach($potentialPeers as $peer) <option value="{{ $peer['id'] }}" {{ in_array($peer['id'], $selectedPeerIds) ? 'selected' : '' }}> {{ $peer['name'] }} </option> @endforeach </select> </div> </div> </div> </div> @endif {{-- Peer Feedback Summary Section --}} @if ($userIsAdmin) <div class="card mt-4" id="peer-feedback-summary-card" style="display: none;"> <div class="card-header"> <h5 class="mb-0">{{ __('Peer Feedback Summary') }} <span class="badge bg-secondary">{{ __('360 Degree Review') }}</span></h5> </div> <div class="card-body"> <div class="table-responsive"> <table class="table table-bordered table-striped" id="peer-feedback-summary-table"> <thead> <tr> <th>{{ __('Item') }}</th> <th>{{ __('Peer') }}</th> <th>{{ __('Rating') }}</th> <th>{{ __('Comment') }}</th> </tr> </thead> <tbody id="peer-feedback-summary-table-body"> {{-- Rows will be populated dynamically by JavaScript --}} </tbody> </table> </div> <p id="no-peer-feedback-message" class="text-muted text-center mt-3" style="display: none;">{{ __('No peer feedback submitted yet for this review.') }}</p> </div> </div> @endif </div> </div> <div class="modal-footer"> <input type="button" value="{{ __('Cancel') }}" class="btn btn-light" data-bs-dismiss="modal"> <button type="submit" class="btn btn-primary">{{ __('Update') }}</button> </div> {{ Form::close() }} <style> .goal-select-container { position: relative } .selected-goals-display { background: #f8f9fa; border: 1px solid #dee2e6; border-radius: .375rem; padding: .5rem; margin-bottom: .5rem; min-height: 2.5rem } .selected-goals-list { display: flex; flex-wrap: wrap; gap: .5rem } .goal-tag, .competency-tag { background: #007bff; color: #fff; padding: .25rem .5rem; border-radius: 1rem; font-size: .875rem; display: flex; align-items: center; gap: .25rem; margin-bottom:10px; } .goal-tag .remove-goal, .competency-tag .remove-competency { background: rgba(255, 255, 255, .3); border: none; border-radius: 50%; width: 1.2rem; height: 1.2rem; display: flex; align-items: center; justify-content: center; cursor: pointer; font-size: .85rem; color: #fff; padding: 0; line-height: 1; box-shadow: none; outline: none; -webkit-appearance: none; -moz-appearance: none; appearance: none; } .goal-tag .remove-goal:hover { background: rgba(255, 255, 255, .5) } .dropdown { border: 1px solid; border-radius: 1rem } .dropdown-item:hover { background: #f8f9fa } .dropdown-item.selected { background: #e3f2fd; color: #1976d2 } .dropdown-item.selected::after { content: '✓'; float: right; color: #1976d2; font-weight: bold } input[readonly] { background-color: #f8f9fa; border-style: dashed; cursor: not-allowed; } </style> <script> $(document).ready(function() { console.log('Appraisal Review Edit Page Loaded'); $('#peerSelect').select2({ placeholder: "Select one or more peers", allowClear: true // Allows clearing all selections }); // Apply the rating type config on page load. applyRatingTypeConfig.call(document.querySelector('[name="rating_type_id"]')); }); var employeeId = {{$appraisalReview->employee_id}}; var reviewType = {!! json_encode($appraisalReview->review_type) !!}; var ratingTypeConfigs = @json($ratingTypesWithConfig); // Roles passed from controller var isManager = {!! json_encode($isManager) !!}; var isEmployee = {!! json_encode($isEmployee) !!}; var isPeer = {!! json_encode($isPeer) !!}; var userIsAdmin = {!! json_encode($userIsAdmin) !!}; // Goal elements var goalDropdownBtn = document.getElementById('goal-dropdown-btn'); var goalDropdownMenu = document.getElementById('goal-dropdown-menu'); var selectedGoalsDisp = document.getElementById('selected-goals-display'); var selectedGoalsList = document.getElementById('selected-goals-list'); var availableGoals = @json($availableGoals); var selectedGoals = new Map(); var goalFeedbacks = @json($feedbackByGoalRole ?? []); // Competency elements var competencyDropdownBtn = document.getElementById('competency-dropdown-btn'); var competencyDropdownMenu = document.getElementById('competency-dropdown-menu'); var selectedCompetenciesDisp = document.getElementById('selected-competencies-display'); var selectedCompetenciesList = document.getElementById('selected-competencies-list'); var availableCompetencies = @json($availableCompetencies); var selectedCompetencies = new Map(); var competencyFeedbacks = @json($feedbackByCompetencyRole ?? []); // Accordion container var standardReviewAccordion = document.getElementById('standard-review-accordion'); var allowEditAfterFinalScore = {!! json_encode($allowEditAfterFinalScore) !!}; /* ---- Preload currently attached goals and competencies ---- */ var preloadedGoals = {!! json_encode($preloadedGoals) !!}; preloadedGoals.forEach(g => { selectedGoals.set(String(g.id), g); if (!(reviewType === '360' && isPeer)) { buildAccordionItem('goal', g); } }); var preloadedCompetencies = {!! json_encode($preloadedCompetencies) !!}; preloadedCompetencies.forEach(c => { selectedCompetencies.set(String(c.id), c); if (!(reviewType === '360' && isPeer)) { buildAccordionItem('competency', c); } }); updateSelectedGoalsDisplay(); updateSelectedCompetenciesDisplay(); toggleAccordionContainer(); /* ---- Goal Functions ---- */ if (goalDropdownBtn) { goalDropdownBtn.addEventListener('click', () => { renderGoalDropdown(); }); } function renderGoalDropdown() { goalDropdownMenu.innerHTML = ''; if (!availableGoals.length) { goalDropdownMenu.innerHTML = `<li><span class="dropdown-item-text text-muted">{{ __('No goals available') }}</span></li>`; return; } availableGoals.forEach(goal => { const li = document.createElement('li'); const a = document.createElement('a'); a.href = '#'; const date = goal.due_date ? new Intl.DateTimeFormat('en-GB', { year: 'numeric', month: 'short', day: 'numeric' }).format(new Date(goal.due_date)) : '—'; a.textContent = `${goal.title} (${date})`; a.className = `dropdown-item ${selectedGoals.has(String(goal.id)) ? 'selected' : ''}`; a.onclick = e => { e.preventDefault(); toggleGoal(goal); }; li.appendChild(a); goalDropdownMenu.appendChild(li); }); } function toggleGoal(goal) { const id = String(goal.id); if (selectedGoals.has(id)) { selectedGoals.delete(id); removeAccordionItem('goal', id); } else { selectedGoals.set(id, goal); buildAccordionItem('goal', goal); } updateSelectedGoalsDisplay(); renderGoalDropdown(); toggleAccordionContainer(); } function updateSelectedGoalsDisplay() { if (!selectedGoalsList || !selectedGoalsDisp) return; selectedGoalsList.innerHTML = ''; if (!selectedGoals.size) { selectedGoalsDisp.style.display = 'none'; return; } selectedGoalsDisp.style.display = 'block'; selectedGoals.forEach((g, id) => { const tag = document.createElement('div'); tag.className = 'goal-tag'; tag.innerHTML = ` <span>${g.title}</span> <button type="button" class="remove-goal" onclick="removeGoal('${id}')">×</button> <input type="hidden" name="goal_ids[]" value="${id}"> `; selectedGoalsList.appendChild(tag); }); updateGoalBtnText(); } function removeGoal(id) { selectedGoals.delete(id); removeAccordionItem('goal', id); updateSelectedGoalsDisplay(); renderGoalDropdown(); toggleAccordionContainer(); } function updateGoalBtnText() { if (!goalDropdownBtn) return; goalDropdownBtn.innerHTML = selectedGoals.size ? `<i class="fas fa-target me-2"></i>${selectedGoals.size} {{ __('Goals selected - Select More') }}` : `<i class="fas fa-target me-2"></i>{{ __('Select Goals') }}`; } /* ---- Competency Functions ---- */ if (competencyDropdownBtn) { competencyDropdownBtn.addEventListener('click', () => { renderCompetencyDropdown(); }); } function renderCompetencyDropdown() { competencyDropdownMenu.innerHTML = ''; if (!availableCompetencies.length) { competencyDropdownMenu.innerHTML = `<li><span class="dropdown-item-text text-muted">{{ __('No competencies available') }}</span></li>`; return; } availableCompetencies.forEach(competency => { const li = document.createElement('li'); const a = document.createElement('a'); a.href = '#'; a.textContent = competency.name; a.className = `dropdown-item ${selectedCompetencies.has(String(competency.id)) ? 'selected' : ''}`; a.onclick = e => { e.preventDefault(); toggleCompetency(competency); }; li.appendChild(a); competencyDropdownMenu.appendChild(li); }); } function toggleCompetency(competency) { const id = String(competency.id); if (selectedCompetencies.has(id)) { selectedCompetencies.delete(id); removeAccordionItem('competency', id); } else { selectedCompetencies.set(id, competency); buildAccordionItem('competency', competency); } updateSelectedCompetenciesDisplay(); renderCompetencyDropdown(); toggleAccordionContainer(); } function updateSelectedCompetenciesDisplay() { if (!selectedCompetenciesList || !selectedCompetenciesDisp) return; selectedCompetenciesList.innerHTML = ''; if (!selectedCompetencies.size) { selectedCompetenciesDisp.style.display = 'none'; return; } selectedCompetenciesDisp.style.display = 'block'; selectedCompetencies.forEach((c, id) => { const tag = document.createElement('div'); tag.className = 'competency-tag'; tag.innerHTML = ` <span>${c.name}</span> <button type="button" class="remove-competency" onclick="removeCompetency('${id}')">×</button> <input type="hidden" name="competency_ids[]" value="${id}"> `; selectedCompetenciesList.appendChild(tag); }); updateCompetencyBtnText(); } function removeCompetency(id) { selectedCompetencies.delete(id); removeAccordionItem('competency', id); updateSelectedCompetenciesDisplay(); renderCompetencyDropdown(); toggleAccordionContainer(); } function updateCompetencyBtnText() { if (!competencyDropdownBtn) return; competencyDropdownBtn.innerHTML = selectedCompetencies.size ? `${selectedCompetencies.size} {{ __('Competencies selected - Select More') }}` : `{{ __('Select Competencies') }}`; } function populatePeerReviewSummary() { const summaryCard = document.getElementById('peer-feedback-summary-card'); const summaryTableBody = document.getElementById('peer-feedback-summary-table-body'); const noFeedbackMessage = document.getElementById('no-peer-feedback-message'); if (isEmployee || !summaryCard || !summaryTableBody) { return; } summaryTableBody.innerHTML = ''; if (reviewType !== '360') { summaryCard.style.display = 'none'; return; } const allPeerFeedbacks = @json($allPeerFeedbacks ?? []); if (allPeerFeedbacks.length) { allPeerFeedbacks.forEach(peerFb => { const tr = document.createElement('tr'); tr.innerHTML = ` <td>{{ __('General') }}</td> <td>${peerFb.giver_name}</td> <td>${peerFb.rating_value ?? 'N/A'}</td> <td>${peerFb.comment ?? 'No comment'}</td> `; summaryTableBody.appendChild(tr); }); } if (allPeerFeedbacks.length > 0) { summaryCard.style.display = ''; if (noFeedbackMessage) noFeedbackMessage.style.display = 'none'; } else { summaryCard.style.display = ''; if (noFeedbackMessage) noFeedbackMessage.style.display = ''; } } /* --- The Core Accordion Functions --- */ function buildAccordionItem(type, item) { if (!standardReviewAccordion) return; const id = String(item.id); const itemName = type === 'goal' ? `${item.title} (${item.due_date ? new Intl.DateTimeFormat('en-GB', { year: 'numeric', month: 'short', day: 'numeric' }).format(new Date(item.due_date)) : '—'})` : item.name; const feedbackSource = type === 'goal' ? goalFeedbacks : competencyFeedbacks; const namePrefix = type === 'goal' ? `ratings[goal][${id}]` : `ratings[competency][${id}]`; const managerRatingVal = (feedbackSource?.[id]?.manager?.rating_value) ?? ''; const managerCommentVal = (feedbackSource?.[id]?.manager?.comment) ?? ''; const employeeRatingVal = (feedbackSource?.[id]?.employee?.rating_value) ?? ''; const employeeCommentVal = (feedbackSource?.[id]?.employee?.comment) ?? ''; const adminRatingVal = (feedbackSource?.[id]?.admin?.rating_value) ?? ''; const adminCommentVal = (feedbackSource?.[id]?.admin?.comment) ?? ''; const isGloballyDisabledOrReadonly = !allowEditAfterFinalScore; const isManagerReadonly = isGloballyDisabledOrReadonly || !isManager; const isEmployeeReadonly = isGloballyDisabledOrReadonly || !isEmployee || reviewType == '90'; const isAdminReadonly = isGloballyDisabledOrReadonly || !userIsAdmin; const accordionItem = document.createElement('div'); accordionItem.className = 'accordion-item'; accordionItem.setAttribute('data-' + type + '-id', id); const headingId = `${type}-heading-${id}`; const collapseId = `${type}-collapse-${id}`; accordionItem.innerHTML = ` <h2 class="accordion-header" id="${headingId}"> <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#${collapseId}" aria-expanded="false" aria-controls="${collapseId}"> ${itemName} </button> </h2> <div id="${collapseId}" class="accordion-collapse collapse" aria-labelledby="${headingId}" data-bs-parent="#standard-review-accordion"> <div class="accordion-body"> <div class="row"> <div class="col-md-6 form-group"> <label class="form-label">{{ __('Manager Rating') }}</label> <input type="text" name="${namePrefix}[manager_rating]" class="form-control" value="${managerRatingVal}" ${isManagerReadonly ? 'readonly title="Only managers can rate this item."' : ''}> </div> <div class="col-md-6 form-group"> <label class="form-label">{{ __('Manager Comment') }}</label> <input type="text" name="${namePrefix}[manager_comment]" class="form-control" value="${managerCommentVal}" ${isManagerReadonly ? 'readonly title="Only managers can comment on this item."' : ''}> </div> <div class="col-md-6 form-group"> <label class="form-label">{{ __('Employee Rating') }}</label> <input type="text" name="${namePrefix}[employee_rating]" class="form-control" value="${employeeRatingVal}" ${isEmployeeReadonly ? 'readonly title="Only the employee can rate this item."' : ''}> </div> <div class="col-md-6 form-group"> <label class="form-label">{{ __('Employee Comment') }}</label> <input type="text" name="${namePrefix}[employee_comment]" class="form-control" value="${employeeCommentVal}" ${isEmployeeReadonly ? 'readonly title="Only the employee can comment on this item."' : ''}> </div> <div class="col-md-6 form-group"> <label class="form-label">{{ __('Admin Rating') }}</label> <input type="text" name="${namePrefix}[admin_rating]" class="form-control" value="${adminRatingVal}" ${isAdminReadonly ? 'readonly title="Only admins can rate this item."' : ''}> </div> <div class="col-md-6 form-group"> <label class="form-label">{{ __('Admin Comment') }}</label> <input type="text" name="${namePrefix}[admin_comment]" class="form-control" value="${adminCommentVal}" ${isAdminReadonly ? 'readonly title="Only admins can comment on this item."' : ''}> </div> </div> </div> </div> `; standardReviewAccordion.appendChild(accordionItem); // Re-apply rating type config to the new elements applyRatingTypeConfig.call(document.querySelector('[name="rating_type_id"]')); } function removeAccordionItem(type, id) { if (!standardReviewAccordion) return; const accordionItem = standardReviewAccordion.querySelector(`[data-${type}-id="${id}"]`); if (accordionItem) { accordionItem.remove(); } } function toggleAccordionContainer() { const hasStandardItems = selectedGoals.size > 0 || selectedCompetencies.size > 0; if (standardReviewAccordion) { standardReviewAccordion.style.display = (hasStandardItems && !(reviewType === '360' && isPeer)) ? '' : 'none'; } } // Update applyRatingTypeConfig to find elements in the new accordion structure function applyRatingTypeConfig() { const typeId = this.value; const config = ratingTypeConfigs[typeId]; if (!config) return; const allReviewFields = document.querySelectorAll('[name*="_rating"]'); const peerRatingField = document.getElementById('peer_rating'); const fieldsToProcess = [...Array.from(allReviewFields), peerRatingField].filter(el => el); fieldsToProcess.forEach(oldEl => { const parentContainer = oldEl.closest('.form-group') || oldEl.parentElement; if (!parentContainer) return; const currentVal = oldEl.value; const name = oldEl.name; const className = oldEl.className; const originalTitle = oldEl.title; const id = oldEl.id; oldEl.remove(); let newEl; let isFieldDisabledOrReadonly = oldEl.hasAttribute('readonly') || oldEl.hasAttribute('disabled'); if (config.options) { newEl = document.createElement('select'); newEl.name = name; newEl.className = className; newEl.id = id; config.options.forEach(option => { const opt = document.createElement('option'); opt.value = option; opt.textContent = option; if (option == currentVal) opt.selected = true; newEl.appendChild(opt); }); if (isFieldDisabledOrReadonly) { newEl.setAttribute('disabled', ''); newEl.title = originalTitle || 'You do not have permission to modify this field.'; } } else { newEl = document.createElement('input'); newEl.type = 'number'; newEl.name = name; newEl.className = className; newEl.id = id; newEl.value = currentVal; if (config.min !== undefined) newEl.min = config.min; if (config.max !== undefined) newEl.max = config.max; if (config.step !== undefined) newEl.step = config.step; newEl.placeholder = `e.g. ${config.min}–${config.max}`; if (isFieldDisabledOrReadonly) { newEl.setAttribute('readonly', ''); newEl.title = originalTitle || 'You do not have permission to modify this field.'; } } parentContainer.appendChild(newEl); }); } document.querySelector('[name="rating_type_id"]').addEventListener('change', applyRatingTypeConfig); // Initial calls updateSelectedGoalsDisplay(); updateSelectedCompetenciesDisplay(); updateGoalBtnText(); updateCompetencyBtnText(); renderGoalDropdown(); renderCompetencyDropdown(); toggleAccordionContainer(); populatePeerReviewSummary(); </script>
| ver. 1.4 |
Github
|
.
| PHP 8.3.30 | Generation time: 0 |
proxy
|
phpinfo
|
Settings