<commit_before>$(document).ready(function(){

  //  This removes the delete button from the first repeater.
  $('.destroy-form-container-repeater').first().hide()

  // need to find the max data entry on the page and start incrementing from there
  $dataEntry = 0;
  $('.form-container-repeater').each(function() {
    if ($dataEntry < $(this).attr('data-entry')) {
      $dataEntry = parseInt($(this).attr('data-entry'));
    }
  });

  // clicking on button to add repeater
  $('.form-container-survey').on("click", '.duplicate-form-container-repeater', function(e){
    e.preventDefault();
    e.stopPropagation();

    $scrollPosition = $(this).offset().top - 50;

    // unbinding events on plugins
    unbindChosenTypes();
    $('.datepicker').datepicker('destroy');
    // cloudinary events
    $.cleanData( $('input.cloudinary-fileupload[type=file]') );

    // find and clone container
    var container = $(this).closest('.form-container-repeater');
    $clonedContainer = container.clone(true);

    // remove hidden field observation ids
    $($clonedContainer).find('.hidden-field-observation-id').remove();
    // remove data-observation-id at the repeater level
    $($clonedContainer).removeAttr('data-observation-id')

    //************** BEGIN repeater ids
    repeaterInputs = $clonedContainer.find(".repeater-inputs")
    repeaterClosestPanel = $(this).parents(".panel-body")
    updateRepeaterIds(repeaterInputs, $clonedContainer, repeaterClosestPanel)
    //************ END repeater ids

    // collect all container items inside cloned container for iteration later to update all attributes
    var containerItems = $($clonedContainer).find('.form-container-entry-item');

    // increment data-entry by 1 on every click
    $dataEntry = $dataEntry + 1;

    // loop through collected container items and update attributes with timestamps
    // CONTAINER ITEMS ARE RELATIVE TO CLONED CONTAINER, THINK OF CLONED CONTAINER AS A SECONDARY DOM OF ITS OWN.
    updateDom(containerItems, $dataEntry);

    // fix repeater container data-entry numbers
    $clonedContainer.attr("data-entry", $dataEntry);
    $clonedContainer.find(".form-container-repeater").attr("data-entry", $dataEntry);

    // set cloned container to display none for fading in
    $clonedContainer.attr("style", "display: none;").addClass("new-clone");
    // commenting out because we don't use fancy preview code for docs and videos, if we bring this back probably need this at this point
    cleartFilePreviewContainers($clonedContainer);

    // clear values
    clearValues($clonedContainer);

    // we need to stringiy and reset before appending to dom becuase without this, certain js events were getting
    // triggered on the current repeater as well as the repeater above it
    stringifyAndResetContainer($clonedContainer);
    $(container).after($clonedContainer);

    $newClone = $(".new-clone");

    $newClone.delay("100").fadeIn(1000).removeClass("new-clone");

    setTimeout(function() {
      $("html, body").animate({
        scrollTop: $scrollPosition
      }, 500);
    }, 200);

    // TODO: figure out how to fix the way we are doing our bind
    bindChosenTypes();

    // remove parsley classes and error messages on clonedContainer
    $clonedContainer.find('div.form-container-entry-item[data-required=true]').find('ul.parsley-errors-list').remove();
    removeErrorBackground('radio', $clonedContainer);
    removeErrorBackground('checkbox', $clonedContainer);
    removeErrorBackground('checkboxes', $clonedContainer);
    removeUserSuccessClass($clonedContainer);

    // bind maps
    setTimeout(function(){
      // setupDefaultMaps and bindButtons are in maps.js
      // TODO move maps.js into hanuman, make these method calls relative to the $clonedContainer
      setupDefaultMaps();
      bindButtons();
      resetMapButtons($clonedContainer);
    },500)

    // bind ConditionalLogic and re-run the logic to hide and show
    cl = new ConditionalLogic;
    cl.findRules();

    // unbind and rebind the pickers
    $(".datepicker").unbind().datepicker();
    $(".timepicki").unbind().timepicki({
      increase_direction: 'up',
      on_change: timepickValidate = function(element) {
        return $(element).parsley().validate();
      }
    });

    // rebind cloudinary
    if ($.fn.cloudinary_fileupload != undefined) {
      $('input.cloudinary-fileupload[type=file]').cloudinary_fileupload()
    }

    bindPhotoUploads()
    bindVideoUploads()
    bindDocumentUploads()


    // removed the pretty doc and video preview in cloudinary upload so commenting this out for now-kdh
    // binds previews
    // window.showVideoPreview();
    // window.documentPreview();
    // window.fileDeleteEvent();

    // resetting parsley required field styling on clonedContainer
    $clonedContainer.find('.parsley-error').removeClass('parsley-error')

    // shows delete button for new repeaters.
    $clonedContainer.find('.destroy-form-container-repeater').show()

    // on edit treat photo, video and doc sections as if new since on edit there is already saved files
    if ($('.survey-edit-mode').length > 0) {
      files = $clonedContainer.find("[data-element-type=file]").find('.custom-cloudinary li a')

      clearFileInputsValuesInEdit(files);

      // the code below is removing an unnecessary input placed in dom by carrierwave for every upload button. If we dont remove this input, we get an error when we submit the form.
      $clonedContainer.find('.file-upload-input-button input[type=hidden]').each(function(i, e){
        if ($(e).attr("name").slice(-4) == "[id]") {
          $(e).remove()
        }
      })

     }
  });

  function updateRepeaterIds(repeaterInputs, $clonedContainer, repeaterClosestPanel) {
    var cloningParentContainer
    var timeStamp = new Date().getTime();

    repeaterInputs.each(function(idx, repeaterInput){
      if ($(repeaterInput).attr('is-parent-repeater') == "true") {<commit_msg>add unique ids to entry inputs fields<commit_after>$(document).ready(function(){

  uniquefyEntryIds()

  //  This removes the delete button from the first repeater.
  $('.destroy-form-container-repeater').first().hide()

  // need to find the max data entry on the page and start incrementing from there
  $dataEntry = 0;
  $('.form-container-repeater').each(function() {
    if ($dataEntry < $(this).attr('data-entry')) {
      $dataEntry = parseInt($(this).attr('data-entry'));
    }
  });

  // clicking on button to add repeater
  $('.form-container-survey').on("click", '.duplicate-form-container-repeater', function(e){
    e.preventDefault();
    e.stopPropagation();

    $scrollPosition = $(this).offset().top - 50;

    // unbinding events on plugins
    unbindChosenTypes();
    $('.datepicker').datepicker('destroy');
    // cloudinary events
    $.cleanData( $('input.cloudinary-fileupload[type=file]') );

    // find and clone container
    var container = $(this).closest('.form-container-repeater');
    $clonedContainer = container.clone(true);

    // remove hidden field observation ids
    $($clonedContainer).find('.hidden-field-observation-id').remove();
    // remove data-observation-id at the repeater level
    $($clonedContainer).removeAttr('data-observation-id')

    //************** BEGIN repeater ids
    repeaterInputs = $clonedContainer.find(".repeater-inputs")
    repeaterClosestPanel = $(this).parents(".panel-body")
    updateRepeaterIds(repeaterInputs, $clonedContainer, repeaterClosestPanel)
    //************ END repeater ids

    // collect all container items inside cloned container for iteration later to update all attributes
    var containerItems = $($clonedContainer).find('.form-container-entry-item');

    // increment data-entry by 1 on every click
    $dataEntry = $dataEntry + 1;

    // loop through collected container items and update attributes with timestamps
    // CONTAINER ITEMS ARE RELATIVE TO CLONED CONTAINER, THINK OF CLONED CONTAINER AS A SECONDARY DOM OF ITS OWN.
    updateDom(containerItems, $dataEntry);

    // fix repeater container data-entry numbers
    $clonedContainer.attr("data-entry", $dataEntry);
    $clonedContainer.find(".form-container-repeater").attr("data-entry", $dataEntry);

    // set cloned container to display none for fading in
    $clonedContainer.attr("style", "display: none;").addClass("new-clone");
    // commenting out because we don't use fancy preview code for docs and videos, if we bring this back probably need this at this point
    cleartFilePreviewContainers($clonedContainer);

    // clear values
    clearValues($clonedContainer);

    // we need to stringiy and reset before appending to dom becuase without this, certain js events were getting
    // triggered on the current repeater as well as the repeater above it
    stringifyAndResetContainer($clonedContainer);
    $(container).after($clonedContainer);

    $newClone = $(".new-clone");

    $newClone.delay("100").fadeIn(1000).removeClass("new-clone");

    setTimeout(function() {
      $("html, body").animate({
        scrollTop: $scrollPosition
      }, 500);
    }, 200);

    // TODO: figure out how to fix the way we are doing our bind
    bindChosenTypes();

    // remove parsley classes and error messages on clonedContainer
    $clonedContainer.find('div.form-container-entry-item[data-required=true]').find('ul.parsley-errors-list').remove();
    removeErrorBackground('radio', $clonedContainer);
    removeErrorBackground('checkbox', $clonedContainer);
    removeErrorBackground('checkboxes', $clonedContainer);
    removeUserSuccessClass($clonedContainer);

    // bind maps
    setTimeout(function(){
      // setupDefaultMaps and bindButtons are in maps.js
      // TODO move maps.js into hanuman, make these method calls relative to the $clonedContainer
      setupDefaultMaps();
      bindButtons();
      resetMapButtons($clonedContainer);
    },500)

    // bind ConditionalLogic and re-run the logic to hide and show
    cl = new ConditionalLogic;
    cl.findRules();

    // unbind and rebind the pickers
    $(".datepicker").unbind().datepicker();
    $(".timepicki").unbind().timepicki({
      increase_direction: 'up',
      on_change: timepickValidate = function(element) {
        return $(element).parsley().validate();
      }
    });

    // rebind cloudinary
    if ($.fn.cloudinary_fileupload != undefined) {
      $('input.cloudinary-fileupload[type=file]').cloudinary_fileupload()
    }

    bindPhotoUploads()
    bindVideoUploads()
    bindDocumentUploads()


    // removed the pretty doc and video preview in cloudinary upload so commenting this out for now-kdh
    // binds previews
    // window.showVideoPreview();
    // window.documentPreview();
    // window.fileDeleteEvent();

    // resetting parsley required field styling on clonedContainer
    $clonedContainer.find('.parsley-error').removeClass('parsley-error')

    // shows delete button for new repeaters.
    $clonedContainer.find('.destroy-form-container-repeater').show()

    // on edit treat photo, video and doc sections as if new since on edit there is already saved files
    if ($('.survey-edit-mode').length > 0) {
      files = $clonedContainer.find("[data-element-type=file]").find('.custom-cloudinary li a')

      clearFileInputsValuesInEdit(files);

      // the code below is removing an unnecessary input placed in dom by carrierwave for every upload button. If we dont remove this input, we get an error when we submit the form.
      $clonedContainer.find('.file-upload-input-button input[type=hidden]').each(function(i, e){
        if ($(e).attr("name").slice(-4) == "[id]") {
          $(e).remove()
        }
      })

     }
     uniquefyEntryIds()
  });

  function uniquefyEntryIds() {
    entryId = 1
    // finding and iterating throught all the parent repeaters.
    $("[is-parent-repeater=true]").each(function(idx, el){

      // Select parent repeater conatiners
      parent = $(el).closest(".form-container-repeater")

      // select all the contaienrs that contain entry id hidden inputs
      entryContainers = parent.find('.form-container-entry-item')

      // find the entry id hidden inputs
      $entryInputs = entryContainers.find("input[name*='[entry]']")

      // in the parent repeater, find all the nested repeater container
      nestedRepeater = parent.find(".form-container-repeater")

      // update all entry inputs found on page.
      $entryInputs.val(entryId)

      // iterating through nested repeaters to update the entry ids with unique id.
      nestedRepeater.each(function(i,el){
        if (i > 0) {
          entryInputWithinRepeaters = $(el).find("input[name*='[entry]']")
          var timeStamp = new Date().getTime();
          entryInputWithinRepeaters.val(timeStamp+i)
        }
      })
      entryId += 1000
    })

    // Keeping for future debbuging
    $("input[name*='[entry]']").each(function(idx, el){
      $(el).after(" entry id: **** " + $(el).val())
    })
  }


  function updateRepeaterIds(repeaterInputs, $clonedContainer, repeaterClosestPanel) {
    var cloningParentContainer
    var timeStamp = new Date().getTime();

    repeaterInputs.each(function(idx, repeaterInput){
      if ($(repeaterInput).attr('is-parent-repeater') == "true") {
{'fraction_non_alphanumeric': 0.13351909029294376, 'fraction_numerical': 0.003915957526922208, 'mean_word_length': 3.4743935309973044, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '365651', 'n_tokens_mistral': 3836, 'n_tokens_neox': 3697, 'n_words': 1005}