Merge branch '16-popraviti-validaciju' into 'master'
dodata provera za email i orgnaziation name Closes #16 See merge request kbr4/riskletpy!19
This commit was merged in pull request #68.
This commit is contained in:
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 5.1.3 on 2025-05-06 16:56
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('core', '0013_alter_organization_change_rate_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='organization',
|
||||||
|
name='customer_base',
|
||||||
|
field=models.CharField(blank=True, help_text='How would you characterize your customer base distribution?', max_length=255, null=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -57,7 +57,7 @@ class Organization(models.Model):
|
|||||||
third_party_vendor_access = models.CharField(max_length=20, help_text="How many third-party vendors have access to your systems?")
|
third_party_vendor_access = models.CharField(max_length=20, help_text="How many third-party vendors have access to your systems?")
|
||||||
internal_software_development = models.CharField(max_length=20, help_text="What is the extent of your internal software development activities?")
|
internal_software_development = models.CharField(max_length=20, help_text="What is the extent of your internal software development activities?")
|
||||||
geographic_scope = models.CharField(max_length=20, null=True, blank=True, help_text="What is your organization's geographic operational scope?")
|
geographic_scope = models.CharField(max_length=20, null=True, blank=True, help_text="What is your organization's geographic operational scope?")
|
||||||
customer_base = models.CharField(max_length=20, null=True, blank=True, help_text="How would you characterize your customer base distribution?")
|
customer_base = models.CharField(max_length=255, null=True, blank=True, help_text="How would you characterize your customer base distribution?")
|
||||||
customer_type = models.CharField(max_length=20, null=True, blank=True, help_text="What is your primary customer type?")
|
customer_type = models.CharField(max_length=20, null=True, blank=True, help_text="What is your primary customer type?")
|
||||||
product_portfolio = models.CharField(max_length=20, null=True, blank=True, help_text="How diversified is your product/service portfolio?")
|
product_portfolio = models.CharField(max_length=20, null=True, blank=True, help_text="How diversified is your product/service portfolio?")
|
||||||
supplier_base = models.CharField(max_length=20, null=True, blank=True, help_text="What is your supplier base structure?")
|
supplier_base = models.CharField(max_length=20, null=True, blank=True, help_text="What is your supplier base structure?")
|
||||||
|
|||||||
@@ -73,13 +73,13 @@ function setUpNavigation() {
|
|||||||
// check if next button should be enabled on every input, checkbox and radio button bellow class of .question change
|
// check if next button should be enabled on every input, checkbox and radio button bellow class of .question change
|
||||||
const inputs = document.querySelectorAll('.question input, .question select, .question textarea');
|
const inputs = document.querySelectorAll('.question input, .question select, .question textarea');
|
||||||
inputs.forEach(input => {
|
inputs.forEach(input => {
|
||||||
input.addEventListener('change', setNextButtonAvailability);
|
input.addEventListener('change',()=> setNextButtonAvailability());
|
||||||
|
input.addEventListener('blur', () => setNextButtonAvailability());
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function setNextButtonAvailability() {
|
async function setNextButtonAvailability() {
|
||||||
console.log('Setting next button availability');
|
console.log('Setting next button availability');
|
||||||
// check if current question is answered
|
// check if current question is answered
|
||||||
// and then enable the next button, disable it otherwise
|
// and then enable the next button, disable it otherwise
|
||||||
@@ -91,8 +91,14 @@ function setNextButtonAvailability() {
|
|||||||
if (document.currentQuestion === 0) {
|
if (document.currentQuestion === 0) {
|
||||||
const name = document.getElementById('name');
|
const name = document.getElementById('name');
|
||||||
const email = document.getElementById('email');
|
const email = document.getElementById('email');
|
||||||
|
const errorDiv = document.getElementById('org-email-error');
|
||||||
|
|
||||||
if (name && email && name.value.trim() && email.value.trim()) {
|
if (name && email && name.value.trim() && email.value.trim()) {
|
||||||
nextEnabled = true;
|
nextEnabled = await validateFormFields(nextButton, errorDiv);
|
||||||
|
}else{
|
||||||
|
nextButton.disabled = true;
|
||||||
|
if (errorDiv) errorDiv.textContent = '';
|
||||||
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const inputs = currentQuestion.querySelectorAll('input, select, textarea');
|
const inputs = currentQuestion.querySelectorAll('input, select, textarea');
|
||||||
@@ -181,4 +187,23 @@ function setButtonVisiblity(buttonId, visible) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function validateFormFields(nextBtn, errorDiv) {
|
||||||
|
const nameInput = document.getElementById('name');
|
||||||
|
const emailInput = document.getElementById('email');
|
||||||
|
const name = nameInput.value.trim();
|
||||||
|
const email = emailInput.value.trim();
|
||||||
|
|
||||||
|
const resp = await fetch(`/api/validate_form_fields/?name=${name}&email=${email}`);
|
||||||
|
const data = await resp.json();
|
||||||
|
if (data.errors && (data.errors.name || data.errors.email)) {
|
||||||
|
errorDiv.textContent = (data.errors.name || '') + ' ' + (data.errors.email || '');
|
||||||
|
nextBtn.disabled = true;
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
errorDiv.textContent = '';
|
||||||
|
nextBtn.disabled = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,16 @@
|
|||||||
<form method="post">
|
<form method="post">
|
||||||
{% if form.errors %}
|
{% if form.errors %}
|
||||||
<div class="alert alert-danger">
|
<div class="alert alert-danger">
|
||||||
{{ form.errors }}
|
<ul class="mb-0">
|
||||||
|
{% for field in form %}
|
||||||
|
{% for error in field.errors %}
|
||||||
|
<li><strong>{{ field.label }}:</strong> {{ error }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
{% for error in form.non_field_errors %}
|
||||||
|
<li>{{ error }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
@@ -27,6 +36,7 @@
|
|||||||
<small class="form-text text-muted py-3">
|
<small class="form-text text-muted py-3">
|
||||||
Enter the organization name and your email address. Both fields are required to continue.
|
Enter the organization name and your email address. Both fields are required to continue.
|
||||||
</small>
|
</small>
|
||||||
|
<div id="org-email-error" class="text-danger py-2"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Employee Headcount -->
|
<!-- Employee Headcount -->
|
||||||
|
|||||||
@@ -13,4 +13,5 @@ urlpatterns = [
|
|||||||
path('preview/<str:name>/', v.template_preview, name='template_preview'),
|
path('preview/<str:name>/', v.template_preview, name='template_preview'),
|
||||||
path("payment/", v.payment_page, name="payment_page"),
|
path("payment/", v.payment_page, name="payment_page"),
|
||||||
path('pdf/<uuid:document_id>/', v.pdf_view, name='pdf_view'),
|
path('pdf/<uuid:document_id>/', v.pdf_view, name='pdf_view'),
|
||||||
|
path('api/validate_form_fields/', v.validate_form_fields, name='validate_form_fields'),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -3,14 +3,17 @@ import yaml
|
|||||||
|
|
||||||
from django.shortcuts import render, redirect , get_object_or_404
|
from django.shortcuts import render, redirect , get_object_or_404
|
||||||
from .forms import OrganizationForm
|
from .forms import OrganizationForm
|
||||||
from .models import Organization,Document, DocumentTemplate,DocumentRiskControl,Risk
|
from .models import Organization,Document, DocumentTemplate
|
||||||
from backend.accounts.utils import send_confirmation_email, send_document_email
|
from backend.accounts.utils import send_confirmation_email, send_document_email
|
||||||
from django.contrib.admin.views.decorators import staff_member_required
|
from django.contrib.admin.views.decorators import staff_member_required
|
||||||
from .utils import generate_pdf, map_weight_to_impact_likelihood, calculate_aggregate_weight, calculate_aggregate_likelihood, generate_risk_graph
|
from .utils import generate_pdf, generate_risk_graph
|
||||||
from .tables import risk_matrix_table ,get_risk_table
|
from .tables import risk_matrix_table ,get_risk_table
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
site_domain = settings.SITE_DOMAIN
|
site_domain = settings.SITE_DOMAIN
|
||||||
from .processors import render_template
|
from .processors import render_template
|
||||||
|
from django.http import JsonResponse
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
from django.core.validators import validate_email
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -45,6 +48,25 @@ def signup(request):
|
|||||||
return render(request, 'signup.html', {'form': form})
|
return render(request, 'signup.html', {'form': form})
|
||||||
|
|
||||||
|
|
||||||
|
def validate_form_fields(request):
|
||||||
|
name = request.GET.get('name', '').strip()
|
||||||
|
email = request.GET.get('email', '').strip()
|
||||||
|
errors = {}
|
||||||
|
|
||||||
|
if name and Organization.objects.filter(name__iexact=name).exists():
|
||||||
|
errors['name'] = 'Organization with this name already exists.'
|
||||||
|
if email:
|
||||||
|
try:
|
||||||
|
validate_email(email)
|
||||||
|
except ValidationError:
|
||||||
|
errors['email'] = 'Please enter a valid email address.'
|
||||||
|
else:
|
||||||
|
if Organization.objects.filter(email__iexact=email).exists():
|
||||||
|
errors['email'] = 'This email is already registered.'
|
||||||
|
|
||||||
|
return JsonResponse({'errors': errors})
|
||||||
|
|
||||||
|
|
||||||
def thankyou(request):
|
def thankyou(request):
|
||||||
return render(request, 'thankyou.html')
|
return render(request, 'thankyou.html')
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user