main.js

About this file

characterCounter and generate_character_counter_handler handles displaying character counters for fields. If current amount of characters is out of the valid range of characters, the text color is red, otherwise black.
regexURLChecker checks whether the url link inputted is value by using a regex expression; return true or false.
notHolidayorWeekend checks whether the date inputted falls on a holiday or weekend.
getRequestAgencyInstructions(): Additional information for an agency is hidden or displayed depending on the type of users.
populateDropdown(): populates an empty dropdown and renders it
renderCustomRequestForm(target): This function renders fields based on the target given; this function also restricts certain key pressed for when choosing data and time; fields are assigned character counters. Popovers and tooltips are assigned to the data fields for placement, trigger, toggle, and content. If the entire form is not displayed, additional content is shown; otherwise, hide the additional content.
handleCategorySwitch handles creating a new form upon a category change. Counters are reset and added divs are removed.
checkRequestTypeDropdowns() checks to ensure that the form has a selected type.
processCustomRequestFormData(): The form is jsonified but if the number of completed fields does not meet the minimum requirement, an alert is displayed.

Code Issues

  • updateCustomRequestFormDropdowns() has 4 nested conditional statements for lines 403-428.
      
        if (this.value !== "") { // if the dropdown is not empty execute this block
          $(requestTypeOptions).each(function () { // loop through each option in the dropdown
              if (this.text !== "" && this.text !== categoryDividerText) { // only update options that actually have text
                  var originalText = originalFormNames[this.value]; // get the actual form name
                  if (backwards[this.value] === 0) { // if there are no instances of the form keep the text at 0
                      if (showMultipleRequestTypes) {
                          $(this).text(originalText + " (" + (backwards[this.value]).toString() + " of " + maxRepeatable[this.value].toString() +  ")");
                      }
                      else {
                          $(this).text(originalText);
                      }
                  }
                  else { // use the following formula, maxRepeatable[this.value] - backwards[this.value] - repeatableCounter[this.value] + 1 to calculate what instance number is currently being processed
                      if (showMultipleRequestTypes) {
                          $(this).text(originalText + " (" + (maxRepeatable[this.value] - backwards[this.value] - repeatableCounter[this.value] + 1).toString() + " of " + maxRepeatable[this.value].toString() +  ")");
                      }
                      else { // use original text if only one custom form can display
                          $(this).text(originalText);
                      }
                  }
                  if (backwards[this.value] > 1) { // update the backwards counter for the next time you see the same form selected in another dropdown
                      backwards[this.value]--;
                  }
              }
          });
      }
      
      
    Recommend refactoring by using functions to reduce the amount of nested conditionals.
  • renderCustomRequestForm(target) runs from lines 465 to 645. Recommend refactoring parts of the function, such as rendering datepicker and timepicker plugins, by taking those chunks fo code and placing them into separate functions.
  • if statement runs from line 531 to 559.
      
        if (e.keyCode !== 8 && // backspace
            e.keyCode !== 9 && // tab
            e.keyCode !== 37 && // left-arrow
            e.keyCode !== 39 && // right-arrow
            e.keyCode !== 48 && // 0
            e.keyCode !== 49 && // 1
            e.keyCode !== 50 && // 2
            e.keyCode !== 51 && // 3
            e.keyCode !== 52 && // 4
            e.keyCode !== 53 && // 5
            e.keyCode !== 54 && // 6
            e.keyCode !== 55 && // 7
            e.keyCode !== 56 && // 8
            e.keyCode !== 57 && // 9
            e.keyCode !== 96 && // num pad 0
            e.keyCode !== 97 && // num pad 1
            e.keyCode !== 98 && // num pad 2
            e.keyCode !== 99 && // num pad 3
            e.keyCode !== 100 && // num pad 4
            e.keyCode !== 101 && // num pad 5
            e.keyCode !== 102 && // num pad 6
            e.keyCode !== 103 && // num pad 7
            e.keyCode !== 104 && // num pad 8
            e.keyCode !== 105 && // num pad 9
            e.keyCode !== 16 && // Shift
            e.keyCode !== 65 && // a
            e.keyCode !== 77 && // m
            e.keyCode !== 80 && // p
            e.keyCode !== 186) {// semi-colon
      
      
    Recommend refactoring this long conditional into a function that returns whether a valid key was pressed. An alternative would also be to have an array of invalid key codes and checking if the key code that was pressed is inside that array.

Code Check Report




   42:16   error    Expected '===' and instead saw '=='                                                                         eqeqeq
  109:55   error    Unexpected string concatenation of literals                                                                 no-useless-concat
  207:56   error    Unexpected string concatenation of literals                                                                 no-useless-concat
  322:26   warning  Method 'success' has a complexity of 7                                                                      complexity
  377:5    error    The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype  guard-for-in
  393:40   warning  Function has a complexity of 7                                                                              complexity
  466:22   warning  Method 'success' has a complexity of 10                                                                     complexity
  512:32   warning  Function has a complexity of 30                                                                             complexity
  553:17   error    The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype  guard-for-in
  560:17   error    The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype  guard-for-in
  560:26   error    'id' is already defined                                                                                     no-redeclare
  572:17   error    The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype  guard-for-in
  572:26   error    'id' is already defined                                                                                     no-redeclare
  593:17   error    The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype  guard-for-in
  593:26   error    'id' is already defined                                                                                     no-redeclare
  727:1    warning  Function 'processCustomRequestFormData' has a complexity of 7                                               complexity
  760:124  error    Don't make functions within a loop                                                                          no-loop-func
  760:124  warning  Function has a complexity of 8                                                                              complexity
  784:29   error    Use '===' to compare with null                                                                              no-eq-null
  784:40   error    Expected '!==' and instead saw '!='                                                                         eqeqeq

✖ 20 problems (14 errors, 6 warnings)
                        

Documentation drawn from source code

/* globals requiredFields: true */
$(function () {
$(function () {
  $(".disable-enter-submit").keypress(function (e) {
function characterCounter(target, maxLength, currentLength, minLength) {
  /* Global character counter
  *
  * Parameters:
  * - target: string of target selector
  * - maxLength: integer of maximum character length
  * - currentLength: integer value of keyed in content
  * - minLength: integer of minimum character length (default = 0)
  *
  * Ex:
  * {
  * target: "#note-content",
  * charLength: 500,
  * contentLength: $(this).val().length,
  * minLength: 0
  * }
  *
  * */
function generateCharacterCounterHandler(id, maxLength, minLength) {
  /*
  * This function creates character counter handlers for when you have multiple events inside a loop
  */
  return function () {
function regexUrlChecker(value) {
  /* Global regexUrlChecker
  *
  * Checks the value of a url link using regex with one of the following allowed protocols: http, https, ftp, git
  *
  * Parameters:
  * value: string of link url
  *
  * Returns: does value match regex object?
  * */
/* jquery datepicker */
function notHolidayOrWeekend(date, forPicker) {
  /* Global notHolidayOrWeekend
  *
  *
  * WARNING:
  * --------
  * 'holiday_dates' must be set globally before calling this function.
  */
function getRequestAgencyInstructions() {
  /* Global getAgencyInstructions
  *
  * ajax call to get additional information for the specified agency
  */
    success: function (data) {
    error: function () {
$('#collapse-agency-instructions').on('shown.bs.collapse', function () {
$('#collapse-agency-instructions').on('hidden.bs.collapse', function () {
function getCustomRequestForms(agencyEin) {
  /* exported getCustomRequestForms
  *
  * function to determine if custom request forms need to be shown on category or agency change
  */
   success: function (data) {
      success: function (data) {
   error: function () {
function populateDropdown(agencyEin) {
  /*
  * function to populate any empty request type dropdowns
  */
  $(".request-type").each(function () {
     success: function (data) {
function updateCustomRequestFormDropdowns() {
  /*
  * Update the dropdowns to disable options where they are no longer repeatable.
  * Update the option text to show instance number of each form and how many more you can create.
  */
  $(".request-type").each(function () {
   $(requestTypeOptions).each(function () {
  $(".request-type").each(function () {
    $(requestTypeOptions).each(function () {
function disableOptions() {
  /*
  * Update the dropdowns to disable all options that don't belong to the current category
  */
  $(".request-type").each(function () {
   $(requestTypeOptions).each(function () {
function renderCustomRequestForm(target) {
  /*
  * function to render custom form fields based on their field definitions.
  * target is the instance number of divs that the form will be rendered to
  */
    success: function (data) {
      }).keydown(function (e) {
     $(".select-multiple").find("option").mousedown(function (e) {
function moreOptions() {
  /*
  * Determine if there are still forms that can be repeated in the request.
  * Return true if there is at least one form that can be rendered.
  * Return false if all options have been rendered already.
  */
function detectChange() {
  /*
  * Detects which request type dropdown was changed and updates the repeatable counter accordingly
  */
function handlePanelDismiss() {
  /*
  * handle the dismissal of a custom request panel. Target is the data target of the dismiss button
  */
function handleCategorySwitch(formId) {
  /*
  * handle a category switch by removing all appended divs,
  * set the new currentCategory,
  * and render a new form belonging to the new category to the first custom request form panel.
  */
   success: function (data) {
function checkRequestTypeDropdowns() {
  /*
  * Function to check if at least one request type dropdown has a selected value
  */
function processCustomRequestFormData() {
  /*
  * Process the custom request form data into a JSON to be passed back on submit
  */
    $("#custom-request-form-content-" + target + " > .custom-request-form-field > .custom-request-form-data").each(function () {
/**
* Check for the presence of a SSN in a string.
* @param {string} text
* @returns {boolean} Whether the string contains an SSN
*/
function checkSSN(text) {
/**
* Cancel form submission if user chooses to review Title and / or Description.
*/
function handlePIIModalReview(){

Source code