- version : 1.2
- description : adding a delete route and the corresponding button in the html file .
هذا الالتزام موجود في:
19
app.py
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 %}
|
||||||
المرجع في مشكلة جديدة
حظر مستخدم