1057 lines
50 KiB
Twig
1057 lines
50 KiB
Twig
{% extends 'base.html.twig' %}
|
|
|
|
{% block title %}پرسیدن سوال جدید - پرسش و پاسخ{% endblock %}
|
|
|
|
{% block body %}
|
|
<main class="min-h-screen bg-gray-50">
|
|
<div class="container mx-auto px-4 py-8">
|
|
<div class="max-w-4xl mx-auto">
|
|
<!-- هدر فرم -->
|
|
<div class="text-center mb-8">
|
|
<h1 class="text-3xl lg:text-4xl font-bold text-gray-900 mb-4">
|
|
پرسیدن سوال جدید
|
|
</h1>
|
|
<p class="text-lg text-gray-600">
|
|
سوال خود را مطرح کنید تا از تجربه دیگران استفاده کنید
|
|
</p>
|
|
</div>
|
|
|
|
<!-- فرم ایجاد سوال -->
|
|
<div class="bg-white rounded-2xl shadow-soft overflow-hidden">
|
|
<div class="p-8">
|
|
{{ form_start(form, {'attr': {'novalidate': 'novalidate', 'class': 'space-y-8', 'data-turbo': 'false'}}) }}
|
|
|
|
<!-- عنوان سوال -->
|
|
<div>
|
|
<label for="{{ form.title.vars.id }}" class="block text-sm font-medium text-gray-700 mb-2">
|
|
عنوان سوال
|
|
</label>
|
|
{{ form_widget(form.title, {'attr': {'class': 'w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200'}}) }}
|
|
{{ form_errors(form.title) }}
|
|
<p class="mt-2 text-sm text-gray-600">
|
|
عنوان سوال باید واضح و مختصر باشد. سعی کنید مشکل خود را در یک جمله خلاصه کنید.
|
|
</p>
|
|
</div>
|
|
|
|
<!-- محتوای سوال -->
|
|
<div>
|
|
<label for="{{ form.content.vars.id }}" class="block text-sm font-medium text-gray-700 mb-2">
|
|
محتوای سوال
|
|
</label>
|
|
|
|
<!-- نوار ابزار ادیتور -->
|
|
<div class="flex flex-wrap gap-2 p-3 bg-gray-50 border border-gray-300 rounded-t-xl">
|
|
<button type="button"
|
|
onclick="formatText('bold')"
|
|
title="پررنگ"
|
|
class="p-2 text-gray-600 hover:text-gray-900 hover:bg-gray-200 rounded-lg transition-colors duration-200">
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"></path>
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"></path>
|
|
</svg>
|
|
</button>
|
|
<button type="button"
|
|
onclick="formatText('italic')"
|
|
title="کج"
|
|
class="p-2 text-gray-600 hover:text-gray-900 hover:bg-gray-200 rounded-lg transition-colors duration-200">
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<line x1="19" y1="4" x2="10" y2="4"></line>
|
|
<line x1="14" y1="20" x2="5" y2="20"></line>
|
|
<line x1="15" y1="4" x2="9" y2="20"></line>
|
|
</svg>
|
|
</button>
|
|
<button type="button"
|
|
onclick="formatText('code')"
|
|
title="کد"
|
|
class="p-2 text-gray-600 hover:text-gray-900 hover:bg-gray-200 rounded-lg transition-colors duration-200">
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<polyline points="16,18 22,12 16,6"></polyline>
|
|
<polyline points="8,6 2,12 8,18"></polyline>
|
|
</svg>
|
|
</button>
|
|
<button type="button"
|
|
onclick="insertList()"
|
|
title="لیست"
|
|
class="p-2 text-gray-600 hover:text-gray-900 hover:bg-gray-200 rounded-lg transition-colors duration-200">
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<line x1="8" y1="6" x2="21" y2="6"></line>
|
|
<line x1="8" y1="12" x2="21" y2="12"></line>
|
|
<line x1="8" y1="18" x2="21" y2="18"></line>
|
|
<line x1="3" y1="6" x2="3.01" y2="6"></line>
|
|
<line x1="3" y1="12" x2="3.01" y2="12"></line>
|
|
<line x1="3" y1="18" x2="3.01" y2="18"></line>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
|
|
{{ form_widget(form.content, {'attr': {'class': 'w-full px-4 py-3 border border-gray-300 border-t-0 rounded-b-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200', 'rows': 10}}) }}
|
|
{{ form_errors(form.content) }}
|
|
<p class="mt-2 text-sm text-gray-600">
|
|
سوال خود را به تفصیل شرح دهید. هرچه جزئیات بیشتری ارائه دهید، پاسخهای بهتری دریافت خواهید کرد.
|
|
<br><span class="text-gray-500">میتوانید از دکمههای بالا برای فرمت کردن متن استفاده کنید.</span>
|
|
</p>
|
|
</div>
|
|
|
|
<!-- تگها -->
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">
|
|
تگها
|
|
<span class="text-red-500">*</span>
|
|
</label>
|
|
<div class="border border-gray-300 rounded-xl p-6 bg-gradient-to-br from-gray-50 to-blue-50">
|
|
<!-- تگهای انتخاب شده -->
|
|
<div class="mb-6">
|
|
<div class="flex items-center justify-between mb-3">
|
|
<h4 class="text-sm font-semibold text-gray-700">تگهای انتخاب شده</h4>
|
|
<span class="text-xs text-gray-500" id="tag-count">0 تگ انتخاب شده</span>
|
|
</div>
|
|
<div class="selected-tags min-h-12 flex flex-wrap gap-2 p-3 bg-white rounded-lg border-2 border-dashed border-gray-200" id="selected-tags">
|
|
<div class="flex items-center text-gray-400 text-sm">
|
|
<svg class="w-4 h-4 ml-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
|
</svg>
|
|
هیچ تگی انتخاب نشده است
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- جستجو و افزودن تگ -->
|
|
<div class="mb-6">
|
|
<div class="relative">
|
|
<input type="text"
|
|
class="w-full px-4 py-3 pr-12 border border-gray-300 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200 text-sm"
|
|
id="tag-input"
|
|
placeholder="نام تگ را تایپ کنید...">
|
|
<button class="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 hover:text-gray-600 transition-colors duration-200"
|
|
type="button"
|
|
id="search-icon">
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
<div class="flex items-center justify-between mt-3">
|
|
<button class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-all duration-200 text-sm font-medium flex items-center space-x-2 space-x-reverse"
|
|
type="button"
|
|
id="add-tag-btn">
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<line x1="12" y1="5" x2="12" y2="19"></line>
|
|
<line x1="5" y1="12" x2="19" y2="12"></line>
|
|
</svg>
|
|
<span>افزودن تگ</span>
|
|
</button>
|
|
<span class="text-xs text-gray-500">حداقل 1 و حداکثر 5 تگ</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- تگهای پیشنهادی -->
|
|
<div>
|
|
<div class="flex items-center justify-between mb-3">
|
|
<h4 class="text-sm font-semibold text-gray-700">تگهای محبوب</h4>
|
|
<button class="text-xs text-blue-600 hover:text-blue-800 transition-colors duration-200"
|
|
type="button"
|
|
id="show-all-tags">
|
|
نمایش همه
|
|
</button>
|
|
</div>
|
|
<div class="flex flex-wrap gap-2" id="tag-suggestions">
|
|
{% for tag in availableTags %}
|
|
<button type="button"
|
|
class="inline-flex items-center px-3 py-2 bg-white text-gray-700 text-sm font-medium rounded-full border border-gray-300 hover:bg-blue-50 hover:border-blue-300 hover:text-blue-700 cursor-pointer transition-all duration-200 tag-suggestion"
|
|
data-tag-id="{{ tag.id }}"
|
|
data-tag-name="{{ tag.name }}">
|
|
<svg class="w-3 h-3 ml-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
|
|
</svg>
|
|
{{ tag.name }}
|
|
</button>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<p class="mt-2 text-sm text-gray-600">
|
|
تگهای مرتبط را انتخاب کنید تا دیگران راحتتر بتوانند سوال شما را پیدا کنند.
|
|
<br><span class="text-gray-500">میتوانید تگ جدید ایجاد کنید یا از تگهای موجود انتخاب کنید.</span>
|
|
</p>
|
|
</div>
|
|
|
|
<!-- اطلاعرسانی ایمیل -->
|
|
<div>
|
|
<div class="flex items-center space-x-3 space-x-reverse">
|
|
{{ form_widget(form.notifyOnAnswer, {'attr': {'class': 'form-check-input'}}) }}
|
|
<label for="{{ form.notifyOnAnswer.vars.id }}" class="text-sm font-medium text-gray-700">
|
|
اطلاعرسانی ایمیل هنگام دریافت پاسخ
|
|
</label>
|
|
</div>
|
|
<p class="mt-2 text-sm text-gray-600">
|
|
در صورت انتخاب این گزینه، هر زمان که برای سوال شما پاسخی ارسال شود، از طریق ایمیل مطلع خواهید شد.
|
|
</p>
|
|
</div>
|
|
|
|
<!-- پیوست فایل -->
|
|
<div>
|
|
<label for="{{ form.attachments.vars.id }}" class="block text-sm font-medium text-gray-700 mb-2">
|
|
پیوست فایل
|
|
<span class="text-gray-500">(اختیاری)</span>
|
|
</label>
|
|
<div class="border-2 border-dashed border-gray-300 rounded-xl p-6 bg-gray-50 hover:bg-gray-100 transition-colors duration-200">
|
|
{{ form_widget(form.attachments, {'attr': {'class': 'w-full', 'id': 'file-input'}}) }}
|
|
{{ form_errors(form.attachments) }}
|
|
|
|
<div class="mt-4 text-center">
|
|
<div class="flex items-center justify-center space-x-2 space-x-reverse text-gray-500">
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"></path>
|
|
</svg>
|
|
<span class="text-sm">فایلهای خود را اینجا بکشید یا کلیک کنید</span>
|
|
</div>
|
|
<p class="text-xs text-gray-400 mt-2">
|
|
فرمتهای مجاز: JPG, PNG, GIF, PDF, DOC, DOCX, XLS, XLSX, PPT, PPTX, TXT
|
|
<br>حداکثر 3 فایل، هر کدام 4 مگابایت
|
|
</p>
|
|
</div>
|
|
|
|
<!-- نمایش فایلهای انتخاب شده -->
|
|
<div id="selected-files" class="mt-4 hidden">
|
|
<h4 class="text-sm font-medium text-gray-700 mb-2">فایلهای انتخاب شده:</h4>
|
|
<div id="file-list" class="space-y-2"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- دکمههای فرم -->
|
|
<div class="flex justify-between items-center pt-6 border-t border-gray-200">
|
|
<a href="{{ path('qa_index') }}"
|
|
class="inline-flex items-center space-x-2 space-x-reverse px-6 py-3 bg-gray-100 text-gray-700 rounded-xl hover:bg-gray-200 transition-all duration-200 font-medium">
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 12H5"></path>
|
|
<polyline points="12,19 5,12 12,5"></polyline>
|
|
</svg>
|
|
<span>انصراف</span>
|
|
</a>
|
|
<button type="submit"
|
|
class="inline-flex items-center space-x-2 space-x-reverse px-8 py-3 bg-blue-600 text-white rounded-xl hover:bg-blue-700 transition-all duration-200 font-medium shadow-lg hover:shadow-xl transform hover:-translate-y-0.5">
|
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<line x1="22" y1="2" x2="11" y2="13"></line>
|
|
<polygon points="22,2 15,22 11,13 2,9 22,2"></polygon>
|
|
</svg>
|
|
<span>ارسال سوال</span>
|
|
</button>
|
|
</div>
|
|
|
|
{{ form_end(form) }}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- راهنمای پرسیدن سوال -->
|
|
<div class="bg-white rounded-2xl shadow-soft mt-8 overflow-hidden">
|
|
<div class="bg-gradient-to-r from-blue-50 to-purple-50 px-8 py-6">
|
|
<h3 class="text-xl font-semibold text-gray-900 flex items-center">
|
|
<svg class="w-6 h-6 text-blue-600 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4"></path>
|
|
<path d="M21 12c.552 0 1-.448 1-1s-.448-1-1-1-1 .448-1 1 .448 1 1 1z"></path>
|
|
<path d="M3 12c.552 0 1-.448 1-1s-.448-1-1-1-1 .448-1 1 .448 1 1 1z"></path>
|
|
<path d="M12 3c.552 0 1-.448 1-1s-.448-1-1-1-1 .448-1 1 .448 1 1 1z"></path>
|
|
<path d="M12 21c.552 0 1-.448 1-1s-.448-1-1-1-1 .448-1 1 .448 1 1 1z"></path>
|
|
</svg>
|
|
راهنمای پرسیدن سوال خوب
|
|
</h3>
|
|
</div>
|
|
<div class="p-8">
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
|
|
<div>
|
|
<h4 class="text-lg font-semibold text-green-700 mb-4 flex items-center">
|
|
<svg class="w-5 h-5 text-green-600 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
|
</svg>
|
|
کارهای درست
|
|
</h4>
|
|
<ul class="space-y-3">
|
|
<li class="flex items-center space-x-3 space-x-reverse">
|
|
<svg class="w-5 h-5 text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
|
</svg>
|
|
<span class="text-gray-700">عنوان واضح و مختصر</span>
|
|
</li>
|
|
<li class="flex items-center space-x-3 space-x-reverse">
|
|
<svg class="w-5 h-5 text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
|
</svg>
|
|
<span class="text-gray-700">شرح کامل مشکل</span>
|
|
</li>
|
|
<li class="flex items-center space-x-3 space-x-reverse">
|
|
<svg class="w-5 h-5 text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
|
</svg>
|
|
<span class="text-gray-700">انتخاب تگهای مناسب</span>
|
|
</li>
|
|
<li class="flex items-center space-x-3 space-x-reverse">
|
|
<svg class="w-5 h-5 text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
|
</svg>
|
|
<span class="text-gray-700">استفاده از کلمات کلیدی</span>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div>
|
|
<h4 class="text-lg font-semibold text-red-700 mb-4 flex items-center">
|
|
<svg class="w-5 h-5 text-red-600 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
|
</svg>
|
|
کارهای نادرست
|
|
</h4>
|
|
<ul class="space-y-3">
|
|
<li class="flex items-center space-x-3 space-x-reverse">
|
|
<svg class="w-5 h-5 text-red-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
|
</svg>
|
|
<span class="text-gray-700">عنوان مبهم</span>
|
|
</li>
|
|
<li class="flex items-center space-x-3 space-x-reverse">
|
|
<svg class="w-5 h-5 text-red-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
|
</svg>
|
|
<span class="text-gray-700">شرح ناکافی</span>
|
|
</li>
|
|
<li class="flex items-center space-x-3 space-x-reverse">
|
|
<svg class="w-5 h-5 text-red-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
|
</svg>
|
|
<span class="text-gray-700">عدم انتخاب تگ</span>
|
|
</li>
|
|
<li class="flex items-center space-x-3 space-x-reverse">
|
|
<svg class="w-5 h-5 text-red-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
|
</svg>
|
|
<span class="text-gray-700">سوال تکراری</span>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
|
|
|
|
<script>
|
|
// سیستم مدیریت تگها
|
|
if (typeof window.QuestionFormClasses === 'undefined') {
|
|
window.QuestionFormClasses = {};
|
|
}
|
|
|
|
if (typeof window.QuestionFormClasses.TagManager === 'undefined') {
|
|
window.QuestionFormClasses.TagManager = class TagManager {
|
|
constructor() {
|
|
this.selectedTags = [];
|
|
this.maxTags = 5;
|
|
this.minTags = 1;
|
|
this.init();
|
|
}
|
|
|
|
init() {
|
|
this.tagInput = document.getElementById('tag-input');
|
|
this.addTagBtn = document.getElementById('add-tag-btn');
|
|
this.selectedTagsContainer = document.getElementById('selected-tags');
|
|
this.tagSuggestions = document.querySelectorAll('.tag-suggestion');
|
|
this.tagCount = document.getElementById('tag-count');
|
|
this.showAllTagsBtn = document.getElementById('show-all-tags');
|
|
|
|
if (!this.tagInput || !this.addTagBtn || !this.selectedTagsContainer) {
|
|
console.error('Required elements not found for tag system');
|
|
return;
|
|
}
|
|
|
|
this.bindEvents();
|
|
this.updateTagCount();
|
|
this.renderSelectedTags();
|
|
}
|
|
|
|
bindEvents() {
|
|
// حذف event listener های قبلی
|
|
this.removeEventListeners();
|
|
|
|
// افزودن تگ با دکمه
|
|
this.addTagBtn.addEventListener('click', this.handleAddTagClick.bind(this));
|
|
|
|
// افزودن تگ با Enter
|
|
this.tagInput.addEventListener('keypress', this.handleKeyPress.bind(this));
|
|
|
|
// جستجوی تگها
|
|
this.tagInput.addEventListener('input', this.handleInputChange.bind(this));
|
|
|
|
// کلیک روی تگهای پیشنهادی
|
|
this.tagSuggestions.forEach(suggestion => {
|
|
suggestion.addEventListener('click', () => this.toggleTagSuggestion(suggestion));
|
|
});
|
|
|
|
// نمایش همه تگها
|
|
if (this.showAllTagsBtn) {
|
|
this.showAllTagsBtn.addEventListener('click', this.handleShowAllTags.bind(this));
|
|
}
|
|
}
|
|
|
|
removeEventListeners() {
|
|
if (this.addTagBtn) {
|
|
this.addTagBtn.removeEventListener('click', this.handleAddTagClick);
|
|
}
|
|
if (this.tagInput) {
|
|
this.tagInput.removeEventListener('keypress', this.handleKeyPress);
|
|
this.tagInput.removeEventListener('input', this.handleInputChange);
|
|
}
|
|
if (this.showAllTagsBtn) {
|
|
this.showAllTagsBtn.removeEventListener('click', this.handleShowAllTags);
|
|
}
|
|
}
|
|
|
|
handleAddTagClick() {
|
|
this.addTagFromInput();
|
|
}
|
|
|
|
handleKeyPress(e) {
|
|
if (e.key === 'Enter') {
|
|
e.preventDefault();
|
|
this.addTagFromInput();
|
|
}
|
|
}
|
|
|
|
handleInputChange() {
|
|
this.filterSuggestions();
|
|
}
|
|
|
|
handleShowAllTags() {
|
|
this.showAllTags();
|
|
}
|
|
|
|
addTag(tagId, tagName) {
|
|
// بررسی محدودیت تعداد تگها
|
|
if (this.selectedTags.length >= this.maxTags) {
|
|
if (window.notification) {
|
|
window.notification.warning(`حداکثر ${this.maxTags} تگ میتوانید انتخاب کنید`);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// بررسی وجود تگ
|
|
if (this.selectedTags.find(tag => tag.id === tagId)) {
|
|
if (window.notification) {
|
|
window.notification.info('این تگ قبلاً انتخاب شده است');
|
|
}
|
|
return false;
|
|
}
|
|
|
|
this.selectedTags.push({ id: tagId, name: tagName });
|
|
|
|
this.updateTagCount();
|
|
this.renderSelectedTags();
|
|
this.updateHiddenInput();
|
|
this.updateSuggestionState(tagId, true);
|
|
|
|
// نمایش پیام موفقیت فقط یک بار
|
|
if (window.notification && !this._showingMessage) {
|
|
this._showingMessage = true;
|
|
window.notification.success(`تگ "${tagName}" اضافه شد`);
|
|
setTimeout(() => {
|
|
this._showingMessage = false;
|
|
}, 1000);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
removeTag(tagId) {
|
|
const tagIndex = this.selectedTags.findIndex(tag => tag.id === tagId);
|
|
if (tagIndex === -1) return false;
|
|
|
|
const removedTag = this.selectedTags[tagIndex];
|
|
this.selectedTags.splice(tagIndex, 1);
|
|
|
|
this.updateTagCount();
|
|
this.renderSelectedTags();
|
|
this.updateHiddenInput();
|
|
this.updateSuggestionState(tagId, false);
|
|
|
|
if (window.notification) {
|
|
window.notification.info(`تگ "${removedTag.name}" حذف شد`);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
addTagFromInput() {
|
|
const tagName = this.tagInput.value.trim();
|
|
|
|
if (!tagName) {
|
|
if (window.notification) {
|
|
window.notification.warning('لطفاً نام تگ را وارد کنید');
|
|
}
|
|
return;
|
|
}
|
|
|
|
// بررسی تگ موجود
|
|
const existingTag = Array.from(this.tagSuggestions).find(suggestion =>
|
|
suggestion.dataset.tagName.toLowerCase() === tagName.toLowerCase()
|
|
);
|
|
|
|
if (existingTag) {
|
|
const tagId = existingTag.dataset.tagId;
|
|
const tagName = existingTag.dataset.tagName;
|
|
this.addTag(tagId, tagName);
|
|
this.tagInput.value = '';
|
|
return;
|
|
}
|
|
|
|
// ایجاد تگ جدید
|
|
this.createNewTag(tagName);
|
|
}
|
|
|
|
createNewTag(tagName) {
|
|
// نمایش حالت بارگذاری
|
|
const originalContent = this.addTagBtn.innerHTML;
|
|
this.addTagBtn.innerHTML = '<div class="loading-spinner"></div>';
|
|
this.addTagBtn.disabled = true;
|
|
|
|
fetch('/qa/tag/create', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
},
|
|
body: `name=${encodeURIComponent(tagName)}&_token={{ csrf_token('vote') }}`
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.error) {
|
|
if (window.notification) {
|
|
window.notification.error(data.error);
|
|
}
|
|
return;
|
|
}
|
|
|
|
// افزودن تگ جدید
|
|
if (this.addTag(data.id, data.name)) {
|
|
this.tagInput.value = '';
|
|
|
|
// افزودن به لیست پیشنهادی
|
|
this.addToSuggestions(data.id, data.name);
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error creating tag:', error);
|
|
if (window.notification) {
|
|
window.notification.error('خطا در ایجاد تگ جدید. لطفاً دوباره تلاش کنید.');
|
|
}
|
|
})
|
|
.finally(() => {
|
|
// بازگردانی دکمه
|
|
this.addTagBtn.innerHTML = originalContent;
|
|
this.addTagBtn.disabled = false;
|
|
});
|
|
}
|
|
|
|
addToSuggestions(tagId, tagName) {
|
|
const suggestionElement = document.createElement('button');
|
|
suggestionElement.type = 'button';
|
|
suggestionElement.className = 'inline-flex items-center px-3 py-2 bg-white text-gray-700 text-sm font-medium rounded-full border border-gray-300 hover:bg-blue-50 hover:border-blue-300 hover:text-blue-700 cursor-pointer transition-all duration-200 tag-suggestion';
|
|
suggestionElement.dataset.tagId = tagId;
|
|
suggestionElement.dataset.tagName = tagName;
|
|
suggestionElement.innerHTML = `
|
|
<svg class="w-3 h-3 ml-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
|
|
</svg>
|
|
${tagName}
|
|
`;
|
|
|
|
suggestionElement.addEventListener('click', () => this.toggleTagSuggestion(suggestionElement));
|
|
|
|
const container = document.getElementById('tag-suggestions');
|
|
if (container) {
|
|
container.appendChild(suggestionElement);
|
|
this.tagSuggestions = document.querySelectorAll('.tag-suggestion');
|
|
}
|
|
}
|
|
|
|
toggleTagSuggestion(suggestion) {
|
|
const tagId = suggestion.dataset.tagId;
|
|
const tagName = suggestion.dataset.tagName;
|
|
|
|
if (this.selectedTags.find(tag => tag.id === tagId)) {
|
|
this.removeTag(tagId);
|
|
} else {
|
|
this.addTag(tagId, tagName);
|
|
}
|
|
}
|
|
|
|
updateSuggestionState(tagId, isSelected) {
|
|
const suggestion = document.querySelector(`[data-tag-id="${tagId}"]`);
|
|
if (!suggestion) return;
|
|
|
|
if (isSelected) {
|
|
suggestion.classList.remove('bg-white', 'text-gray-700', 'border-gray-300');
|
|
suggestion.classList.add('bg-blue-600', 'text-white', 'border-blue-600');
|
|
} else {
|
|
suggestion.classList.remove('bg-blue-600', 'text-white', 'border-blue-600');
|
|
suggestion.classList.add('bg-white', 'text-gray-700', 'border-gray-300');
|
|
}
|
|
}
|
|
|
|
renderSelectedTags() {
|
|
this.selectedTagsContainer.innerHTML = '';
|
|
|
|
if (this.selectedTags.length === 0) {
|
|
this.selectedTagsContainer.innerHTML = `
|
|
<div class="flex items-center text-gray-400 text-sm">
|
|
<svg class="w-4 h-4 ml-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
|
</svg>
|
|
هیچ تگی انتخاب نشده است
|
|
</div>
|
|
`;
|
|
return;
|
|
}
|
|
|
|
this.selectedTags.forEach(tag => {
|
|
const tagElement = document.createElement('div');
|
|
tagElement.className = 'inline-flex items-center px-3 py-2 bg-blue-600 text-white text-sm font-medium rounded-full shadow-sm';
|
|
tagElement.innerHTML = `
|
|
<svg class="w-3 h-3 ml-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z"></path>
|
|
</svg>
|
|
${tag.name}
|
|
<button type="button"
|
|
class="tag-remove mr-2 text-white hover:text-red-200 transition-colors duration-200"
|
|
data-tag-id="${tag.id}">
|
|
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<line x1="18" y1="6" x2="6" y2="18"></line>
|
|
<line x1="6" y1="6" x2="18" y2="18"></line>
|
|
</svg>
|
|
</button>
|
|
`;
|
|
|
|
// رویداد حذف تگ
|
|
const removeBtn = tagElement.querySelector('.tag-remove');
|
|
removeBtn.addEventListener('click', () => this.removeTag(tag.id));
|
|
|
|
this.selectedTagsContainer.appendChild(tagElement);
|
|
});
|
|
}
|
|
|
|
updateTagCount() {
|
|
if (this.tagCount) {
|
|
this.tagCount.textContent = `${this.selectedTags.length} تگ انتخاب شده`;
|
|
}
|
|
}
|
|
|
|
updateHiddenInput() {
|
|
// حذف input های قبلی
|
|
const existingInputs = document.querySelectorAll('input[name="question[tags][]"]');
|
|
existingInputs.forEach(input => input.remove());
|
|
|
|
// افزودن input های جدید
|
|
this.selectedTags.forEach(tag => {
|
|
const input = document.createElement('input');
|
|
input.type = 'hidden';
|
|
input.name = 'question[tags][]';
|
|
input.value = tag.id;
|
|
document.querySelector('form').appendChild(input);
|
|
});
|
|
}
|
|
|
|
filterSuggestions() {
|
|
const searchTerm = this.tagInput.value.toLowerCase();
|
|
|
|
this.tagSuggestions.forEach(suggestion => {
|
|
const tagName = suggestion.dataset.tagName.toLowerCase();
|
|
if (tagName.includes(searchTerm)) {
|
|
suggestion.style.display = 'inline-flex';
|
|
} else {
|
|
suggestion.style.display = 'none';
|
|
}
|
|
});
|
|
}
|
|
|
|
showAllTags() {
|
|
this.tagSuggestions.forEach(suggestion => {
|
|
suggestion.style.display = 'inline-flex';
|
|
});
|
|
this.tagInput.value = '';
|
|
}
|
|
|
|
validateTags() {
|
|
if (this.selectedTags.length < this.minTags) {
|
|
// نمایش پیام خطای زیبا
|
|
this.showValidationError(`حداقل ${this.minTags} تگ باید انتخاب کنید`);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
showValidationError(message) {
|
|
// حذف پیام خطای قبلی اگر وجود دارد
|
|
const existingError = document.querySelector('.tag-validation-error');
|
|
if (existingError) {
|
|
existingError.remove();
|
|
}
|
|
|
|
// ایجاد پیام خطای زیبا
|
|
const errorDiv = document.createElement('div');
|
|
errorDiv.className = 'tag-validation-error mt-4 p-4 bg-red-50 border border-red-200 rounded-lg';
|
|
errorDiv.innerHTML = `
|
|
<div class="flex items-center">
|
|
<svg class="w-5 h-5 text-red-500 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
|
</svg>
|
|
<span class="text-red-700 font-medium">${message}</span>
|
|
</div>
|
|
`;
|
|
|
|
// اضافه کردن پیام خطا به فرم
|
|
const form = document.querySelector('form');
|
|
if (form) {
|
|
const submitButton = form.querySelector('button[type="submit"]');
|
|
if (submitButton) {
|
|
submitButton.parentNode.insertBefore(errorDiv, submitButton);
|
|
}
|
|
}
|
|
|
|
// حذف خودکار پیام خطا بعد از 5 ثانیه
|
|
setTimeout(() => {
|
|
if (errorDiv.parentNode) {
|
|
errorDiv.remove();
|
|
}
|
|
}, 5000);
|
|
}
|
|
}
|
|
}
|
|
|
|
// ادیتور متن
|
|
if (typeof window.QuestionFormClasses.TextEditor === 'undefined') {
|
|
window.QuestionFormClasses.TextEditor = class TextEditor {
|
|
constructor() {
|
|
this.textarea = document.querySelector('textarea[name="question[content]"]');
|
|
}
|
|
|
|
formatText(command) {
|
|
if (!this.textarea) return;
|
|
|
|
const start = this.textarea.selectionStart;
|
|
const end = this.textarea.selectionEnd;
|
|
const selectedText = this.textarea.value.substring(start, end);
|
|
|
|
let formattedText = '';
|
|
|
|
switch(command) {
|
|
case 'bold':
|
|
formattedText = `**${selectedText}**`;
|
|
break;
|
|
case 'italic':
|
|
formattedText = `*${selectedText}*`;
|
|
break;
|
|
case 'code':
|
|
formattedText = `\`${selectedText}\``;
|
|
break;
|
|
}
|
|
|
|
this.textarea.value = this.textarea.value.substring(0, start) + formattedText + this.textarea.value.substring(end);
|
|
this.textarea.focus();
|
|
this.textarea.setSelectionRange(start + formattedText.length, start + formattedText.length);
|
|
}
|
|
|
|
insertList() {
|
|
if (!this.textarea) return;
|
|
|
|
const start = this.textarea.selectionStart;
|
|
const end = this.textarea.selectionEnd;
|
|
const selectedText = this.textarea.value.substring(start, end);
|
|
|
|
const listText = selectedText.split('\n').map(line => `- ${line}`).join('\n');
|
|
this.textarea.value = this.textarea.value.substring(0, start) + listText + this.textarea.value.substring(end);
|
|
this.textarea.focus();
|
|
}
|
|
}
|
|
}
|
|
|
|
// مدیریت فایلها
|
|
if (typeof window.QuestionFormClasses.FileManager === 'undefined') {
|
|
window.QuestionFormClasses.FileManager = class FileManager {
|
|
constructor() {
|
|
this.maxFiles = 3;
|
|
this.maxFileSize = 4 * 1024 * 1024; // 4MB
|
|
this.allowedTypes = [
|
|
'image/jpeg', 'image/png', 'image/gif',
|
|
'application/pdf',
|
|
'application/msword',
|
|
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
'application/vnd.ms-excel',
|
|
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
'application/vnd.ms-powerpoint',
|
|
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
|
'text/plain'
|
|
];
|
|
this.selectedFiles = [];
|
|
this.init();
|
|
}
|
|
|
|
init() {
|
|
this.fileInput = document.getElementById('file-input');
|
|
this.selectedFilesDiv = document.getElementById('selected-files');
|
|
this.fileListDiv = document.getElementById('file-list');
|
|
|
|
if (!this.fileInput) return;
|
|
|
|
this.bindEvents();
|
|
}
|
|
|
|
bindEvents() {
|
|
this.fileInput.addEventListener('change', (e) => this.handleFileSelect(e));
|
|
|
|
// Drag and drop
|
|
const dropZone = this.fileInput.closest('.border-dashed');
|
|
if (dropZone) {
|
|
dropZone.addEventListener('dragover', (e) => this.handleDragOver(e));
|
|
dropZone.addEventListener('drop', (e) => this.handleDrop(e));
|
|
dropZone.addEventListener('dragleave', (e) => this.handleDragLeave(e));
|
|
}
|
|
}
|
|
|
|
handleFileSelect(event) {
|
|
const files = Array.from(event.target.files);
|
|
this.processFiles(files);
|
|
}
|
|
|
|
handleDragOver(event) {
|
|
event.preventDefault();
|
|
event.currentTarget.classList.add('bg-blue-50', 'border-blue-400');
|
|
}
|
|
|
|
handleDragLeave(event) {
|
|
event.preventDefault();
|
|
event.currentTarget.classList.remove('bg-blue-50', 'border-blue-400');
|
|
}
|
|
|
|
handleDrop(event) {
|
|
event.preventDefault();
|
|
event.currentTarget.classList.remove('bg-blue-50', 'border-blue-400');
|
|
|
|
const files = Array.from(event.dataTransfer.files);
|
|
this.processFiles(files);
|
|
}
|
|
|
|
processFiles(files) {
|
|
files.forEach(file => {
|
|
if (this.validateFile(file)) {
|
|
this.addFile(file);
|
|
}
|
|
});
|
|
this.updateFileInput();
|
|
}
|
|
|
|
validateFile(file) {
|
|
// بررسی تعداد فایلها
|
|
if (this.selectedFiles.length >= this.maxFiles) {
|
|
if (window.notification) {
|
|
window.notification.warning(`حداکثر ${this.maxFiles} فایل میتوانید انتخاب کنید`);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// بررسی نوع فایل
|
|
if (!this.allowedTypes.includes(file.type)) {
|
|
if (window.notification) {
|
|
window.notification.error('فرمت فایل مجاز نیست');
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// بررسی حجم فایل
|
|
if (file.size > this.maxFileSize) {
|
|
if (window.notification) {
|
|
window.notification.error('حجم فایل نمیتواند بیش از 4 مگابایت باشد');
|
|
}
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
addFile(file) {
|
|
const fileId = Date.now() + Math.random();
|
|
this.selectedFiles.push({
|
|
id: fileId,
|
|
file: file,
|
|
name: file.name,
|
|
size: file.size,
|
|
type: file.type
|
|
});
|
|
|
|
this.renderFiles();
|
|
}
|
|
|
|
removeFile(fileId) {
|
|
this.selectedFiles = this.selectedFiles.filter(f => f.id !== fileId);
|
|
this.renderFiles();
|
|
this.updateFileInput();
|
|
}
|
|
|
|
renderFiles() {
|
|
if (this.selectedFiles.length === 0) {
|
|
this.selectedFilesDiv.classList.add('hidden');
|
|
return;
|
|
}
|
|
|
|
this.selectedFilesDiv.classList.remove('hidden');
|
|
this.fileListDiv.innerHTML = '';
|
|
|
|
this.selectedFiles.forEach(fileData => {
|
|
const fileElement = document.createElement('div');
|
|
fileElement.className = 'flex items-center justify-between p-3 bg-white rounded-lg border border-gray-200';
|
|
fileElement.innerHTML = `
|
|
<div class="flex items-center space-x-3 space-x-reverse">
|
|
<div class="flex-shrink-0">
|
|
${this.getFileIcon(fileData.type)}
|
|
</div>
|
|
<div class="flex-1 min-w-0">
|
|
<p class="text-sm font-medium text-gray-900 truncate">${fileData.name}</p>
|
|
<p class="text-xs text-gray-500">${this.formatFileSize(fileData.size)}</p>
|
|
</div>
|
|
</div>
|
|
<button type="button"
|
|
class="flex-shrink-0 text-red-600 hover:text-red-800 transition-colors duration-200"
|
|
onclick="fileManager.removeFile(${fileData.id})">
|
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<line x1="18" y1="6" x2="6" y2="18"></line>
|
|
<line x1="6" y1="6" x2="18" y2="18"></line>
|
|
</svg>
|
|
</button>
|
|
`;
|
|
this.fileListDiv.appendChild(fileElement);
|
|
});
|
|
}
|
|
|
|
getFileIcon(type) {
|
|
if (type.startsWith('image/')) {
|
|
return '<svg class="w-6 h-6 text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><circle cx="8.5" cy="8.5" r="1.5"></circle><polyline points="21,15 16,10 5,21"></polyline></svg>';
|
|
} else if (type === 'application/pdf') {
|
|
return '<svg class="w-6 h-6 text-red-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z"></path></svg>';
|
|
} else if (type.includes('word') || type.includes('document')) {
|
|
return '<svg class="w-6 h-6 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z"></path></svg>';
|
|
} else {
|
|
return '<svg class="w-6 h-6 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z"></path></svg>';
|
|
}
|
|
}
|
|
|
|
formatFileSize(bytes) {
|
|
if (bytes === 0) return '0 Bytes';
|
|
const k = 1024;
|
|
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
}
|
|
|
|
updateFileInput() {
|
|
// ایجاد DataTransfer object جدید
|
|
const dt = new DataTransfer();
|
|
this.selectedFiles.forEach(fileData => {
|
|
dt.items.add(fileData.file);
|
|
});
|
|
this.fileInput.files = dt.files;
|
|
}
|
|
}
|
|
}
|
|
|
|
// متغیرهای سراسری - استفاده از window object
|
|
if (!window.questionFormManager) {
|
|
window.questionFormManager = {
|
|
tagManager: null,
|
|
textEditor: null,
|
|
fileManager: null,
|
|
initialized: false
|
|
};
|
|
}
|
|
|
|
// توابع سراسری برای HTML
|
|
window.formatText = function(command) {
|
|
if (window.questionFormManager.textEditor) {
|
|
window.questionFormManager.textEditor.formatText(command);
|
|
}
|
|
};
|
|
|
|
window.insertList = function() {
|
|
if (window.questionFormManager.textEditor) {
|
|
window.questionFormManager.textEditor.insertList();
|
|
}
|
|
};
|
|
|
|
// مقداردهی اولیه
|
|
function initializeQuestionForm() {
|
|
if (typeof window.notification === 'undefined') {
|
|
setTimeout(initializeQuestionForm, 100);
|
|
return;
|
|
}
|
|
|
|
// جلوگیری از مقداردهی مجدد
|
|
if (window.questionFormManager.initialized) {
|
|
return;
|
|
}
|
|
|
|
// ایجاد instance های جدید
|
|
if (typeof window.QuestionFormClasses.TagManager !== 'undefined') {
|
|
window.questionFormManager.tagManager = new window.QuestionFormClasses.TagManager();
|
|
}
|
|
if (typeof window.QuestionFormClasses.TextEditor !== 'undefined') {
|
|
window.questionFormManager.textEditor = new window.QuestionFormClasses.TextEditor();
|
|
}
|
|
if (typeof window.QuestionFormClasses.FileManager !== 'undefined') {
|
|
window.questionFormManager.fileManager = new window.QuestionFormClasses.FileManager();
|
|
}
|
|
|
|
// اعتبارسنجی فرم
|
|
const form = document.querySelector('form');
|
|
if (form) {
|
|
// حذف event listener قبلی اگر وجود دارد
|
|
form.removeEventListener('submit', handleFormSubmit);
|
|
form.addEventListener('submit', handleFormSubmit, false);
|
|
|
|
// اطمینان از اینکه form دارای data-turbo="false" است
|
|
form.setAttribute('data-turbo', 'false');
|
|
}
|
|
|
|
window.questionFormManager.initialized = true;
|
|
}
|
|
|
|
function handleFormSubmit(e) {
|
|
// اطمینان از اینکه تگها به فرم اضافه شدهاند
|
|
if (window.questionFormManager.tagManager) {
|
|
window.questionFormManager.tagManager.updateHiddenInput();
|
|
|
|
// اعتبارسنجی تگها
|
|
if (!window.questionFormManager.tagManager.validateTags()) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// غیرفعال کردن Turbo برای این فرم
|
|
const form = e.target;
|
|
if (form) {
|
|
form.setAttribute('data-turbo', 'false');
|
|
}
|
|
}
|
|
|
|
// اجرا در بارگذاری صفحه
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Reset initialization state
|
|
window.questionFormManager.initialized = false;
|
|
initializeQuestionForm();
|
|
});
|
|
|
|
document.addEventListener('turbo:load', function() {
|
|
// Reset initialization state for Turbo navigation
|
|
window.questionFormManager.initialized = false;
|
|
initializeQuestionForm();
|
|
});
|
|
</script>
|
|
{% endblock %}
|