<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="https://cdn.jsdelivr.net/npm/remixicon@2.5.0/fonts/remixicon.css" rel="stylesheet"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA==" crossorigin="anonymous" referrerpolicy="no-referrer" /> <style> @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap'); * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Roboto', sans-serif; } body { position: relative; width: 100%; height: 100vh; /* Ensure full viewport height */ overflow: hidden; /* Prevent body scrolling */ } .header { height: 60px; width: 100%; display: flex; align-items: center; border-bottom: 2px solid #F1F1F1; background-color: #fff; z-index: 1000; /* Ensure header stays on top */ position: fixed; top: 0; } .logo { display: flex; align-items: center; width: 300px; padding-left: 40px; } .logo span { color: #5073FB; } .search--notification--profile { display: flex; align-items: center; justify-content: space-between; width: calc(100% - 300px); padding: 0 40px; } .search { margin-left: 500px; background-color: #F1F4F8; border-radius: 50px; width: 400px; padding: 5px; display: flex; align-items: center; justify-content: space-between; } .search input { background-color: transparent; outline: none; border: none; text-indent: 15px; width: 85%; } .search button { outline: none; border: none; border-radius: 50%; background-color: #fff; padding: 8px; display: flex; align-items: center; justify-content: center; } .search button i { font-size: 1.1rem; color: #5073FB; } .notification--profile { display: flex; align-items: center; } .picon { margin-left: 20px; font-size: 1.1rem; padding: 5px; border-radius: 5px; } .lock { color: #5073FB; background-color: rgba(80, 115, 251, .2); } .bell { color: #F1D243; background-color: rgba(241, 210, 67, .2); } .chat { color: #70D7A5; background-color: rgba(112, 215, 165, .2); } .profile { position: relative; width: 40px; height: 40px; border-radius: 50%; overflow: hidden; } .main { position: relative; width: 100%; height: calc(100vh - 60px); overflow-y: auto; overflow-x: hidden; } .sidebar { position: fixed; top: 60px; /* Start after header */ left: 0; height: calc(100vh - 60px); /* Full height minus header */ width: 300px; background-color: #fff; padding: 30px; display: flex; flex-direction: column; justify-content: space-between; border-right: 2px solid #F1F1F1; transition: 0.3s; z-index: 900; /* Ensure sidebar is below header */ } .sidebar.active { width: 103px; overflow: hidden; } .sidebar.active .sidebar--item { display: none; } li { list-style: none; } a { text-decoration: none; } .sidebar--items a, .sidebar--bottom-items a { display: flex; align-items: center; margin-bottom: 10px; font-size: 1.1rem; color: #000; padding: 10px; border-radius: 10px; } .sidebar--items a:hover, .sidebar--bottom-items a:hover { background-color: #5073FB; color: #fff; } #active--link { background-color: #5073FB; color: #fff; } .sidebar--bottom-items li:last-child a { margin-bottom: 0; } .icon { position: relative; display: flex; align-items: center; justify-content: center; margin-right: 20px; font-size: 1.3rem; } .icon-0 { color: #5073FB; } .icon-1 { color: #C5BC58; } .icon-2 { color: #A280E9; } .icon-3 { color: #85ADE3; } .icon-4 { color: #E36AC8; } .icon-5 { color: #70D7A5; } .icon-6 { color: #5F5CE0; } .icon-7 { color: #E86786; } .icon-8 { color: #F1D243; } .main::-webkit-scrollbar, .sidebar::-webkit-scrollbar { width: 10px; } .main::-webkit-scrollbar-track, .sidebar::-webkit-scrollbar-track { background: #f1f1f1; } .main::-webkit-scrollbar-thumb, .sidebar::-webkit-scrollbar-thumb { background: #888; } .main::-webkit-scrollbar-thumb:hover, .sidebar::-webkit-scrollbar-thumb:hover { background: #555; } </style> <title>Dashboard</title> </head> <body> <section class="header"> <div class="logo"> <i class="ri-menu-line icon icon-0 menu"></i> <h2><nobr>{{ first_name }} Dashboard</nobr></h2> </div> <div class="search--notification--profile"> <div class="search"> <input type="text" placeholder="Search"> <button><i class="ri-search-2-line"></i></button> </div> <div class="notification--profile"> <div class="picon bell"> <i class="ri-notification-2-line"></i> </div> <div class="picon chat"> <i class="ri-wechat-2-line"></i> </div> </div> </div> </section> <section class="main"> <div class="sidebar"> <ul class="sidebar--items"> <li> <a href="#" id="active--link"> <span class="icon icon-0"><i class="fas fa-tachometer-alt"></i></span> <span class="sidebar--item">Dashboard</span> </a> </li> <li> <a href="#" id="newJobPosting" onclick="loadUserPage('/new_job_posting/', '{{ user_id }}');"> <span class="icon icon-3"><i class="far fa-calendar-alt"></i></span> <span class="sidebar--item" style="white-space: nowrap;">New Jobs Postings</span> </a> </li> <!-- <li>--> <!-- <a href="#">--> <!-- <span class="icon icon-4"><i class="fa-solid fa-address-card"></i></span>--> <!-- <span class="sidebar--item"> Add Recruiter</span>--> <!-- </a>--> <!-- </li>--> <!-- <li>--> <!-- <a href="#">--> <!-- <span class="icon icon-4"><i class="fa-solid fa-person"></i></span>--> <!-- <span class="sidebar--item">Recruiter List</span>--> <!-- </a>--> <!-- </li>--> <li> <a href="#" id="allJobPosting" onclick="loadUserPage('/all_job_postings/', '{{ user_id }}');"> <span class="icon icon-2"><i class="far fa-calendar-alt"></i></span> <span class="sidebar--item">All Jobs Postings</span> </a> </li> <li> <a href="#" id="Messages" onclick="loadUserPage('/messages/', '{{ user_id }}');"> <span class="icon icon-4"><i class="fas fa-envelope"></i></span> <span class="sidebar--item">Messages</span> </a> </li> <li> <a href="#"> <span class="icon icon-4"><i class="fa-regular fa-clock"></i></span> <span class="sidebar--item">Pending Process</span> </a> </li> <li> <a href="#"> <span class="icon icon-5"><i class="fa fa-paper-plane"></i></span> <span class="sidebar--item">Submitted Resumes</span> </a> </li> <li> <a href="#"> <span class="icon icon-6"><i class="fa-solid fa-person"></i></span> <span class="sidebar--item">Client Details</span> </a> </li> <li> <a href="#"> <span class="icon icon-6"><i class="fas fa-chart-bar"></i></span> <span class="sidebar--item">Activity Report</span> </a> </li> </ul> <ul class="sidebar--bottom-items"> <li> <a href="#"> <span class="icon icon-7"><i class="fas fa-cog"></i></span> <span class="sidebar--item">Settings</span> </a> </li> <li> <a href="{% url 'logout' %}"> <span class="icon icon-8"><i class="fas fa-sign-out-alt"></i></span> <span class="sidebar--item">Logout</span> </a> </li> </ul> </div> <div id="dynamicContentContainer"> </div> <!-- <div id="hyperlinkContainer" style="display: none;">--> <!-- <div class="hyperlink-content" id="customModal" style="background-color: red;margin-top: -500px; width: 400px; margin-left: 700px;">--> <!-- <h5>Access Restricted</h5>--> <!-- <p>You are assigned a band level below 5. You cannot access the job posting page.</p>--> <!-- </div>--> <!-- </div>--> </section> <script> document.addEventListener('DOMContentLoaded', function() { //to show popup of job posting details for jobId in all job posting document.addEventListener('click', function(event) { if (event.target && event.target.matches('.jobId-link')) { event.preventDefault(); const jobId = event.target.getAttribute('data-JobId'); let xhr = new XMLHttpRequest(); xhr.open('GET', `/get_jobPosting/?JobId=${encodeURIComponent(jobId)}`, true); xhr.onload = function() { if (xhr.status === 200) { const details = JSON.parse(xhr.responseText); console.log('Details received:', details); showPopup(details); } else { console.error('Request failed. Status:', xhr.status); } }; xhr.send(); } }); function showPopup(data) { const popup = document.getElementById('detailsModal2'); if (popup) { // Fill in the popup with data document.getElementById('Client').textContent = (data.Client || ''); document.getElementById('JobID').textContent = (data.JobID || ''); document.getElementById('Location').textContent = (data.Location || ''); document.getElementById('SPOC').textContent = (data.SPOC || ''); document.getElementById('SPOC2').textContent = (data.SPOC2 || ''); document.getElementById('NoOfPosting').textContent = (data.NoOfPosting || ''); document.getElementById('StartDate').textContent = (data.StartDate || ''); document.getElementById('CloseDate').textContent = (data.CloseDate || ''); document.getElementById('Experience_in_Yrs').textContent = (data.Experience_in_Yrs || ''); document.getElementById('BudgetMin').textContent = (data.BudgetMin || ''); document.getElementById('Qualification').textContent = (data.Qualification || ''); document.getElementById('Header').textContent = (data.Header || ''); document.getElementById('JobDescription').textContent = (data.JobDescription || ''); document.getElementById('SpecialInstructions').textContent = (data.SpecialInstructions || ''); // Attach the close button event listener each time the popup is shown document.getElementById('closePopup2').addEventListener('click', function() { popup.style.display = 'none'; }); // Display the popup popup.style.display = 'block'; } else { console.error('Popup element not found'); } } }); function validateSalary() { var minSalary = parseInt(document.getElementById("minAmount").value); var maxSalary = parseInt(document.getElementById("maxAmount").value); if (maxSalary <= minSalary) { alert("max salary must be greater than min salary."); document.getElementById("maxAmount").value = ""; document.getElementById("maxAmount").focus(); } } document.addEventListener('input', function (event) { var target = event.target; if (target && target.id === 'maxAmount') { const amount = target.value.trim(); if (!amount.trim()) { document.getElementById('Salary').textContent = ''; return; } if (!/^\d+(\.\d+)?$/.test(amount) || parseFloat(amount) < 1) { document.getElementById('Salary').textContent = 'Invalid input'; return; } const num = parseFloat(amount.replace(/,/g, '')); // Remove commas and parse to a number const formattedSalary = SalaryToWords(num); document.getElementById('Salary').textContent = formattedSalary + ' rupees'; } }); document.addEventListener('input', function (event) { var target = event.target; if (target && target.id === 'minAmount') { const amount = target.value.trim(); if (!amount.trim()) { document.getElementById('Salary').textContent = ''; return; } if (!/^\d+(\.\d+)?$/.test(amount) || parseFloat(amount) < 1) { document.getElementById('Salary').textContent = 'Invalid input'; return; } const num = parseFloat(amount.replace(/,/g, '')); // Remove commas and parse to a number const formattedSalary = SalaryToWords(num); document.getElementById('Salary').textContent = formattedSalary + ' rupees'; } }); window.SalaryToWords = function (num) { const ones = [ '', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen', ]; const tens = [ '', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety', ]; const scales = ['crore', 'lakh', 'thousand', 'hundred', '']; // Indian number system const scaleNumbers = [10000000, 100000, 1000, 100, 1]; if (num === 0) return 'zero'; let result = ''; let remainder = num; for (let i = 0; i < scales.length; i++) { const scaleValue = Math.floor(remainder / scaleNumbers[i]); remainder %= scaleNumbers[i]; if (scaleValue > 0) { if (scaleNumbers[i] >= 100) { result += `${SalaryToWords(scaleValue)} ${scales[i]} `; } else if (scaleValue < 20) { result += `${ones[scaleValue]} `; } else { result += `${tens[Math.floor(scaleValue / 10)]} ${ones[scaleValue % 10]} `; } } } return result.trim(); // Remove extra spaces }; function toggleConditionalFields() { const budgetDropdown = document.getElementById('BudgetMin'); const conditionalFields = document.getElementById('conditionalFields'); const minAmount = document.getElementById('minAmount'); const maxAmount = document.getElementById('maxAmount'); let industryText = document.getElementById('industryText'); const amountFields = document.getElementById('amountFields'); const minSalary = document.getElementById('Salary'); // Create and position the 'Please Select Salary' text if it doesn't already exist if (!industryText) { industryText = document.createElement('p'); industryText.id = 'industryText'; industryText.style.position = 'fixed'; industryText.style.marginLeft = '820px'; industryText.style.marginTop = '-325px'; document.body.appendChild(industryText); } if (budgetDropdown.value === "Fixed") { // Show fields for Fixed budget conditionalFields.style.display = "block"; timePeriodWrapper.style.display = "flex"; industryText.style.marginTop = '-319px'; amountFields.style.marginLeft = '640px'; minAmount.style.marginLeft = '-100px'; maxAmount.style.marginLeft = '-100px'; minSalary.textContent = ''; minAmount.value = ""; maxAmount.value = ""; } else if (budgetDropdown.value === "Industry Standard") { // Show fields for Industry Standard conditionalFields.style.display = "block"; timePeriodWrapper.style.display = "none"; industryText.style.marginTop = '-320px'; amountFields.style.marginLeft = '480px'; minAmount.style.marginLeft = '-160px'; maxAmount.style.marginLeft = '-100px'; minSalary.textContent = ''; minAmount.value = ""; maxAmount.value = ""; }else { // Hide all fields for other options conditionalFields.style.display = "none"; timePeriodWrapper.style.display = "none"; industryText.style.marginTop = '-100px'; } } // Function to convert number to words function numberToWords(num) { const belowTen = ["", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"]; const belowTwenty = ["Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"]; const belowHundred = ["", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"]; if (num === 0) return "Zero"; // Function for recursive processing function convert(num) { if (num < 10) return belowTen[num]; if (num < 20) return belowTwenty[num - 10]; if (num < 100) return belowHundred[Math.floor(num / 10)] + (num % 10 ? " " + belowTen[num % 10] : ""); if (num < 1000) return belowTen[Math.floor(num / 100)] + " Hundred" + (num % 100 ? " " + convert(num % 100) : ""); if (num < 1000000) return convert(Math.floor(num / 1000)) + " Thousand" + (num % 1000 ? " " + convert(num % 1000) : ""); if (num < 1000000000) return convert(Math.floor(num / 1000000)) + " Million" + (num % 1000000 ? " " + convert(num % 1000000) : ""); } return convert(num); } // Function to handle input change and convert numbers to words function convertInputToWords(inputElement) { let inputValue = inputElement.value; const numericValue = parseInt(inputValue.replace(/[^0-9]/g, '')); // Remove non-numeric characters if (!isNaN(numericValue)) { const wordValue = numberToWords(numericValue); inputElement.value = wordValue; // Update input value with the word } } document.addEventListener('DOMContentLoaded', function() { document.addEventListener('change', function(event) { var target = event.target; if (target && target.id === 'ClientDropdown') { var parentCompany = target.value; // Get selected client var subClientDropdown = target.closest('form').querySelector('#SubClientDropdown'); var formId = target.closest('form').id; // Make an AJAX request to fetch sub-clients filtered by selected client var xhr = new XMLHttpRequest(); xhr.open('GET', '/skyonnadmin/get_subclients/?parent_company=' + parentCompany, true); xhr.onload = function() { if (xhr.status === 200) { subClientDropdown.innerHTML = '<option value="">Select SubClient</option>'; var subClients = JSON.parse(xhr.responseText); subClients.forEach(function(subClient) { var option = document.createElement('option'); option.value = subClient; option.text = subClient; subClientDropdown.appendChild(option); }); } else { console.error('Request failed. Status: ' + xhr.status); } }; xhr.send(); } }); }); function goBack() { document.getElementById("addContactPopup").style.display = "none"; } document.getElementById('newJobPosting').addEventListener('click', function () { const main = document.getElementById('dynamicContentContainer'); main.style.display ='none'; setTimeout(function () { const container = document.getElementById('jobPostingForm'); const restricted = document.getElementById('restrictedField').value; console.log('Restricted value:', restricted); if (restricted === 'True') { // Check against 'True', not 'true' console.log('Access is restricted'); alert('You are assigned a level above 5. You cannot access New job posting page'); container.style.display='none'; } else { main.style.display='block'; } }, 100) }); function validateLength(input) { const maxLength = 8; if (input.value.length > maxLength) { input.value = input.value.slice(0, maxLength); } } document.getElementById('allJobPosting').addEventListener('click', function () { setTimeout(function () { const container = document.getElementById('AllJobPostingTable'); const restricted = document.getElementById('restrictedField').value; console.log('Restricted value:', restricted); if (restricted === 'True') { console.log('Access is restricted'); alert('You are assigned a level below 5. You cannot access All job postings page'); container.style.display='none'; } }, 100) }); let menu = document.querySelector('.menu') let sidebar = document.querySelector('.sidebar') let mainContent = document.querySelector('.main--content') menu.onclick = function() { sidebar.classList.toggle('active') mainContent.classList.toggle('active') } function loadUserPage(pageName, userId) { var urlWithUserId = pageName + "?user_id=" + userId; // Append admin_id as query parameter var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { document.getElementById("dynamicContentContainer").innerHTML = this.responseText; } }; xhttp.open("GET", urlWithUserId, true); xhttp.send(); } <!-- function activateSidebarLink(clickedLink) {--> <!-- // Remove 'active' class from all sidebar links--> <!-- var sidebarLinks = document.querySelectorAll('.sidebar-link');--> <!-- sidebarLinks.forEach(function(link) {--> <!-- link.classList.remove('active');--> <!-- });--> <!-- // Add 'active' class to the clicked sidebar link--> <!-- clickedLink.classList.add('active');--> <!-- }--> document.addEventListener('DOMContentLoaded', function() { //to show popup for client details document.addEventListener('click', function(event) { if (event.target && event.target.matches('.client-link')) { event.preventDefault(); const client = event.target.getAttribute('data-client'); let xhr = new XMLHttpRequest(); xhr.open('GET', `/get_client_details/?client=${encodeURIComponent(client)}`, true); xhr.onload = function() { if (xhr.status === 200) { const details = JSON.parse(xhr.responseText); console.log('Details received:', details); showPopup(details); } else { console.error('Request failed. Status:', xhr.status); } }; xhr.send(); } }); function showPopup(data) { const popup = document.getElementById('detailsModal'); console.log('Popup element:', popup); // Check if popup is found if (popup) { // Fill in the popup with data document.getElementById('parentCompany').textContent = (data.parent_company || ''); document.getElementById('gstNo').textContent = (data.GST_No || ''); document.getElementById('locationId').textContent = (data.Location_Id || ''); document.getElementById('address1').textContent = (data.Address_1 || ''); document.getElementById('address2').textContent = (data.Address_2 || ''); document.getElementById('city').textContent = (data.City || ''); document.getElementById('state').textContent = (data.State || ''); document.getElementById('pincode').textContent = (data.Pincode || ''); document.getElementById('country').textContent = (data.Country || ''); // Attach the close button event listener each time the popup is shown document.getElementById('closePopup').addEventListener('click', function() { popup.style.display = 'none'; }); // Display the popup popup.style.display = 'block'; } else { console.error('Popup element not found'); } } }); document.addEventListener('DOMContentLoaded', function() { document.addEventListener('change', function(event) { var target = event.target; if (target && target.id === 'Client') { var client = target.value; // Get selected client let SPOC1 = document.getElementById('SPOC'); if (!SPOC1) return; let SPOC2 = document.getElementById('SPOC2'); if (!SPOC2) return; SPOC1.innerHTML = '<option value="">Select SPOC1</option>'; SPOC2.innerHTML = '<option value="">Select SPOC2</option>'; // Make AJAX request to get filtered data let xhr = new XMLHttpRequest(); xhr.open('GET', '/get_contacts/?Client=' + client, true); xhr.onload = function() { if (xhr.status === 200) { var spocData = JSON.parse(xhr.responseText); spocData.forEach(function(contact) { const option1 = document.createElement('option'); option1.value = `${contact.FirstName} ${contact.LastName}`; option1.textContent = `${contact.FirstName} ${contact.LastName}`; SPOC1.appendChild(option1); const option2 = document.createElement('option'); option2.value = `${contact.FirstName} ${contact.LastName}`; option2.textContent = `${contact.FirstName} ${contact.LastName}`; SPOC2.appendChild(option2); }); } else { console.error('Request failed. Status: ' + xhr.status); } }; xhr.onerror = function() { console.error('Request failed.'); }; xhr.send(); } }) }); document.addEventListener('DOMContentLoaded', function() { document.addEventListener('change', function() { const form = document.getElementById('AddSPOCform'); if (!form) return; const emailInput = document.getElementById('Email'); const phoneNumberInput = document.getElementById('Phone_number'); const requiredFields = form.querySelectorAll('input[required], select[required]'); const validateField = (field) => { if (!field.value.trim()) { field.style.borderColor = ''; field.setCustomValidity('Please fill out this field.'); field.reportValidity(); return false; } else { field.style.borderColor = 'black'; field.setCustomValidity(''); return true; } }; const clearValidation = (field) => { field.setCustomValidity(''); field.style.borderColor = ''; }; emailInput.addEventListener('input', () => { clearValidation(emailInput); }); phoneNumberInput.addEventListener('input', () => { clearValidation(phoneNumberInput); }); emailInput.addEventListener('blur', () => { if (emailInput.value.trim() && (!emailInput.value.match(/^[^\s@]+@[^\s@]+\.[a-zA-Z]{2,}$/) || emailInput.value.includes('..') || !emailInput.value.match(/^[^\s@]{1,64}@([^\s@_]+\.)+[a-zA-Z]{2,}$/))) { emailInput.style.borderColor = ''; emailInput.setCustomValidity('Invalid email format.'); emailInput.reportValidity(); } else { clearValidation(emailInput); if (emailInput.value.trim()) { checkFieldExists('Email', emailInput); } } }); phoneNumberInput.addEventListener('blur', () => { if (phoneNumberInput.value.trim() && !phoneNumberInput.value.match(/^[6-9]\d{9}$/)) { phoneNumberInput.style.borderColor = ''; phoneNumberInput.setCustomValidity('Invalid phone number format.'); phoneNumberInput.reportValidity(); } else { clearValidation(phoneNumberInput); if (phoneNumberInput.value.trim()) { checkFieldExists('Phone_number', phoneNumberInput); } } }); function checkFieldExists(fieldName, field) { const value = field.value.trim(); fetch(`/validate_field/?${fieldName}=${value}`) .then(response => response.json()) .then(data => { if (data.exists) { if (fieldName === 'Phone_number') { field.setCustomValidity('Phone number already exists.'); } else { field.setCustomValidity('Email already exists.'); } field.style.borderColor = 'red'; field.reportValidity(); } else { field.setCustomValidity(''); field.style.borderColor = 'black'; } }) .catch(error => { console.error('Error:', error); }); } }) }); window.saveAdd_SPOC = async function() { const form = document.getElementById('AddSPOCform'); const requiredFields = form.querySelectorAll('input[required], select[required]'); const emailInput = document.getElementById('Email'); const phoneNumberInput = document.getElementById('Phone_number'); let isValid = true; requiredFields.forEach(field => { field.setCustomValidity(''); field.style.borderColor = ''; }); for (let field of requiredFields) { if (!field.value.trim()) { isValid = false; field.setCustomValidity('Please fill out this field.'); field.reportValidity(); } } const validateEmail = (emailInput) => { if (emailInput.value.trim() && (!emailInput.value.match(/^[^\s@]+@[^\s@]+\.[a-zA-Z]{2,}$/) || emailInput.value.includes('..') || !emailInput.value.match(/^[^\s@]{1,64}@([^\s@_]+\.)+[a-zA-Z]{2,}$/))) { isValid = false; emailInput.style.borderColor = ''; emailInput.setCustomValidity('Please enter a valid Email address'); emailInput.reportValidity(); } else { emailInput.setCustomValidity(''); emailInput.style.borderColor = 'black'; } } const checkValidity = (field,pattern,errorMsg) =>{ if (field.value.trim() && !field.value.match(pattern)) { field.setCustomValidity(errorMsg); field.reportValidity(); isValid=false; } else { field.setCustomValidity(''); field.style.borderColor = 'black'; } }; checkValidity(phoneNumberInput, /^[6-9]\d{9}$/, 'Invalid Phone number format.'); validateEmail(emailInput); if (!isValid) { console.log("Validation failed. Please fill out the required fields."); return; } const checkFieldExists = (fieldName, field) => { return new Promise((resolve, reject) => { const value = field.value.trim(); fetch(`/validate_field/?${fieldName}=${value}`) .then(response => response.json()) .then(data => { if (data.exists) { if (fieldName === 'Phone_number') { field.setCustomValidity('Phone number already exists.'); } else { field.setCustomValidity('Email already exists.'); } field.style.borderColor = 'red'; field.reportValidity(); resolve(false); } else { field.setCustomValidity(''); field.style.borderColor = 'black'; resolve(true); } }) .catch(error => { console.error('Error:', error); reject(error); }); }); } const phoneNoValid = await checkFieldExists('Phone_number', phoneNumberInput); const emailValid = await checkFieldExists('Email', emailInput); isValid = isValid && phoneNoValid && emailValid; if (!isValid) { console.log("Validation failed. Please fill out the required fields."); return; } const formData = new FormData(form); const url = form.getAttribute('action'); console.log("Submitting form to:", url); console.log("Form data:", [...formData.entries()]); // Log the form data fetch(url, { method: 'POST', body: formData, headers: { 'X-CSRFToken': '{{ csrf_token }}', }, }) .then(response => { if (!response.ok) { throw new Error('Failed to save contact'); } return response.json(); }) .then(data => { console.log('Success:', data); form.reset(); hidePopup(); showSuccessPopup(); }) .catch(error => { console.error('Error:', error); }) } function refreshSPOCs() { //to refresh SPOC when refresh button clicked console.log('refreshing SPOCs'); let client = document.getElementById('Client').value; let SPOC1 = document.getElementById('SPOC'); if (!SPOC1) return; let SPOC2 = document.getElementById('SPOC2'); if (!SPOC2) return; SPOC1.innerHTML = '<option value="">Select SPOC1</option>'; SPOC2.innerHTML = '<option value="">Select SPOC2</option>'; // Make AJAX request to get filtered data let xhr = new XMLHttpRequest(); xhr.open('GET', '/get_contacts/?Client=' + client, true); xhr.onload = function() { if (xhr.status === 200) { var spocData = JSON.parse(xhr.responseText); spocData.forEach(function(contact) { const option1 = document.createElement('option'); option1.value = `${contact.FirstName} ${contact.LastName}`; option1.textContent = `${contact.FirstName} ${contact.LastName}`; SPOC1.appendChild(option1); const option2 = document.createElement('option'); option2.value = `${contact.FirstName} ${contact.LastName}`; option2.textContent = `${contact.FirstName} ${contact.LastName}`; SPOC2.appendChild(option2); }); } else { console.error('Request failed. Status: ' + xhr.status); } }; xhr.onerror = function() { console.error('Request failed.'); }; xhr.send(); } function limitNumberOfPostings(input) { var maxPostings = 100; if (input.value > maxPostings) { input.value = maxPostings; // Set the value to the maximum allowed } } function updateInputField() { var selectedStatesInput = document.getElementById("selectedStatesInput"); var selectedStates = []; var checkboxes = document.querySelectorAll('input[type="checkbox"]:checked'); for (var i = 0; i < checkboxes.length; i++) { selectedStates.push(checkboxes[i].value); } selectedStatesInput.value = selectedStates.join(", "); // Close the dropdown after updating the input field var dropdownContent = document.getElementById("checkboxContainer"); dropdownContent.style.display = "none"; } function toggleOtherInputField() { var otherCheckbox = document.getElementById("OtherCheckbox"); var selectedStatesInput = document.getElementById("selectedStatesInput"); var dropdownContent = document.getElementById("checkboxContainer"); if (otherCheckbox.checked) { // Show the modal for adding a new location showAddLocationModal(); dropdownContent.style.display = "none"; } else { // If "Other" is unchecked, clear the input field, make it readonly again, and show dropdown content selectedStatesInput.value = ""; selectedStatesInput.readOnly = true; dropdownContent.style.display = "block"; } } function toggleDropdown() { var dropdownContent = document.getElementById("checkboxContainer"); if (dropdownContent.style.display === "none") { dropdownContent.style.display = "block"; } else { dropdownContent.style.display = "none"; } } function showAddLocationModal() { document.getElementById("addLocationModal").style.display = "block"; } function closeAddLocationModal() { document.getElementById("addLocationModal").style.display = "none"; document.getElementById("OtherCheckbox").checked = false; } function saveNewLocation() { var newLocation = document.getElementById("newLocationInput").value.trim(); var selectedStatesInput = document.getElementById("selectedStatesInput"); if (newLocation) { // Add new location to the dropdown addLocationToDropdown(newLocation); // Save new location to local storage saveLocation(newLocation); // Update the input field with the new location var currentInput = selectedStatesInput.value; selectedStatesInput.value = currentInput ? currentInput + ", " + newLocation : newLocation; // Clear and reset the input field document.getElementById("newLocationInput").value = ""; closeAddLocationModal(); } else { alert("Please enter a location."); } } function addLocationToDropdown(location) { var checkboxContainer = document.getElementById("checkboxItems"); if (!checkboxContainer) { return; } var newCheckbox = document.createElement("input"); newCheckbox.type = "checkbox"; newCheckbox.value = location; newCheckbox.style.marginLeft = "-50px"; newCheckbox.id = "checkbox_" + location.replace(/\s+/g, '_'); newCheckbox.name = "checkbox_" + location.replace(/\s+/g, '_'); newCheckbox.onchange = updateInputField; var newCheckboxLabel = document.createElement("label"); newCheckboxLabel.style.marginLeft = "-48px"; newCheckboxLabel.setAttribute("for", newCheckbox.id); newCheckboxLabel.appendChild(document.createTextNode(" " + location)); checkboxContainer.appendChild(newCheckbox); checkboxContainer.appendChild(newCheckboxLabel); checkboxContainer.appendChild(document.createElement("br")); } function saveLocation(location) { var locations = JSON.parse(localStorage.getItem('locations')) || []; locations.push(location); localStorage.setItem('locations', JSON.stringify(locations)); } function loadLocations() { var locations = JSON.parse(localStorage.getItem('locations')) || []; locations.forEach(function(location) { addLocationToDropdown(location); }); } document.addEventListener('DOMContentLoaded',function() { document.addEventListener('change',function(event) { var target = event.target; if (target && target.id === 'Client') { var client = target.value; let xhr= new XMLHttpRequest(); xhr.open('GET',`/get_locations/?Client=${client}`,true); xhr.onload = function() { if (xhr.status === 200) { const locations = JSON.parse(xhr.responseText); updateCheckboxItems(locations); } else { console.error('Request failed. Status: ' + xhr.status); } }; xhr.send() } function updateCheckboxItems(locations) { const checkboxItems = document.getElementById('checkboxItems'); checkboxItems.innerHTML = ` <input type="checkbox" id="anyWhereCheckbox" name="anyWhereCheckbox" value="Anywhere" onchange="updateInputField()" style="margin-left: -50px;"> <label for="anyWhereCheckbox" style="margin-left: -50px;">Anywhere</label><br> `; locations.forEach(function(location) { const existingLocation = checkboxItems.querySelector(`input[value="${location}"]`) if (!existingLocation) { // Create a checkbox and label for each location const checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.name = location; checkbox.value = location; checkbox.style.marginLeft = '-50px'; checkbox.onchange = updateInputField; const label = document.createElement('label'); label.textContent = location; label.style.marginLeft = '-45px'; label.htmlFor = location; // Append checkbox and label to the container checkboxItems.appendChild(checkbox); checkboxItems.appendChild(label); checkboxItems.appendChild(document.createElement('br')); } }); } }); }); function showPopup() { document.getElementById('addContactPopup').style.display = 'flex'; } function hidePopup() { document.getElementById('addContactPopup').style.display = 'none'; } function showSuccessPopup() { document.getElementById('successPopup').style.display = 'flex'; } function hideSuccessPopup() { document.getElementById('successPopup').style.display = 'none'; } // Function to validate the job posting form (to be implemented) function saveJobPosting() { // Add your form validation and submission logic here alert('Job posting saved!'); } function saveJobPosting() { const form = document.getElementById('jobPostingForm'); const orderedFieldIds = [ 'Client', 'JobID', 'selectedStatesInput', 'SPOC', 'SPOC2', 'NoOfPosting', 'StartDate', 'CloseDate', 'Type', 'Experience', 'BudgetMin', 'timePeriod','minAmount','maxAmount', 'Header', 'JobDescription', 'SpecialInstructions', 'JD' ]; const minSalary = document.getElementById('minSalary'); const maxSalary = document.getElementById('maxSalary'); const minAmount = document.getElementById('minAmount'); const maxAmount = document.getElementById('maxAmount'); let isValid = true; let firstInvalidField = null; // Clear any previous custom validation messages and reset border colors orderedFieldIds.forEach(id => { const field = document.getElementById(id); if (field) { field.setCustomValidity(''); // Clear previous validation message field.style.borderColor = ''; // Reset border color } }); // Iterate over each field in the specified order to validate for (let id of orderedFieldIds) { const field = document.getElementById(id); if (field && !field.value.trim() && field !== 'JD') { isValid = false; field.setCustomValidity('Please fill out this field.'); field.reportValidity(); // Focus the first invalid field if (!firstInvalidField) { firstInvalidField = field; } break; } if (field && field === 'JD' && !field.value.trim()) { isValid = false; field.setCustomValidity('Please upload a file'); field.reportValidity(); if (!firstInvalidField) { firstInvalidField = field; } } } if (minSalary && minSalary.textContent === 'Invalid input') { isValid = false; minAmount.setCustomValidity('Please enter correct salary amount.'); minAmount.reportValidity(); if (!firstInvalidField) { firstInvalidField = minAmount; } } if (!isValid) { // Focus on the first invalid field according to the specified order if (firstInvalidField) { firstInvalidField.focus(); } console.log("Validation failed. Please fill out the required fields."); return; } // Proceed with saving data if all fields are valid const formData = new FormData(form); const url = form.getAttribute('action'); console.log("Submitting form to:", url); console.log("Form data:", [...formData.entries()]); // Log the form data fetch(url, { method: 'POST', body: formData, headers: { 'X-CSRFToken': '{{ csrf_token }}', // Assuming you have CSRF token available }, }) .then(response => { if (!response.ok) { throw new Error('Failed to save job posting.'); } return response.json(); }) .then(data => { console.log('Success:', data); alert('Job saved successfully.'); document.getElementById('Salary').textContent = ''; document.getElementById('BudgetMin').value = ''; document.getElementById('conditionalFields').style.display = 'none'; }) .catch(error => { console.error('Error:', error); alert('Error: ' + error.message); }) .finally(() => { // Clear all fields in the form whether success or error form.reset(); // Reset field borders to their default state orderedFieldIds.forEach(id => { const field = document.getElementById(id); if (field) { field.style.borderColor = 'initial'; // Reset to default border color } }); }); } function validateDates() { var startDate = new Date(document.getElementById("StartDate").value); var closeDate = new Date(document.getElementById("CloseDate").value); if (closeDate <= startDate) { alert("Close Date must be greater than Start Date."); document.getElementById("CloseDate").value = ""; } } function validateAmount() { // Get values for minAmount and maxAmount fields var minAmount = parseInt(document.getElementById("minAmount").value); var maxAmount = parseInt(document.getElementById("maxAmount").value); console.log(minAmount,maxAmount); // Get input elements and error popup elements var minAmountInput = document.getElementById("minAmount"); var maxAmountInput = document.getElementById("maxAmount"); var maxAmountErrorPopup = document.getElementById("maxAmountErrorPopup"); <!-- // Check if minAmount is a valid number--> <!-- if (isNaN(minAmount) || minAmount <= 0) {--> <!-- maxAmountErrorPopup.textContent = "Min amount must be greater than zero.";--> <!-- maxAmountErrorPopup.style.display = "block";--> <!-- maxAmountErrorPopup.style.borderColor = "red"; // Optionally, visually indicate error--> <!-- maxAmountErrorPopup.focus();--> <!-- return; // Prevent further validation--> <!-- } else {--> <!-- minAmountErrorPopup.style.display = "none"; // Hide error popup--> <!-- minAmountInput.style.borderColor = ""; // Reset border color--> <!-- }--> <!-- // Check if maxAmount is a valid number--> <!-- if (isNaN(maxAmount) || maxAmount <= 0) {--> <!-- alert("Max amount must be greater than zero.");--> <!-- maxAmountErrorPopup.textContent = "Max amount must be greater than zero.";--> <!-- maxAmountErrorPopup.style.display = "block";--> <!-- maxAmountInput.style.borderColor = "red"; // Optionally, visually indicate error--> <!-- maxAmountInput.focus();--> <!-- return; // Prevent further validation--> <!-- } else {--> <!-- maxAmountErrorPopup.style.display = "none"; // Hide error popup--> <!-- maxAmountInput.style.borderColor = ""; // Reset border color--> <!-- }--> // Check if maxAmount is less than or equal to minAmount if (maxAmount <= minAmount) { alert("Max amount must be greater than Min amount."); maxAmountErrorPopup.textContent = "Max amount must be greater than Min amount."; maxAmountErrorPopup.style.display = "block"; maxAmountInput.style.borderColor = "red"; // Optionally, visually indicate error maxAmountInput.focus(); return; } else { maxAmountErrorPopup.style.display = "none"; // Hide error popup maxAmountInput.style.borderColor = ""; // Reset border color } } // Attach the validation function to input and blur events for both fields <!--document.getElementById("minAmount").addEventListener("input", validateAmount);--> <!--document.getElementById("minAmount").addEventListener("blur", validateAmount);--> document.getElementById("maxAmount").addEventListener("input", validateAmount); document.getElementById("maxAmount").addEventListener("blur", validateAmount); function searchJob() { var input, filter, table, tr, i, txtValue; input = document.getElementById("searchInput"); filter = input.value.toUpperCase(); table = document.querySelector("table"); tr = table.getElementsByTagName("tr"); for (i = 1; i < tr.length; i++) { var found = false; // Check Client Name (1st column) var clientTd = tr[i].getElementsByTagName("td")[0]; if (clientTd) { txtValue = clientTd.textContent || clientTd.innerText; if (txtValue.toUpperCase().indexOf(filter) > -1) { found = true; } } // Check JobID (2nd column) var jobIdTd = tr[i].getElementsByTagName("td")[1]; if (jobIdTd) { txtValue = jobIdTd.textContent || jobIdTd.innerText; if (txtValue.toUpperCase().indexOf(filter) > -1) { found = true; } } // Show or hide the row based on search results tr[i].style.display = found ? "" : "none"; } } function validateExperience(input) { // Convert the input value to a string and ensure only up to two digits if (input.value.length > 2) { input.value = input.value.slice(0, 2); } } function limitToThreeDigits(input) { // Convert the input value to a string and ensure only up to two digits if (input.value.length > 3) { input.value = input.value.slice(0, 3); } } </script> </body> </html>