(function () { try{ // Define all variables here const server_url = "https://hirenext.io/" let preClass = "rankwatch"; const style = document.createElement('style'); // The current page number let currentPage = 1; // count job length per page let joblistlenth = ''; // Settings loaded during fetching of js script let rwsc___settings = { rwsc__loc_flag: 1, rwsc__emp_flag: 1, rwsc__cat_flag: 1, rwsc__yoe_flag: 1, rwsc__salary_flag: 1, rwsc__bg_col: "ffffff", rwsc__border_col: "505050", rwsc__shadow_col: "00ff00", rwsc__prime_col: "3e4aea", rwsc__sec_col: "000000", rwsc__comp_id: 45, rwsc__per_page: 5, rwsc__total_jobs: 4, } style.innerHTML = ` @import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap'); * {font-family: "Inter", system-ui !important;} a {text-decoration: none;} img {max-width: 100%;} a:hover, .pointer:hover {text-decoration: underline;} .${preClass}user-table {font-size: 0.875rem;} .${preClass}all-ques-type, .${preClass}jobs__form_label {font-size: 0.75rem;} .${preClass}pointer {cursor: pointer;} .${preClass}fs10 {font-size: 10px;} .${preClass}fs20 {font-size: 1.25rem;} .${preClass}margin-bottom {margin-bottom: 1.5rem;} .${preClass}margin-bottom-0 {margin-bottom: 0 !important;} .${preClass}text-green {color: #55D369 !important;} .${preClass}text-green-dark {color: #209934;} .${preClass}text-light-gray{color: #C6D4C7 !important;} .${preClass}text-dark-grey{color: #475467;} .${preClass}text-bold{font-weight: 700 !important;} .${preClass}text-medium{font-weight: 500 !important;} .${preClass}heading {font-size: 1.5rem;color: #18181B;font-weight: 600;margin-bottom: 1.5rem;position: relative;} .${preClass}content-para {color: #495057;font-size: 0.875rem;line-height: 1.5;} .${preClass}section-devider {height: 1px;background: rgba(255, 255, 255, 1);margin: 2rem 0;} .${preClass}interviews-opt {border: 1px solid #E3E3E5;border-radius: 8px;padding: 1.25rem 2.75rem 1.25rem 1.25rem;position: relative;} .${preClass}opt-title {font-size: 1rem;font-weight: 500;color: #18181B;margin-bottom: 0.5rem;} .${preClass}opt-status {background: #F6FFFB;font-size: 0.75rem;padding: 2px 6px;border-radius: 4px;font-weight: 500;} .${preClass}opt-details {display: flex;align-items: center;gap: 1rem;font-size: 0.75rem;color: #495057;font-weight: 400;} .${preClass}position-right {position: absolute;right: 1rem;top: 50%;transform: translateY(-50%);} .${preClass}flex-box {display: flex;align-items: center;justify-content: space-between;position: relative;gap: 2rem;} #${preClass}pagination-list {padding: 0;list-style: none;gap: 0.5rem;margin: 0 0.75rem;} #${preClass}pagination-list li button {background: #fff;border: 1px solid #DEE2E6;border-radius: 4px;font-size: 0.75rem;padding: 5px;min-width: 30px;display: flex;align-items: center;justify-content: center;min-height: 30px;} # .${preClass}job-badge {padding: 0.125rem 0.5rem;font-size: 0.75rem;border-radius: 50px;margin-left: auto;border: 1px solid #DEE2E6;margin: 0.625rem;} .${preClass}jobs___fmrgrp {flex: 1 1 auto;} .${preClass}jobs__form_label {margin-bottom: 4px;} .${preClass}jobs__form_control {padding: 9px 16px;border-radius: 6px;border: 1px solid #DEE2E6;background: #FFF;outline: none !important;box-shadow: none !important;display: block;width: 100%;} .${preClass}jobs___modal {background-color: #fff; padding: 0 30px 30px; ; border-radius: 8px; max-width: 500px; width: 100%; box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 50px;margin: auto;} #jobs___modal-1 {max-width: 1000px;} .${preClass}jobs__modal_btn {background-color: transparent;border: 1px solid transparent;border-radius: 8px;padding: 0.5rem 1rem;min-width: 140px;font-size: 1rem;font-weight: bold;margin-left: 1rem;} .${preClass}jobs__close-button, .${preClass}jobs__back-button, .${preClass}closejobmodal {border-color: #E3E3E5;color: #344054;margin-left: 0;} .${preClass}jobs__next-button {border-color: #209934;background-color: #209934;color: #fff;} .${preClass}jobs___modal__footer {text-align: right;} #jobs___modal-2 {max-width: 750px;} .${preClass}inputfile-box {position: relative;} .${preClass}file-box {display: inline-block;width: 100%;border: 1px solid;padding: 5px 0px 5px 5px;box-sizing: border-box;height: calc(2rem - 2px);} .${preClass}file-button {padding: 9px 20px;position: absolute;border-left: 1px solid #DEE2E6;top: 0px;right: 0px;} .${preClass}jobs___invalid-feedback {font-size: 12px;color: #FE5A5A;padding: 4px 0;} `; style.innerHTML += ` .${preClass}jobs___modal_header { position: sticky; top: 0; z-index: 2; background: #fff; margin-top: -30px; /* pull header up into the container's top padding */ padding: 30px 48px 12px 0;/* keep the visual top space + room for the × on the right */ border-bottom: 1px solid rgba(0,0,0,0.06); box-shadow: 0 1px 0 rgba(0,0,0,0.02); } /* Hard reset so host page styles can't leak in */ .${preClass}jobs__close-x{ all: unset; /* wipe inherited/host styles */ position: absolute; top: 8px; right: 8px; display: grid; /* easy centering */ place-items: center; width: 32px; height: 32px; cursor: pointer; border-radius: 8px; background: transparent !important; border: none !important; z-index: 5; -webkit-appearance: none; appearance: none; } .${preClass}jobs__close-x:hover{ background: rgba(0,0,0,0.06) !important; } .${preClass}jobs__close-x:focus{ outline: 2px solid rgba(0,0,0,0.35); outline-offset: 2px; } /* Lock the icon look */ .${preClass}jobs__close-x > svg{ width: 16px; height: 16px; display: block; } .${preClass}jobs__close-x > svg path{ stroke: #475467; /* icon color */ stroke-width: 2; stroke-linecap: round; fill: none; } /* ——— Normalize icon rows everywhere ——— */ .${preClass}opt-details{ display:flex; align-items:center; /* vertically center the whole row */ gap: 1rem; flex-wrap: wrap; /* wrap nicely on smaller widths */ } /* each icon+label group */ .${preClass}opt-details > .${preClass}u_location, .${preClass}opt-details > .${preClass}u_exp, .${preClass}opt-details > .${preClass}u_time, .${preClass}opt-details > .${preClass}coston{ display:inline-flex; /* treat each pair as a tiny flex row */ align-items:center; /* center the icon with the text */ gap: 8px; line-height: 1; /* avoid odd baselines */ } /* make SVGs not sit on the baseline */ .${preClass}opt-details svg{ display:block; /* remove baseline/descender gap */ width:16px; height:16px; flex:0 0 16px; } /* keep labels tight */ .${preClass}opt-details span{ line-height:1; } /* optional: neutralize inline vertical-align you add in HTML */ .${preClass}opt-details span[style*="vertical-align"]{ vertical-align: initial !important; } /* Skills layout – container controls spacing (host CSS can't break it) */ .${preClass}job___skill{ display: flex; flex-wrap: wrap; gap: 8px 12px; /* row gap / column gap */ margin-top: 8px; } /* Individual chip */ .${preClass}job-badge{ display: inline-flex; align-items: center; box-sizing: border-box; padding: 6px 12px; border: 1px solid #DEE2E6; border-radius: 9999px; background: #fff; font-size: 0.75rem; line-height: 1.1; font-weight: 500; margin: 0 !important; /* ensure host margins can't leak in */ } /* Guard against host link/reset styles */ .${preClass}jobs___modal .${preClass}job___skill .${preClass}job-badge{ text-decoration: none !important; } /* ——— Consistent vertical spacing inside the modal body ——— */ .${preClass}jobs___modal__body{ --section-gap: 24px; /* tune once, used below */ } /* Give paragraphs and lists a reliable bottom margin */ .${preClass}jobs___modal__body p, .${preClass}jobs___modal__body ul, .${preClass}jobs___modal__body ol{ margin-top: 0 !important; margin-bottom: 16px !important; } /* Nice bullets + indentation regardless of host CSS */ .${preClass}jobs___modal__body ul{ padding-left: 1.2rem !important; list-style: disc outside !important; } /* Space ABOVE section titles like “Responsibilities”, “Skills” */ .${preClass}jobs___modal__body > .${preClass}opt-title{ margin-top: var(--section-gap) !important; } /* But not for the very first title (“Job Description”) */ .${preClass}jobs___modal__body > .${preClass}opt-title:first-child{ margin-top: 0 !important; } /* Keep a little gap before the badges row */ .${preClass}job___skill{ margin-top: 12px !important; } /* (Optional) Hide the divider immediately under the sticky header */ .${preClass}jobs___modal__content > .${preClass}jobs___modal_header + .${preClass}section-devider{ display: none !important; } /* Keep the body clear of the sticky header */ .${preClass}jobs___modal__body{ padding-top: 14px !important; /* adjust 12–20px to taste */ } /* If you ever scroll to anchors inside the modal, avoid header overlap */ .${preClass}jobs___modal{ scroll-padding-top: 64px; /* approximate header height */ } /* Make sure the divider under the header doesn't reintroduce double spacing */ .${preClass}jobs___modal__content > .${preClass}jobs___modal_header + .${preClass}section-devider{ display: none !important; } /* Also prevent the very first child’s margin from collapsing into the header */ .${preClass}jobs___modal__body > *:first-child{ margin-top: 0 !important; } /* --- responsive padding variable for the modal --- */ .${preClass}jobs___modal{ --pad-x: 30px; /* desktop inline padding */ padding: 0 var(--pad-x) 30px; scroll-padding-top: 72px; /* safe anchor/scroll offset */ } @media (max-width: 640px){ .${preClass}jobs___modal{ --pad-x: 16px; } /* tighter on phones */ } /* --- FIX: sticky header without negative top margin --- */ .${preClass}jobs___modal_header{ position: sticky; top: 0; z-index: 2; background:#fff; /* remove the old hack */ margin-top: 0 !important; /* make the header full-bleed while the modal keeps side padding */ margin-left: calc(var(--pad-x) * -1); margin-right: calc(var(--pad-x) * -1); padding: 16px var(--pad-x) 12px; /* consistent on all screens */ border-bottom: 1px solid rgba(0,0,0,.06); box-shadow: 0 1px 0 rgba(0,0,0,.02); } /* small breathing room under the header */ .${preClass}jobs___modal__content{ padding-top: 8px; } /* keep the divider under the header hidden (avoid double line) */ .${preClass}jobs___modal__content > .${preClass}jobs___modal_header + .${preClass}section-devider{ display: none !important; } /* section spacing stays consistent */ .${preClass}jobs___modal__body{ --section-gap:24px; } .${preClass}jobs___modal__body > .${preClass}opt-title{ margin-top: var(--section-gap) !important; } .${preClass}jobs___modal__body > .${preClass}opt-title:first-child{ margin-top: 0 !important; } `; document.head.appendChild(style); // count page numbers const totalPage = Math.ceil(rwsc___settings['rwsc__total_jobs']/rwsc___settings['rwsc__per_page']) let conatiner__elem try{ conatiner__elem = document.getElementById('job-container'); } catch (error){ console.log('Could Not Find Job Containder Id id:job-container') return } conatiner__elem.style="padding: 20px;margin: 20px auto;" // job list container const jobListCont = document.createElement('div'); jobListCont.id = 'job____list_itm' //jobListCont.style = 'height: 350px;' // set heading and location and position dropdowns const add___header = document.createElement('div'); add___header.classList = `${preClass}flex-box ${preClass}margin-bottom`; add___header.innerHTML = `
Job Openings
` // job list pagination const total___jobs = document.createElement('div'); total___jobs.id = 'job_____list__pages' total___jobs.style = 'text-align: right;position: relative;' total___jobs.innerHTML = ` ` conatiner__elem.appendChild(add___header) conatiner__elem.appendChild(jobListCont) conatiner__elem.appendChild(total___jobs); // modal element const overlay = document.createElement('div'); const popup = document.createElement('div'); // ADD THESE RIGHT AFTER overlay/popup are created (top-level, not inside openPopup) let overlayCloseBound = false; function getVisibleModal() { return Array.from(popup.querySelectorAll(`.${preClass}jobs___modal`)) .find(m => m.style.display !== 'none'); } function bindOverlayCloseHandlers() { if (overlayCloseBound) return; // prevent duplicate listeners // Close on header × click (event delegation) overlay.addEventListener('click', (e) => { const xBtn = e.target.closest(`.${preClass}jobs__close-x`); if (xBtn) { const visible = getVisibleModal(); if (visible) closeJobsModal(visible); } }); // Optional: close on Escape document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && document.body.contains(overlay)) { const visible = getVisibleModal(); if (visible) closeJobsModal(visible); } }); overlayCloseBound = true; } // pegination buttons const prevButton = document.getElementById(`${preClass}_prev-button`); const nextButton = document.getElementById(`${preClass}_next-button`); // showing job list function createJobElement(job) { const jobElement = document.createElement('div'); jobElement.innerHTML = `
${job['job_name']}
${ job['workplace_id'] === 1 ? job['location'] : job['workplace_id'] === 2 ? "Hybrid" : job['workplace_id'] === 3 ? "Remote" : "" }
${ job['experience'] !== null ? `
${job['experience']} Years
` : "" }
${job['type']}
${ job['salary_up'] !== null ? `
${job['currency_symbol']}${job['salary_down']} to ${job['currency_symbol']}${job['salary_up']}/ ${job['sal_period'] === 1 ? "Monthly" : job['sal_period'] === 2 ? "Yearly" : ""}
` : "" }
` // Event listener to open popup jobElement.addEventListener('click', () => { openPopup(job); }); return jobElement; } function openPopup(job) { let requirementHTML = typeof job['requirement'] === "string" ? job['requirement'].replace(/\n/g, "
") : ""; let jd_html = typeof job['jd'] === "string" ? job['jd'].replace(/\n/g, "
") : ""; // Initialize an empty array for skills let skillsArray = []; // Check if the job.skills property exists and is a non-empty string if (job.skills && job.skills.trim() !== "") { // Split the string by commas, trim whitespace, and filter out any empty strings skillsArray = job.skills.split(",") .map(skill => skill.trim()) .filter(skill => skill.length > 0); } // Create the HTML string where each skill is wrapped in a span with a dynamic class let skill_html = ""; if (skillsArray.length > 0) { // Map each skill to the desired HTML span and join them into one string skill_html = skillsArray.map(skill => `${skill}`).join(" "); } else { // Handle case of no skills – could be empty or provide a default message if desired skill_html = ""; } document.body.style.overflow = 'hidden' // BEFORE // overlay.style = 'position: fixed; overflow : auto; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); display: flex; justify-content: center; align-items: center; z-index: 1000;'; // AFTER const OFFSET = '12dvh'; // adjust to taste (e.g. '80px', '10vh', etc.) overlay.style.cssText = ` position: fixed; inset: 0; background: rgba(0,0,0,0.5); z-index: 1000; display: grid; /* grid makes it easy to place content */ place-items: start center; /* horizontally center, top-align */ padding: ${OFFSET} 16px 24px; /* <-- the top gap lives here */ overflow: auto; /* page scrolls under the overlay if needed */ `; // Create popup container // popup.style = 'background-color: #fff; padding: 20px; border-radius: 8px; max-width: 500px; width: 90%; box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 50px;'; popup.style.width = '100%' popup.innerHTML = ` ` popup.querySelectorAll(`.${preClass}jobs___modal`).forEach(m => { m.style.maxHeight = `calc(100dvh - ${OFFSET} - 24px)`; // 24px = bottom padding m.style.overflow = 'auto'; }); // Inject a close (×) button into every modal header once popup.querySelectorAll(`.${preClass}jobs___modal_header`).forEach(h => { if (!h.querySelector(`.${preClass}jobs__close-x`)) { const btn = document.createElement('button'); btn.type = 'button'; btn.className = `${preClass}jobs__close-x`; btn.setAttribute('aria-label', 'Close'); btn.innerHTML = ` `; h.appendChild(btn); } }); bindOverlayCloseHandlers(); overlay.appendChild(popup); document.body.appendChild(overlay); const descModal = document.getElementById('jobs___modal-1') const frmModal = document.getElementById('jobs___modal-2') const mailsendModal = document.getElementById('jobs___modal-3') const jobAppBtn = document.getElementById('jobs__apply__btn') const jobsubBtn = document.getElementById('jobs__subapp__btn') const jobsubmitdoneBtn = document.getElementById('jobs__appdn__btn') const closeButton = document.querySelectorAll(`.${preClass}closejobmodal`); const modals = document.querySelectorAll(`.${preClass}jobs___modal`); const backButton = document.querySelectorAll(`.${preClass}jobs__back-button`) const jobsErrorMOdal = document.getElementById('jobs___modal-4') showjobsModal(descModal) // show modal on load descModal.style.display = 'block'; let currentModalIndex = 0; closeButton.forEach((btn) => { btn.addEventListener('click', () => { const current = btn.closest(`.${preClass}jobs___modal`); if (current) closeJobsModal(current); }); }); jobAppBtn.addEventListener('click', (e) => { currentModalIndex++ closeJobsModal(descModal) showjobsModal(frmModal) }); jobsubBtn.addEventListener('click', (e) => { e.preventDefault(); currentModalIndex++ if(jobsFormValidations()!==false) { jobsSendingFromData() } }); // add event listeners to the back buttons backButton.forEach((btn) => { btn.addEventListener('click', () => { const current = btn.closest(`.${preClass}jobs___modal`); const all = Array.from(popup.querySelectorAll(`.${preClass}jobs___modal`)); const idx = all.indexOf(current); if (idx > 0) { current.style.display = 'none'; const prev = all[idx - 1]; prev.style.display = 'block'; overlay.appendChild(popup); document.body.appendChild(overlay); } else { // if first modal, just close overlay closeJobsModal(current); } }); }); jobsubmitdoneBtn.addEventListener('click', () => { closeJobsModal(mailsendModal) }) function jobsSendingFromData() { const jobs__subapp__btn = document.getElementById('jobs__subapp__btn') // Disable the button jobs__subapp__btn.innerText = "Submitting..." jobs__subapp__btn.setAttribute("disabled", true); // Get the form input values const jobid = document.getElementById('jobs___jobid').value; const email = document.getElementById('eml-add').value; const phone_number = document.getElementById('phone-add').value; const firstName = document.getElementById('fst-name').value; const lastName = document.getElementById('lst-name').value; // const name = firstName; // Create a new FormData object const formData = new FormData(); // Add the parameter to the FormData object formData.append('rwsc_name',firstName); formData.append('rwsc_lastName', lastName); formData.append('rwsc_job_id', jobid); formData.append('rwsc_email', email); formData.append('rwsc_phone', phone_number); formData.append('rwsc_compid', rwsc___settings['rwsc__comp_id']); // Set up the API endpoint and data to be sent const apiUrl = `${server_url}/submit-form-embed`; // Set up the Fetch API request fetch(apiUrl, { method: 'POST', body: formData }) .then(response => response.json()) .then(data => { jobs__subapp__btn.innerText = "Submit Application" jobs__subapp__btn.setAttribute("disabled", false); closeJobsModal(frmModal) showjobsModal(mailsendModal) // Process the response data }) .catch(error => { jobs__subapp__btn.innerText = "Submit Application" jobs__subapp__btn.setAttribute("disabled", false); // Handle the error jobsErrorMOdal closeJobsModal(frmModal) showjobsModal(jobsErrorMOdal) console.error(error); }); // Show the loader jobs__subapp__btn.setAttribute("disabled", true); } } function closeJobsModal(modals) { document.body.style.overflow = '' modals.style.display = 'none'; document.body.removeChild(overlay); } function showjobsModal(modals) { modals.style.display = 'block'; overlay.appendChild(popup); document.body.appendChild(overlay); } function jobsFormValidations() { const email = document.getElementById('eml-add').value; const phone = document.getElementById('phone-add').value; const firstName = document.getElementById('fst-name').value; const lastName = document.getElementById('lst-name').value; const jobs__email = document.getElementById('jobs__email'); const jobs__phone = document.getElementById('jobs__phone'); const jobs__fstname = document.getElementById('jobs__fstname'); const jobs__lstname = document.getElementById('jobs__lstname'); const valErr = []; // Email validation const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; // Name validation (only alphabets and spaces) const nameRegex = /^[a-zA-Z ]+$/; // Phone validation (allows digits, spaces, parentheses, and optional leading +) const phoneRegex = /^[+\d() -]+$/; // Validate email if (!emailRegex.test(email)) { jobs__email.textContent = `Email: ${email} (not valid)`; valErr.push(1); } // Validate first name if (!nameRegex.test(firstName)) { jobs__fstname.textContent = `First name: ${firstName} (not valid)`; valErr.push(1); } // Validate last name if (!nameRegex.test(lastName)) { jobs__lstname.textContent = `Last name: ${lastName} (not valid)`; valErr.push(1); } // Validate phone number if (!phoneRegex.test(phone)) { jobs__phone.textContent = `Phone: ${phone} (not valid - use only digits, spaces, (), +)`; valErr.push(1); } else { // Remove non-numeric characters except "+" const cleanPhone = phone.replace(/[^\d+]/g, ''); // Ensure at least 10 and at most 15 numeric digits const digitCount = cleanPhone.replace(/\D/g, '').length; if (digitCount < 10 || digitCount > 15) { jobs__phone.textContent = `Phone: ${phone} (not valid - must have 10-15 digits)`; valErr.push(1); } } return !(valErr.length > 0); } prevButton.addEventListener('click', () => { jobListCont.innerHTML = `
Loading...
` handlePrevButtonClick() }) nextButton.addEventListener('click', () => { jobListCont.innerHTML = `
Loading...
` handleNextButtonClick() }) // Function to handle the next button click function handleNextButtonClick() { currentPage++; loadJobs(currentPage); } // Function to handle the previous button click function handlePrevButtonClick() { if (currentPage > 1) { currentPage--; loadJobs(currentPage); } } function loadJobs(currentPage) { jobListCont.innerHTML = `
Loading...
` const apiUrl = `${server_url}get-jobs/${rwsc___settings['rwsc__comp_id']}/${currentPage}/${rwsc___settings['rwsc__per_page']}`; nextButton.disabled = true; prevButton.disabled = true; fetch(apiUrl) .then(response => response.json()) .then(data => { nextButton.disabled = false; prevButton.disabled = false; const parseData = JSON.parse(data) const jobs = parseData['job_detail']; joblistlenth = jobs.length jobListCont.innerHTML = `` jobs.forEach(job => { const jobElement = createJobElement(job); jobListCont.appendChild(jobElement); }); if(joblistlenth { nextButton.disabled = true; prevButton.disabled = true; jobListCont.innerHTML = `
Loading...
` console.error('Error fetching jobs:', error) }); } window.addEventListener('DOMContentLoaded', (event) => { // paginationcontrols() loadJobs(currentPage); // Load jobs when the widget is loaded }); } catch(error){ console.log("Script Has Some Error: Contact Support: @hirenext.io") console.log(error) } })();