toggling between manual entry and csv file entry in index.html
- version : 1.9 //############################################// modified: templates/index.html //############################################//
هذا الالتزام موجود في:
@@ -1,4 +1,3 @@
|
|||||||
{# templates/index.html #}
|
|
||||||
{% extends 'template.html' %}
|
{% extends 'template.html' %}
|
||||||
|
|
||||||
{% block title %}الصفحة الرئيسية{% endblock %}
|
{% block title %}الصفحة الرئيسية{% endblock %}
|
||||||
@@ -82,7 +81,15 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="bg-white p-6 rounded-xl shadow-lg mb-8">
|
{# NEW: Button to toggle CSV Import section #}
|
||||||
|
<div class="text-center mb-6">
|
||||||
|
<button id="toggle-csv-import-button" class="px-6 py-2 bg-gray-300 text-gray-800 font-semibold rounded-lg shadow-md hover:bg-gray-400 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 transition-all">
|
||||||
|
استيراد من CSV
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{# WRAPPED: CSV Import section is now initially hidden #}
|
||||||
|
<div id="csv-import-section" class="bg-white p-6 rounded-xl shadow-lg mb-8 hidden">
|
||||||
<h2 class="text-2xl font-semibold mb-4 text-gray-800 border-b pb-4">استيراد من ملف CSV</h2>
|
<h2 class="text-2xl font-semibold mb-4 text-gray-800 border-b pb-4">استيراد من ملف CSV</h2>
|
||||||
<div class="bg-yellow-50 border border-yellow-200 text-yellow-800 text-sm p-4 rounded-lg mt-4">
|
<div class="bg-yellow-50 border border-yellow-200 text-yellow-800 text-sm p-4 rounded-lg mt-4">
|
||||||
<p class="font-bold">هام: تنسيق ملف CSV</p>
|
<p class="font-bold">هام: تنسيق ملف CSV</p>
|
||||||
@@ -91,7 +98,7 @@
|
|||||||
<p class="mt-2" style="direction: ltr; text-align: right;">
|
<p class="mt-2" style="direction: ltr; text-align: right;">
|
||||||
<code class="text-xs font-mono">اسم الطالب, العمر, اسم ولي الأمر, هاتف ولي الأمر 1, هاتف ولي الأمر 2, هاتف الطالب, الصف, اسم المدرسة, العنوان, المحفوظات, الملاحظات, تاريخ التسجيل</code>
|
<code class="text-xs font-mono">اسم الطالب, العمر, اسم ولي الأمر, هاتف ولي الأمر 1, هاتف ولي الأمر 2, هاتف الطالب, الصف, اسم المدرسة, العنوان, المحفوظات, الملاحظات, تاريخ التسجيل</code>
|
||||||
</p>
|
</p>
|
||||||
<p>إذا كانت الحقول الاختيارية (هاتف ولي الأمر 2، هاتف الطالب، الملاحظات، تاريخ التسجيل) فارغة، اتركها كذلك. تاريخ التسجيل سيُعيّن تلقائياً لليوم الحالي إذا تُرِك فارغاً. **النقاط تبدأ من صفر ولا تُدرج في الملف CSV.**</p>
|
<p>إذا كانت الحقول الاختيارية (هاتف ولي الأمر 2، هاتف الطالب، الملاحظات، تاريخ التسجيل) فارغة، اتركها كذلك. تاريخ التسجيل سيُعيّن تلقائياً لليوم الحالي إذا تُرِك فارغاً. **النقاط تبدأ من صفر ولا تُدرج في ملف CSV.**</p>
|
||||||
<p class="mt-3">
|
<p class="mt-3">
|
||||||
<a href="{{ url_for('download_csv_template') }}" class="text-blue-600 hover:underline font-semibold" download>
|
<a href="{{ url_for('download_csv_template') }}" class="text-blue-600 hover:underline font-semibold" download>
|
||||||
تنزيل قالب CSV
|
تنزيل قالب CSV
|
||||||
@@ -144,7 +151,7 @@
|
|||||||
<th class="px-6 py-3 text-xs font-medium text-gray-500 uppercase tracking-wider">المحفوظات</th>
|
<th class="px-6 py-3 text-xs font-medium text-gray-500 uppercase tracking-wider">المحفوظات</th>
|
||||||
<th class="px-6 py-3 text-xs font-medium text-gray-500 uppercase tracking-wider">تاريخ التسجيل</th>
|
<th class="px-6 py-3 text-xs font-medium text-gray-500 uppercase tracking-wider">تاريخ التسجيل</th>
|
||||||
<th class="px-6 py-3 text-xs font-medium text-gray-500 uppercase tracking-wider">ملاحظات</th>
|
<th class="px-6 py-3 text-xs font-medium text-gray-500 uppercase tracking-wider">ملاحظات</th>
|
||||||
<th class="px-6 py-3 text-xs font-medium text-gray-500 uppercase tracking-wider">النقاط</th> {# ADDED: Points header for table #}
|
<th class="px-6 py-3 text-xs font-medium text-gray-500 uppercase tracking-wider">النقاط</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="bg-white divide-y divide-gray-200" id="students-table-body">
|
<tbody class="bg-white divide-y divide-gray-200" id="students-table-body">
|
||||||
@@ -176,11 +183,11 @@
|
|||||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600">{{ student['memorizing'] }}</td>
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600">{{ student['memorizing'] }}</td>
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600">{{ student['registration_date'] }}</td>
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600">{{ student['registration_date'] }}</td>
|
||||||
<td class="px-6 py-4 text-sm text-gray-600 max-w-xs overflow-hidden text-ellipsis">{{ student['notes'] or 'لا يوجد' }}</td>
|
<td class="px-6 py-4 text-sm text-gray-600 max-w-xs overflow-hidden text-ellipsis">{{ student['notes'] or 'لا يوجد' }}</td>
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-blue-700 font-semibold">{{ student['points'] }}</td> {# ADDED: Display points #}
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-blue-700 font-semibold">{{ student['points'] }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% else %}
|
{% else %}
|
||||||
<tr id="no-students-row">
|
<tr id="no-students-row">
|
||||||
<td colspan="13" class="text-center py-6 text-gray-500">لم تتم إضافة أي طالب بعد.</td> {# Adjusted colspan #}
|
<td colspan="13" class="text-center py-6 text-gray-500">لم تتم إضافة أي طالب بعد.</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -201,22 +208,24 @@
|
|||||||
const addStudentForm = document.getElementById('add-student-form');
|
const addStudentForm = document.getElementById('add-student-form');
|
||||||
const submitAddButton = document.getElementById('submit-add-button');
|
const submitAddButton = document.getElementById('submit-add-button');
|
||||||
|
|
||||||
|
// NEW: CSV Import section and toggle button
|
||||||
|
const csvImportSection = document.getElementById('csv-import-section');
|
||||||
|
const toggleCsvImportButton = document.getElementById('toggle-csv-import-button');
|
||||||
|
|
||||||
const searchInput = document.getElementById('search-input');
|
const searchInput = document.getElementById('search-input');
|
||||||
const studentsTableBody = document.getElementById('students-table-body');
|
const studentsTableBody = document.getElementById('students-table-body');
|
||||||
const noStudentsRow = document.getElementById('no-students-row');
|
const noStudentsRow = document.getElementById('no-students-row');
|
||||||
const noSearchResultsDiv = document.getElementById('no-search-results');
|
const noSearchResultsDiv = document.getElementById('no-search-results');
|
||||||
|
|
||||||
// Store original student data and row elements for efficient filtering and restoration
|
|
||||||
const allStudentData = [];
|
const allStudentData = [];
|
||||||
studentsTableBody.querySelectorAll('tr').forEach(row => {
|
studentsTableBody.querySelectorAll('tr').forEach(row => {
|
||||||
if (row.id === 'no-students-row') {
|
if (row.id === 'no-students-row') {
|
||||||
return; // Skip the "no students" row from data processing
|
return;
|
||||||
}
|
}
|
||||||
allStudentData.push({
|
allStudentData.push({
|
||||||
element: row,
|
element: row,
|
||||||
student_name: row.children[2] ? row.children[2].textContent : '',
|
student_name: row.children[2] ? row.children[2].textContent : '',
|
||||||
parent_name: row.children[4] ? row.children[4].textContent : '',
|
parent_name: row.children[4] ? row.children[4].textContent : '',
|
||||||
// Store original HTML of potentially highlighted cells to restore them later
|
|
||||||
originalStudentNameHTML: row.children[2] ? row.children[2].innerHTML : '',
|
originalStudentNameHTML: row.children[2] ? row.children[2].innerHTML : '',
|
||||||
originalParentNameHTML: row.children[4] ? row.children[4].innerHTML : ''
|
originalParentNameHTML: row.children[4] ? row.children[4].innerHTML : ''
|
||||||
});
|
});
|
||||||
@@ -325,8 +334,25 @@
|
|||||||
|
|
||||||
addManuallyButton.addEventListener('click', () => {
|
addManuallyButton.addEventListener('click', () => {
|
||||||
addStudentSection.classList.toggle('hidden');
|
addStudentSection.classList.toggle('hidden');
|
||||||
|
// Hide CSV import section if manual add is shown
|
||||||
|
csvImportSection.classList.add('hidden');
|
||||||
|
toggleCsvImportButton.textContent = 'استيراد من CSV'; // Reset button text
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// NEW: Toggle CSV Import section visibility
|
||||||
|
toggleCsvImportButton.addEventListener('click', () => {
|
||||||
|
csvImportSection.classList.toggle('hidden');
|
||||||
|
// Hide manual add section if CSV import is shown
|
||||||
|
addStudentSection.classList.add('hidden');
|
||||||
|
// Update button text based on visibility
|
||||||
|
if (csvImportSection.classList.contains('hidden')) {
|
||||||
|
toggleCsvImportButton.textContent = 'استيراد من CSV';
|
||||||
|
} else {
|
||||||
|
toggleCsvImportButton.textContent = 'إخفاء استيراد CSV';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
importForm.addEventListener('submit', () => {
|
importForm.addEventListener('submit', () => {
|
||||||
submitImportButton.disabled = true;
|
submitImportButton.disabled = true;
|
||||||
submitImportButton.textContent = 'جاري الرفع...';
|
submitImportButton.textContent = 'جاري الرفع...';
|
||||||
|
|||||||
المرجع في مشكلة جديدة
حظر مستخدم