1/** 2 * Simple Job Board Core Front-end JS File - V 2.10.0 3 * 4 * @author PressTigers <[email protected]>, 2016 5 * 6 * Actions List 7 * - Job Application Submission Callbacks 8 * - Date Picker Initialization 9 * - Validate Email 10 * - Initialize TelInput Plugin 11 * - Validate Phone Number 12 * - Allowable Uploaded File's Extensions 13 * - Validate Required Inputs ( Attachment, Phone & Email ) 14 * - Checkbox Group Required Attribute Callbacks 15 * - Custom Styling of File Upload Button 16 */ 17(function ($) { 18 "use strict"; 19 20 $(document).ready(function () { 21 var jobpost_submit_button = $(".app-submit"); 22 23 var jobpost_form_status = $("#jobpost_form_status"); 24 25 $(document).ready(function () { 26 27 /* Add custom validation method for file extensions */ 28 $.validator.addMethod( 29 "filetype", 30 function (value, element, param) { 31 return this.optional(element) || param.test(value.toLowerCase()); 32 }, 33 application_form.jquery_alerts["invalid_extension"] 34 ); 35 36 /* Initialize validation on the form */ 37 $(".jobpost-form").validate({ 38 ignore: [], /* Ensure hidden fields are also validated */ 39 errorPlacement: function (error, element) { 40 /* Customize error messages */ 41 error.insertAfter(element); 42 }, 43 submitHandler: function (form) { 44 45 /* Add your submission function here */ 46 var formObj = $("#sjb-application-form"); 47 var datastring = new FormData(formObj[0]); 48 submitForm(datastring); 49 }, 50 }); 51 52 53 /* Add rules for required fields with class 'sjb-required' */ 54 $(".sjb-required").each(function () { 55 let fieldName = $(this).attr("name"); 56 /* Check if fieldName exists and is a string */ 57 if (typeof fieldName === "string") { 58 fieldName = fieldName.replace(/^jobapp_/, ""); 59 60 /* Replace underscores with spaces and capitalize each word */ 61 var fieldLabel = $(this).data("label") || fieldName.replace(/_/g, " ").replace(/\b\w/g, (char) => char.toUpperCase()); 62 $(this).css("color", "black"); 63 if(fieldLabel == 'Tc' || fieldLabel == 'Pp'){ 64 $(this).rules("add", { 65 required: true, 66 messages: { 67 required: application_form.jquery_alerts["sjb_application_input_required"], 68 }, 69 }); 70 }else{ 71 $(this).rules("add", { 72 required: true, 73 messages: { 74 required: fieldLabel + ' ' + application_form.is_required, 75 }, 76 }); 77 } 78 } 79 }); 80 81 /* Add email validation for fields with class 'sjb-email-address' */ 82 $(".sjb-email-address").each(function () { 83 let fieldName = $(this).attr("name"); /* Get the field name */ 84 85 86 if (typeof fieldName === "string") { 87 fieldName = fieldName.replace(/^jobapp_/, ""); 88 var fieldLabel = $(this).data("label") || fieldName.charAt(0).toUpperCase() + fieldName.slice(1); 89 fieldLabel = fieldLabel.replace('_', ' '); 90 91 92 $(this).css("color", "black"); /* Set text color to black */ 93 $(this).rules("add", { 94 required: true, 95 email: true, 96 messages: { 97 required: fieldLabel + ' ' + application_form.is_required, 98 email: application_form.jquery_alerts["sjb_application_enter_valid"] + fieldLabel, 99 }, 100 }); 101 } 102 }); 103 var allowed_file_exts = Array.isArray(application_form.setting_extensions) 104 ? application_form.setting_extensions.filter(ext => typeof ext === "string").join(",") 105 : ""; 106 if(allowed_file_exts == ''){ 107 allowed_file_exts = application_form.allowed_extensions.filter(ext => typeof ext === "string").join(",") 108 } 109 var fileTypePattern = new RegExp( 110 `(\\.${allowed_file_exts.replace(/,/g, "|")})$`, 111 "i" 112 ); 113 114 /* File type validation for applicant resume */ 115 if (!$("#applicant-resume").hasClass("sjb-not-required")) { 116 $("#applicant-resume").rules("add", { 117 required: true, 118 filetype: fileTypePattern, 119 messages: { 120 required: 121 application_form.jquery_alerts["sjb_application_resume_required"] + application_form.is_required, 122 filetype: application_form.jquery_alerts["invalid_extension"], 123 }, 124 }); 125 } 126 }); 127 128 129 function initializePopupValidation() { 130 /* Reapply validation to dynamically added popup form */ 131 const popupForm = $(".jobpost-form"); 132 133 134 popupForm.validate({ 135 ignore: [], /* Ensure hidden fields are also validated */ 136 errorPlacement: function (error, element) { 137 error.insertAfter(element); 138 }, 139 submitHandler: function (form) { 140 /* Custom submission logic */ 141 const formObj = $(form); 142 const datastring = new FormData(formObj[0]); 143 submitForm(datastring); 144 }, 145 }); 146 147 /* Add rules for required fields with class 'sjb-required' */ 148 popupForm.find(".sjb-required").each(function () { 149 let fieldName = $(this).attr("name"); 150 if (typeof fieldName === "string") { 151 fieldName = fieldName.replace(/^jobapp_/, ""); 152 var fieldLabel = $(this).data("label") || fieldName.replace(/_/g, " ").replace(/\b\w/g, (char) => char.toUpperCase()); 153 $(this).css("color", "black"); 154 if(fieldLabel == 'Tc' || fieldLabel == 'Pp'){ 155 $(this).rules("add", { 156 required: true, 157 messages: { 158 required: application_form.jquery_alerts["sjb_application_input_required"], 159 }, 160 }); 161 }else{ 162 $(this).rules("add", { 163 required: true, 164 messages: { 165 required: fieldLabel + ' ' + application_form.is_required, 166 }, 167 }); 168 } 169 } 170 }); 171 172 /* Add email validation for fields with class 'sjb-email-address' */ 173 popupForm.find(".sjb-email-address").each(function () { 174 let fieldName = $(this).attr("name"); 175 if (typeof fieldName === "string") { 176 fieldName = fieldName.replace(/^jobapp_/, ""); 177 var fieldLabel = $(this).data("label") || fieldName.charAt(0).toUpperCase() + fieldName.slice(1); 178 fieldLabel = fieldLabel.replace('_', ' '); 179 180 $(this).css("color", "black"); 181 $(this).rules("add", { 182 required: true, 183 email: true, 184 messages: { 185 required: fieldLabel + ' ' + application_form.is_required, 186 email: application_form.jquery_alerts["sjb_application_enter_valid"] + fieldLabel, 187 }, 188 }); 189 } 190 }); 191 192 /* File type validation for applicant resume */ 193 var allowed_file_exts = Array.isArray(application_form.setting_extensions) 194 ? application_form.setting_extensions.filter(ext => typeof ext === "string").join(",") 195 : ""; 196 197 if(allowed_file_exts == ''){ 198 allowed_file_exts = application_form.allowed_extensions.filter(ext => typeof ext === "string").join(",") 199 } 200 const fileTypePattern = new RegExp(`(\\.${allowed_file_exts.replace(/,/g, "|")})$`, "i"); 201 setTimeout(function() { 202 if (!popupForm.find("#applicant-resume").hasClass("sjb-not-required")) { 203 popupForm.find("#applicant-resume").rules("add", { 204 required: true, 205 filetype: fileTypePattern, 206 messages: { 207 required: application_form.jquery_alerts["sjb_application_resume_required"]+ application_form.is_required, 208 filetype: application_form.jquery_alerts["invalid_extension"], 209 }, 210 }); 211 } 212 }, 500); 213 } 214 215 function submitForm(datastring) { 216 217 const jobpost_form_status = $("#jobpost_form_status"); 218 const jobpost_submit_button = $(".jobpost-form .app-submit"); 219 220 $(".sjb-loading").show(); 221 $.ajax({
222 url: application_form.ajaxurl, 223 type: "POST", 224 dataType: "json", 225 data: datastring, 226 async: true, 227 cache: false, 228 contentType: false, 229 processData: false, 230 statusCode: { 231 500: function (responseObject, textStatus, jqXHR) { 232 alert( 233 "505: Server internal error occurred while processing application. Please try again." 234 ); 235 $(".sjb-loading").hide(); 236 237 /* Translation Ready String Through Script Localization */ 238 jobpost_form_status.html( 239 responseObject.responseJSON["error"] + 240 " " + 241 application_form.jquery_alerts["application_not_submitted"] + 242 "</div>" 243 ); 244 }, 245 503: function (responseObject, textStatus, errorThrown) { 246 alert("503: Service Unavailable. Please try again."); 247 $(".sjb-loading").hide(); 248 249 /* Translation Ready String Through Script Localization */ 250 jobpost_form_status.html( 251 responseObject.responseJSON["error"] + 252 " " + 253 application_form.jquery_alerts["application_not_submitted"] + 254 "</div>" 255 ); 256 }, 257 }, 258 beforeSend: function () { 259 jobpost_submit_button.attr("disabled", "disabled"); 260 }, 261 success: function (response) { 262 if (response["success"] == true) { 263 $(".jobpost-form").slideUp(); 264 265 /* Translation Ready String Through Script Localization */ 266 jobpost_form_status.html(response["success_alert"]); 267 } 268 269 if (response["success"] == false) { 270 /* Translation Ready String Through Script Localization */ 271 jobpost_form_status.html( 272 response["error"] + 273 " " + 274 application_form.jquery_alerts["application_not_submitted"] + 275 "</div>" 276 ); 277 278 $(".sjb-loading").hide(); 279 280 jobpost_submit_button.removeAttr("disabled"); 281 } 282 }, 283 }); 284 } 285 286 287 /** 288 * Initialize Datepicker 289 * 290 * @since 2.10.0 291 */ 292 function initialize_date() { 293 /* Date Picker */ 294 295 $(".sjb-datepicker").datepicker({ 296 dateFormat: application_form.sjb_date_format, 297 changeMonth: true, 298 changeYear: true, 299 yearRange: "-100:+50", 300 }); 301 } 302 initialize_date(); 303 304 /** 305 * Application Form -> On Input Email Validation 306 * 307 * @since 2.2.0 308 */ 309 $(document).on("input", ".sjb-email-address", function () { 310 var input = $(this); 311 var re = 312 /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/; 313 var is_email = re.test(input.val()); 314 var error_element = $(this).next(); 315 if (is_email) { 316 input.removeClass("invalid").addClass("valid"); 317 error_element.hide(); 318 } else { 319 input.removeClass("valid").addClass("invalid"); 320 } 321 }); 322 323 /** 324 * Initialize TelInput Plugin 325 * 326 * @since 2.2.0 327 */ 328 function initialize_tel() { 329 if ($(".sjb-phone-number").length) { 330 var telInput_id = $(".sjb-phone-number") 331 .map(function () { 332 return this.id; 333 }) 334 .get(); 335 336 for (var input_ID in telInput_id) { 337 var telInput = $("#" + telInput_id[input_ID]); 338 // Check if the intlTelInput function exists (i.e., the library is loaded) 339 if (typeof $.fn.intlTelInput === 'undefined') { 340 // If the intlTelInput library is not loaded or missing, exit the function 341 return; 342 } 343 telInput.intlTelInput({ 344 initialCountry: "auto", 345 geoIpLookup: function (callback) { 346 $.get("https://ipinfo.io", function () {}, "jsonp").always( 347 function (resp) { 348 var countryCode = resp && resp.country ? resp.country : ""; 349 callback(countryCode); 350 } 351 ); 352 }, 353 }); 354 } 355 } 356 } 357 if(application_form.isPhoneFormattingdisabled !='yes'){ 358 initialize_tel(); 359 } 360 361 /** 362 * Application Form -> Phone Number Validation 363 * 364 * @since 2.2.0 365 */ 366 $(document).on("input", ".sjb-phone-number", function () { 367 var telInput = $(this); 368 var telInput_id = $(this).attr("id"); 369 var error_element = $("#" + telInput_id + "-invalid-phone"); 370 error_element.hide(); 371 372 /* Validate Phone Number */ 373 if ($.trim(telInput.val())) { 374 if (typeof telInput.intlTelInput === "function" && telInput.intlTelInput("isValidNumber")) {
375 telInput.removeClass("invalid").addClass("valid"); 376 error_element.hide(); 377 } else { 378 telInput.removeClass("valid").addClass("invalid"); 379 } 380 } 381 }); 382 383 384 /** 385 * Stop Form Submission -> On Required Attachments 386 * 387 * @since 2.3.0 388 */ 389 function sjb_is_attachment(event) { 390 var error_free = true; 391 $(".sjb-attachment").each(function () { 392 var element = $("#" + $(this).attr("id")); 393 var valid = element.hasClass("valid"); 394 var is_required_class = element.hasClass("sjb-not-required"); 395 396 /* Set Error Indicator on Invalid Attachment */ 397 if (!valid) { 398 if (!(is_required_class && 0 === element.get(0).files.length)) { 399 error_free = false; 400 } 401 } 402 403 /* Stop Form Submission */ 404 if (!error_free) { 405 event.preventDefault(); 406 } 407 }); 408 409 return error_free; 410 } 411 412 /** 413 * Stop Form Submission -> On Invalid Email/Phone 414 * 415 * @since 2.2.0 416 */ 417 function sjb_is_valid_input(event, input_type, input_class) { 418 var jobpost_form_inputs = $("." + input_class).serializeArray(); 419 var error_free = true; 420 421 for (var i in jobpost_form_inputs) { 422 var element = $("#" + jobpost_form_inputs[i]["name"]);
423 var valid = element.hasClass("valid"); 424 var is_required_class = element.hasClass("sjb-not-required"); 425 if (!(is_required_class && "" === jobpost_form_inputs[i]["value"])) { 426 if ("email" === input_type) { 427 var error_element = $("span", element.parent()); 428 } else if ("phone" === input_type) { 429 var error_element = $( 430 "#" + jobpost_form_inputs[i]["name"] + "-invalid-phone" 431 ); 432 } 433 434 /* Set Error Indicator on Invalid Input */ 435 if (!valid) { 436 error_element.show(); 437 error_free = false; 438 } else { 439 error_element.hide(); 440 } 441 442 /* Stop Form Submission */ 443 if (!error_free) { 444 event.preventDefault(); 445 } 446 } 447 } 448 return error_free; 449 } 450 451 /** 452 * Remove Required Attribute from Checkbox Group -> When one of the option is selected. 453 * 454 * Add Required Attribute from Checkboxes Group -> When none of the option is selected. 455 * 456 * @since 2.3.0 457 */ 458 function initialize_checkbox() { 459 var requiredCheckboxes = $(":checkbox[required]"); 460 requiredCheckboxes.on("change", function () { 461 var checkboxGroup = requiredCheckboxes.filter( 462 '[name="' + $(this).attr("name") + '"]' 463 ); 464 var isChecked = checkboxGroup.is(":checked"); 465 checkboxGroup.prop("required", !isChecked); 466 }); 467 } 468 initialize_checkbox(); 469 470 /* Accept Numbers Input Only */ 471 function initialize_keypress() { 472 $(".sjb-numbers-only").keypress(function (evt) { 473 evt = evt ? evt : window.event; 474 var charCode = evt.which ? evt.which : evt.keyCode; 475 if (charCode > 31 && (charCode < 48 || charCode > 57)) { 476 return false; 477 } 478 return true; 479 }); 480 } 481 initialize_keypress(); 482 483 /* 484 * Custom Styling of Upload Field Button 485 * 486 * @since 2.4.0 487 */ 488 var file = { 489 maxlength: 20, /* maximum length of filename before it's trimmed */ 490 491 convert: function () { 492 /* Convert all file type inputs. */ 493 $("input[type=file].sjb-attachment").each(function () { 494 $(this).wrap('<div class="file" />'); 495 $(this) 496 .parent() 497 .prepend("<div>" + application_form.file["browse"] + "</div>"); 498 $(this) 499 .parent() 500 .prepend( 501 "<span>" + application_form.file["no_file_chosen"] + "</span>" 502 ); 503 $(this).fadeTo(0, 0); 504 $(this).attr("size", "50"); /* Use this to adjust width for FireFox. */ 505 }); 506 }, 507 update: function (x) { 508 /* Update the filename display. */ 509 var filename = x.val().replace(/^.*\\/g, ""); 510 if (filename.length > $(this).maxlength) { 511 trim_start = $(this).maxlength / 2 - 1; 512 trim_end = trim_start + filename.length - $(this).maxlength + 1; 513 filename = 514 filename.substr(0, trim_start) + 515 "…" + 516 filename.substr(trim_end); 517 } 518 519 if (filename == "") filename = application_form.file["no_file_chosen"]; 520 x.siblings("span").html(filename); 521 }, 522 }; 523 524 file.convert(); 525 $(document).on("change", "input[type=file].sjb-attachment", function () { 526 file.update($(this)); 527 }); 528 529 $(document).on("click", "body #quick-apply-btn", function (e) { 530 e.preventDefault(); 531 532 var obj = $(this); 533 var job_id = obj.attr("job_id"); 534 if (obj.data("loading")) { 535 return; 536 } 537 obj.data("loading", true); 538 $.ajax({
539 url: application_form.ajaxurl, 540 type: "POST", 541 data: { 542 action: "fetch_quick_job", 543 job_id: job_id, 544 }, 545 success: function (response) { 546 $(".sjb-page").append(response); 547 $(".sjb-page").find(".popup-outer").fadeIn(); 548 file.convert(); 549 initialize_date(); 550 initialize_tel(); 551 initialize_checkbox(); 552 initialize_keypress(); 553 initializePopupValidation(); 554 $(".popup-outer .sjb-page .sjb-detail") 555 .prepend(`<div class="sjb-quick-apply-modal-close-btn"> 556 <span class="close">x</span> 557 </div>`); 558 }, 559 complete: function () { 560 obj.data("loading", false); 561 }, 562 error: function () { 563 obj.data("loading", false); 564 }, 565 }); 566 }); 567 568 $(document).on("click", ".sjb-quick-apply-modal-close-btn", function () { 569 if (confirm(application_form.jquery_alerts.sjb_quick_job_close)) { 570 $(".sjb-page .popup-outer").fadeOut(); 571 $(".sjb-page .popup-outer").remove(); 572 } 573 }); 574 575 $(".sjb_view_more_btn").on("click", function () { 576 var post_id = $(this).data("id"); 577 $("#sjb_more_content_" + post_id).css("display", "block"); 578 $("#sjb_less_content_" + post_id).css("display", "none"); 579 $("#sjb_view_less_btn_" + post_id).css("display", "inline"); 580 }); 581 582 $(".sjb_view_less_btn").on("click", function () { 583 var post_id = $(this).data("id"); 584 $("#sjb_more_content_" + post_id).css("display", "none"); 585 $("#sjb_less_content_" + post_id).css("display", "block"); 586 $("#sjb_view_less_btn_" + post_id).css("display", "none"); 587 }); 588 var filess = { 589 maxlength: 20, /* maximum length of filename before it's trimmed */ 590 591 update: function (x) { 592 /* Update the filename display. */ 593 var files = x.prop("files"); 594 var fileList = ""; 595 var count = 0; 596 for (var i = 0; i < files.length; i++) { 597 fileList += "<p>" + files[i].name + "</p>"; 598 count++; 599 } 600 601 if (count > 1) { 602 x.siblings("span").html(count + "" + " Files Selected"); 603 } else if (count == 1) { 604 x.siblings("span").html(files[0].name); 605 } 606 }, 607 }; 608 /* Update the resume field value */ 609 $(document).on("change", "input[name='applicant_resume[]']", function () { 610 filess.update($(this)); 611 }); 612 613 /* Tags in Search filter */ 614 $(".sjb-tags-search").on("click", function (event) { 615 event.preventDefault(); /* Prevent default link behavior */ 616 617 if ($(this).hasClass("tag-active")) { 618 $(this).removeClass("tag-active"); 619 } else { 620 $(this).addClass("tag-active"); 621 } 622 623 var linkValue = $(".tag-active") 624 .map(function () { 625 return $(this).data("value"); 626 }) 627 .get(); 628 629 $("#selected_tag").val(linkValue); 630 $(".filters-form").submit(); /* Submit the form */ 631 }); 632 }); 633 634 $(document).on('click', '.btn-app-modal-close', function(e) { 635 e.preventDefault(); 636 $('.sjb-quick-apply-modal-close-btn').trigger('click'); 637 }); 638 639 })(jQuery); 640
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.