- version : 1.2

- description : adding a delete route and the corresponding button in
  the html file .
هذا الالتزام موجود في:
2025-06-12 15:58:27 +03:00
الأصل e96de0d016
التزام ad95102ae9
2 ملفات معدلة مع 63 إضافات و27 حذوفات

19
app.py
عرض الملف

@@ -214,6 +214,25 @@ def modify_student(student_id):
return redirect(url_for('index')) return redirect(url_for('index'))
@app.route('/delete_student/<int:student_id>', methods=['POST'])
def delete_student(student_id):
try:
with get_db_connection() as conn:
# First, check if the student exists
student = conn.execute('SELECT id FROM students WHERE id = ?', (student_id,)).fetchone()
if student is None:
flash('الطالب غير موجود.', 'danger')
return redirect(url_for('index'))
conn.execute('DELETE FROM students WHERE id = ?', (student_id,))
conn.commit()
flash('تم حذف الطالب بنجاح!', 'success')
except sqlite3.Error as e:
flash(f'خطأ في قاعدة البيانات أثناء الحذف: {str(e)}', 'danger')
except Exception as e:
flash(f'خطأ غير متوقع أثناء الحذف: {str(e)}', 'danger')
return redirect(url_for('index'))
@app.route('/import_csv', methods=['POST']) @app.route('/import_csv', methods=['POST'])
def import_csv(): def import_csv():

عرض الملف

@@ -131,7 +131,7 @@
<thead class="bg-gray-50"> <thead class="bg-gray-50">
<tr> <tr>
<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> {# Moved this header here #}
<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>
@@ -145,12 +145,21 @@
<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">
{% for student in students %} {% for student in students %}
<tr class="hover:bg-gray-50 transition-colors duration-200"> <tr class="hover:bg-gray-50 transition-colors duration-200">
<td class="px-6 py-4 whitespace-nowrap text-sm font-bold text-gray-700">{{ loop.index }}</td> <td class="px-6 py-4 whitespace-nowrap text-sm font-bold text-gray-700">{{ loop.index }}</td>
{# Moved the actions column here #}
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium"> <td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
<a href="{{ url_for('modify_student', student_id=student['id']) }}" class="text-indigo-600 hover:text-indigo-900"> <a href="{{ url_for('modify_student', student_id=student['id']) }}" class="text-indigo-600 hover:text-indigo-900 mx-1">
<i class="fas fa-pen"></i> {# Pen icon #} <i class="fas fa-pen" title="تعديل"></i> {# Pen icon #}
</a> </a>
{# You can add a delete button here later if needed #} <a href="#" onclick="confirmDelete({{ student['id'] }}, '{{ student['student_name'] }}')" class="text-red-600 hover:text-red-900 mx-1">
<i class="fas fa-trash-alt" title="حذف"></i> {# Trash can icon #}
</a>
{# A hidden form for deletion, used by JavaScript.
In a real application, consider adding a CSRF token for security. #}
<form id="delete-form-{{ student['id'] }}" action="{{ url_for('delete_student', student_id=student['id']) }}" method="POST" style="display: none;">
{# Example for CSRF token (requires Flask-WTF or similar setup): #}
{# <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"> #}
</form>
</td> </td>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">{{ student['student_name'] }}</td> <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">{{ student['student_name'] }}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600">{{ student['age'] }}</td> <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600">{{ student['age'] }}</td>
@@ -206,11 +215,11 @@
} }
allStudentData.push({ allStudentData.push({
element: row, element: row,
student_name: row.children[1] ? row.children[1].textContent : '', student_name: row.children[2] ? row.children[2].textContent : '', // Adjusted index for student_name
parent_name: row.children[3] ? row.children[3].textContent : '', parent_name: row.children[4] ? row.children[4].textContent : '', // Adjusted index for parent_name
// Store original HTML of potentially highlighted cells to restore them later // Store original HTML of potentially highlighted cells to restore them later
originalStudentNameHTML: row.children[1] ? row.children[1].innerHTML : '', originalStudentNameHTML: row.children[2] ? row.children[2].innerHTML : '', // Adjusted index
originalParentNameHTML: row.children[3] ? row.children[3].innerHTML : '' originalParentNameHTML: row.children[4] ? row.children[4].innerHTML : '' // Adjusted index
}); });
}); });
@@ -257,11 +266,11 @@
allStudentData.forEach(data => { allStudentData.forEach(data => {
data.element.classList.remove('hidden'); data.element.classList.remove('hidden');
// Restore original HTML for highlighted cells // Restore original HTML for highlighted cells
if (data.element.children[1]) { if (data.element.children[2]) { // Adjusted index
data.element.children[1].innerHTML = data.originalStudentNameHTML; data.element.children[2].innerHTML = data.originalStudentNameHTML;
} }
if (data.element.children[3]) { if (data.element.children[4]) { // Adjusted index
data.element.children[3].innerHTML = data.originalParentNameHTML; data.element.children[4].innerHTML = data.originalParentNameHTML;
} }
}); });
noSearchResultsDiv.classList.add('hidden'); // Hide no results message noSearchResultsDiv.classList.add('hidden'); // Hide no results message
@@ -285,21 +294,21 @@
foundResults++; foundResults++;
// Apply highlighting to the student name cell // Apply highlighting to the student name cell
if (data.element.children[1]) { if (data.element.children[2]) { // Adjusted index
data.element.children[1].innerHTML = highlightText(studentName, searchTerm); data.element.children[2].innerHTML = highlightText(studentName, searchTerm);
} }
// Apply highlighting to the parent name cell // Apply highlighting to the parent name cell
if (data.element.children[3]) { if (data.element.children[4]) { // Adjusted index
data.element.children[3].innerHTML = highlightText(parentName, searchTerm); data.element.children[4].innerHTML = highlightText(parentName, searchTerm);
} }
} else { } else {
data.element.classList.add('hidden'); // Hide the row data.element.classList.add('hidden'); // Hide the row
// Restore original content if the row is hidden // Restore original content if the row is hidden
if (data.element.children[1]) { if (data.element.children[2]) { // Adjusted index
data.element.children[1].innerHTML = data.originalStudentNameHTML; data.element.children[2].innerHTML = data.originalStudentNameHTML;
} }
if (data.element.children[3]) { if (data.element.children[4]) { // Adjusted index
data.element.children[3].innerHTML = data.originalParentNameHTML; data.element.children[4].innerHTML = data.originalParentNameHTML;
} }
} }
}); });
@@ -358,5 +367,13 @@
submitAddButton.disabled = true; submitAddButton.disabled = true;
submitAddButton.textContent = 'جاري الحفظ...'; // "Saving..." submitAddButton.textContent = 'جاري الحفظ...'; // "Saving..."
}); });
// --- New JavaScript for Delete Confirmation ---
function confirmDelete(studentId, studentName) {
if (confirm(`هل أنت متأكد أنك تريد حذف الطالب "${studentName}"؟ هذا الإجراء لا يمكن التراجع عنه.`)) {
// If confirmed, submit the hidden form for deletion
document.getElementById(`delete-form-${studentId}`).submit();
}
}
</script> </script>
{% endblock %} {% endblock %}