[FIX] RECRUITMENT: #811
This commit is contained in:
@@ -532,19 +532,23 @@ class ApplicationForm(RegistrationForm):
|
||||
self.fields["profile"].required = False
|
||||
|
||||
def clean(self, *args, **kwargs):
|
||||
name = self.cleaned_data["name"]
|
||||
name = self.cleaned_data.get("name")
|
||||
request = getattr(_thread_locals, "request", None)
|
||||
|
||||
errors = {}
|
||||
profile = self.cleaned_data["profile"]
|
||||
resume = self.cleaned_data["resume"]
|
||||
recruitment: Recruitment = self.cleaned_data["recruitment_id"]
|
||||
if not resume and not recruitment.optional_resume:
|
||||
errors["resume"] = _("This field is required")
|
||||
if not profile and not recruitment.optional_profile_image:
|
||||
errors["profile"] = _("This field is required")
|
||||
profile = self.cleaned_data.get("profile")
|
||||
resume = self.cleaned_data.get("resume")
|
||||
recruitment: Recruitment = self.cleaned_data.get("recruitment_id")
|
||||
|
||||
if recruitment:
|
||||
if not resume and not recruitment.optional_resume:
|
||||
errors["resume"] = _("This field is required")
|
||||
if not profile and not recruitment.optional_profile_image:
|
||||
errors["profile"] = _("This field is required")
|
||||
|
||||
if errors:
|
||||
raise ValidationError(errors)
|
||||
|
||||
if (
|
||||
not profile
|
||||
and request
|
||||
@@ -552,6 +556,7 @@ class ApplicationForm(RegistrationForm):
|
||||
):
|
||||
profile_pic_url = f"https://ui-avatars.com/api/?name={name}"
|
||||
self.cleaned_data["profile"] = profile_pic_url
|
||||
|
||||
super().clean()
|
||||
return self.cleaned_data
|
||||
|
||||
|
||||
@@ -1,490 +1,365 @@
|
||||
{% extends 'candidate/application_form_component.html' %} {% block content %}
|
||||
{% load static %} {% load i18n %} {{form.load}}
|
||||
{% load static %} {% load i18n %} {{ form.load }}
|
||||
<div id="main">
|
||||
<div class="oh-wrapper mt-5">
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-6 col-lg-6">
|
||||
<div class="oh-onboarding-card oh-onboarding-card--top-bar w-100">
|
||||
<div
|
||||
class="oh-onboarding-card__container oh-onboarding-card__container--wide"
|
||||
>
|
||||
<form action="" method="post" enctype="multipart/form-data">
|
||||
{% if messages %}
|
||||
<div class="oh-alert-container">
|
||||
{% for message in messages %}
|
||||
<div class="oh-alert oh-alert--animated {{message.tags}}">
|
||||
{{ message }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %} {% csrf_token %}
|
||||
<div class="row">
|
||||
<div
|
||||
class="oh-modal"
|
||||
id="uploadPhotoModal"
|
||||
role="dialog"
|
||||
aria-labelledby="uploadPhotoModal"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div class="oh-modal__dialog">
|
||||
<div class="oh-modal__dialog-header">
|
||||
<span
|
||||
class="oh-modal__dialog-title"
|
||||
id="uploadPhotoModalLabel"
|
||||
>Upload Photo</span
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
onclick="event.stopPropagation()"
|
||||
class="oh-modal__close"
|
||||
aria-label="Close"
|
||||
>
|
||||
<ion-icon name="close-outline"></ion-icon>
|
||||
</button>
|
||||
<div class="oh-wrapper mt-5">
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-6 col-lg-6">
|
||||
<div class="oh-onboarding-card oh-onboarding-card--top-bar w-100">
|
||||
<div class="oh-onboarding-card__container oh-onboarding-card__container--wide">
|
||||
<form action="" method="post" enctype="multipart/form-data">
|
||||
{% if messages %}
|
||||
<div class="oh-alert-container">
|
||||
{% for message in messages %}
|
||||
<div class="oh-alert oh-alert--animated {{ message.tags }}">
|
||||
{{ message }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %} {% csrf_token %}
|
||||
<div class="row">
|
||||
<div class="oh-modal" id="uploadPhotoModal" role="dialog"
|
||||
aria-labelledby="uploadPhotoModal" aria-hidden="true">
|
||||
<div class="oh-modal__dialog">
|
||||
<div class="oh-modal__dialog-header">
|
||||
<span class="oh-modal__dialog-title" id="uploadPhotoModalLabel">
|
||||
Upload Photo
|
||||
</span>
|
||||
<button type="button" onclick="event.stopPropagation()"
|
||||
class="oh-modal__close" aria-label="Close">
|
||||
<ion-icon name="close-outline"></ion-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oh-modal__dialog-body">
|
||||
<div class="oh-profile-section__image-container">
|
||||
<div class="oh-profile-section__modal-avatar">
|
||||
<img src="{% static " /images/ui/user.jpg" %}"
|
||||
class="oh-profile-section__modal-image oh-upload-photo"
|
||||
alt="User Photo" />
|
||||
</div>
|
||||
<input type="file" id="photo" name="profile"
|
||||
class="oh-input oh-input--file oh-input--file-sm mt-4 oh-upload-input"
|
||||
accept=".jpg, .jpeg, .png" data-target=".oh-upload-photo" />
|
||||
<div
|
||||
class="d-flex justify-content-between w-100 align-items-center mt-4">
|
||||
<button class="oh-btn oh-btn--light-danger mr-1 oh-remove-image"
|
||||
data-target=".oh-upload-photo">
|
||||
<ion-icon class="me-1" name="trash-outline"></ion-icon>
|
||||
{% trans "Delete image" %}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-2 col-lg-2">
|
||||
<label class="oh-label {% if not recruitment.optional_profile_image %}required-star{% endif %}" for="photo">{% trans "Profile" %} </label>
|
||||
<div class="oh-profile-section__edit-photo me-4 mb-3" data-toggle="oh-modal-toggle"
|
||||
data-target="#uploadPhotoModal">
|
||||
<img src="{% static '/images/ui/user.jpg' %}" class="oh-profile-section__avatar oh-upload-photo" alt="" />
|
||||
</div>
|
||||
</div>
|
||||
{{ form.profile.errors }}
|
||||
<div class="col-sm-12 col-md-12 col-lg-12">
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label required-star" for="name">{% trans "Name" %}</label>
|
||||
<input type="text" id="name" name="name" required class="oh-input w-100"
|
||||
placeholder="e.g. Jane Doe" value="{{ form.name.value|default:'' }}"/>
|
||||
{{ form.name.errrors }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if not request.GET.recruitmentId %}
|
||||
<div class="col-sm-12 col-md-6 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label required-star" for="recuitment"> {% trans "Open Recruitment" %}
|
||||
</label>
|
||||
{{ form.recruitment_id }} {{ form.recruitment_id.errors }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-6 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label required-star" for="recuitment">{% trans "Choose Open Position" %}
|
||||
</label>
|
||||
{{ form.job_position_id }} {{ form.job_position_id.errors }}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<input type="text" name="recruitment_id" hidden value="{{ recruitment.id }}" />
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label" for="recuitment">{% trans "Choose Job Position" %}
|
||||
</label>
|
||||
|
||||
<select name="job_position_id" class="oh-select oh-select2 w-100"
|
||||
style="height: 50px">
|
||||
{% for job in recruitment.open_positions.all %}
|
||||
<option value="{{ job.id }}">{{ job.job_position }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="col-sm-12 col-md-6 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label required-star" for="email">{% trans "Email" %}</label>
|
||||
<input type="email" id="email" name="email" class="oh-input w-100" required
|
||||
placeholder="e.g. janedoe@example.com" value="{{ form.email.value|default:'' }}" />
|
||||
</div>
|
||||
{{ form.email.errors }}
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 col-md-6 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label required-star" for="phone">{% trans "Phone" %}</label>
|
||||
<input type="text" id="phone" class="oh-input w-100" name="mobile"
|
||||
placeholder="e.g. +1 245 999 999" value="{{ form.mobile.value|default:'' }}" />
|
||||
{{ form.mobile.errors }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-6 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label" for="portfolio">{% trans "Portfolio" %}</label>
|
||||
<input type="text" id="portfolio" name="portfolio" class="oh-input w-100"
|
||||
placeholder="e.g. https://www.linktoportfolio.com/" value="{{ form.portfolio.value|default:'' }}"/>
|
||||
{{ form.portfolio.errors }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 col-md-12 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label {% if not recruitment.optional_resume %}required-star{% endif %}" for="resume">{% trans "Resume" %}</label>
|
||||
{% if resume.file %}
|
||||
<p>Currently: <a href="{{ resume.file.url }}" target="_blank">{{ resume.file.name }}</a></p>
|
||||
<p>Change: </p>
|
||||
<input type="hidden" id="matching_resume" data-value="{{ resume.file.url }}"
|
||||
data-id="{{ resume.id }}" name="initial_resume" value="{{ resume.file.url }}">
|
||||
{% endif %}
|
||||
<input type="file" id="id_resume" name="resume" accept=".pdf"
|
||||
class="oh-input w-100 px-0" />
|
||||
{{ form.resume.errors }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-6 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label required-star" for="gender">{% trans "Gender" %}</label>
|
||||
{{ form.gender }} {{ form.gender.errros }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-6 col-lg-12">
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label required-star" for="address">{% trans "Address" %}</label>
|
||||
<textarea id="address" name="address" required class="oh-input oh-input--textarea w-100">{{ form.address.value|default:'' }}</textarea>
|
||||
{{ form.address.errors }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 col-md-6 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label required-star" for="id_country">{% trans "Country" %}</label>
|
||||
<select name="country" id="id_country" required
|
||||
class="oh-select oh-select-2" data-selected="{{ form.country.value|default:'' }}"></select>
|
||||
{{ form.country.errors }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 col-md-6 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label required-star" for="id_state">{% trans "State" %}</label>
|
||||
<select name="state" required id="id_state"
|
||||
class="oh-select oh-select-2" data-selected="{{ form.state.value|default:'' }}"></select>
|
||||
{{ form.state.errors }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 col-md-6 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label required-star" for="city">{% trans "City" %}</label>
|
||||
<input type="text" id="city" required name="city" class="oh-input w-100"
|
||||
placeholder="e.g. Kerala" value="{{ form.city.value|default:'' }}"/>
|
||||
{{ form.city.errors }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 col-md-6 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label required-star" for="zip">{% trans "Zip Code" %}</label>
|
||||
<input type="text" id="zip" required name="zip" class="oh-input w-100"
|
||||
placeholder="e.g. 611 293" value="{{ form.zip.value|default:'' }}"/>
|
||||
{{ form.zip.errors }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 col-md-12 col-lg-12">
|
||||
<button type="submit" class="oh-btn mt-4 oh-btn--secondary w-100 mb-4"
|
||||
onclick="validateForm(event)">
|
||||
<ion-icon name="checkmark-outline" class="me-2"></ion-icon>
|
||||
{% trans "Apply" %}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 col-md-12 col-lg-12">
|
||||
<p class="small text-muted text-center">
|
||||
© {% now 'Y' %} {{ white_label_company_name }}. All rights resevered.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="oh-modal__dialog-body">
|
||||
<div class="oh-profile-section__image-container">
|
||||
<div class="oh-profile-section__modal-avatar">
|
||||
<img
|
||||
src="{% static "/images/ui/user.jpg" %}"
|
||||
class="oh-profile-section__modal-image oh-upload-photo"
|
||||
alt="User Photo"
|
||||
/>
|
||||
</div>
|
||||
<input
|
||||
type="file"
|
||||
id="photo"
|
||||
name="profile"
|
||||
class="oh-input oh-input--file oh-input--file-sm mt-4 oh-upload-input"
|
||||
accept=".jpg, .jpeg, .png"
|
||||
data-target=".oh-upload-photo"
|
||||
/>
|
||||
<div
|
||||
class="d-flex justify-content-between w-100 align-items-center mt-4"
|
||||
>
|
||||
<button
|
||||
class="oh-btn oh-btn--light-danger mr-1 oh-remove-image"
|
||||
data-target=".oh-upload-photo"
|
||||
>
|
||||
<ion-icon
|
||||
class="me-1"
|
||||
name="trash-outline"
|
||||
></ion-icon
|
||||
>{% trans "Delete image" %}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if resume %}
|
||||
<div class="col-12 col-md-6 col-lg-6 sticky">
|
||||
<iframe style="width: 100%;height:90vh" height="100" src="{{ resume.file.url }}"
|
||||
frameborder="0"></iframe>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="col-12 col-md-6 col-lg-6">
|
||||
<div class="oh-onboarding-preview oh-onboarding-card--top-bar w-100">
|
||||
{{recruitment.description|safe}}
|
||||
<div class="oh-onboarding-preview__content" id="recruitmentInfoBody"
|
||||
style="border-bottom: solid rgba(128, 128, 128, 0.281) 1px"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-2 col-lg-2">
|
||||
<div
|
||||
class="oh-profile-section__edit-photo me-4 mb-3"
|
||||
data-toggle="oh-modal-toggle"
|
||||
data-target="#uploadPhotoModal"
|
||||
>
|
||||
<img
|
||||
src="{% static "/images/ui/user.jpg" %}"
|
||||
class="oh-profile-section__avatar oh-upload-photo"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{{form.profile.errors}}
|
||||
{% comment %} <ul id="error-list" class="errorlist" style="display: none">
|
||||
<li>{% trans "Please select profile image" %}.</li>
|
||||
</ul> {% endcomment %}
|
||||
<div class="col-sm-12 col-md-12 col-lg-12">
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label required-star" for="name"
|
||||
>{% trans "Name" %}</label
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
id="name"
|
||||
name="name"
|
||||
required
|
||||
class="oh-input w-100"
|
||||
placeholder="e.g. Jane Doe"
|
||||
/>
|
||||
{{form.name.errrors}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if not request.GET.recruitmentId %}
|
||||
<div class="col-sm-12 col-md-6 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label required-star" for="recuitment"
|
||||
> {% trans "Open Recruitment" %}
|
||||
</label>
|
||||
{{form.recruitment_id}} {{form.recruitment_id.errors}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-6 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label required-star" for="recuitment"
|
||||
>{% trans "Choose Open Position" %}
|
||||
</label>
|
||||
{{form.job_position_id}} {{form.job_position_id.errors}}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<input
|
||||
type="text"
|
||||
name="recruitment_id"
|
||||
hidden
|
||||
value="{{recruitment.id}}"
|
||||
/>
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label" for="recuitment"
|
||||
>{% trans "Choose Job Position" %}
|
||||
</label>
|
||||
|
||||
<select
|
||||
name="job_position_id"
|
||||
class="oh-select oh-select2 w-100"
|
||||
style="height: 50px"
|
||||
>
|
||||
{% for job in recruitment.open_positions.all %}
|
||||
<option value="{{job.id}}">{{job.job_position}}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="col-sm-12 col-md-6 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label required-star" for="email"
|
||||
>{% trans "Email" %}</label
|
||||
>
|
||||
<input
|
||||
type="email"
|
||||
id="email"
|
||||
name="email"
|
||||
class="oh-input w-100"
|
||||
required
|
||||
placeholder="e.g. janedoe@example.com"
|
||||
/>
|
||||
</div>
|
||||
{{form.email.errors}}
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 col-md-6 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label required-star" for="phone"
|
||||
>{% trans "Phone" %}</label
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
id="phone"
|
||||
class="oh-input w-100"
|
||||
name="mobile"
|
||||
placeholder="e.g. +1 245 999 999"
|
||||
/>
|
||||
{{form.mobile.errors}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-6 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label" for="portfolio"
|
||||
>{% trans "Portfolio" %}</label
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
id="portfolio"
|
||||
name="portfolio"
|
||||
class="oh-input w-100"
|
||||
placeholder="e.g. https://www.linktoportfolio.com/"
|
||||
/>
|
||||
{{form.portfolio.errors}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 col-md-12 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label" for="resume"
|
||||
>{% trans "Resume" %}</label
|
||||
>
|
||||
{% if resume.file %}
|
||||
<p>Currently: <a href="{{ resume.file.url }}" target="_blank">{{ resume.file.name }}</a></p>
|
||||
<p>Change: </p>
|
||||
<input type="hidden" id="matching_resume" data-value = "{{ resume.file.url }}" data-id="{{resume.id}}" name="initial_resume" value="{{ resume.file.url }}">
|
||||
{% endif %}
|
||||
<input
|
||||
type="file"
|
||||
id="id_resume"
|
||||
name="resume"
|
||||
accept=".pdf"
|
||||
class="oh-input w-100 px-0"
|
||||
/>
|
||||
{{form.resume.errors}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-6 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label required-star" for="gender"
|
||||
>{% trans "Gender" %}</label
|
||||
>
|
||||
{{form.gender}} {{form.gender.errros}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-6 col-lg-12">
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label required-star" for="address"
|
||||
>{% trans "Address" %}</label
|
||||
>
|
||||
<textarea
|
||||
id="address"
|
||||
name="address"
|
||||
required
|
||||
class="oh-input oh-input--textarea w-100"
|
||||
></textarea>
|
||||
{{form.address.errors}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 col-md-6 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label required-star" for="id_country"
|
||||
>{% trans "Country" %}</label
|
||||
>
|
||||
<select
|
||||
name="country"
|
||||
id="id_country"
|
||||
required
|
||||
class="oh-select oh-select-2"
|
||||
></select>
|
||||
{{form.country.errors}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 col-md-6 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label required-star" for="id_state"
|
||||
>{% trans "State" %}</label
|
||||
>
|
||||
<select
|
||||
name="state"
|
||||
required
|
||||
id="id_state"
|
||||
class="oh-select oh-select-2"
|
||||
></select>
|
||||
{{form.state.errors}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 col-md-6 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label required-star" for="city"
|
||||
>{% trans "City" %}</label
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
id="city"
|
||||
required
|
||||
name="city"
|
||||
class="oh-input w-100"
|
||||
placeholder="e.g. Kerala"
|
||||
/>
|
||||
{{form.city.errors}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 col-md-6 col-lg-6">
|
||||
<div class="oh-input-group">
|
||||
<label class="oh-label required-star" for="zip"
|
||||
>{% trans "Zip Code" %}</label
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
id="zip"
|
||||
required
|
||||
name="zip"
|
||||
class="oh-input w-100"
|
||||
placeholder="e.g. 611 293"
|
||||
/>
|
||||
{{form.zip.errors}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 col-md-12 col-lg-12">
|
||||
<button
|
||||
type="submit"
|
||||
class="oh-btn mt-4 oh-btn--secondary w-100 mb-4"
|
||||
onclick="validateForm(event)"
|
||||
>
|
||||
<ion-icon name="checkmark-outline" class="me-2"></ion-icon>
|
||||
{% trans "Apply" %}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 col-md-12 col-lg-12">
|
||||
<p class="small text-muted text-center">
|
||||
© {% now 'Y' %} {{white_label_company_name}}. All rights resevered.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% if resume %}
|
||||
<div class="col-12 col-md-6 col-lg-6 sticky">
|
||||
<iframe style="width: 100%;height:90vh" height="100" src="{{ resume.file.url }}" frameborder="0"></iframe>
|
||||
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="col-12 col-md-6 col-lg-6">
|
||||
<div class="oh-onboarding-preview oh-onboarding-card--top-bar w-100">
|
||||
{{recruitment.description|safe}}
|
||||
<div
|
||||
class="oh-onboarding-preview__content"
|
||||
id="recruitmentInfoBody"
|
||||
style="border-bottom: solid rgba(128, 128, 128, 0.281) 1px"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
{% include 'country.js' %}
|
||||
{% include 'select2.js' %}
|
||||
var resume = "{{resume.file.url}}"
|
||||
{% if resume %}
|
||||
$("#resume").val(resume)
|
||||
{% endif %}
|
||||
var description = `{{form.instance.recruitment_id.description|safe}}`
|
||||
var formattedDescription = description.replace(/\n/g, "<br>");
|
||||
$("#recruitmentInfoBody").html(formattedDescription);
|
||||
|
||||
$('form label').each(function() {
|
||||
var text = $(this).text();
|
||||
if (text.startsWith('*')) {
|
||||
$(this).html('<strong>' + text + '</strong>');
|
||||
}
|
||||
});
|
||||
function validateForm(event) {
|
||||
var fileInput = document.getElementById("photo");
|
||||
var errorList = document.getElementById("error-list");
|
||||
{% if not perms.recruitment.add_candidate %}
|
||||
if (!fileInput.value) {
|
||||
errorList.scrollIntoView({ behavior: "smooth", block: "center" });
|
||||
errorList.style.display = "block"; // Show error message
|
||||
} else {
|
||||
errorList.style.display = "none"; // Hide error message
|
||||
}
|
||||
{% include 'country.js' %}
|
||||
{% include 'select2.js' %}
|
||||
var resume = "{{resume.file.url}}"
|
||||
{% if resume %}
|
||||
$("#resume").val(resume)
|
||||
{% endif %}
|
||||
}
|
||||
$(document).ready(function(){
|
||||
function getCookie(name) {
|
||||
let cookieValue = null;
|
||||
if (document.cookie && document.cookie !== "") {
|
||||
const cookies = document.cookie.split(";");
|
||||
for (let i = 0; i < cookies.length; i++) {
|
||||
const cookie = cookies[i].trim();
|
||||
// Does this cookie string begin with the name we want?
|
||||
if (cookie.substring(0, name.length + 1) === name + "=") {
|
||||
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
||||
break;
|
||||
}
|
||||
var description = `{{form.instance.recruitment_id.description|safe}}`
|
||||
var formattedDescription = description.replace(/\n/g, "<br>");
|
||||
$("#recruitmentInfoBody").html(formattedDescription);
|
||||
|
||||
$('form label').each(function () {
|
||||
var text = $(this).text();
|
||||
if (text.startsWith('*')) {
|
||||
$(this).html('<strong>' + text + '</strong>');
|
||||
}
|
||||
}
|
||||
return cookieValue;
|
||||
});
|
||||
function validateForm(event) {
|
||||
var fileInput = document.getElementById("photo");
|
||||
var errorList = document.getElementById("error-list");
|
||||
{% if not perms.recruitment.add_candidate %}
|
||||
if (!fileInput.value) {
|
||||
errorList.scrollIntoView({ behavior: "smooth", block: "center" });
|
||||
errorList.style.display = "block"; // Show error message
|
||||
} else {
|
||||
errorList.style.display = "none"; // Hide error message
|
||||
}
|
||||
{% endif %}
|
||||
}
|
||||
|
||||
function setIfEmpty(selector, value) {
|
||||
if ($(selector).val() === "" ){
|
||||
$(selector).val(value);
|
||||
$(selector).change();
|
||||
|
||||
$("[name=country]").parent().find("span").remove()
|
||||
$("[name=country]").select2()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$("#matching_resume").on("click", function(){
|
||||
var file = $(this).data("value");
|
||||
var resume_id = $(this).data("id");
|
||||
|
||||
$.ajax({
|
||||
url: "{% url 'matching-resume-completion' %}",
|
||||
type: 'GET',
|
||||
data: {
|
||||
"resume_id": resume_id,
|
||||
"file":file
|
||||
},
|
||||
success: function(response) {
|
||||
var full_name = response.full_name;
|
||||
var address = response.address;
|
||||
var country = response.country;
|
||||
var state = response.state;
|
||||
var phone = response.phone_number;
|
||||
var dob = response.dob;
|
||||
var email = response.email_id;
|
||||
var zip = response.zip;
|
||||
|
||||
setIfEmpty("[name='name']", full_name);
|
||||
setIfEmpty("[name='email']", email);
|
||||
setIfEmpty("[name='mobile']", phone);
|
||||
setIfEmpty("[name='address']", address);
|
||||
setIfEmpty("[name='country']", country);
|
||||
setIfEmpty("[name='state']", state);
|
||||
setIfEmpty("[name='zip']", zip);
|
||||
$("[name='dob']").val(dob);
|
||||
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error('File upload failed: ', status, error);
|
||||
$(document).ready(function () {
|
||||
function getCookie(name) {
|
||||
let cookieValue = null;
|
||||
if (document.cookie && document.cookie !== "") {
|
||||
const cookies = document.cookie.split(";");
|
||||
for (let i = 0; i < cookies.length; i++) {
|
||||
const cookie = cookies[i].trim();
|
||||
// Does this cookie string begin with the name we want?
|
||||
if (cookie.substring(0, name.length + 1) === name + "=") {
|
||||
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return cookieValue;
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
$("#matching_resume").click()
|
||||
function setIfEmpty(selector, value) {
|
||||
if ($(selector).val() === "") {
|
||||
$(selector).val(value);
|
||||
$(selector).change();
|
||||
|
||||
$("[name='resume']").on("change", function(){
|
||||
var formData = new FormData();
|
||||
var file = this.files[0];
|
||||
formData.append('resume', file);
|
||||
|
||||
$.ajax({
|
||||
url: "{% url 'resume-completion' %}",
|
||||
type: 'POST',
|
||||
data: formData,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie("csrftoken")
|
||||
},
|
||||
success: function(response) {
|
||||
|
||||
var full_name = response.full_name;
|
||||
var address = response.address;
|
||||
var country = response.country;
|
||||
var state = response.state;
|
||||
var phone = response.phone_number;
|
||||
var dob = response.dob;
|
||||
var email = response.email_id;
|
||||
var zip = response.zip;
|
||||
|
||||
setIfEmpty("[name='name']", full_name);
|
||||
setIfEmpty("[name='email']", email);
|
||||
setIfEmpty("[name='mobile']", phone);
|
||||
setIfEmpty("[name='address']", address);
|
||||
setIfEmpty("[name='country']", country);
|
||||
setIfEmpty("[name='state']", state);
|
||||
setIfEmpty("[name='zip']", zip);
|
||||
$("[name='dob']").val(dob);
|
||||
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error('File upload failed: ', status, error);
|
||||
$("[name=country]").parent().find("span").remove()
|
||||
$("[name=country]").select2()
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$("#matching_resume").on("click", function () {
|
||||
var file = $(this).data("value");
|
||||
var resume_id = $(this).data("id");
|
||||
|
||||
$.ajax({
|
||||
url: "{% url 'matching-resume-completion' %}",
|
||||
type: 'GET',
|
||||
data: {
|
||||
"resume_id": resume_id,
|
||||
"file": file
|
||||
},
|
||||
success: function (response) {
|
||||
var full_name = response.full_name;
|
||||
var address = response.address;
|
||||
var country = response.country;
|
||||
var state = response.state;
|
||||
var phone = response.phone_number;
|
||||
var dob = response.dob;
|
||||
var email = response.email_id;
|
||||
var zip = response.zip;
|
||||
|
||||
setIfEmpty("[name='name']", full_name);
|
||||
setIfEmpty("[name='email']", email);
|
||||
setIfEmpty("[name='mobile']", phone);
|
||||
setIfEmpty("[name='address']", address);
|
||||
setIfEmpty("[name='country']", country);
|
||||
setIfEmpty("[name='state']", state);
|
||||
setIfEmpty("[name='zip']", zip);
|
||||
$("[name='dob']").val(dob);
|
||||
|
||||
},
|
||||
error: function (xhr, status, error) {
|
||||
console.error('File upload failed: ', status, error);
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
$("#matching_resume").click()
|
||||
|
||||
$("[name='resume']").on("change", function () {
|
||||
var formData = new FormData();
|
||||
var file = this.files[0];
|
||||
formData.append('resume', file);
|
||||
|
||||
$.ajax({
|
||||
url: "{% url 'resume-completion' %}",
|
||||
type: 'POST',
|
||||
data: formData,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie("csrftoken")
|
||||
},
|
||||
success: function (response) {
|
||||
|
||||
var full_name = response.full_name;
|
||||
var address = response.address;
|
||||
var country = response.country;
|
||||
var state = response.state;
|
||||
var phone = response.phone_number;
|
||||
var dob = response.dob;
|
||||
var email = response.email_id;
|
||||
var zip = response.zip;
|
||||
|
||||
setIfEmpty("[name='name']", full_name);
|
||||
setIfEmpty("[name='email']", email);
|
||||
setIfEmpty("[name='mobile']", phone);
|
||||
setIfEmpty("[name='address']", address);
|
||||
setIfEmpty("[name='country']", country);
|
||||
setIfEmpty("[name='state']", state);
|
||||
setIfEmpty("[name='zip']", zip);
|
||||
$("[name='dob']").val(dob);
|
||||
|
||||
},
|
||||
error: function (xhr, status, error) {
|
||||
console.error('File upload failed: ', status, error);
|
||||
}
|
||||
});
|
||||
})
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
{% endblock content %}
|
||||
{% endblock content %}
|
||||
|
||||
@@ -338,7 +338,6 @@ def application_form(request):
|
||||
"""
|
||||
This method renders candidate form to create candidate
|
||||
"""
|
||||
form = ApplicationForm()
|
||||
recruitment = None
|
||||
recruitment_id = request.GET.get("recruitmentId")
|
||||
resume_id = request.GET.get("resumeId")
|
||||
@@ -357,12 +356,7 @@ def application_form(request):
|
||||
messages.error(request, _("Invalid Recruitment ID"))
|
||||
return redirect("open-recruitments")
|
||||
|
||||
if resume_obj:
|
||||
initial_data = {"resume": resume_obj.file.url if resume_obj else None}
|
||||
form = ApplicationForm(initial=initial_data)
|
||||
|
||||
if request.POST:
|
||||
|
||||
if "resume" not in request.FILES and resume_id:
|
||||
if resume_obj and resume_obj.file:
|
||||
file_content = resume_obj.file.read()
|
||||
@@ -428,6 +422,11 @@ def application_form(request):
|
||||
form.fields["job_position_id"].queryset = (
|
||||
form.instance.recruitment_id.open_positions.all()
|
||||
)
|
||||
else:
|
||||
# 811
|
||||
initial_data = {"resume": resume_obj.file.url} if resume_obj else {}
|
||||
form = ApplicationForm(initial=initial_data)
|
||||
|
||||
return render(
|
||||
request,
|
||||
"candidate/application_form.html",
|
||||
|
||||
@@ -687,43 +687,49 @@ s_a[252] =
|
||||
"Bulawayo|Harare|ManicalandMashonaland Central|Mashonaland East|Mashonaland West|Masvingo|Matabeleland North|Matabeleland South|Midlands";
|
||||
|
||||
function populateStates(countryElementId, stateElementId) {
|
||||
var selectedCountryIndex =
|
||||
document.getElementById(countryElementId).selectedIndex;
|
||||
|
||||
var selectedCountryIndex = document.getElementById(countryElementId).selectedIndex;
|
||||
var stateElement = document.getElementById(stateElementId);
|
||||
var selectedState = stateElement?.dataset.selected;
|
||||
|
||||
stateElement.length = 0;
|
||||
stateElement.options[0] = new Option("Select State", "");
|
||||
stateElement.selectedIndex = 0;
|
||||
|
||||
if (s_a[selectedCountryIndex]) {
|
||||
state_arr = s_a[selectedCountryIndex].split("|");
|
||||
for (var i = 0; i < state_arr.length; i++) {
|
||||
let state = state_arr[i].replace(/'/g, '`');
|
||||
stateElement.options[stateElement.length] = new Option(
|
||||
state_arr[i],
|
||||
state
|
||||
);
|
||||
let stateValue = state_arr[i].replace(/'/g, '`');
|
||||
let option = new Option(state_arr[i], stateValue);
|
||||
if (selectedState && selectedState === stateValue) {
|
||||
option.selected = true;
|
||||
}
|
||||
stateElement.options[stateElement.length] = option;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function populateCountries(countryElementId, stateElementId) {
|
||||
// given the id of the <select> tag as function argument, it inserts <option> tags
|
||||
var countryElement = document.getElementById(countryElementId);
|
||||
var value = countryElement?.value;
|
||||
if (value != undefined) {
|
||||
var selectedCountry = countryElement?.dataset.selected;
|
||||
|
||||
if (countryElement) {
|
||||
countryElement.length = 0;
|
||||
countryElement.options[0] = new Option("Select Country", "-1");
|
||||
countryElement.selectedIndex = 0;
|
||||
|
||||
for (var i = 0; i < country_arr.length; i++) {
|
||||
let country = country_arr[i].replace(/'/g, '`');
|
||||
countryElement.options[countryElement.length] = new Option(
|
||||
country_arr[i],
|
||||
country
|
||||
);
|
||||
let option = new Option(country_arr[i], country);
|
||||
if (selectedCountry && selectedCountry === country) {
|
||||
option.selected = true;
|
||||
}
|
||||
countryElement.options[countryElement.length] = option;
|
||||
}
|
||||
|
||||
// trigger state population if needed
|
||||
if (stateElementId) {
|
||||
populateStates(countryElementId, stateElementId); // populate on load
|
||||
|
||||
countryElement.onchange = function () {
|
||||
populateStates(countryElementId, stateElementId);
|
||||
};
|
||||
@@ -731,5 +737,8 @@ function populateCountries(countryElementId, stateElementId) {
|
||||
}
|
||||
}
|
||||
|
||||
populateCountries("id_country", "id_state");
|
||||
populateCountries("country", "state");
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
populateCountries("id_country", "id_state");
|
||||
populateCountries("country", "state");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user