CINXE.COM

New Ticket - Ballotpedia Support

<!DOCTYPE html> <html lang="en"> <head> <title>New Ticket - Ballotpedia Support</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="ROBOTS" content="NOINDEX, NOFOLLOW"> <link rel="stylesheet" href="https://hf-files-oregon.s3.amazonaws.com/hdpballotpedia_user_customized/support_center_brand_primary_dynamic.css?key=82cb6664-883c-4bb9-8974-d28848181df3"> <link rel="shortcut icon" href="https://hf-files-oregon.s3.amazonaws.com/hdpballotpedia_user_customized/favicon.png" /> <link href="https://d12tly1s0ox52d.cloudfront.net/static/100425114413/support_center/css/vendor.css" rel="stylesheet" type="text/css"> <script src="https://d12tly1s0ox52d.cloudfront.net/static/100425114413/support_center/js/vendor.js"></script> </head> <body class="hf-support-center "> <div class=""> <div id="announcementBanner" style=" display: none; padding: 12px 0; border-bottom: 1px solid #a9d5de; background: #f8ffff; text-align: center; color: #333; font-size: 14px; clear: both;" class="hf-announcement-banner"> You are using an unsupported browser. Please update your browser to the latest version on or before July 31, 2020. <div id="announcementClose" style="padding: 2px 10px; cursor: pointer; float: right;"> <img src="/media/svgs/close-icon.svg" alt="close" /> </div> </div> <div id="articlePreviewBanner" style=" display: none; padding: 12px 0; border-bottom: 1px solid #a9d5de; background: #f8ffff; text-align: center; color: #333; font-size: 14px; clear: both;" class="hf-announcement-banner"> You are viewing the article in preview mode. It is not live at the moment. </div> <div class="above_header"> </div> <div class="hf-header"> <div class="hf-user-profile-overlay" id="hf-user-profile-overlay"></div> <div data-printable="false" class="hf-header_wrap" id="hf-header-wrap_2"> <header id="hf-header_2" class="hf-header"> <div class="hf-u-vertically-centered-container"> <div class="hf-header_logo-wrap hf-mod-desktop"> <a href="https://ballotpedia.happyfox.com/home"><img src="https://s3-us-west-2.amazonaws.com/hf-files-oregon/hdpballotpedia_user_customized/2020/06-18/0fa04f8f-8c00-4861-ab2a-896b4401d95f/BP-Initials-ballotpedia-logo-small.png" class="hf-header_logo" alt="company logo"></a> </div> <div class="hf-header_logo-wrap hf-mod-mobile"> <a href="https://ballotpedia.happyfox.com/home"><img src="https://s3-us-west-2.amazonaws.com/hf-files-oregon/hdpballotpedia_user_customized/2020/06-18/0fa04f8f-8c00-4861-ab2a-896b4401d95f/BP-Initials-ballotpedia-logo-small.png" class="hf-header_logo hf-mod-mobile-logo" alt="company logo"></a> </div> <div class="hf-header-support-center-name">Ballotpedia Support</div> </div> <nav class="hf-u-vertically-centered-container hf-margin-left-auto" aria-label="Main Menu"> <a class="skip-to-content-link" href="#main"> Skip to content </a> <div class="hf-header_link"><a href="https://ballotpedia.happyfox.com/new/" class="hf-header_link-text" title="Submit Ticket">Submit Ticket</a></div> <div class="hf-header_link"><a href="https://ballotpedia.happyfox.com/?login=1" class="hf-header_link-text" title="Login">Login</a></div> </nav> <div class="hf-hamburger-menu-container"> <input type="checkbox" class="hf-open-hamburger-menu" id="hf-open-hamburger-menu"> <label for="hf-open-hamburger-menu" class="hf-hamburger-menu-toggle" role="navigation"> <p class="hf-menu-label-text">Menu</p> <div class="hf-spinner hf-diagonal hf-part-1"></div> <div class="hf-spinner hf-horizontal"></div> <div class="hf-spinner hf-diagonal hf-part-2"></div> </label> <nav id="hf-hamburger-menu"> <ul class="hf-hamburger-menu-inner"> <li class="hf-header_mobile-link"><a href="https://ballotpedia.happyfox.com/new/" class="hf-header_link-text">Submit Ticket</a></li> <li class="hf-header_mobile-link"><a href="https://ballotpedia.happyfox.com/?login=1" class="hf-header_link-text">Login</a></li> </ul> </nav> </div> </header> </div> <style> .hf-sc-search-loader.loader { position: absolute; right: 10px; top: calc(50% - 10px); width: 20px; padding: 2px; aspect-ratio: 1; border-radius: 50%; background: rgba(32, 32, 45, 1); --mask: conic-gradient(#0000 10%,#000), linear-gradient(#000 0 0) content-box; -webkit-mask: var(--mask); mask: var(--mask); -webkit-mask-composite: source-out; mask-composite: subtract; animation: loader-spin 1s infinite linear; } @keyframes loader-spin {to{transform: rotate(1turn)}} .hf-mobile-search-bar .hf-sc-search-loader.loader { right: -5px; } .hf-banner_search-box { padding: 20px 35px 20px 40px; } @media only screen and (max-width : 812px) { .hf-banner_search-box { padding: 10px 35px 10px 40px; } } </style> <script type="text/javascript"> /** * TLS Deprecation announcement banner. This needs to be rendered above all widgets and hence the * HTML part is added in base.html above the user announcement section. The script to show/hide * is added here in order to get the SSL Protocol from the request which is set in the context * object for header. * **/ var isBannerDismissed = localStorage.getItem('hf-tls-deprecation_warning_dismissed'); var sslProtocol = "None"; if (['TLSv1', 'TLSv1.0', 'TLSv1.1'].indexOf(sslProtocol) > -1 && !isBannerDismissed) { var bannerElement = document.querySelector('#announcementBanner'); bannerElement.style.display = 'block'; bannerElement.classList.add('hf-announcement-banner-open'); document.querySelector('#announcementClose').addEventListener('click', function() { localStorage.setItem('hf-tls-deprecation_warning_dismissed', true); bannerElement.style.display = 'none'; bannerElement.classList.remove('hf-announcement-banner-open'); var ticketListWrap = $('.hf-ticket-list-wrap'); var ticketDetailsWrap = $('.hf-ticket-details'); var mySettingsWrap = $('.hf-settings-wrap'); var is_sticky = "True"; if (is_sticky == "True") { onScroll(); // To reset the sticky header positions } if (ticketListWrap.length) { ticketListWrap.css('top', ticketListWrap.position().top - 44); } if (ticketDetailsWrap.length) { ticketDetailsWrap.css('top', ticketDetailsWrap.position().top - 44); } if (mySettingsWrap.length) { mySettingsWrap.css('top', mySettingsWrap.position().top - 44); } }, { once: true }); } </script> <script type="text/javascript"> window.onscroll = function() { onScroll() }; function clearTicketSearch(){ var url = new URLSearchParams(window.location.search); url.delete('q'); window.location.href = '/tickets/?' + url.toString(); } function onScroll() { var is_sticky = "True"; if (is_sticky == "True") { var announcementHeight = $('.hf-announcement').outerHeight() || 0; var windowScrollValue = $(window).scrollTop() if ( windowScrollValue >= announcementHeight) { var bodyPadding = 60 + ($('.hf-announcement-banner-open').outerHeight() || 0); $('.hf-header, .hf-announcement-banner, .hf-mobile-search-bar').addClass('hf-mod-sticky'); $('body').css("padding-top", bodyPadding + 'px'); } else{ $('.hf-header, .hf-announcement-banner, .hf-mobile-search-bar').removeClass('hf-mod-sticky'); $('body').css("padding-top", '0'); } } if (window.pageYOffset > 50) { $('#hf-scroll-to-top').fadeIn(); } else { $('#hf-scroll-to-top').fadeOut(); } } $(document).ready(function() { $('.hf-mobile-search-trigger').click(function(){ $('.hf-mobile-search-bar').slideDown(); $('#hf-clear-mobile-search').click(function() { $('.hf-mobile-search-bar input').val(""); $('.hf-mobile-search-bar').slideUp(); }) }) $(window).resize(function() { if( $(this).width() > 812 ) { $('.hf-mobile-search-bar').hide(); } }); $('#hf-supportCenterLanguageSwitcher').on('keydown click', function(e) { if(e.keyCode === 13 || e.type == "click") { $('#hf-supportCenterLanguageSwitcher').addClass('hf-sc-dropdown-open'); $('.hf-sc-language-dropdown-option').attr('tabindex', '0'); $(document).on('click.languageSwitcher', function(event) { if (!$(event.target).parents().hasClass('hf-sc-custom-dropdown')) { $('#hf-supportCenterLanguageSwitcher').removeClass('hf-sc-dropdown-open'); $('.hf-sc-language-dropdown-option').removeAttr('tabindex'); $(document).off('.hf-languageSwitcher'); } }); } }); $('.hf-sc-language-dropdown-option').on('keydown click', function(e) { if(e.keyCode === 13 || e.type == "click") { var currentLocation = window.location; var language_code = $(this).data('value'); var language_id = $(this).data('index'); if (currentLocation.pathname.includes("/kb/article")){ var available_translations = ""; var available_translation_ids = available_translations.map(function(item) { return item.language_id }); var articleMapping = {}; available_translations.forEach(function(item){ articleMapping[item.language_id] = item.article_id }); if(available_translation_ids.indexOf(language_id) >= 0){ document.cookie = "sc_language=" + language_code + "; path=/ "; window.location = "/kb/article/" + articleMapping[language_id]; } } document.cookie = "sc_language=" + language_code + "; path=/ "; window.location.reload(); } }); $('#hf-user-profile-trigger').on('click', function() { if($('#hf-user-profile-dropdown').attr('data-open') == 'true') { $('#hf-user-profile-dropdown').attr('data-open', 'false'); $('#hf-user-profile-overlay').hide(); } else { var bannerHeight = $('.hf-announcement').is(':visible') ? $('.hf-announcement').outerHeight(true) : 0; var headerHeight = $('.hf-header').outerHeight(true); $('#hf-user-profile-dropdown').attr('data-open', 'true'); $('.hf-user-profile-overlay').css('top', bannerHeight + headerHeight); $('#hf-user-profile-overlay').show(); } return false; }); var delay = (function() { let timer = 0; return function (callback, ms) { clearTimeout(timer); timer = setTimeout(callback, ms); }; })(); $('.hf-sc-search-box').on({ keyup: function(e) { e.stopPropagation(); var search_text = encodeURIComponent($(this).val()); var search_suggestions_container = $(e.target).siblings('.hf-sc-search-suggestions'); var currentlyHighlightedOption = search_suggestions_container.find('.hf-sc-search-suggestion[aria-current=true]'); if (e.keyCode === 13) { if (currentlyHighlightedOption.length) { window.location.href = currentlyHighlightedOption.find('a').attr('href'); } else { const searchLoader = e.target.parentElement.querySelector('.hf-sc-search-loader'); if (searchLoader) { searchLoader.style.display = 'block'; } window.location.href = '/kb/search/?q=' + search_text; } } else if (e.keyCode === 40) { if (currentlyHighlightedOption.next().length) { currentlyHighlightedOption.attr('aria-current', false); currentlyHighlightedOption.next().attr('aria-current', true); } else { currentlyHighlightedOption.attr('aria-current', false); currentlyHighlightedOption = search_suggestions_container.find('li:first'); currentlyHighlightedOption.attr('aria-current', true); search_suggestions_container.scrollTop(0); } } else if (e.keyCode === 38) { if (currentlyHighlightedOption.prev().length) { currentlyHighlightedOption.attr('aria-current', false); currentlyHighlightedOption.prev().attr('aria-current', true); } } else { if (search_text.length >= 3) { $('.hf-sc-search-suggestions').remove(); $('.hf-sc-search-container').removeClass('hf-mod-open'); delay(function() { $.ajax('/get_related_kb_forums/', { contentType: 'application/json', data: { 'text': search_text }, success: function(results) { if (results.length) { $('.hf-sc-search-container').addClass('hf-mod-open'); $('<div class="hf-mobile-overlay"></div>').appendTo('body'); var $ul = $('<ul class="hf-sc-search-suggestions"></ul>'); results.forEach(function(result) { if (result.type === 'kb') { $ul.append('<li class="hf-sc-search-suggestion hf-mod-' + result.type +'"><a href="/kb/article/' + result["id"] +'/">' + '<span class="hf-sc-search-suggestion_title" title="Go to KB article">' + result["title"] + '</span>' +"</a></li>"); } if (result.type === 'forum') { $ul.append('<li class="hf-sc-search-suggestion hf-mod-' + result.type +'"><a href="/forum/post/' + result["id"] +'/">' + '<span class="hf-sc-search-suggestion_title" title="Go to forum post">' + result["title"] + '</span>' +"</a></li>"); } if (result.type === 'assist_ai_result') { $ul.append('<li class="hf-sc-search-suggestion hf-mod-' + result.type +'"><a href="' + result["url"] +'">' + '<span class="hf-sc-search-suggestion_title" title="Go to ' + result["source"] + ' article">' + result["title"] + '</span>' +'<em class="hf-sc-search-suggestion_source">' + result["source"] + '</em></a></li>'); } }); $ul.appendTo($('.hf-sc-search-container')); $ul.find('li:first').attr('aria-current', true); } } }) }, 600); } else { $('.hf-sc-search-suggestions').remove(); $('.hf-sc-search-container').removeClass('hf-mod-open'); $('.hf-mobile-overlay').remove(); } } if(search_suggestions_container.length && currentlyHighlightedOption.length) { var search_suggestions_container_top = search_suggestions_container.offset().top; var search_suggestions_container_bottom = search_suggestions_container_top + search_suggestions_container.height(); var elemTop = currentlyHighlightedOption.offset().top; var elemBottom = elemTop + currentlyHighlightedOption.height(); if (elemBottom >= search_suggestions_container_bottom) { search_suggestions_container.scrollTop(0); search_suggestions_container.scrollTop(currentlyHighlightedOption.offset().top - search_suggestions_container.height()); } } } }); $(document).click( function(){ $('.hf-sc-search-suggestions').remove(); $('.hf-sc-search-container').removeClass('hf-mod-open'); $('.hf-mobile-overlay').remove(); $('#hf-user-profile-dropdown').attr('data-open', 'false'); $('#hf-user-profile-overlay').hide(); }); }); window.addEventListener("pagehide", function(event) { $('.hf-sc-search-loader').hide(); } ); </script> </div> <style type="text/css" rel="stylesheet"> .hf-form-field_currency-container { display: flex; align-items: center; margin: 5px 0; } .hf-form-field_currency-container .hf-form-field_currency-sign { display: inline-block; padding: 10px 12px; border: 1px solid #e8e8e8; border-right: 0; border-top-left-radius: 5px; border-bottom-left-radius: 5px; font-size: 14px; background-color: #fafafa; } .hf-form-field_currency-container .hf-form-field_value { margin: 0; border-top-left-radius: 0; border-bottom-left-radius: 0; } </style> <div id="main" class="hf-main"> <div class="hf-toast-message hf-u-hide hf-mod-error"> <div class="hf-toast-message_text"></div> </div> <section class="hf-new-ticket-page "> <section class="hf-welcome-banner hf-welcome-banner_16" id="hf-welcome-banner-wrap_16"> <div class="hf-welcome-banner_overlay hf-welcome-banner_overlay_16"></div> <div class="hf-custom-container"> <div class="hf-welcome-banner_content"> <div class="hf-welcome-banner_heading hf-welcome-banner_heading_16">How can we help?</div> </div> </div> </section> <section data-printable="false" class="hf-custom-textarea_17"> <div class="hf-custom-container"> <div class="hf-custom-textarea_content_17 hf-editor-reset_list"><span style="font-family:Helvetica;"><span style="font-size:14px;">Please fill out and submit the form below, making sure to include any information we might need to complete your request.</span></span> <span style="font-family:Helvetica;"><span style="font-size:14px;">We appreciate your help in building the encyclopedia of American politics!</span></span></div> </div> </section> <section class="hf-custom-message-after-ticket-creation" style="display:none;"> <div class="hf-custom-container"> <div class="hf-custom-message-container"> <div class="hf-custom-message-after-ticket-creation_content hf-editor-reset_list"><p><span style="font-size:14px"><span style="font-family:Helvetica">Thanks for reaching out to Ballotpedia! We&#39;ll be in touch shortly. </span></span></p></div> </div> </div> </section> <script id="google_recaptcha_url" src='https://recaptcha.net/recaptcha/api.js'></script> <div class="hf-custom-container"> <form class="hf-new-ticket-form " id="new-ticket-form" action="" method="POST" xhr="xhr"> <input type='hidden' name='from_v2' value=true /> <input type='hidden' name='csrfmiddlewaretoken' value='aYv17FnXq9NvjacmLEJLxkbaPkqaWkEAakNIojgjxatu0HbfQkc0hT3GdtCrkeog' /> <h6 class="hf-new-ticket-header" role="heading" aria-level="2"> Create a New Ticket </h6> <div class="hf-ticket-fields"> <p class="hf-ticket-fields_header">Tell us more</p> <input type="hidden" name="category" id="id_category" value="2"> <div id="ticket-custom-fields-container" class="hf-mod-small_width"></div> <div class="hf-form-field"> <label for="id_subject" class="hf-form-field_label hf-form-field_required">Subject</label> <div class="hf-subject-field-input-container" id="subject-input-container"> <input type="text" class="hf-form-field_value hf-subject-field-input" id="id_subject" autocomplete="off" name="subject" placeholder="Enter subject" data-required="true"> <span class="hf-form-field_error-text"></span> </div> </div> <div class="hf-form-field hf-ticket-message-container hf-u-position-relative"> <label for="id_html" class="hf-form-field_label hf-form-field_required">Message</label> <textarea class="hf-form-field_value" id="id_html" name="html" data-required="true"></textarea> <span class="hf-form-field_error-text"></span> </div> <div class="hf-attach-file-container" id="attach-file-drop-area"> <input class="hf-form-attach_button" type="file" name="files" id="attach-file-input" multiple onchange="handleUploadedFiles(this)" /> <div class="hf-form-field_label">Drag & drop a file to attach it, or</div> <label onClick="triggerExternalFileUpload(event)" onKeyDown="triggerExternalFileUpload(event)" tabindex="0"> <a class="hf-attach-file_link">Browse for a file</a> </label> </div> <div class="hf-attach-file_list" id="attached-files-list"></div> <span class="hf-form-field_error-text"></span> </div> <div class="hf-contact-fields"> <p class="hf-contact-fields_header">How can we contact you?</p> <div class="hf-form-field hf-mod-small_width"> <label for="id_name" class="hf-form-field_label hf-form-field_required">Full name</label> <input type="text" class="hf-form-field_value" id="id_name" name="name" placeholder="Enter name" data-required="true"> <span class="hf-form-field_error-text"></span> </div> <div class="hf-form-field hf-mod-small_width"> <label for="id_email" class="hf-form-field_label hf-form-field_required">Email</label> <input type="text" class="hf-form-field_value" id="id_email" name="email" placeholder="Enter email" data-required="true"> <span class="hf-form-field_error-text"></span> </div> <div id="contact-custom-fields-container" class="hf-mod-small_width"></div> <div class="hf-form-field hf-mod-small_width"> <label for="id_phone" class="hf-form-field_label ">Phone</label> <input type="text" class="hf-form-field_value" id="id_phone" name="phone" placeholder="Enter phone number" > <span class="hf-form-field_error-text"></span> </div> </div> <div style="" id="recaptcha" class="g-recaptcha" data-sitekey="6LcoTEwUAAAAAM0Mst78EhadVrHJDjCONZBcIvz8"></div> <div class="hf-form-field"> <button id="submit" type="submit" class="hf-form-field_btn hf-mod-form-field-btn-small">Submit Ticket</button> <a class="hf-u-cursor-pointer" href="/">Cancel</a> </div> </form> </div> </section> </div> <script src="https://d12tly1s0ox52d.cloudfront.net/static/100425114413/support_center/ckeditor/ckeditor.js"></script> <script type="text/javascript">function setupDropZone(dropArea, dragDrop, highlightClass) { var dropArea = document.getElementById(dropArea); if(dropArea) { ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(function(eventName) { dropArea.addEventListener(eventName, preventDefaults, false) }); dropArea.addEventListener('drop', dragDrop, false) if (highlightClass) { function highlight(e) { dropArea.classList.add(highlightClass) } function unhighlight(e) { dropArea.classList.remove(highlightClass) } ['dragenter', 'dragover'].forEach(function(eventName) { dropArea.addEventListener(eventName, highlight, false) }); ['dragleave', 'drop'].forEach(function(eventName) { dropArea.addEventListener(eventName, unhighlight, false) }); } } function preventDefaults(e) { e.preventDefault() e.stopPropagation() } }</script> <script type="text/javascript">var CURRENCY_UTILS = {}; /* - These utility functions also used in Agent portal. - Make sure to keep the functions in sync with the Agent portal. */ (function () { var DEFAULT_DECIMAL_SEPARATOR = '.'; var DEFAULT_GROUP_SEPARATOR = ','; var DEFAULT_CURRENCY_SYMBOL = '$'; var DEFAULT_CURRENCY_CODE = 'USD'; var DEFAULT_DECIMALS_LIMIT = 2; var DEFAULT_LITERAL_SPACE = '\u00A0'; // non-breaking space /* - Since we are not collecting locale information, we are using a set of predefined locales for popular currencies. - Note: For EUR currency, there can be different formats for different countries. Eg: Germany (de-DE) -> 12345.00 -> 12.345,00 € France (fr-FR) -> 12345.00 -> 12 345,00 € Instead of handling for different countries, we are using a generic (widely used) format for EUR for now. */ var CURRENCY_LOCALE_MAP = { 'USD': 'en-US', 'EUR': 'de-DE', 'GBP': 'en-GB', 'JPY': 'ja-JP', 'INR': 'en-IN' }; /* Group and decimal separators can be different for different currencies Example: - US Dollar: 1,234.56 -> group separator is ',' and decimal separator is '.' - Euro: 1.234,56 -> group separator is '.' and decimal separator is ',' */ function getSeparators(currencyCode) { let separators = { group: DEFAULT_GROUP_SEPARATOR, decimal: DEFAULT_DECIMAL_SEPARATOR, currencySign: DEFAULT_CURRENCY_SYMBOL, literal: DEFAULT_LITERAL_SPACE }; if (!currencyCode) { return separators; } let locale = CURRENCY_LOCALE_MAP[currencyCode] || undefined; let formatter = new Intl.NumberFormat(locale, { style: 'currency', currency: currencyCode }); let parts = formatter.formatToParts(123456.78); separators.decimal = parts.find(({ type }) => type === 'decimal').value; separators.group = parts.find(({ type }) => type === 'group').value; separators.currencySign = parts.find(({ type }) => type === 'currency').value; let literal = parts.find(({ type }) => type === 'literal'); if (literal) { separators.literal = literal.value; } return separators; } function convertValueToStandardDecimal(value, decimalSeparator, groupSeparator) { let valueWithoutGroup = value.replace(new RegExp(`\\${groupSeparator}`, 'g'), ''); let valueWithDecimal = valueWithoutGroup.replace(decimalSeparator, '.'); return valueWithDecimal.replace(new RegExp('[^0-9.]', 'g'), ''); } function getNumberValue(formattedValue, decimalSeparator, groupSeparator) { if (!formattedValue) { return null; } let isNegative = formattedValue.startsWith('-'); let value = convertValueToStandardDecimal( formattedValue, decimalSeparator, groupSeparator ); value = parseFloat(value); return isNegative ? -value : value; } function setCursorPosition({ inputElement, selectionStart, currentValue, updatedValue }) { var position = selectionStart + (updatedValue.length - currentValue.length); inputElement.setSelectionRange(position, position); } function prefixCurrencySign(formattedValue, displaySymbol = false, prefixCurrencySign = true, currencySign, literal) { let _value = formattedValue; if (displaySymbol) { if (prefixCurrencySign) { _value = _value.replace(currencySign, ''); _value = `${currencySign}${_value}`; _value = _value.endsWith(literal) ? _value.slice(0, -1) : _value; } } else { // Remove currency symbol if it is not allowed _value = _value.replace(currencySign, ''); /* For some currencies, there is a literal space between value and currency symbol Eg: 12345.00 € -> ' ' is the literal space If we are not displaying currency symbol, then we should remove the literal space as well */ if (_value.endsWith(literal)) { _value = _value.slice(0, -1); } } return _value; } function getFormattedValue(value, config = {}) { let { currencyCode = DEFAULT_CURRENCY_CODE, displaySymbol = false, useCurrencySignAsPrefix = true, decimalsLimit = DEFAULT_DECIMALS_LIMIT } = config; let { currencySign, literal, decimal } = getSeparators(currencyCode); let decimalSeparator = decimal; let locale = CURRENCY_LOCALE_MAP[currencyCode] || undefined; let formattedValue = ''; let _value = typeof value === 'number' ? String(value) : value; if (!_value) { return null; } let formatter = new Intl.NumberFormat(locale, { style: 'currency', currency: currencyCode, currencyDisplay: 'narrowSymbol', minimumFractionDigits: 0, maximumFractionDigits: 10 }); if (_value.startsWith(decimalSeparator)) { _value = `0${_value}`; } let valueWithStandardDecimal = _value.replace(decimalSeparator, '.'); let numberValue = Number(valueWithStandardDecimal); formattedValue = formatter.format(numberValue); formattedValue = prefixCurrencySign( formattedValue, displaySymbol, useCurrencySignAsPrefix, currencySign, literal ); /* If the last character is decimal separator, then `NumberFormat.format()` will remove it. We need to add it back so that the user can continue typing decimals. */ let isLastCharacterDecimal = _value.endsWith(decimalSeparator); if (isLastCharacterDecimal) { formattedValue = `${formattedValue}${decimalSeparator}`; } /* Handle decimal places */ let [, decimalPart] = valueWithStandardDecimal.split('.'); if (decimalPart) { decimalPart = decimalPart.slice(0, decimalsLimit); if (formattedValue.includes(decimalSeparator)) { // pattern to replace is `decimalSeparator` followed by any numeric chartacters formattedValue = formattedValue.replace( new RegExp(`${decimalSeparator}[0-9]+$`, 'g'), `${decimalSeparator}${decimalPart}` ); } else { formattedValue = `${formattedValue}${decimalSeparator}${decimalPart}`; } } return formattedValue; } function sanitizeUserValue(value, decimal, group, currencySign) { let decimalSeparator = decimal; let groupSeparator = group; let sanitizedValue = ''; // Remove any group separators sanitizedValue = value.replace(groupSeparator, ''); // Remove any currency symbols sanitizedValue = sanitizedValue.replace(currencySign, ''); // Remove any non numeric characters except decimal separator sanitizedValue = sanitizedValue.replace(new RegExp(`[^0-9${decimalSeparator}]`, 'g'), ''); // decimal separator should only be allowed once if (value.split(`${decimalSeparator}`).length > 2) { const [firstDecimalPart, ...rest] = value.split(`${decimalSeparator}`); const cleanedRest = rest.join('').replace(new RegExp(`\\${decimalSeparator}`, 'g'), ''); sanitizedValue = firstDecimalPart + (cleanedRest ? decimalSeparator + cleanedRest : decimalSeparator); } // Negative let isNegative = value.indexOf('-') === 0; if (isNegative && sanitizedValue[0] !== '-') { sanitizedValue = `-${sanitizedValue}`; } return sanitizedValue; } CURRENCY_UTILS.getFormattedValue = getFormattedValue; CURRENCY_UTILS.getSeparators = getSeparators; CURRENCY_UTILS.getNumberValue = getNumberValue; CURRENCY_UTILS.setCursorPosition = setCursorPosition; CURRENCY_UTILS.sanitizeUserValue = sanitizeUserValue; })();</script> <script type="text/javascript">var CUSTOM_FIELD_HELPERS = {}; (function () { var multipleOptionMaxLength = 45; function renderDropdownField(prefix, field, selectedCFValue, isArchiveCustomFieldOptionEnabled = false, useDefault = true) { var fieldName = prefix + '-cf-' + field.id; var html = '<div><select class="hf-form-field_value"'; html += 'id="'+ fieldName + '"'; html += prefix + '_field_id="' + field.id + '"'; html += 'name="'+ fieldName + '"'; html += 'cf_type="' + prefix + '"'; if(field.compulsory) { html += 'data-required="true"'; } html += 'cf_field_type="' + field.type + '">'; html += '<option value="" selected="selected">---------</option>'; var canArchiveCfOption = (prefix == 't') && isArchiveCustomFieldOptionEnabled; $.each(field.options, function(index, option) { var isOptionArchived = canArchiveCfOption && option.is_archived if (isOptionArchived) { return true; // Do not show the option as it is archived } html += '<option '; optionValue = option.value; if(selectedCFValue) { if(selectedCFValue == option.id) { html += 'selected="selected"'; } } else { if(option.is_default && useDefault) { html += 'selected="selected"'; } } html += 'value="' + option.id + '">' + optionValue + '</option>'; }); html += '</select>'; return html; } function renderMultipleOptionField(prefix, field, multiOptionValues, isArchiveCustomFieldOptionEnabled = false, useDefault = true, sendNameAsMultipleOption=false) { multiOptionValues = multiOptionValues || []; var fieldName = prefix + '-cf-' + field.id; var html = '<div class="hf-form-field hf-form-field_value-multioption">'; html += '<ul class="hf-clearfix hf-multioption-wrap" '; html += 'id="'+ fieldName + '"'; html += 'cf_type="' + prefix + '"'; html += prefix + '_field_id="' + field.id + '"'; if(field.compulsory) { html += 'data-required="true"'; } html += 'cf_field_type="' + field.type + '">'; var canArchiveCfOption = (prefix == 't') && isArchiveCustomFieldOptionEnabled; $.each(field.options, function(index, option) { if (canArchiveCfOption && option.is_archived) { return true; // Do not show the option as it is archived } html += '<li><label class="hf-checkbox">'; if (sendNameAsMultipleOption) { html += '<input type="checkbox" name="'+ fieldName + '[]"' + 'id="'+ fieldName + '"'; } else { html += '<input type="checkbox" name="'+ fieldName + '"' + 'id="'+ fieldName + '"'; } if(multiOptionValues.length) { if(multiOptionValues.indexOf(option.id) !== -1) { html += 'checked="checked"'; } } else { if(option.is_default && useDefault) { html += 'checked="checked"'; } } html += 'value="' + option.id + '">'; if (option.value.toString().length <= multipleOptionMaxLength) { optionValue = option.value html += '<span class="hf-checkbox_text">' + optionValue + '</span>'; } else { optionValue = option.value.substring(0, multipleOptionMaxLength) + "..." html += '<span class="hf-checkbox_text hf-tooltip-toggle hf-mod-new-ticket-tooltip" aria-label="' + option.value + '">' + optionValue + '</span>' } html += '</li></label></input>'; }); html += '</ul>'; return html; } function renderDateField(prefix, field, selectedCFValue, useDefault = true) { var fieldName = prefix + '-cf-' + field.id; var html = '<div><input placeholder="DD MMM YYYY" class="hf-form-field_value" autocomplete="hide"'; html += 'id="'+ fieldName + '" name="'+ fieldName +'"'; html += 'cf_type="' + prefix + '"'; if(field.compulsory) { html += 'data-required="true"'; } var customFieldValue = useDefault ? selectedCFValue || field.default_value : selectedCFValue; if(customFieldValue) { var defaultValue = moment(customFieldValue, 'YYYY-MM-DD').format('DD MMM YYYY'); html += 'value="' + defaultValue + '"'; html += 'data-value="' + customFieldValue + '"'; } html += 'cf_field_type="' + field.type + '">'; return html; } function renderNumberField(prefix, field, selectedCFValue, useDefault = true) { var fieldName = prefix + '-cf-' + field.id; var html = '<div><input type="number" autocomplete="hide" class="hf-form-field_value" step="any" '; html += 'id="'+ fieldName + '"'; html += prefix + '_field_id="' + field.id + '"'; html += 'name="'+ fieldName + '"'; html += 'cf_type="' + prefix + '"'; if(field.compulsory) { html += 'data-required="true"'; } var customFieldValue = useDefault ? selectedCFValue || field.default_value : selectedCFValue; if(customFieldValue) { html += 'value="' + customFieldValue + '"'; } html += 'cf_field_type="' + field.type + '">'; return html; } function renderCurrencyField(prefix, field, selectedCFValue) { var fieldName = prefix + '-cf-' + field.id; var currencyCode = field.currency_code; var currencySign = CURRENCY_UTILS.getSeparators(currencyCode).currencySign; var currencySignEl = '<div class="hf-form-field_currency-sign">' + currencySign + '</div>'; var currencyElement = '<div class="hf-form-field_currency-container">' + currencySignEl; var inputHtml = '<input type="text" autocomplete="hide" class="hf-form-field_value hf-mod-currency"'; inputHtml += 'id="'+ fieldName + '"'; inputHtml += prefix + '_field_id="' + field.id + '"'; inputHtml += 'name="'+ fieldName + '"'; inputHtml += 'cf_type="' + prefix + '"'; if(field.compulsory) { inputHtml += 'data-required="true"'; } if (selectedCFValue == null || selectedCFValue == undefined || selectedCFValue == 'None') { inputHtml += 'value=""'; } else { var computedValue = CURRENCY_UTILS.getFormattedValue( selectedCFValue.toString(), {currencyCode} ); inputHtml += 'value="' + computedValue + '"'; } inputHtml += 'cf_field_type="currency">'; currencyElement += inputHtml + '</div>'; return currencyElement; } function renderTextField(prefix, field, inputValue, useDefault = true) { var fieldName = prefix + '-cf-' + field.id; var html = '<div><textarea autocomplete="hide" class="hf-form-field_value" '; html += 'id="'+ fieldName + '"'; html += prefix + '_field_id="' + field.id + '"'; html += 'name="'+ fieldName + '"'; html += 'cf_type="' + prefix + '"'; if(field.compulsory) { html += 'data-required="true"'; } html += 'cf_field_type="' + field.type + '">'; var customFieldValue = useDefault ? inputValue || field.default_value : inputValue; if(customFieldValue) { html += customFieldValue; } html += '</textarea>'; return html; } function getOrderedCustomFields(cfOrder, customFieldsData) { var orderedCustomFields = []; (cfOrder||[]).forEach(function(cfID) { var customFieldData = customFieldsData[cfID]; if (customFieldData) { orderedCustomFields.push(customFieldData); } }); return orderedCustomFields; } /* Get the top level custom fields i.e independent custom fields */ function getTopLevelCustomFields(customFieldsData) { var topLevelFields = []; customFieldsData.forEach(function(customField) { if (customField && !customField.depends_on) { topLevelFields.push(customField); } }); return topLevelFields; } function findObjectInArray(array, key, value) { var length = array.length; var i = 0; while(i < length) { if(array[i][key]== value) { return array[i]; } i++; } return undefined; } function getDropdownDependantFields(parentField, selectedValue) { var dependantFieldIds = []; if (!selectedValue) { return dependantFieldIds; } parentField.options.forEach(function(cfOption) { var isSelected = selectedValue == cfOption.id if(isSelected && cfOption.dependent_fields) { dependantFieldIds = dependantFieldIds.concat(cfOption.dependent_fields); } }); // unique fields dependantFieldIds = dependantFieldIds.filter(function(item, pos) { return dependantFieldIds.indexOf(item) == pos; }); return dependantFieldIds; } function getMultichoiceDependantFields(parentField, selectedValue) { var dependantFieldIds = []; if (!selectedValue) { return dependantFieldIds; } parentField.options.forEach(function(cfOption) { var isSelected = selectedValue.includes(cfOption.id); if(isSelected && cfOption.dependent_fields) { dependantFieldIds = dependantFieldIds.concat(cfOption.dependent_fields); } }); // unique fields dependantFieldIds = dependantFieldIds.filter(function(item, pos) { return dependantFieldIds.indexOf(item) == pos; }); return dependantFieldIds; } function getCustomFieldDefaultValue(customField) { var defaultValue = null; if (customField.type === 'dropdown') { var [defaultValue] = customField.options.filter(function(cfOption) { return cfOption.is_default; }); } else if(customField.type === 'multiple_option') { defaultValue = customField.options.filter(function(cfOption) { return cfOption.is_default; }); } else { defaultValue = customField.default_value; } return defaultValue; } CUSTOM_FIELD_HELPERS.renderDropdownField = renderDropdownField; CUSTOM_FIELD_HELPERS.renderMultipleOptionField = renderMultipleOptionField; CUSTOM_FIELD_HELPERS.renderDateField = renderDateField; CUSTOM_FIELD_HELPERS.renderNumberField = renderNumberField; CUSTOM_FIELD_HELPERS.renderCurrencyField = renderCurrencyField; CUSTOM_FIELD_HELPERS.renderTextField = renderTextField; CUSTOM_FIELD_HELPERS.getOrderedCustomFields = getOrderedCustomFields; CUSTOM_FIELD_HELPERS.getTopLevelCustomFields = getTopLevelCustomFields; CUSTOM_FIELD_HELPERS.getDropdownDependantFields = getDropdownDependantFields; CUSTOM_FIELD_HELPERS.getMultiChoiceDependantFields = getMultichoiceDependantFields; CUSTOM_FIELD_HELPERS.getCustomFieldDefaultValue = getCustomFieldDefaultValue; CUSTOM_FIELD_HELPERS.findObjectInArray = findObjectInArray; })();</script> <script type="text/javascript"> var multipleOptionMaxLength = 45; var customFieldMap = {}; var isArchiveCustomFieldOptionEnabled = false; /* - This file is used across different pages for rendering custom fields of different types (ticket, contact, incident, service_request) - Archive feature is applicable only for ticket custom fields in HD. All other page contexts need not know about this feature - So we check if archive_custom_field_option_enabled is present in context - Eg: New ticket page, ticket details page will have the context whereas pages like confirm registration will not require the context */ isArchiveCustomFieldOptionEnabled = true; var isCurrencyCustomFieldEnabled = false; isCurrencyCustomFieldEnabled = false; var isRefactorContactPortalEnabled = false; isRefactorContactPortalEnabled = false; function getCustomFieldData(cfPrefix, cfID) { var customFields = getCustomFieldsData(cfPrefix).customFields; return customFields[cfID]; } function createDatePickerInstance(container) { $(container).find("[cf_field_type=date]").each(function() { new Pikaday({ field: $(this)[0], format: 'DD MMM YYYY', i18n: { months : moment.months(), weekdays : moment.weekdays(), weekdaysShort : moment.weekdaysShort() } }); }); } function getCustomFieldsData(cfPrefix) { if (cfPrefix === 't' || cfPrefix === 'ic') { return { customFields: ticketCustomFields, cfOrder: ticketCustomFieldsOrder }; } else if (cfPrefix === 'c') { return { customFields: contactCustomFields, cfOrder: contactCustomFieldsOrder }; } else if (cfPrefix === 'sr') { return { customFields: srCustomFields, cfOrder: srCustomFieldsOrder }; } } function selectedValueHasDependants(customFieldData, customFieldValues={}) { var { type } = customFieldData; var selectedCFValue = customFieldValues[customFieldData.id] || {}; var value = selectedCFValue.value; var hasDependantFields = false; if (value) { hasDependantFields = type == 'dropdown' ? CUSTOM_FIELD_HELPERS.getDropdownDependantFields(customFieldData, value).length : type == 'multiple_option' ? CUSTOM_FIELD_HELPERS.getMultiChoiceDependantFields(customFieldData, value).length : false; } else { var defaultValue = CUSTOM_FIELD_HELPERS.getCustomFieldDefaultValue(customFieldData); hasDependantFields = type == 'dropdown' ? defaultValue && defaultValue.dependent_fields && defaultValue.dependent_fields.length : type == 'multiple_option' ? defaultValue.some((option) => option.dependent_fields && option.dependent_fields.length) : false; } return hasDependantFields; } function displayParentCustomFieldsV2(container, cfPrefix) { var html = ''; var customFields = getCustomFieldsData(cfPrefix).customFields; var customFieldValues = []; if (cfPrefix === 'c') { customFieldValues = contactCustomFieldValues; } if (customFieldValues.length) { customFieldValues.forEach(function(item) { customFieldMap[item.id] = item; }); } var useDefault = true; var cfOrder = getCustomFieldsData(cfPrefix).cfOrder; var orderedCustomFields = CUSTOM_FIELD_HELPERS.getOrderedCustomFields(cfOrder, customFields); var topLevelFields = CUSTOM_FIELD_HELPERS.getTopLevelCustomFields(orderedCustomFields); var dropdownCustomFieldIds = topLevelFields.filter(function(field) { return field.type === 'dropdown'; }).map((field) => field.id); var multiChoiceCustomFieldIds = topLevelFields.filter(function(field) { return field.type === 'multiple_option'; }).map((field) => field.id); var triggerParentCustomFields = []; topLevelFields.forEach(function(customFieldData) { html += renderFieldHTMLV2(cfPrefix, customFieldData, useDefault); if (customFieldData.type === 'dropdown' || (cfPrefix == 't' && customFieldData.type === 'multiple_option')) { if (selectedValueHasDependants(customFieldData, customFieldMap)) { triggerParentCustomFields.push(customFieldData.id); } } }); $(container).html(html); if(typeof(createDropdownInstance) == 'function') { createDropdownInstance(container); } createDatePickerInstance(container); initializeDropdownFieldsListener(cfPrefix, dropdownCustomFieldIds, triggerParentCustomFields); initializeMultiChoiceFieldsListener(cfPrefix, multiChoiceCustomFieldIds, triggerParentCustomFields); initializeCurrencyFieldsListener(cfPrefix, container); } function displayChildCustomFieldsV2(parentElement) { var cfPrefix = parentElement.attr('cf_type'); var fieldType = parentElement.attr('cf_field_type'); var cfOrder = getCustomFieldsData(cfPrefix).cfOrder; var id = parseInt(parentElement.attr(cfPrefix + '_field_id')); var value; if (fieldType === 'multiple_option') { value = Array.from(parentElement[0].querySelectorAll('input[type="checkbox"]:checked')) .map((el) => parseInt(el.value)); } else { value = parseInt(parentElement.val()); } var parentCfData = getCustomFieldData(cfPrefix, id); var childFieldIds = []; if (parentCfData.type == 'dropdown') { childFieldIds = CUSTOM_FIELD_HELPERS.getDropdownDependantFields( parentCfData, value ); } else if (cfPrefix == 't' && parentCfData.type == 'multiple_option') { childFieldIds = CUSTOM_FIELD_HELPERS.getMultiChoiceDependantFields( parentCfData, value ); } childFieldIds = childFieldIds.sort((a, b) => cfOrder.indexOf(a) - cfOrder.indexOf(b)); /* Cache current values of child fields only if the parent is of type multi-select */ if (cfPrefix == 't' && parentCfData.type == 'multiple_option') { var currentValues = {}; childFieldIds.forEach(function(cfId) { var childFieldElement = $('#'+ cfPrefix +'-cf-' + cfId + '-container'); if (childFieldElement.length) { if (childFieldElement.find('input[type="checkbox"]').length) { // For multiple option fields, store the checked values currentValues[cfId] = childFieldElement.find('input[type="checkbox"]:checked').map(function() { return $(this).val(); }).get(); } else { // For other fields, store the value directly currentValues[cfId] = childFieldElement.find('.hf-form-field_value').val(); } } }); } /* Get custom field data for child fields - if there are internal fields then it wont be part of customFields data - So we filter out those fields */ var childFields = childFieldIds.map((cfId) => getCustomFieldData(cfPrefix, cfId)).filter((field) => field); var selectedValues = {}; var triggerChildCustomFields = []; var dropdownCustomFieldIds = childFields.filter((field) => field.type === 'dropdown').map((field) => field.id); var multiChoiceCustomFieldIds = childFields.filter((field) => field.type === 'multiple_option').map((field) => field.id); var html = ''; childFields.forEach(function(customFieldData) { html += renderFieldHTMLV2(cfPrefix, customFieldData); if (customFieldData.type === 'dropdown' || (cfPrefix == 't' && customFieldData.type === 'multiple_option')) { if (selectedValueHasDependants(customFieldData, selectedValues)) { triggerChildCustomFields.push(customFieldData.id); } } }); var dependentFieldsContainer = $('#'+ cfPrefix +'-cf-' + id + '-container').next(); $(dependentFieldsContainer).html(html); if(typeof(createDropdownInstance) == 'function') { createDropdownInstance(dependentFieldsContainer); } createDatePickerInstance(dependentFieldsContainer); initializeDropdownFieldsListener(cfPrefix, dropdownCustomFieldIds, triggerChildCustomFields); initializeMultiChoiceFieldsListener(cfPrefix, multiChoiceCustomFieldIds, triggerChildCustomFields); initializeCurrencyFieldsListener(cfPrefix, dependentFieldsContainer); // Reapply cached values to child fields if (cfPrefix == 't' && parentCfData.type == 'multiple_option') { Object.keys(currentValues).forEach(function(cfId) { var childFieldElement = $('#'+ cfPrefix +'-cf-' + cfId + '-container'); if (childFieldElement.length) { if (childFieldElement.find('input[type="checkbox"]').length) { // For multiple option fields, reapply the checked values currentValues[cfId].forEach(function(value) { childFieldElement.find('input[type="checkbox"][value="' + value + '"]').prop('checked', true); }); } else { // For other fields, reapply the value childFieldElement.find('.hf-form-field_value').val(currentValues[cfId]); if (childFieldElement.find('.hf-form-field_value').attr('cf_field_type') === 'dropdown') { childFieldElement.find('.hf-form-field_value').trigger('change'); } } } }); } } function initializeDropdownFieldsListener(cfPrefix, fieldIds, triggerFields) { fieldIds.forEach(function(cf_id) { $('select#' + cfPrefix + '-cf-' + cf_id).change(function(event) { displayChildCustomFieldsV2($(event.target)); }); if (triggerFields.indexOf(cf_id) !== -1) { $('select#' + cfPrefix + '-cf-' + cf_id).trigger('change'); } }); } function initializeMultiChoiceFieldsListener(cfPrefix, fieldIds, triggerFields) { if (cfPrefix !== 't') { return; } fieldIds.forEach(function(cf_id) { $('input#' + cfPrefix + '-cf-' + cf_id).change(function(event) { let target = $(event.target).closest('[cf_field_type]'); displayChildCustomFieldsV2(target); }); if (triggerFields.indexOf(cf_id) !== -1) { $('input#' + cfPrefix + '-cf-' + cf_id).trigger('change'); } }); }; function initializeCurrencyFieldsListener(cfPrefix, container) { if ((cfPrefix === 't' || cfPrefix === 'ic' || cfPrefix === 'sr') && isCurrencyCustomFieldEnabled) { var currencyFields = $(container).find('input[cf_field_type="currency"]'); if (currencyFields.length) { intializeCurrencyInputListeners(cfPrefix); } } } function renderFieldHTMLV2(prefix, field) { var useDefault = true; var html = ''; var displayName = field.display_name_for_contacts ? field.display_name_for_contacts : field.name; html = '<div class="hf-form-field hf-mod-small_width hf-custom-field hf-field-'+field.id+'" id="'+ prefix +'-cf-'+field.id+'-container">' html += '<div class="hf-form-field_label hf-mod-custom_field_label' if (field.compulsory) html += ' hf-form-field_required'; html += '">' + displayName + '</div>'; // TODO Added the 'none' check to handle custom fields created from v1. Need to remove this once all customers are ported to v2 if(field.help_text_for_contacts && field.help_text_for_contacts !== 'None' && field.contact_help_text_display_format == 'hover') { html += '<span class="hf-tooltip-toggle hf-mod-custom_field_tooltip" aria-label="' + field.help_text_for_contacts + '">'; html += '<img src="https://d12tly1s0ox52d.cloudfront.net/static/100425114413/support_center/svgs/info.svg"></span>' } var selectedCF = customFieldMap[field.id] || {}; var selectedCFValue = selectedCF.value; if(field.type === 'dropdown') { html += CUSTOM_FIELD_HELPERS.renderDropdownField( prefix, field, selectedCFValue, isArchiveCustomFieldOptionEnabled, useDefault ) } else if(field.type === 'multiple_option') { html += CUSTOM_FIELD_HELPERS.renderMultipleOptionField( prefix, field, selectedCFValue, isArchiveCustomFieldOptionEnabled, useDefault ); } else if(field.type === 'date') { html += CUSTOM_FIELD_HELPERS.renderDateField(prefix, field, selectedCFValue, useDefault); } else if(field.type === 'number') { var isCurrency = isCurrencyCustomFieldEnabled && field.format_type && field.format_type === 'currency'; if (isCurrency && (prefix == 't' || prefix == 'ic' || prefix == 'sr')) { html += CUSTOM_FIELD_HELPERS.renderCurrencyField(prefix, field, selectedCFValue); } else { html += CUSTOM_FIELD_HELPERS.renderNumberField(prefix, field, selectedCFValue, useDefault); } } else { html += CUSTOM_FIELD_HELPERS.renderTextField(prefix, field, selectedCFValue, useDefault); } html += '<span class="hf-form-field_error-text"></span>'; // TODO Added the 'none' check to handle custom fields created from v1. Need to remove this once all customers are ported to v2 if(field.help_text_for_contacts && field.help_text_for_contacts !== 'None' && field.contact_help_text_display_format == 'inline'){ html += '<div class="hf-mod-custom-field-helptext">' + field.help_text_for_contacts + '</div>'; } html += '</div></div><div class="hf-dependent-fields-container"></div>'; return html; } function displayParentCustomFields(container, cfPrefix) { if (isRefactorContactPortalEnabled) { displayParentCustomFieldsV2(container, cfPrefix); return; } var html = ''; var customFields = getCustomFieldsData(cfPrefix).customFields; var cfOrder = getCustomFieldsData(cfPrefix).cfOrder; var dropdownCustomFields = []; var triggerParentCustomFields = []; var customFieldValues = []; if(cfPrefix === 'c') { customFieldValues = contactCustomFieldValues; } if(customFieldValues.length) { customFieldValues.forEach(function(item){ customFieldMap[item.id] = item; }); } cfOrder.forEach(function(cfID) { var customFieldData = customFields[cfID]; if(customFieldData && !customFieldData.depends_on) { if(customFieldData.type === 'dropdown') { dropdownCustomFields.push(customFieldData.id); var selectedCF = customFieldMap[customFieldData.id]|| {}; var selectedCFValue = selectedCF.value; customFieldData.options.forEach(function(cfOption) { if((cfOption.is_default || cfOption.id == selectedCFValue) && cfOption.dependent_fields) { triggerParentCustomFields.push(customFieldData.id); } }); } html += renderFieldHTML(cfPrefix, customFieldData); } }); $(container).html(html); if(typeof(createDropdownInstance) == 'function') { createDropdownInstance(container); } createDatePickerInstance(container); dropdownCustomFields.forEach(function(cf_id) { $('select#' + cfPrefix + '-cf-' + cf_id).change(function(event) { displayChildCustomFields($(event.target)); }); }); if ((cfPrefix === 't' || cfPrefix === 'ic' || cfPrefix === 'sr') && isCurrencyCustomFieldEnabled) { var currencyFields = $(container).find('input[cf_field_type="currency"]'); if (currencyFields.length) { intializeCurrencyInputListeners(cfPrefix); } } // Trigger a change event to render the dependent fields when default value is selected triggerParentCustomFields.forEach(function(cf_id) { $('select#' + cfPrefix + '-cf-' + cf_id).trigger('change'); }); } function displayChildCustomFields(parentElement) { var cfPrefix = parentElement.attr('cf_type'); var cfOrder = getCustomFieldsData(cfPrefix).cfOrder; var id = parseInt(parentElement.attr(cfPrefix + '_field_id')); var value = parseInt(parentElement.val()); var parentCfData = getCustomFieldData(cfPrefix, id); var dropdownCustomFields = []; var triggerChildCustomFields = []; var html = ''; parentCfData.options.forEach(function(cfOption) { var cfOptionDependentFields = cfOption.dependent_fields; if(cfOption.id === value && cfOptionDependentFields.length) { cfOrder.forEach(function(cfOrderID) { if(cfOptionDependentFields.indexOf(cfOrderID) != -1) { var customField = getCustomFieldData(cfPrefix, cfOrderID); if(customField) { if(customField.type === 'dropdown') { dropdownCustomFields.push(customField.id); customField.options.forEach(function(cfOption) { if(cfOption.is_default && cfOption.dependent_fields) { triggerChildCustomFields.push(customField.id); } }); } html += renderFieldHTML(cfPrefix, customField); } } }); } }); var dependentFieldsContainer = $('#'+ cfPrefix +'-cf-' + id + '-container').next(); $(dependentFieldsContainer).html(html); if(typeof(createDropdownInstance) == 'function') { createDropdownInstance(dependentFieldsContainer); } createDatePickerInstance(dependentFieldsContainer); dropdownCustomFields.forEach(function(cf_id) { $('select#' + cfPrefix + '-cf-' + cf_id).change(function(event) { displayChildCustomFields($(event.target)); }); }); if ((cfPrefix === 't' || cfPrefix === 'ic' || cfPrefix === 'sr') && isCurrencyCustomFieldEnabled) { var currencyFields = $(dependentFieldsContainer).find('input[cf_field_type="currency"]'); if (currencyFields.length) { intializeCurrencyInputListeners(cfPrefix); } } triggerChildCustomFields.forEach(function(cf_id) { $('select#' + cfPrefix + '-cf-' + cf_id).trigger('change'); }); } function renderFieldHTML(prefix, field) { var html = ''; var displayName = field.display_name_for_contacts ? field.display_name_for_contacts : field.name; html = '<div class="hf-form-field hf-mod-small_width hf-custom-field hf-field-'+field.id+'" id="'+ prefix +'-cf-'+field.id+'-container">' html += '<div class="hf-form-field_label hf-mod-custom_field_label' if (field.compulsory) html += ' hf-form-field_required'; html += '">' + displayName + '</div>'; // TODO Added the 'none' check to handle custom fields created from v1. Need to remove this once all customers are ported to v2 if(field.help_text_for_contacts && field.help_text_for_contacts !== 'None' && field.contact_help_text_display_format == 'hover') { html += '<span class="hf-tooltip-toggle hf-mod-custom_field_tooltip" aria-label="' + field.help_text_for_contacts + '">'; html += '<img src="https://d12tly1s0ox52d.cloudfront.net/static/100425114413/support_center/svgs/info.svg"></span>' } var selectedCF = customFieldMap[field.id] || {}; var selectedCFValue = selectedCF.value; if(field.type === 'dropdown') { html += renderDropdownField(prefix, field, selectedCFValue) } else if(field.type === 'multiple_option') { html += renderMultipleOptionField(prefix, field, selectedCFValue); } else if(field.type === 'date') { html += renderDateField(prefix, field, selectedCFValue); } else if(field.type === 'number') { var isCurrency = isCurrencyCustomFieldEnabled && field.format_type && field.format_type === 'currency'; if (isCurrency && (prefix == 't' || prefix == 'ic' || prefix == 'sr')) { html += renderCurrencyField(prefix, field, selectedCFValue); } else { html += renderNumberField(prefix, field, selectedCFValue); } } else { html += renderDefaultField(prefix, field, selectedCFValue); } html += '<span class="hf-form-field_error-text"></span>'; // TODO Added the 'none' check to handle custom fields created from v1. Need to remove this once all customers are ported to v2 if(field.help_text_for_contacts && field.help_text_for_contacts !== 'None' && field.contact_help_text_display_format == 'inline'){ html += '<div class="hf-mod-custom-field-helptext">' + field.help_text_for_contacts + '</div>'; } html += '</div></div><div class="hf-dependent-fields-container"></div>'; return html; } function renderDropdownField(prefix, field, selectedCFValue) { var fieldName = prefix + '-cf-' + field.id; var html = '<div><select class="hf-form-field_value"'; html += 'id="'+ fieldName + '"'; html += prefix + '_field_id="' + field.id + '"'; html += 'name="'+ fieldName + '"'; html += 'cf_type="' + prefix + '"'; if(field.compulsory) { html += 'data-required="true"'; } html += 'cf_field_type="' + field.type + '">'; html += '<option value="" selected="selected">---------</option>'; var canArchiveCfOption = (prefix == 't') && isArchiveCustomFieldOptionEnabled; $.each(field.options, function(index, option) { var isOptionArchived = canArchiveCfOption && option.is_archived if (isOptionArchived) { return true; // Do not show the option as it is archived } html += '<option '; optionValue = option.value; if(selectedCFValue) { if(selectedCFValue == option.id) { html += 'selected="selected"'; } } else { if(option.is_default) { html += 'selected="selected"'; } } html += 'value="' + option.id + '">' + optionValue + '</option>'; }); html += '</select>'; return html; } function renderMultipleOptionField(prefix, field, multiOptionValues) { multiOptionValues = multiOptionValues || []; var fieldName = prefix + '-cf-' + field.id; var html = '<div class="hf-form-field hf-form-field_value-multioption">'; html += '<ul class="hf-clearfix hf-multioption-wrap" '; html += 'id="'+ fieldName + '"'; html += 'cf_type="' + prefix + '"'; if(field.compulsory) { html += 'data-required="true"'; } html += 'cf_field_type="' + field.type + '">'; var canArchiveCfOption = (prefix == 't') && isArchiveCustomFieldOptionEnabled; $.each(field.options, function(index, option) { if (canArchiveCfOption && option.is_archived) { return true; // Do not show the option as it is archived } html += '<li><label class="hf-checkbox">'; html += '<input type="checkbox" name="'+ fieldName + '"' + 'id="'+ fieldName + '"'; if(multiOptionValues.length) { if(multiOptionValues.indexOf(option.id) !== -1) { html += 'checked="checked"'; } } else { if(option.is_default) { html += 'checked="checked"'; } } html += 'value="' + option.id + '">'; if (option.value.toString().length <= multipleOptionMaxLength) { optionValue = option.value html += '<span class="hf-checkbox_text">' + optionValue + '</span>'; } else { optionValue = option.value.substring(0, multipleOptionMaxLength) + "..." html += '<span class="hf-checkbox_text hf-tooltip-toggle hf-mod-new-ticket-tooltip" aria-label="' + option.value + '">' + optionValue + '</span>' } html += '</li></label></input>'; }); html += '</ul>'; return html; } function renderDateField(prefix, field, selectedCFValue) { var fieldName = prefix + '-cf-' + field.id; var html = '<div><input placeholder="DD MMM YYYY" class="hf-form-field_value" autocomplete="hide"'; html += 'id="'+ fieldName + '" name="'+ fieldName +'"'; html += 'cf_type="' + prefix + '"'; if(field.compulsory) { html += 'data-required="true"'; } var customFieldValue = selectedCFValue || field.default_value; if(customFieldValue) { var defaultValue = moment(customFieldValue, 'YYYY-MM-DD').format('DD MMM YYYY'); html += 'value="' + defaultValue + '"'; } html += 'cf_field_type="' + field.type + '">'; return html; } function renderNumberField(prefix, field, selectedCFValue) { var fieldName = prefix + '-cf-' + field.id; var html = '<div><input type="number" autocomplete="hide" class="hf-form-field_value" step="any" '; html += 'id="'+ fieldName + '"'; html += prefix + '_field_id="' + field.id + '"'; html += 'name="'+ fieldName + '"'; html += 'cf_type="' + prefix + '"'; if(field.compulsory) { html += 'data-required="true"'; } var customFieldValue = selectedCFValue || field.default_value; if(customFieldValue) { html += 'value="' + customFieldValue + '"'; } html += 'cf_field_type="' + field.type + '">'; return html; } function renderCurrencyField(prefix, field, selectedCFValue) { var fieldName = prefix + '-cf-' + field.id; var currencyCode = field.currency_code; var currencySign = CURRENCY_UTILS.getSeparators(currencyCode).currencySign; var currencySignEl = '<div class="hf-form-field_currency-sign">' + currencySign + '</div>'; var currencyElement = '<div class="hf-form-field_currency-container">' + currencySignEl; var inputHtml = '<input type="text" autocomplete="hide" class="hf-form-field_value hf-mod-currency"'; inputHtml += 'id="'+ fieldName + '"'; inputHtml += prefix + '_field_id="' + field.id + '"'; inputHtml += 'name="'+ fieldName + '"'; inputHtml += 'cf_type="' + prefix + '"'; if(field.compulsory) { inputHtml += 'data-required="true"'; } if (selectedCFValue == null || selectedCFValue == undefined || selectedCFValue == 'None') { inputHtml += 'value=""'; } else { var computedValue = CURRENCY_UTILS.getFormattedValue( selectedCFValue.toString(), {currencyCode} ); inputHtml += 'value="' + computedValue + '"'; } inputHtml += 'cf_field_type="currency">'; currencyElement += inputHtml + '</div>'; return currencyElement; } function renderDefaultField(prefix, field, selectedCFValue) { var fieldName = prefix + '-cf-' + field.id; var html = '<div><textarea autocomplete="hide" class="hf-form-field_value" '; html += 'id="'+ fieldName + '"'; html += prefix + '_field_id="' + field.id + '"'; html += 'name="'+ fieldName + '"'; html += 'cf_type="' + prefix + '"'; if(field.compulsory) { html += 'data-required="true"'; } html += 'cf_field_type="' + field.type + '">'; var customFieldValue = selectedCFValue || field.default_value; if(customFieldValue) { html += customFieldValue; } html += '</textarea>'; return html; } function intializeCurrencyInputListeners(cfPrefix) { $('input[cf_field_type="currency"]').on('input', function(event) { // get t_field_id attribute from element let fieldAttribute = cfPrefix + '_field_id'; let customFieldId = event.target.getAttribute(fieldAttribute); let customField if (cfPrefix === 'sr') { customField = srCustomFields[customFieldId]; } else { customField = ticketCustomFields[customFieldId]; } let currencyCode = customField.currency_code; let { target: inputElement } = event; let { selectionStart } = inputElement; let numberValue = null; let userValue = inputElement.value; let { group, decimal, currencySign } = CURRENCY_UTILS.getSeparators(currencyCode); let sanitizedValue = CURRENCY_UTILS.sanitizeUserValue(userValue, decimal, group, currencySign); // if value has only negative or currency symbol, then don't format it let canFormatValue = sanitizedValue && sanitizedValue !== '-' && sanitizedValue !== currencySign; if (canFormatValue) { let _formattedValue = CURRENCY_UTILS.getFormattedValue( sanitizedValue, { displaySymbol: false, currencyCode } ); inputElement.value = _formattedValue; CURRENCY_UTILS.setCursorPosition({ inputElement, selectionStart, currentValue: userValue, updatedValue: _formattedValue }); } else { inputElement.value = sanitizedValue; } }); };</script> <script type="text/javascript"> var SUPPORTED_IMAGE_FORMATS = ['jpg', 'jpeg', 'png', 'bmp', 'gif', 'tiff']; var dropArea; var contactCustomFields = ''; var contactCustomFieldsOrder = ''; var contactCustomFieldValues = []; var ticketCustomFields = ''; var ticketCustomFieldsOrder = ''; var dateDisplayFormat = 'DD MMM YYYY'; var dropdownFields = ['id_category', 'id_priority', 'id_contact_group', 'id_team', 'id_impact', 'id_urgency']; var datePickerFields = ['id_due_date']; var attachedFiles = []; var isServiceDesk = false; var ENTER_KEY = 13; $(document).ready(function() { dropdownFields.forEach(function(field) { $('select[id='+ field + ']').each(function() { $(this).select2({ containerCssClass: 'hf-select2-container', dropdownCssClass: 'hf-newticket-select2-dropdown', minimumResultsForSearch: 10, width: '100%' }); }); }); datePickerFields.forEach(function(field) { $('input[id='+ field + ']').each(function() { new Pikaday({ field: $(this)[0], format: dateDisplayFormat, minDate: new Date(), i18n: { months : moment.months(), weekdays : moment.weekdays(), weekdaysShort : moment.weekdaysShort() } }); }); }); contactCustomFields = {}; contactCustomFieldsOrder = []; displayParentCustomFields('#contact-custom-fields-container', 'c'); if(1 == 1) { fetchTicketCustomFields(2); } else { $('#id_category').change(function(event) { var categoryID = parseInt($(event.target).val()); if(categoryID) { fetchTicketCustomFields(categoryID); } else { ticketCustomFields = {}; ticketCustomFieldsOrder = []; displayParentCustomFields('#ticket-custom-fields-container', 't'); } }); } $('#id_team').change(function(event) { var teamId = parseInt($(event.target).val()); renderIncidentCustomFields(teamId); }); var editorConfig = { title: false, toolbar: [ { name: 'basicstyles', items: ['Link', 'Unlink', 'Bold', 'Italic', 'Underline', 'Font', 'FontSize', 'TextColor', 'BGColor'] }, { name: 'advancestyles', items: ['BulletedList', 'NumberedList', 'RemoveFormat', 'BidiLtr', 'BidiRtl', 'Maximize', 'Blockquote'] }], removeButtons: 'JustifyCenter', extraPlugins: 'divarea,font,colorbutton,maximize,clipboard,colordialog,bidi', allowedContent: true, disableNativeSpellChecker: false, pasteFromWordRemoveStyles: false, pasteFromWordRemoveFontStyles: false, removePlugins: 'elementspath,tableselection,scayt,blockquote', font_defaultLabel: 'Open Sans', fontSize_defaultLabel: '14px', height: '300px', startupFocus: false, font_names: 'Andale Mono;Arial;Arial Black;Book Antiqua;Calibri;Comic Sans Ms;Courier New;Georgia;Helvetica;Impact;Symbol;Tahoma;Terminal;Times New Roman;Trebuchet MS;Verdana', enterTag: 'BR', customConfig: '' } var editor = CKEDITOR.replace('id_html', editorConfig); editor.on('paste', function(event) { var dataObj = event.data; var data = dataObj.dataValue; var dataTransfer = dataObj.dataTransfer; var latestId; var isUserLoggedIn = 'False' == 'True'; if (!data && dataObj.method == 'paste' && dataTransfer && dataTransfer.getFilesCount() == 1 && latestId != dataTransfer.id) { var file = dataTransfer.getFile(0); if(isUserLoggedIn) { if (CKEDITOR.tools.indexOf(['image/png', 'image/jpeg'], file.type) != -1) { var fileReader = new FileReader(); // Convert image file to img tag with base64 image. fileReader.addEventListener('load', function() { event.data.dataValue = '<img src="' + fileReader.result + '" />'; editor.fire('paste', event.data); }, false); // Proceed with normal flow if reading file was aborted. fileReader.addEventListener('abort', function() { editor.fire('paste', event.data); }, false); // Proceed with normal flow if reading file failed. fileReader.addEventListener('error', function() { editor.fire('paste', event.data); }, false); fileReader.readAsDataURL(file); latestId = dataObj.dataTransfer.id; event.stop(); } } else { // If the image is copy pasted for logged out case, ignore the event as image upload is not supported event.stop(); } } }, null, null, 0); editor.on('fileUploadRequest', function(event) { var fileLoader = event.data.fileLoader; var formData = new FormData(); var xhr = fileLoader.xhr; xhr.setRequestHeader("X-CSRFToken", 'aYv17FnXq9NvjacmLEJLxkbaPkqaWkEAakNIojgjxatu0HbfQkc0hT3GdtCrkeog'); formData.append('file', fileLoader.file, fileLoader.fileName); fileLoader.xhr.send(formData); event.stop(); }); editor.on('fileUploadResponse', function(event) { event.stop(); // Get XHR and response. var data = event.data; var xhr = data.fileLoader.xhr; var response = xhr.responseText.split('|'); if (response[1]) { // An error occurred during upload. data.message = response[1]; event.cancel(); } else { // Below are the expected response of CKEDITOR to insert the image tag. var attachmentURL = JSON.parse(response[0]).url; data.url = window.location.origin + attachmentURL; data.uploaded = 1; data.fileName = attachmentURL; } }); var delay = (function() { var timer = 0; return function (callback, ms) { clearTimeout(timer); timer = setTimeout(callback, ms); }; })(); $('#id_subject').on({ keyup: function(e) { e.stopPropagation(); var search_text = $(this).val(); var search_suggestions_container = $(e.target).siblings('.hf-article-search-result'); var currentlyHighlightedOption = search_suggestions_container.find('.hf-search-item[aria-current=true]'); if (e.keyCode === 40) { if (currentlyHighlightedOption.next().length) { currentlyHighlightedOption.attr('aria-current', false); currentlyHighlightedOption.next().attr('aria-current', true); } else { currentlyHighlightedOption.attr('aria-current', false); currentlyHighlightedOption = search_suggestions_container.find('li:first'); currentlyHighlightedOption.attr('aria-current', true); search_suggestions_container.scrollTop(0); } } else if (e.keyCode === 38) { if (currentlyHighlightedOption.prev().length && currentlyHighlightedOption.prev().attr('id') !== 'article-search-header') { currentlyHighlightedOption.attr('aria-current', false); currentlyHighlightedOption.prev().attr('aria-current', true); } } else { if (search_text.length >= 3) { $('.hf-article-search-result').remove(); $('#subject-input-container').removeClass('hf-mod-open'); delay(function() { $.ajax('/get_related_kb_forums/', { contentType: 'application/json', data: { 'text': search_text }, success: function(results) { if (results.length) { $('#subject-input-container').addClass('hf-mod-open'); $('<div class="hf-mobile-overlay"></div>').appendTo('body'); var $ul = $('<ul class="hf-article-search-result"></ul>'); $ul.append('<li class="hf-article-search-result_header" id="article-search-header"><span>Someone may have asked your question already. See if you can find an answer below.</li>'); results.forEach(function(result) { if(result['type'] === 'kb') { $ul.append('<li class="hf-search-item"><a href="/kb/article/' + result["id"] +'/">' + '<span class="hf-search-item_title" title="Go to KB article">' + result["title"] + '</span></a></li>'); } if(result['type'] === 'assist_ai_result') { $ul.append('<li class="hf-search-item"><a href="' + result["url"] +'">' + '<span class="hf-search-item_title" title="Go to ' + result["source"] + ' article">' + result["title"] + '</span>' + '<em class="hf-search-item_source">' + result["source"] + '</em></a></li>'); } }); $ul.appendTo($('#subject-input-container')); $ul.find('li').eq(1).attr('aria-current', true); $(".hf-search-item").hover(function() { $('.hf-search-item[aria-current=true]').attr('aria-current', false); $(this).attr('aria-current', true); }); } } }); }, 600); } else { $('.hf-article-search-result').remove(); $('#subject-input-container').removeClass('hf-mod-open'); $('.hf-mobile-overlay').remove(); } } if(search_suggestions_container.length && currentlyHighlightedOption.length) { var search_suggestions_container_top = search_suggestions_container.offset().top; var search_suggestions_container_bottom = search_suggestions_container_top + search_suggestions_container.height(); var elemTop = currentlyHighlightedOption.offset().top; var elemBottom = elemTop + currentlyHighlightedOption.height(); if (elemBottom >= search_suggestions_container_bottom) { search_suggestions_container.scrollTop(0); search_suggestions_container.scrollTop(currentlyHighlightedOption.offset().top - search_suggestions_container.height()); } } } }); $(document).click( function(){ $('.hf-article-search-result').remove(); $('.hf-subject-field-input-container').removeClass('hf-mod-open'); $('.hf-mobile-overlay').remove(); }); setupDropZone("attach-file-drop-area",handleUploadedFiles, "hf-mod-attach-file-dragover"); var url = window.location.origin + '/api/v2/sc/new/'; var form = $('#new-ticket-form'); $(form).submit(function(event) { $(".hf-form-field").removeClass('hf-error'); $('.hf-form-field_error-text').empty(); $("#hf-form-error").empty().hide(); $(".g-recaptcha").removeClass('hf-error'); event.preventDefault(); var array = $('#new-ticket-form').serializeArray(); var isNewTicketFormValid = validateForm(array); if(isNewTicketFormValid) { var payload; var enctype = ''; var payloadSettings; if(attachedFiles.length) { payloadSettings = { type: 'POST', url: url, data: constructFormData(array), enctype: 'multipart/form-data', contentType: false, processData: false, beforeSend:function(xhr) { xhr.setRequestHeader("X-CSRFToken", 'aYv17FnXq9NvjacmLEJLxkbaPkqaWkEAakNIojgjxatu0HbfQkc0hT3GdtCrkeog'); } } } else { payloadSettings = { type: 'POST', url: url, data: JSON.stringify(convertFormToJSON(array)), contentType: 'application/json', dataType: 'json', processData: false, beforeSend:function(xhr) { xhr.setRequestHeader("X-CSRFToken", 'aYv17FnXq9NvjacmLEJLxkbaPkqaWkEAakNIojgjxatu0HbfQkc0hT3GdtCrkeog'); } } } $('#submit').addClass('hf-mod-button-disabled'); $.ajax(payloadSettings).done(function(data, textStatus, jqXHR) { if(jqXHR.status == 201) { $('.hf-custom-message-after-ticket-creation').show(); var offset = $('.hf-custom-message-after-ticket-creation').offset().top + $('.hf-footer').height(); $('.hf-custom-message-after-ticket-creation').css('min-height', 'calc(100vh - ' + offset + 'px)'); $('.hf-new-ticket-form').hide(); } }).fail(function(error) { var errorData = error.responseJSON || {}; var errors = Object.keys(errorData); errors.forEach(function(error, index) { var errorElementIndex = index; var elementID = ''; var fieldElementToFocus = ''; if(error == 'contact_custom_fields' || error == 'custom_fields') { var customFieldErrors = errorData[error]; Object.keys(customFieldErrors).forEach(function(elementID, customFieldIndex) { var elementPrefix = error == 'contact_custom_fields' ? 'c-cf-' : 't-cf-'; var fieldElement = $('#'+ elementPrefix + elementID); handleFieldErrors(fieldElement, customFieldErrors[elementID][0]); if(errorElementIndex == 0 && customFieldIndex == 0) { fieldElementToFocus = fieldElement; } }); } else if (error == 'recaptcha') { $(".g-recaptcha").addClass('hf-error'); } else { elementID = "#id_"+ error; var fieldElement = $(elementID); if(fieldElement.length) { handleFieldErrors(fieldElement, errorData[error][0]); } else { $('#hf-form-error').append(errorData[error][0]); $('#hf-form-error').show(); showToastMessage(errorData[error][0]); } if(errorElementIndex === 0) { fieldElementToFocus = fieldElement; } } if(fieldElementToFocus.length) { $("html, body").animate({ scrollTop: fieldElementToFocus.offset().top - 200 }, 'slow'); } }); if($('#recaptcha').length) { grecaptcha.reset(); } $('#submit').removeClass('hf-mod-button-disabled'); }) } }); showContactGroupBanner(); }); function fetchTicketCustomFields(categoryID) { var url = '/api/v2/sc/categories/' + categoryID + '/ticket-custom-fields/'; if (null != null){ url += '?brand_id=' + None; } $('#ticket-custom-fields-container').html('<div class="hf-ticket-cf-loading-container"><span class="hf-loading-circle"></span><span class="hf-loading-circle hf-mod-center-loading-circle"></span><span class="hf-loading-circle"></span></div>'); $.ajax(url, { contentType: 'application/json', success: function(customFieldsObj) { ticketCustomFields = customFieldsObj.fields; ticketCustomFieldsOrder = customFieldsObj.order; displayParentCustomFields('#ticket-custom-fields-container', 't'); }, error: function (jqXHR, exception) { if (jqXHR.status === 401) { window.location = "/tickets"; } }, }); } function preventDefaults (e) { e.preventDefault() e.stopPropagation() } function validateForm(array) { var isFormValid = true; var fieldElementToFocus = ''; $('[data-required]').each(function(index) { var fieldElement = $(this); var fieldID = fieldElement.attr('id'); var showFieldError = false; if(fieldElement.attr('cf_field_type') === 'multiple_option') { if($('#' + fieldID + ':checked').length == 0) { showFieldError = true; } } else if(fieldID == 'id_html') { if(!CKEDITOR.instances["id_html"].getData()) { showFieldError = true; } } else if(!fieldElement.val()) { showFieldError = true; } if(showFieldError) { handleFieldErrors(fieldElement, "This field is required."); isFormValid = false; if(!fieldElementToFocus) { fieldElementToFocus = fieldElement; $("html, body").animate({ scrollTop: fieldElement.offset().top - 200 }, 'slow'); } } }); var fieldErrors = []; $('[cf_field_type="number"]').each(function() { var fieldElement = $(this); var decimalPart = fieldElement.val().toString().split('.')[1]; if (decimalPart && decimalPart.length > 2) { isFormValid = false; fieldErrors.push(fieldElement); handleFieldErrors(fieldElement, "Ensure that there are no more than 2 decimal places."); } }); if (fieldErrors.length && !fieldElementToFocus) { $("html, body").animate({ scrollTop: fieldErrors[0].offset().top - 200 }, 'slow'); } return isFormValid; } function handleUploadedFiles(event) { var attachedFileSize = 0; var attachmentFileSizeLimit = 25*1024*1024; // File size limit is 25MB $('#attach-file-drop-area').siblings('.hf-form-field_error-text').empty(); var attachmentFileSize = 0; var fileList = event.files || event.dataTransfer.files; var errorFileNames = []; for(i=0; i<fileList.length; i++) { if(attachmentFileSize + fileList[i].size + attachedFileSize < attachmentFileSizeLimit) { attachmentFileSize += fileList[i].size; attachedFiles.push(fileList[i]); } else { var fileName = fileList[i].name.length > 30 ? fileList[i].name.substring(0, 30) + '...' : fileList[i].name; errorFileNames.push(fileName) } } if(errorFileNames.length > 0) { handleFieldErrors($('#attach-file-drop-area'), "Can't upload this file " + errorFileNames.join(', ') + " Total attachment limit is 25MB.") } attachedFileSize = attachedFileSize + attachmentFileSize; renderAttachedFiles(attachedFiles); } function renderAttachedFiles(attachedFiles) { var html = ''; attachedFiles.forEach(function(file, index) { var attachedFileName = file.name; if(attachedFileName.length > 30) { attachedFileName = '<span class="hf-tooltip-toggle hf-mod-new-ticket-tooltip" aria-label="' + file.name + '">' + attachedFileName.substring(0, 30) + '...</span>'; } html += '<div class="hf-attach-file_content" tabindex="0" data-file-id=' + index + '>' html += '<span class="hf-attach-file_name" id="hf-afn-' + index + '"></span>'; html += '<span class="hf-attach-file_close" tabindex="0"></span></div>'; }); $('#attached-files-list').html(html); attachedFiles.forEach(function(file, index) { $('#hf-afn-' + index)[0].textContent = file.name; }); $('.hf-attach-file_close').on('click keydown', function(event) { if(event.keyCode === ENTER_KEY || event.type == "click") { var attachmentId = $(event.target).parent().attr('data-file-id'); attachedFiles.splice(attachmentId, 1); renderAttachedFiles(attachedFiles); } }); } function displayRecepientField(a, container, input) { $(a).addClass('hf-mod-button-disabled'); $(container).slideDown('fast', function(){ $(input).focus(); }); return false; }; function openCCSection() { return displayRecepientField('#add-cc', '#cc', '#cc input'); } function openBCCSection() { return displayRecepientField('#add-bcc', '#bcc', '#bcc input'); } function convertFormToJSON(array) { var dateSubmitFormat = 'YYYY-MM-DD'; var json = {}; $.each(array, function() { if(this.name == 'cc' || this.name == 'bcc') { var valuesList = this.value ? this.value.split(',') : []; json[this.name] = valuesList; } else if (this.name == 'due_date' && this.value) { var dueDateValue; dueDateValue = moment(this.value, dateDisplayFormat).format(dateSubmitFormat); json[this.name] = dueDateValue; } else if ($('#' + this.name).attr('cf_field_type') === 'date') { var dateValue; if(this.value) { dateValue = moment(this.value, dateDisplayFormat).format(dateSubmitFormat); json[this.name] = dateValue; } } else if (this.name === 'html' || this.name === 'description') { json[this.name] = CKEDITOR.instances["id_html"].getData(); } else if ($('#' + this.name).attr('cf_field_type') === 'multiple_option') { if (json[this.name]) { json[this.name].push(this.value); } else { json[this.name] = [this.value]; } } else if (isCurrencyCustomFieldEnabled && $('#' + this.name).attr('cf_field_type') === 'currency') { var fieldIdentifier = 't_field_id'; if (isServiceDesk) { fieldIdentifier = 'ic_field_id'; } var fieldId = $('#' + this.name).attr(fieldIdentifier); var fieldMeta = ticketCustomFields[Number(fieldId)] || {}; var currencyCode = fieldMeta.currency_code; var { decimal, group } = CURRENCY_UTILS.getSeparators(currencyCode); json[this.name] = CURRENCY_UTILS.getNumberValue(this.value, decimal, group); } else if(this.value) { json[this.name] = this.value; } }); return json; } function constructFormData(array) { var json = convertFormToJSON(array); var formattedArray = []; Object.keys(json).forEach(function(key) { formattedArray.push({ name: key, value: json[key]}); }); var formData = new FormData(); $.each(formattedArray, function() { if(Array.isArray(this.value)) { var fieldName = this.name; this.value.forEach(function(value, index) { formData.append(fieldName + '[]', value); }); } else { var value = this.value || ''; formData.append(this.name, value); } }); for(var i = 0;i < attachedFiles.length; i++){ formData.append('attachments', attachedFiles[i]); } return formData; } function handleFieldErrors(fieldElement, Error) { fieldElement.parents('.hf-form-field').addClass('hf-error'); var errorTextElement = ''; if(fieldElement.attr('id') === 'id_gdpr_consent' || fieldElement.attr('cf_field_type') == 'currency') { errorTextElement = fieldElement.parent().siblings('.hf-form-field_error-text'); } else { errorTextElement = fieldElement.siblings('.hf-form-field_error-text'); } errorTextElement.append(Error); } function createDropdownInstance(container) { $(container).find("[cf_field_type=dropdown]").each(function() { $(this).select2({ containerCssClass: 'hf-select2-container', dropdownCssClass: 'hf-newticket-select2-dropdown', minimumResultsForSearch: 10, width: '100%' }) }); } function triggerExternalFileUpload(event) { if(event.type == "click" || event.keyCode == ENTER_KEY){ $('#attach-file-input').click(); } } setupDropZone("hf-inline-attachment-file-container",handleImageDrop); function handleImageDrop(e) { var fileList = e.files || e.dataTransfer.files; var fileFormats = SUPPORTED_IMAGE_FORMATS; var invalidFilesName = []; for(i=0; i<fileList.length; i++){ var type = fileList[i].type; var fileType = type.slice(type.indexOf('/') + 1, type.length); if(!(fileFormats.indexOf(fileType.toLowerCase()) > -1)){ invalidFilesName.push(fileList[i].name); } } if(invalidFilesName.length) { $('#hf-inline-attachment-error-container').text("Unsupported file type " + invalidFilesName.join(', ')); } else { handleUploadedFiles(e); } }; function formatTimeInHourMinutes(timeInMinutes=0) { var isTimeNeagtive = false; if (timeInMinutes < 0) { timeInMinutes = -(timeInMinutes); isTimeNeagtive = true; } var hours = Math.floor(parseInt(timeInMinutes)/60); var minutes = parseInt(timeInMinutes) % 60; if(hours > 0){ return isTimeNeagtive ? `- ${hours}h ${minutes}m.` : `${hours}h ${minutes}m.`; } else { return isTimeNeagtive? `-${minutes}m.` : `${minutes}m.`; } } function showContactGroupBanner() { if($('#hf-cg-available_time').length){ $('#hf-cg-available_time').hide(); var name = $('#id_contact_group').find(':selected').text() var availableTime = $('#id_contact_group').find(':selected').attr('data-available-time'); var allotedTime = $('#id_contact_group').find(':selected').attr('data-allotted-time'); if (availableTime < 60) { allotedTimeFormated = formatTimeInHourMinutes(allotedTime); availableTimeFormated = formatTimeInHourMinutes(availableTime); $('#cg-name').text(name); $('#cg-alloted-time').text(allotedTimeFormated); $('#cg-available-time').text(availableTimeFormated); $('#hf-cg-available_time').show() } } } $('#id_contact_group').on('change', function() { showContactGroupBanner() }); function showToastMessage(message) { var toastMessage = $('.hf-toast-message'); toastMessage.find('.hf-toast-message_text').text(message); toastMessage.show(); setTimeout(function(){ toastMessage.hide(); }, 5000); } function renderIncidentCustomFields(teamId) { let $teamFields = $('.hf-team-form-fields'); $teamFields.hide(); let form = forms.find((form) => form.team == teamId); if (!form) { return ''; } ticketCustomFields = "" ticketCustomFieldsOrder = []; orderedFields = []; let contactPortalFields = ['subject', 'description', 'priority', 'impact', 'urgency'] form.fields.forEach((field) => { if (field.type === 'custom' && field.active_for_contacts) { ticketCustomFieldsOrder.push(field.id); orderedFields.push('.hf-field-' + field.id); } else if (field.type === 'standard' && contactPortalFields.includes(field.id)) { let $field = $('#' + field.id + '-field') if(!field.active_for_contacts) { $field.hide(); $field.find('input, select, textarea').attr('disabled', true); } else { $field.show(); $field.find('input, select, textarea').removeAttr('disabled'); } if (field.mandatory_for_contacts) { $field.find('label').addClass('hf-form-field_required'); $field.find('input, select, textarea').not('input[type=file], #hf-image-url').attr('data-required', true); } else { $field.find('label').removeClass('hf-form-field_required'); $field.find('input, select, textarea').removeAttr('data-required'); } orderedFields.push('.hf-field-' + field.id); } }); // Remove all incident custom fields $('.hf-custom-field').each(function () { let $field = $(this); if ($field.closest('.hf-team-form-fields').length !== 0) { $field.remove(); } }); displayParentCustomFields('#ticket-custom-fields-container', 'ic'); // Detaching and appending to the team fields container as per the order orderedFields.forEach((field) => { let $field = $(field); if ($field.hasClass('hf-custom-field')) { let $depFieldContainer = $field.next(); $field.detach(); $depFieldContainer.detach(); $teamFields.append($field); $teamFields.append($depFieldContainer); } else { $field.detach(); $teamFields.append($field); } }); $teamFields.show(); }</script> <script type="text/javascript">$(document).ready(function(){ var isSafari = window.navigator.userAgent.indexOf("Safari") >= 0 && window.navigator.userAgent.indexOf("Chrome") < 0; if(isSafari) { $('body').addClass('hf-mod-safari'); } });</script> <script type="text/javascript"> var is_preview = ""; if(is_preview == "True") { document.addEventListener("click",PreviewMode,true); function PreviewMode(e){ e.stopPropagation(); e.preventDefault(); } } </script> <footer data-printable="false" class="hf-footer"> <div class="hf-footer_content"> <nav> </nav> <span class="hf-footer_copyright-text">Copyright 2019, All rights reserved</span> </div> <div class="hf-branding"> <span class="hf-branding_text"> <a href="https://www.happyfox.com/" class="hf-branding-link">Help Desk Software</a> &nbsp;by HappyFox </span> </div> </footer> <script type="text/javascript"> if (window.location.href.includes('/new') && window.location.search) { window.addEventListener('load', (event) => { const query = window.location.search.substring(1); const parameters = query.split('&'); let pair = ''; for (const p of parameters) { pair = p.split('='); if (pair && pair[0] === 'topic') { let selectTopic = document.getElementById('t-cf-11'); if (selectTopic) { if (pair[1] === 'error') { selectTopic.value = '5'; // report an error } else if (pair[1] === 'sampleballot') { selectTopic.value = '11'; //Sample Ballot Lookup Tool } selectTopic.dispatchEvent(new Event('change')); } } } }); } </script> <div id="hf-scroll-to-top" class="hf-scroll-to-top"><img src="https://d12tly1s0ox52d.cloudfront.net/static/100425114413/support_center/svgs/go-to-top.svg" alt="scroll to top icon"/></div> </div> </body> <script type="text/javascript"> $(document).ready(function() { $("#hf-scroll-to-top").click(function() { $("html, body").animate({ scrollTop: 0 }, "slow"); }); if($('.hf-toast-message').length) { setTimeout(closeToastMessage, 3500); } bodyBottomPadding(); $(window).resize(function() { bodyBottomPadding(); }); }); function closeToastMessage() { var toastMessageElement = $('.hf-toast-message').not('.hf-u-hide'); if(toastMessageElement.length) { toastMessageElement.addClass('hf-toast-message-collapse'); setTimeout(function() { toastMessageElement.remove(); }, 500); } } function getCookie(name) { var cookieValue = null; if (document.cookie && document.cookie !== '') { var cookies = document.cookie.split(';'); for (var i = 0; i < cookies.length; i++) { var cookie = cookies[i].trim(); if (cookie.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } function showTopBanner(widget_id, cache_key) { if ('' == 'preview') { $('#hf-announcement-' + widget_id).slideDown('fast'); } else { var topBannerCookie = getCookie('top_banner_' + widget_id); if ((typeof topBannerCookie === "undefined") || (topBannerCookie != cache_key)) { $('#hf-announcement-' + widget_id).slideDown('fast'); } $('#top_banner_' + widget_id).click(function() { $('#hf-announcement-' + widget_id).slideUp('fast'); document.cookie = "top_banner_" + widget_id + "=" + cache_key + "; path=/"; if(typeof handleAnnouncementClose == 'function') { // callback function to handle repositioning elements if the announcement bar closes setTimeout(handleAnnouncementClose, 200); } }); } } function bodyBottomPadding() { if( $('.hf-footer').length ) { var footerHeight = $('.hf-footer').innerHeight(); $('body').css("padding-bottom", footerHeight); } } </script> <script type="text/javascript"> window.HAPPYFOX_CONTACT = {}; </script> </html>

Pages: 1 2 3 4 5 6 7 8 9 10