diff src/add-one-spectrum-index.js @ 1:7e3085fc60c1 draft default tip

master branch Updating
author lain
date Wed, 30 Aug 2023 14:21:18 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/add-one-spectrum-index.js	Wed Aug 30 14:21:18 2023 +0000
@@ -0,0 +1,2627 @@
+
+var token = "{{ PF_TOKEN_PLACEHOLDER }}" ;
+if ({{ TAB_INDEX_PLACEHOLDER }} == 1) {
+}
+
+context_{{ TAB_INDEX_PLACEHOLDER }} = {
+  prefix: "#accordion-{{ TAB_INDEX_PLACEHOLDER }} ",
+  name: "Context[{{ TAB_INDEX_PLACEHOLDER }}]",
+  produce_json: {{ PRODUCE_JSON_PLACEHOLDER }},
+  DEFAULT_MS_PEAK_VALUES: {{ MS_PEAK_VALUES_PLACEHOLDER }},
+  DEFAULT_DATA: {{ DEFAULT_DATA }},
+  peakforest_url: "{{ PF_URL_PLACEHOLDER }}",
+  tab_index: "{{ TAB_INDEX_PLACEHOLDER }}",
+  modeEditSpectrum: false,
+  isSeparationFlowRateInit: false,
+  isMSpeaksInit: false,
+  isLC: false,
+  isGC: false,
+  isIC: false,
+  hot_LC_SFG: null ,
+  hot_MS_Peaks: null,
+  hot_RCC_ADDED: null,
+  jsonSpectrumType: null,
+  isJsonSpectrumTypeComplete: false,
+  jsonSample: null,
+  isJsonSampleComplete: false,
+  isJsonRCCaddedComplete: false,
+  jsonChromato: null,
+  isJsonChromatoComplete: false,
+  jsonAnalyzer: null,
+  isJsonAnalyzerComplete: false,
+  jsonPeaksList: [],
+  isJsonPeaksListComplete: false,
+  jsonOtherMetadata: null,
+  isJsonOtherMetadataComplete: false,
+  jsonMolIonization: null,
+  jsonMolIonBeam: null,
+  cptPeakListTab: 0,
+  jsonAnalyzerAcquisition: [],
+  idMetadataMap: {},
+  listOfViewableSpectra: [],
+  singlePick: true,
+  multiPickLine: -1,
+  subjects: [],
+  fitlerSearchLoadlCpd: 5,
+  inchikey: null,
+  initialized: false,
+  selected_ion_index: null,
+  lock: {
+    precursor_ion: false
+  },
+
+  sent_json: null,
+
+  init: function() {
+
+    var self = this ;
+
+    $(document).ready(() => self.on_ready());
+    $(document).ready(function() {
+      console.log("adding click on open_tab_{{ TAB_INDEX_PLACEHOLDER }}.") ;
+      var activate_tab = function() {
+        if (self.initialized) {
+          return ;
+        }
+        self.auto_set_spec_type() ;
+      }
+      if (self.is_ref()) {
+        $("#open_tab_{{ TAB_INDEX_PLACEHOLDER }}").click(activate_tab) ;
+      }
+      if ({{ TAB_INDEX_PLACEHOLDER }} == 1) {
+        activate_tab() ;
+      }
+    }) ;
+
+    return (self) ;
+
+  },
+
+  on_ready: function() {
+    var self = this ;
+
+    $(self.prefix+".pickChemicalCompound").click(self.pickChemicalCompound);
+    $(self.prefix+".add1spectrum").change(
+      function(){self.add1spectrum_change_handler(this)}
+    )
+    self.attach_search() ;
+    self.add_date_check() ;
+    self.populate_selects() ;
+    self.add_change_handlers() ;
+    self.show_hide_ms_ms2_fields() ;
+  },
+
+  populate_selects: function() {
+    var self = this ;
+    var choose_in_list ;
+
+    choose_in_list = `
+      <option value="" selected="selected" disabled="disabled">
+        choose in list&hellip;
+      </option>
+    ` ;
+    $("#add1spectrum-chromatoLC-method-{{ TAB_INDEX_PLACEHOLDER }}").append(choose_in_list) ;
+    $("#add1spectrum-chromatoLC-colConstructor-{{ TAB_INDEX_PLACEHOLDER }}").append(choose_in_list) ;
+    $("#add1spectrum-chromatoLC-separationSolvA-{{ TAB_INDEX_PLACEHOLDER }}").append(choose_in_list) ;
+    $("#add1spectrum-chromatoLC-separationSolvB-{{ TAB_INDEX_PLACEHOLDER }}").append(choose_in_list) ;
+    $("#add1spectrum-sample-lcmsSolvent-{{ TAB_INDEX_PLACEHOLDER }}").append(choose_in_list) ;
+    $.getJSON("{{ PF_URL_PLACEHOLDER }}/webapp/resources/json/list-lc-methods.json", self.populate_lc_methods) ;
+    $.getJSON("{{ PF_URL_PLACEHOLDER }}/webapp/resources/json/list-lc-columns.json", self.populate_lc_columns) ;
+    $.getJSON("{{ PF_URL_PLACEHOLDER }}/webapp/resources/json/list-lc-solvents.json", self.populate_lc_solvents) ;
+    $.getJSON("{{ PF_URL_PLACEHOLDER }}/webapp/resources/json/list-ms-ionization-methods.json", self.populate_ms_ionization) ;
+    $.getJSON("{{ PF_URL_PLACEHOLDER }}/webapp/resources/json/list-lcms-solvents.json", self.populate_lcms_solvents) ;
+    self.resetFromColors();
+  },
+
+  attach_search: function() {
+    var self = this ;
+
+    $("#add-one-cc-s1-value-{{ TAB_INDEX_PLACEHOLDER }}").bind("keypress", function(e) {
+      var code = e.keyCode || e.which;
+      if (code == 13) {
+        self.searchLocalCompound();
+      }
+    });
+    $("#add-one-cc-s1-value-{{ TAB_INDEX_PLACEHOLDER }}").typeahead({
+      source: function(query, process) {
+        return self.searchAjax();
+      }
+    });
+  },
+
+  add_date_check: function() {
+    var self = this ;
+
+    $("#add1spectrum-other-date-{{ TAB_INDEX_PLACEHOLDER }}").focusout(function() {
+      var element = $(this) ;
+      self.rm_warning(element);
+      self.rm_success(element) ;
+      if (element.val() == "") {
+        element.parent().addClass("has-warning");
+      } else {
+        element.parent().addClass("has-success");
+      }
+    });
+  },
+
+  populate_lc_methods: function(data) {
+    // load data from json
+    $.each(data.methods,function() {
+      if (this.name !== undefined) {
+        if (this.value !== undefined) {
+          $("#add1spectrum-chromatoLC-method-{{ TAB_INDEX_PLACEHOLDER }}").append(
+            `<option value="${this.value}">${this.name}</option>`
+          );
+        } else {
+          $("#add1spectrum-chromatoLC-method-{{ TAB_INDEX_PLACEHOLDER }}").append(
+            `<option disabled>${this.name}</option>`
+          );
+        }
+      }
+    });
+  },
+
+  populate_lc_columns: function(data) {
+    // load data from json
+    $.each(data.columns, function() {
+      $("#add1spectrum-chromatoLC-colConstructor-{{ TAB_INDEX_PLACEHOLDER }}").append(
+        `<option value="${this.value}">${this.name}</option>`
+      );
+    });
+    $("#add1spectrum-chromatoLC-colConstructor-{{ TAB_INDEX_PLACEHOLDER }}").append(
+      '<option value="other" >Other</option>'
+    );
+  },
+
+  populate_lc_solvents: function(data) {
+    // load data from json
+    $.each(data.solvents, function() {
+      $("#add1spectrum-chromatoLC-separationSolvA-{{ TAB_INDEX_PLACEHOLDER }}").append(
+        `<option value="${this.value}">${this.name}</option>`
+      );
+      $("#add1spectrum-chromatoLC-separationSolvB-{{ TAB_INDEX_PLACEHOLDER }}").append(
+        `<option value="${this.value}">${this.name}</option>`
+      );
+    });
+  },
+
+  populate_ms_ionization: function(data) {
+    // load data from json
+    $.each(data.methods,function() {
+      if (this.name !==undefined) {
+        if (this.value !==undefined) {
+          $("#add1spectrum-analyzserMS-ionizationMethod-pos-{{ TAB_INDEX_PLACEHOLDER }}").append(
+            `<option value="${this.value}">${this.name}</option>`
+          );
+          $("#add1spectrum-analyzserMS-ionizationMethod-neg-{{ TAB_INDEX_PLACEHOLDER }}").append(
+            `<option value="${this.value}">${this.name}</option>`
+          );
+        } else {
+          $("#add1spectrum-analyzserMS-ionizationMethod-pos-{{ TAB_INDEX_PLACEHOLDER }}").append(
+            `<option disabled>${this.name}</option>`
+          );
+          $("#add1spectrum-analyzserMS-ionizationMethod-neg-{{ TAB_INDEX_PLACEHOLDER }}").append(
+            `<option disabled>${this.name}</option>`
+          );
+        }
+      }
+    });
+  },
+
+  populate_lcms_solvents: function(data) {
+    // load data from json
+    $.each(data.solvents, function () {
+      $("#add1spectrum-sample-lcmsSolvent-{{ TAB_INDEX_PLACEHOLDER }}").append(
+        `<option value="${this.value}" class="${this.classD}">${this.name}</option>`
+      );
+    });
+  },
+
+  add_change_handlers: function() {
+    var self = this ;
+
+    $("#add1spectrum-ionTrapBeam-type-{{ TAB_INDEX_PLACEHOLDER }}").on("change", function() {
+      var v = $("#add1spectrum-ionTrapBeam-type-{{ TAB_INDEX_PLACEHOLDER }}").val();
+      $(self.prefix + ".add1spectrum-ionTrap").hide();
+      if (v == "beam") {
+      } else if (v == "trap") {
+        $(self.prefix + ".add1spectrum-ionTrap").show();
+      }
+    }) ;
+  },
+
+  show_hide_ms_ms2_fields: function() {
+    var self = this ;
+    $(self.prefix + " .disabled-if-ms").attr("disabled", self.is_ms())
+    $(self.prefix + " .disabled-if-msms").attr("disabled", self.is_ms2())
+    $(self.prefix + " .disabled-if-ms2").attr("disabled", self.is_ms2())
+    if (self.is_ms()) {
+      self.hide(self.prefix + " .hidden-if-ms") ;
+    }
+    if (self.is_ms2()) {
+      self.hide(self.prefix + " .hidden-if-msms") ;
+      self.hide(self.prefix + " .hidden-if-ms2") ;
+    }
+  },
+
+  is_mix: function() {
+    return this.DEFAULT_DATA["sample_type"] == "compound-mix" ;
+  },
+
+  is_ref: function() {
+    return this.DEFAULT_DATA["sample_type"] == "compound-ref" ;
+  },
+
+  is_ms: function() {
+    return this.DEFAULT_DATA["spectrum_type"] == "LC_MS" ;
+  },
+
+  is_ms2: function() {
+    return this.DEFAULT_DATA["spectrum_type"] == "LC_MSMS" ;
+  },
+
+  is_other_in_mix() {
+    return this.is_mix() && {{ TAB_INDEX_PLACEHOLDER }} > 1 ;
+  },
+
+  hide: function(id) {
+    if (typeof id == Array) {
+      return (id.forEach(hide)) ;
+    }
+    $(id).hide()
+  },
+
+  rm_success: function(element) {
+    return (this.rm_parent_class(element, "has-success"))
+  },
+  rm_error: function(element) {
+    return (this.rm_parent_class(element, "has-error"))
+  },
+  rm_warning: function(element) {
+    return (this.rm_parent_class(element, "has-warning"))
+  },
+  set_success: function(element) {
+    return (this.set_parent_class(element, "has-success"))
+  },
+  set_error: function(element) {
+    return (this.set_parent_class(element, "has-error"))
+  },
+  set_warning: function(element) {
+    return (this.set_parent_class(element, "has-warning"))
+  },
+  rm_parent_class: function(element, cls) {
+    var parent ;
+
+    if ((parent = element.parent()) == null) {
+      return false ;
+    }
+    return this.rm_class(parent, cls) ;
+  },
+  set_parent_class: function(element, cls) {
+    var parent ;
+
+    if ((parent = element.parent()) == null) {
+      return false ;
+    }
+    return this.set_class(parent, cls) ;
+  },
+  rm_class: function(element, cls) {
+    if (element.hasClass(cls)) {
+      element.removeClass(cls) ;
+      return true ;
+    }
+    return false ;
+  },
+  set_class: function(element, cls) {
+    if (element.hasClass(cls)) {
+      return false ;
+    }
+    element.addClass(cls) ;
+    return true ;
+  },
+  is_success: function(element) {
+    return (this.parent_has_class(element, "has-success"))
+  },
+  is_warning: function(element) {
+    return (this.parent_has_class(element, "has-warning"))
+  },
+  is_error: function(element) {
+    return (this.parent_has_class(element, "has-error"))
+  },
+  is_optional: function(element) {
+    return (element.hasClass("is-optional"))
+  },
+  is_mandatory: function(element) {
+    return (element.hasClass("is-mandatory"))
+  },
+  parent_has_class: function(element, cls) {
+    var parent ;
+
+    if ((parent = element.parent()) == null) {
+      return false ;
+    }
+    return (parent.hasClass(cls)) ;
+  },
+
+  add1spectrum_change_handler: function(element) {
+    var self = this ;
+    var idElem ;
+    var valElem ;
+    var isSuccess ;
+    var isWarning ;
+    var isError ;
+    var isOptional ;
+    var isMandatory ;
+
+    element = $(element) ;
+    idElem = element.attr("id") ;
+    valElem = element.val();
+    console.log(`Change handler called for [${idElem}]=${valElem}`) ;
+    if (idElem.split("-").slice(0, -1).join("-") == "add1spectrum-peaksMS-msPrecursorIon") {
+      var index = idElem.split("-")[3] - 1 ;
+      if (all_contexts[index] !== null && all_contexts[index] !== undefined) {
+        all_contexts[index].sync_precursor_ion() ;
+        if (all_contexts[index].hot_MS_Peaks != null) {
+          all_contexts[index].hot_MS_Peaks.render()
+        }
+      }
+    }
+    isSuccess = self.is_success(element);
+    isWarning = self.is_warning(element);
+    isError = self.is_error(element);
+    isOptional = self.is_optional(element);
+    isMandatory = self.is_mandatory(element);
+
+    switch(idElem) {
+    case "add1spectrum-sample-type-{{ TAB_INDEX_PLACEHOLDER }}":
+      if (valElem == "compound-ref") {
+        $("#add1spectrum-sample-type-compound-ref-{{ TAB_INDEX_PLACEHOLDER }}").show();
+        $("#add1spectrum-sample-type-compound-mix-{{ TAB_INDEX_PLACEHOLDER }}").hide();
+        $("#add1spectrum-sample-type-rcc-added-{{ TAB_INDEX_PLACEHOLDER }}").hide();
+      } else if (valElem == "compound-mix") {
+        $("#add1spectrum-sample-type-compound-mix-{{ TAB_INDEX_PLACEHOLDER }}").show();
+        $("#add1spectrum-sample-type-compound-ref-{{ TAB_INDEX_PLACEHOLDER }}").hide();
+        $("#add1spectrum-sample-type-rcc-added-{{ TAB_INDEX_PLACEHOLDER }}").show();
+        self.handsontableRefChemCpdAdded(null);
+      }
+      break;
+    case "add1spectrum-chromatoLC-colConstructor-{{ TAB_INDEX_PLACEHOLDER }}":
+      self.resetElemColor("add1spectrum-chromatoLC-colConstructorOther-{{ TAB_INDEX_PLACEHOLDER }}");
+      if (valElem == "" || valElem == null || valElem != "other" ) {
+        self.disableElem("add1spectrum-chromatoLC-colConstructorOther-{{ TAB_INDEX_PLACEHOLDER }}");
+      } else {
+        self.enableElem("add1spectrum-chromatoLC-colConstructorOther-{{ TAB_INDEX_PLACEHOLDER }}");
+      }
+      break;
+    case "add1spectrum-chromatoLC-method-{{ TAB_INDEX_PLACEHOLDER }}":
+      self.fulfillLCdata(valElem);
+      break;
+    case "add1spectrum-analyzserMS-ionizationMethod-pos-{{ TAB_INDEX_PLACEHOLDER }}":
+      if ($("#add1spectrum-analyzserMS-ionizationMethod-pos-{{ TAB_INDEX_PLACEHOLDER }}").val() != null) {
+        $($("#add1spectrum-peaksMS-polarity-{{ TAB_INDEX_PLACEHOLDER }} option")[1]).attr("disabled", false);
+      }
+      break;
+    case "add1spectrum-analyzserMS-ionizationMethod-neg-{{ TAB_INDEX_PLACEHOLDER }}":
+      if ($("#add1spectrum-analyzserMS-ionizationMethod-neg-{{ TAB_INDEX_PLACEHOLDER }}").val() != null) {
+        $($("#add1spectrum-peaksMS-polarity-{{ TAB_INDEX_PLACEHOLDER }} option")[2]).attr("disabled", false);
+      }
+      break;
+    }
+    if ((isMandatory || isOptional) && (valElem == "" || valElem == null)) {
+      if (isSuccess) {
+        self.rm_success(element) ;
+      } else if (isWarning) {
+        self.rm_warning(element) ;
+      } else if (isError) {
+        self.rm_error(element) ;
+      }
+      if (isMandatory) {
+        self.set_error(element) ;
+      } else {
+        self.set_warning(element) ;
+      }
+    }
+    if (isMandatory && (valElem != "" && valElem != null)) {
+      if (isError) {
+        self.rm_error(element) ;
+      }
+      self.set_success(element) ;
+    } else if (isOptional && valElem != "") {
+      if (isWarning) {
+        self.rm_warning(element) ;
+      }
+      self.set_success(element) ;
+    }
+    if (element.parent().children("input").size() == 2) {
+      if (isMandatory) {
+        if (isSuccess) {
+          self.rm_success(element) ;
+        } else if (isWarning) {
+          self.rm_warning(element) ;
+        } else if (isError) {
+          self.rm_error(element) ;
+        }
+        if (element.parent().children("input").toArray().some(
+          (el) => $(el).val() === null || $(el).val() === ""
+        )) {
+          self.set_error(element) ;
+        } else {
+          self.set_success(element) ;
+        }
+      } else if (isOptional) {
+        isSuccess = self.is_success(element);
+        isWarning = self.is_warning(element);
+        isError = self.is_error(element);
+        if (isSuccess) {
+          self.rm_success(element)
+        } else if (isWarning) {
+          self.rm_warning(element) ;
+        } else if (isError) {
+          self.rm_error(element) ;
+        }
+        if (element.parent().children("input").toArray().some(
+          (el) => ($(el).val() == null || $(el).val() == "")
+        )) {
+          self.set_warning(element) ;
+        } else {
+          self.set_success(element) ;
+        }
+      }
+    }
+    if (element.hasClass("one-or-more")) {
+      // get parent class
+      isSuccess = self.is_success(element);
+      isWarning = self.is_warning(element);
+      isError = self.is_error(element);
+      // reset class
+      if (isSuccess) {
+        self.rm_success(element) ;
+      } else if (isWarning) {
+        self.rm_warning(element) ;
+      } else if (isError) {
+        self.rm_error(element) ;
+      }
+      isTmpSuccess = false;
+      $.each(element.parent().children("input"), function(id, child){
+        if ($(child).val() != null && $(child).val() != "") {
+          isTmpSuccess = true;
+        }
+      });
+      $.each(element.parent().children("select"), function(id, child){
+        if ($(child).val() != null && $(child).val() != "") {
+          isTmpSuccess = true;
+        }
+      });
+      // end parkour
+      element.parent().addClass(
+        isTmpSuccess ? "has-success" : "has-error"
+      );
+    }
+    // CHECK IF OK STEP 2
+    if (element.hasClass("add1spectrum-sampleForm")) {
+      var isBtnStep2OK = true;
+      $.each($(self.prefix + ".add1spectrum-sampleForm"), (id, elem) => {
+        if (self.is_error($(elem)) && $(elem).is(":visible")) {
+          isBtnStep2OK = false;
+        }
+      });
+      if (isBtnStep2OK) {
+        self.rm_class($("#btnSwitch-gotoStep2-{{ TAB_INDEX_PLACEHOLDER }}"), "btn-disabled") ;
+        self.set_class($("#btnSwitch-gotoStep2-{{ TAB_INDEX_PLACEHOLDER }}"), "btn-primary") ;
+        $("#btnSwitch-gotoStep2-{{ TAB_INDEX_PLACEHOLDER }}").prop("disabled", false);
+      } else {
+        self.set_class($("#btnSwitch-gotoStep2-{{ TAB_INDEX_PLACEHOLDER }}"), "btn-disabled") ;
+        self.rm_class($("#btnSwitch-gotoStep2-{{ TAB_INDEX_PLACEHOLDER }}"), "btn-primary") ;
+        $("#btnSwitch-gotoStep2-{{ TAB_INDEX_PLACEHOLDER }}").prop("disabled", true);
+      }
+    }
+    // CHECK IF OK STEP 3 - LC
+    if (
+      element.hasClass("add1spectrum-chromatoLCForm")
+      && $("#btnSwitch-gotoStep3-lc-{{ TAB_INDEX_PLACEHOLDER }}").is(":visible")
+    ) {
+      var isBtnStep3OK = true;
+      $.each($(self.prefix+".add1spectrum-chromatoLCForm"), (id, elem) => {
+        if (self.is_error($(elem)) && $(elem).is(":visible"))
+          isBtnStep3OK = false;
+      });
+      if (isBtnStep3OK) {
+        self.rm_class($("#btnSwitch-gotoStep3-lc-{{ TAB_INDEX_PLACEHOLDER }}"), "btn-disabled") ;
+        self.set_class($("#btnSwitch-gotoStep3-lc-{{ TAB_INDEX_PLACEHOLDER }}"), "btn-primary") ;
+        $("#btnSwitch-gotoStep3-lc-{{ TAB_INDEX_PLACEHOLDER }}").prop("disabled", false);
+      } else {
+        self.set_class($("#btnSwitch-gotoStep3-lc-{{ TAB_INDEX_PLACEHOLDER }}"), "btn-disabled") ;
+        self.rm_class($("#btnSwitch-gotoStep3-lc-{{ TAB_INDEX_PLACEHOLDER }}"), "btn-primary") ;
+        $("#btnSwitch-gotoStep3-lc-{{ TAB_INDEX_PLACEHOLDER }}").prop("disabled", true);
+      }
+    }
+    // TODO CHECK IF OK STEP 3 - GC
+    // CHECK IF OK STEP 4 - MS ANALYZER
+    if (
+      element.hasClass("add1spectrum-analyzerMSForm")
+      && $("#btnSwitch-gotoStep4-ms-{{ TAB_INDEX_PLACEHOLDER }}").is(":visible")
+    ) {
+      var isBtnStep4OK = true;
+      $.each($(self.prefix+".add1spectrum-analyzerMSForm"), (id, elem) => {
+        if (self.is_error($(elem)) && $(elem).is(":visible"))
+          isBtnStep4OK = false;
+      });
+      if (isBtnStep4OK) {
+        self.rm_class($("#btnSwitch-gotoStep4-ms-{{ TAB_INDEX_PLACEHOLDER }}"), "btn-disabled") ;
+        self.set_class($("#btnSwitch-gotoStep4-ms-{{ TAB_INDEX_PLACEHOLDER }}"), "btn-primary") ;
+        $("#btnSwitch-gotoStep4-ms-{{ TAB_INDEX_PLACEHOLDER }}").prop("disabled", false);
+      } else {
+        self.set_class($("#btnSwitch-gotoStep4-ms-{{ TAB_INDEX_PLACEHOLDER }}"), "btn-disabled") ;
+        self.rm_class($("#btnSwitch-gotoStep4-ms-{{ TAB_INDEX_PLACEHOLDER }}"), "btn-primary") ;
+        $("#btnSwitch-gotoStep4-ms-{{ TAB_INDEX_PLACEHOLDER }}").prop("disabled", true);
+      }
+    }
+    // CHECK IF OK STEP 5 - PEAKS
+    if (
+      element.hasClass("add1spectrum-peaksMSForm-peaklist")
+      && $("#btnSwitch-gotoStep5-ms-{{ TAB_INDEX_PLACEHOLDER }}").is(":visible")
+    ) {
+      var isBtnStep5OK = true;
+      $.each($(self.prefix+".add1spectrum-peaksMSForm-peaklist"), (id, elem) => {
+        if (self.is_error($(elem)) && $(elem).is(":visible"))
+          isBtnStep5OK = false;
+      });
+      if (isBtnStep5OK && (self.is_ms() || self.a_ion_parent_is_selected())) {
+        self.rm_class($("#btnSwitch-gotoStep5-ms-{{ TAB_INDEX_PLACEHOLDER }}"), "btn-disabled") ;
+        self.set_class($("#btnSwitch-gotoStep5-ms-{{ TAB_INDEX_PLACEHOLDER }}"), "btn-primary") ;
+        $("#btnSwitch-gotoStep5-ms-{{ TAB_INDEX_PLACEHOLDER }}").prop("disabled", false);
+      } else {
+        self.set_class($("#btnSwitch-gotoStep5-ms-{{ TAB_INDEX_PLACEHOLDER }}"), "btn-disabled") ;
+        self.rm_class($("#btnSwitch-gotoStep5-ms-{{ TAB_INDEX_PLACEHOLDER }}"), "btn-primary") ;
+        $("#btnSwitch-gotoStep5-ms-{{ TAB_INDEX_PLACEHOLDER }}").prop("disabled", true);
+      }
+    }
+    // CHECK IF OK STEP 6 - OTHER DATA
+    if (
+      element.hasClass("add1spectrum-otherForm")
+      && $("#btnSwitch-gotoStep6-{{ TAB_INDEX_PLACEHOLDER }}").is(":visible")
+    ) {
+      self.checkIfEnableSubmit() ;
+    }
+  },
+
+  a_ion_parent_is_selected: function() {
+    return (this.get_selected_parent_ion_mz() !== null) ;
+  },
+
+  get_selected_parent_ion_index: function() {
+    var curent_mz = this.get_selected_parent_ion_mz() ;
+    if (curent_mz === null) {
+      return null;
+    }
+    if (this.hot_MS_Peaks == undefined) {
+      return null ;
+    }
+    var data = this.hot_MS_Peaks.getData() ;
+    for (var i = 0 ; i < data.length ; i += 1) {
+      if (Math.abs(data[i][0] - curent_mz) < 0.0001) {
+        return i ;
+      }
+    }
+    return null ;
+  },
+
+  get_selected_parent_ion_mz: function() {
+    return $(
+      "#add1spectrum-peaksMS-msPrecursorIon-{{ TAB_INDEX_PLACEHOLDER }}"
+    ).val() || null ;
+  },
+
+  auto_set_spec_type: function() {
+    console.log("auto_set_spec_type...") ;
+    var self = this ;
+    var id = `#set_${self.DEFAULT_DATA["spectrum_type"]}_spectrum_button` ;
+    var element = $(self.prefix + id) ;
+    if (element.length) {
+      element.click() ;
+      console.log(`auto_set_spec_type to ${self.DEFAULT_DATA["spectrum_type"]} ok.`)
+    } else {
+      console.log(element)
+      console.log("Failed!")
+    }
+    if (self.DEFAULT_DATA["sample_type"]) {
+      self.auto_set_sample_type(self) ;
+    }
+  },
+
+  auto_set_sample_type: function() {
+    console.log("auto_set_sample_type...") ;
+    var self = this ;
+    var id = "#add1spectrum-sample-type-{{ TAB_INDEX_PLACEHOLDER }}" ;
+    var element = $(id) ;
+    if (element.length) {
+      element.val(self.DEFAULT_DATA["sample_type"]).change() ;
+      console.log(`auto_set_sample_type to ${self.DEFAULT_DATA["sample_type"]} ok.`) ;
+      if (self.DEFAULT_DATA["sample_type"] == "compound-ref") {
+        $("#add1spectrum-sample-mixSolvent-{{ TAB_INDEX_PLACEHOLDER }}").val(
+          "H2O/ethanol (75/25)"
+        ).change() ;
+      }
+    } else {
+      console.log(element)
+      console.log("Failed!")
+    }
+    if (self.DEFAULT_DATA["inchikey"]) {
+      setTimeout(() => self.auto_set_inchikey(self), 1000) ;
+    }
+  },
+
+  auto_set_inchikey: function() {
+    console.log("auto_set_inchikey...") ;
+    var self = this ;
+    var id ;
+    var element ;
+    self.inchikey = self.DEFAULT_DATA["inchikey"] ;
+    if (self.is_ref()) {
+      id = "#add1spectrum-sample-inchikey-{{ TAB_INDEX_PLACEHOLDER }}:text" ;
+      element = $(id) ;
+      if (element.length) {
+        console.log(`auto_set_inchikey to ${self.inchikey} ok.`)
+        element.val(self.inchikey).change() ;
+        console.log(`Inchikey set!`) ;
+      } else {
+        console.log(element)
+        console.log("Failed!")
+      }
+    } else {
+      for (var index = 0 ; index < all_contexts.length ; index += 1) {
+        if (all_contexts[index] === null || all_contexts[index] === undefined) {
+          continue;
+        }
+        var inchikey = all_contexts[index].DEFAULT_DATA["inchikey"] ;
+        id = `#container_RCC_ADDED-1 tbody:nth(0) tr:nth(${index}) td:nth(1)` ;
+        element = $(id) ;
+        if (element.length) {
+          console.log(`auto_set_inchikey to ${inchikey} ok.`)
+          self.hot_RCC_ADDED.setDataAtCell(index, 1, inchikey) ;
+          element.innerHTML = inchikey ;
+          element.change() ;
+          console.log(element) ;
+          console.log(`Inchikey set!`) ;
+        } else {
+          console.log(element)
+          console.log("Failed!")
+        }
+      }
+      console.log(self.hot_RCC_ADDED)
+      self.hot_RCC_ADDED.render() ;
+    }
+    $("#btnSwitch-gotoStep2-{{ TAB_INDEX_PLACEHOLDER }}").click() ;
+    if (self.DEFAULT_DATA["method"]) {
+      setTimeout(() => self.auto_set_method(self), 1000) ;
+    }
+  },
+
+  auto_set_method: function() {
+    console.log("auto_set_method...") ;
+    var self = this ;
+    var id = "#add1spectrum-chromatoLC-method-{{ TAB_INDEX_PLACEHOLDER }}" ;
+    var element = $(id) ;
+    element.length && element.val(self.DEFAULT_DATA["method"]).change() ;
+    $("#btnSwitch-gotoStep3-lc-{{ TAB_INDEX_PLACEHOLDER }}").click() ;
+    setTimeout(() => {
+      (() => {
+        $("#btnSwitch-gotoStep4-ms-{{ TAB_INDEX_PLACEHOLDER }}").click() ;
+        console.log(`auto_set_method to ${self.DEFAULT_DATA["method"]} ok.`)
+        if (self.DEFAULT_DATA["scan_type"]) {
+
+          // The scan type needs to be skipped, as it is already defined
+          // at build-time
+          // The code is kept for future modifications of this behavior
+          setTimeout(() => self.auto_set_scan_type(self, skip = true), 1000) ;
+        }
+      })(self)
+    }, 1000) ;
+  },
+
+  auto_set_scan_type: function(skip = false) {
+    var self = this ;
+    if (!skip) {
+      console.log("auto_set_scan_type...") ;
+      var id = "#add1spectrum-peaksMS-msLevel-{{ TAB_INDEX_PLACEHOLDER }}" ;
+      var element = $(id) ;
+      if (element.length) {
+        element.val(self.DEFAULT_DATA["scan_type"]).change() ;
+        console.log(`auto_set_scan_type to ${self.DEFAULT_DATA["scan_type"]} ok.`)
+      } else {
+        console.log("Failed!")
+      }
+    }
+    if (self.DEFAULT_DATA["polarity"]) {
+      self.auto_set_polarity(self) ;
+    }
+  },
+
+  auto_set_polarity: function() {
+    console.log("auto_set_polarity...") ;
+    var self = this ;
+    var id = "#add1spectrum-peaksMS-polarity-{{ TAB_INDEX_PLACEHOLDER }}" ;
+    var element = $(id) ;
+    if (element.length) {
+      element.val(self.DEFAULT_DATA["polarity"]).change() ;
+      console.log(`auto_set_polarity to ${self.DEFAULT_DATA["polarity"]} ok.`)
+    } else {
+      console.log("Failed!")
+    }
+    if (self.DEFAULT_DATA["resolution"]) {
+      self.auto_set_resolution(self) ;
+    }
+  },
+
+  auto_set_resolution: function() {
+    console.log("auto_set_resolution...") ;
+    var self = this ;
+    var id = "#add1spectrum-peaksMS-resolution-{{ TAB_INDEX_PLACEHOLDER }}" ;
+    var element = $(id) ;
+    if (element.length) {
+      element.val(self.DEFAULT_DATA["resolution"]).change() ;
+      console.log(`auto_set_resolution to ${self.DEFAULT_DATA["resolution"]} ok.`)
+    } else {
+      console.log("Failed!")
+    }
+    if (self.DEFAULT_DATA["next"] || true) {
+      setTimeout(() => self.finish_initialized(self), 1000) ;
+    }
+  },
+
+  finish_initialized: function() {
+    var self = this ;
+    if (ctx() === self) {
+      self.initialized = true ;
+    }
+  },
+
+  //USED IN HTML
+  updateLCMSspectraViewer: function() {
+    var self = this ;
+    var tab_no ;
+    console.log(`Updating spectral view for tab {{ TAB_INDEX_PLACEHOLDER }}`) ;
+    // reset current viewer
+    $("#containter-lcms-spectrum-preview-{{ TAB_INDEX_PLACEHOLDER }}").empty();
+    // reset data.
+
+    if (self.is_mix()) {
+      tab_no = 1 ;
+    } else {
+      tab_no = {{ TAB_INDEX_PLACEHOLDER }} ;
+    }
+    var range_from = $(`#add1spectrum-peaksMS-rangeFrom-${tab_no}`) ;
+    if ((spectrumMinPPM = Number(range_from.val())) == "") {
+      spectrumMinPPM = 10000;
+    }
+    var range_to = $(`#add1spectrum-peaksMS-rangeTo-${tab_no}`) ;
+    if ((spectrumMaxPPM = Number(range_to.val())) == "") {
+      spectrumMaxPPM = 0;
+    }
+    maxGraph = 0;
+    var localData = [];
+    var localDataAnnot = [];
+    // gather new data
+    // TODO switch tab in function of technic
+    $.each(self.hot_MS_Peaks.getData(), function() {
+      if(this[0] != undefined && this[0] != "") {
+        var x = (Number(this[0]));
+        var y = Number(this[2]);
+        var a = this[6];
+        localData.push([(x-0.000001),-150]);
+        localData.push([(x+0.000001),-150]);
+        localData.push([x,y]);
+        localDataAnnot[x] = a;
+        if (x < spectrumMinPPM) {
+          spectrumMinPPM = x;
+        }
+        if (x > spectrumMaxPPM) {
+          spectrumMaxPPM = x;
+        }
+        if (y > maxGraph) {
+          maxGraph = y;
+        }
+      }
+    });
+    
+    // build new one
+    spectrumMinPPM = spectrumMinPPM - (0.1 * spectrumMinPPM);
+    spectrumMaxPPM = spectrumMaxPPM + (0.1 * spectrumMaxPPM);
+    maxGraph = maxGraph + (0.1 * maxGraph);
+    localData.sort();
+    console.log(localData)
+    // build graph
+    $("#containter-lcms-spectrum-preview-{{ TAB_INDEX_PLACEHOLDER }}").highcharts({
+      chart: {
+        zoomType: "x",
+        spacingRight: 10,
+        spacingLeft: 10,
+        type: "scatter"
+      },
+      title: {
+        text: "Spectrum Preview",
+        useHTML: true
+      },
+      subtitle: {
+        text: (
+          document.ontouchstart === undefined
+          ? "Select area"
+          : "Pinch the chart to zoom in"
+        )
+      },
+      xAxis: {
+        type: "number",
+        title: {text: "m/z"},
+        min: spectrumMinPPM,
+        max: spectrumMaxPPM,
+        labels: {
+          formatter: function() {
+            return (Math.abs(this.value) + "");
+          }
+        }
+      },
+      yAxis: {
+        title: {text: "Relative Intensity (%)"},
+        min: 0,
+        max: maxGraph
+      },
+      tooltip: {
+        crosshairs: true,
+        formatter: function() {
+          var compo = "";
+          return (
+            "<b>" + this.series.name
+            + "</b><br/>m/z:" + Math.abs(this.x) + ""
+            + ";<br/>Relative Intensity: " + this.y
+            + "%;<br/>Annotation: " + localDataAnnot[ this.x]
+            + ""
+          );
+        }
+      },
+      legend: {enabled: false},
+      plotOptions: {scatter: {}},
+      series: [{
+        name: "preview",
+        showInLegend: true,
+        color: "#f00",
+        lineColor: "#f00",
+        pointInterval: 10,
+        pointStart: 100,
+        lineWidth : 2,
+        marker: {
+          enabled: true,
+          radius: 2,
+          lineColor: "#f00"
+        },
+        data: localData,
+        zIndex: 10
+      }]
+    });
+  },
+
+  //USED HERE
+  fulfillLCdata: function(jsonFileName) {
+    var self = this ;
+    var url = `{{ PF_URL_PLACEHOLDER }}/webapp/resources/json/lc-methods/${jsonFileName}.json` ;
+    $.getJSON(url, function(json) {
+      // $.POST
+      console.log(json);
+      // lc chromato
+      if (json.lc_chromatography != null) {
+        [
+          ["colConstructor", "column_constructor"],
+          ["colConstructorOther", "column_constructor_other"],
+          ["colName", "column_name"],
+          ["colLength", "column_length"],
+          ["colDiameter", "column_diameter"],
+          ["colParticuleSize", "particule_size"],
+          ["colTemperature", "column_temperature"],
+          ["separationFlowRate", "separation_flow_rate"],
+          ["separationSolvA", "separation_solvent_a"],
+          ["separationSolvApH", "ph_solvent_a"],
+          ["separationSolvB", "separation_solvent_b"],
+          ["separationSolvBpH", "ph_solvent_b"]
+        ].forEach((arr) => {
+          var el ;
+          console.log(arr)
+          el = $(`#add1spectrum-chromatoLC-${arr[0]}-{{ TAB_INDEX_PLACEHOLDER }}`)
+          el.val(json.lc_chromatography[arr[1]]) ;
+          el.change()
+        })
+        try {
+          $("#add1spectrum-chromatoLC-LCMode-{{ TAB_INDEX_PLACEHOLDER }}").val(json.lc_chromatography.LC_mode);
+          $("#add1spectrum-chromatoLC-LCMode-{{ TAB_INDEX_PLACEHOLDER }}").change();
+        } catch (e) {}
+        var handsontableSeparationFlowRateData = [] ;
+        if (json.lc_chromatography.separation_flow_gradient != null) {
+          $.each(json.lc_chromatography.separation_flow_gradient, function() {
+            var e = [
+              "" + this.time,
+              "" + this.solvA,
+              "" + this.solvB
+            ];
+            handsontableSeparationFlowRateData.push(e);
+          });
+        } else {
+          handsontableSeparationFlowRateData = null;
+        }
+        self.handsontableSeparationFlowRate(handsontableSeparationFlowRateData);
+      }
+      // ms_analyzer
+      if (json.ms_analyzer != null) {
+        $("#add1spectrum-analyzer-ms-instrument-{{ TAB_INDEX_PLACEHOLDER }}").val(json.ms_analyzer.instrument);
+        $("#add1spectrum-analyzer-ms-instrument-{{ TAB_INDEX_PLACEHOLDER }}").change();
+        $("#add1spectrum-analyzer-ms-model-{{ TAB_INDEX_PLACEHOLDER }}").val(json.ms_analyzer.model);
+        $("#add1spectrum-analyzer-ms-model-{{ TAB_INDEX_PLACEHOLDER }}").change();
+        $("#add1spectrum-analyzer-ms-resolutionFWHM-{{ TAB_INDEX_PLACEHOLDER }}").val(json.ms_analyzer.resolution_FWHM);
+        $("#add1spectrum-analyzer-ms-resolutionFWHM-{{ TAB_INDEX_PLACEHOLDER }}").change();
+        $("#add1spectrum-analyzer-ms-ionAnalyzerType-{{ TAB_INDEX_PLACEHOLDER }}").val(json.ms_analyzer.ion_analyzer_type);
+        $("#add1spectrum-analyzer-ms-ionAnalyzerType-{{ TAB_INDEX_PLACEHOLDER }}").change();
+      }
+      if (json.molecule_ionization != null) {
+        ["pos", "neg"].forEach((mode) => {
+          if (json.molecule_ionization[`mode_${mode}`] != null) {
+            [
+              ["ionizationMethod", "ionisation_method"],
+              ["sprayGazFlow", "spray_gaz_flow"],
+              ["vaporizerGazFlow", "vaporizer_gaz_flow"],
+              ["vaporizerTemperature", "vaporizer_temperature"],
+              ["sourceGazFlow", "source_gaz_flow"],
+              ["ionTransferTubeTemperatureOrTransferCapillaryTemperature", "transfer_tube_or_capillary_temperature"],
+              ["highVoltageOrCoronaVoltage", "voltage"],
+            ].forEach((tuple) => {
+              var el ;
+              var id = tuple[0] ;
+              var key = tuple[1] ;
+              el = $(`#add1spectrum-analyzserMS-${id}-${mode}-{{ TAB_INDEX_PLACEHOLDER }}`) ;
+              console.log(el)
+              el.val(json.molecule_ionization[`mode_${mode}`][key]);
+              el.change() ;
+            })
+          }
+        })
+      }
+
+      if (json.molecule_beamOrTrap != null) {
+        if (json.molecule_beamOrTrap.ion_beam != null) {
+          $("#add1spectrum-ionTrapBeam-type-{{ TAB_INDEX_PLACEHOLDER }}").val("beam").change();
+          $("#add1spectrum-ionTrapBeam-ionGas-{{ TAB_INDEX_PLACEHOLDER }}").val(json.molecule_beamOrTrap.ion_beam.ion_gas).change();
+          $("#add1spectrum-ionTrapBeam-ionGasPressureValue-{{ TAB_INDEX_PLACEHOLDER }}").val(json.molecule_beamOrTrap.ion_beam.ion_pressure_value).change();
+          $("#add1spectrum-ionTrapBeam-ionGasPressureUnit-{{ TAB_INDEX_PLACEHOLDER }}").val(json.molecule_beamOrTrap.ion_beam.ion_pressure_unit).change();
+        }
+        if (json.molecule_beamOrTrap.ion_trap != null) {
+          $("#add1spectrum-ionTrapBeam-type-{{ TAB_INDEX_PLACEHOLDER }}").val("trap").change();
+          $("#add1spectrum-ionTrapBeam-ionGas-{{ TAB_INDEX_PLACEHOLDER }}").val(json.molecule_beamOrTrap.ion_trap.ion_gas).change();
+          $("#add1spectrum-ionTrapBeam-ionGasPressureValue-{{ TAB_INDEX_PLACEHOLDER }}").val(json.molecule_beamOrTrap.ion_trap.ion_pressure_value).change();
+          $("#add1spectrum-ionTrapBeam-ionGasPressureUnit-{{ TAB_INDEX_PLACEHOLDER }}").val(json.molecule_beamOrTrap.ion_trap.ion_pressure_unit).change();
+          $("#add1spectrum-ionTrapBeam-ionNumber-{{ TAB_INDEX_PLACEHOLDER }}").val(json.molecule_beamOrTrap.ion_trap.ion_number).change();
+          $("#add1spectrum-ionTrapBeam-ionFrequencyShift-{{ TAB_INDEX_PLACEHOLDER }}").val(json.molecule_beamOrTrap.ion_trap.ion_freq_shift).change();
+        }
+      }
+      // other
+      if (json.other != null) {
+        $("#add1spectrum-other-author-{{ TAB_INDEX_PLACEHOLDER }}").val(json.other.data_authors);
+        $("#add1spectrum-other-author-{{ TAB_INDEX_PLACEHOLDER }}").change();
+        $("#add1spectrum-other-validator-{{ TAB_INDEX_PLACEHOLDER }}").val(json.other.data_validator);
+        $("#add1spectrum-other-validator-{{ TAB_INDEX_PLACEHOLDER }}").change();
+        $("#add1spectrum-other-date-{{ TAB_INDEX_PLACEHOLDER }}").val(json.other.acquisition_date);
+        $("#add1spectrum-other-date-{{ TAB_INDEX_PLACEHOLDER }}").change();
+        $("#add1spectrum-other-owner-{{ TAB_INDEX_PLACEHOLDER }}").val(json.other.data_ownership);
+        $("#add1spectrum-other-owner-{{ TAB_INDEX_PLACEHOLDER }}").change();
+      }
+    }).error(function(event, jqxhr, exception) {
+      if (event.status == 404) {
+        $("#alertBoxSelectTemplate-{{ TAB_INDEX_PLACEHOLDER }}").html(`
+          <div class="alert alert-danger alert-dismissible" role="alert">
+            <button type="button" class="close" data-dismiss="alert">
+              <span aria-hidden="true">&times;</span>
+              <span class="sr-only"><spring:message code="alert.close" text="Close" /></span>
+            </button>
+            <strong>
+              <spring:message code="alert.strong.error" text="Error!" />
+            </strong> unable to load pre-filled data!
+          </div>
+        `);
+      }
+    });
+  },
+
+  //USED HERE
+  resetFromColors: function() {
+
+    var self = this ;
+    $.each($(self.prefix+".add1spectrum"), function(id, elem) {
+      element = $(elem)
+      self.rm_success(element) ;
+      self.rm_warning(element) ;
+      self.rm_error(element) ;
+      if ($(elem).hasClass("is-mandatory") &&  ($(elem).val() == "" || $(elem).val() == null)) {
+        self.set_error($(elem)) ;
+      }
+      if ($(elem).hasClass("is-optional") &&  ($(elem).val() == "" || $(elem).val() == null)) {
+        self.set_warning($(elem)) ;
+      }
+      if ($(elem).val() != "" && $(elem).val() != null) {
+        self.set_success($(elem)) ;
+      }
+    });
+    $.each($(self.prefix+"button.switchStep"), function(id, elem) {
+      if (!$(this).hasClass("btn-disabled")) {
+        $(this).addClass("btn-disabled");
+      }
+      if ($(this).hasClass("btn-primary")) {
+        $(this).removeClass("btn-primary");
+      }
+      $(this).prop("disabled", true);
+    });
+
+    // peak list: no data to check
+    $("#btnSwitch-gotoStep5-ms-{{ TAB_INDEX_PLACEHOLDER }}").removeClass("btn-disabled");
+    $("#btnSwitch-gotoStep5-ms-{{ TAB_INDEX_PLACEHOLDER }}").addClass("btn-primary");
+    $("#btnSwitch-gotoStep5-ms-{{ TAB_INDEX_PLACEHOLDER }}").prop("disabled", false);
+
+    $("#add1spectrum-other-author-{{ TAB_INDEX_PLACEHOLDER }}").prop("disabled", false);
+    $("#add1spectrum-other-validator-{{ TAB_INDEX_PLACEHOLDER }}").prop("disabled", false);
+    $("#add1spectrum-other-date-{{ TAB_INDEX_PLACEHOLDER }}").prop("disabled", false);
+    $("#add1spectrum-other-owner-{{ TAB_INDEX_PLACEHOLDER }}").prop("disabled", false);
+    $("#add1spectrum-other-fileName-{{ TAB_INDEX_PLACEHOLDER }}").prop("disabled", false);
+    $("#add1spectrum-other-fileSize-{{ TAB_INDEX_PLACEHOLDER }}").prop("disabled", false);
+  },
+
+  //USED IN HTML
+  switchToStep: function(step) {
+
+    var self = this ;
+    switch(step) {
+      case 2:
+        // hide after step 2 / alt step 2
+        $("#add1spectrum-chromatographyData-LC-{{ TAB_INDEX_PLACEHOLDER }}").hide();
+        $("#add1spectrum-chromatographyData-GC-{{ TAB_INDEX_PLACEHOLDER }}").hide();
+        $("#add1spectrum-analyserData-MS-{{ TAB_INDEX_PLACEHOLDER }}").hide();
+        $("#add1spectrum-peaksData-MS-{{ TAB_INDEX_PLACEHOLDER }}").hide();
+        $("#add1spectrum-otherData-{{ TAB_INDEX_PLACEHOLDER }}").hide();
+        if ($("#step1sign-{{ TAB_INDEX_PLACEHOLDER }}").hasClass("fa-question-circle")) {
+          $("#step1sign-{{ TAB_INDEX_PLACEHOLDER }}").removeClass("fa-question-circle").addClass("fa-check-circle");
+        }
+        if (self.is_ms()) {
+          $("#add1spectrum-chromatoLC-method-{{ TAB_INDEX_PLACEHOLDER }}").empty();
+          $("#add1spectrum-chromatoLC-method-{{ TAB_INDEX_PLACEHOLDER }}").append(
+            '<option value="" selected="selected" disabled="disabled">choose in list&hellip;</option>'
+          );
+          $.getJSON("{{ PF_URL_PLACEHOLDER }}/webapp/resources/json/list-lc-methods.json", function(data) {
+            // load data from json
+            $.each(data.methods,function() {
+              if (this.name !== undefined) {
+                if (this.value !== undefined) {
+                  $("#add1spectrum-chromatoLC-method-{{ TAB_INDEX_PLACEHOLDER }}").append(
+                    `<option value="${this.value}">${this.name}</option>`
+                  );
+                } else {
+                  $("#add1spectrum-chromatoLC-method-{{ TAB_INDEX_PLACEHOLDER }}").append(
+                    `<option disabled>${this.name}</option>`
+                  );
+                }
+              }
+            });
+          });
+        } else if (self.is_ms2()) {
+          $("#add1spectrum-chromatoLC-method-{{ TAB_INDEX_PLACEHOLDER }}").empty();
+          $("#add1spectrum-chromatoLC-method-{{ TAB_INDEX_PLACEHOLDER }}").append(
+            '<option value="" selected="selected" disabled="disabled">choose in list&hellip;</option>'
+          );
+          $.getJSON(
+            "{{ PF_URL_PLACEHOLDER }}/webapp/resources/json/list-lc-msms-methods.json",
+            function(data) {
+              // load data from json
+              $.each(data.methods, function() {
+                if (this.name !== undefined) {
+                  if (this.value !== undefined) {
+                    $("#add1spectrum-chromatoLC-method-{{ TAB_INDEX_PLACEHOLDER }}").append(
+                      `<option value="${this.value}">${this.name}</option>`
+                    );
+                  } else {
+                    $("#add1spectrum-chromatoLC-method-{{ TAB_INDEX_PLACEHOLDER }}").append(
+                      `<option disabled>${this.name}</option>`
+                    );
+                  }
+                }
+              });
+            }
+          );
+        }
+        // check panel to show
+        if (self.isLC) {
+          $("#add1spectrum-chromatographyData-LC-{{ TAB_INDEX_PLACEHOLDER }}").show();
+          $("#linkActivateStep2-lc-{{ TAB_INDEX_PLACEHOLDER }}").trigger("click");
+          var sign = $("#step2-lc-sign-{{ TAB_INDEX_PLACEHOLDER }}") ;
+          self.rm_class(sign, "fa-check-circle") && self.set_class(sign, "fa-question-circle") ;
+          if (!self.isSeparationFlowRateInit) {
+            self.handsontableSeparationFlowRate(null);
+            self.isSeparationFlowRateInit = true;
+          }
+        } else if (self.isGC) {
+          $("#add1spectrum-chromatographyData-GC-{{ TAB_INDEX_PLACEHOLDER }}").show();
+          $("#linkActivateStep2-gc-{{ TAB_INDEX_PLACEHOLDER }}").trigger("click");
+          var sign = $("#step2-gc-sign-{{ TAB_INDEX_PLACEHOLDER }}") ;
+          sign.removeClass("fa-check-circle").addClass("fa-question-circle");
+          if ($("#step2-gc-sign-{{ TAB_INDEX_PLACEHOLDER }}").hasClass("fa-check-circle")) {
+          }
+        } else if (self.isIC) {
+          $("#add1spectrum-chromatographyData-IC-{{ TAB_INDEX_PLACEHOLDER }}").show();
+          $("#linkActivateStep2-ic-{{ TAB_INDEX_PLACEHOLDER }}").trigger("click");
+          if ($("#step2-ic-sign-{{ TAB_INDEX_PLACEHOLDER }}").hasClass("fa-check-circle")) {
+            $("#step2-ic-sign-{{ TAB_INDEX_PLACEHOLDER }}").removeClass("fa-check-circle").addClass("fa-question-circle");
+          }
+        }
+        break;
+      case 3:
+        // hide after step 3 / alt step 3
+        $("#add1spectrum-analyserData-MS-{{ TAB_INDEX_PLACEHOLDER }}").hide();
+        $("#add1spectrum-peaksData-MS-{{ TAB_INDEX_PLACEHOLDER }}").hide();
+        $("#add1spectrum-otherData-{{ TAB_INDEX_PLACEHOLDER }}").hide();
+        // step 2 ok 
+        if ($("#step2-lc-sign-{{ TAB_INDEX_PLACEHOLDER }}").hasClass("fa-question-circle")) {
+          $("#step2-lc-sign-{{ TAB_INDEX_PLACEHOLDER }}").removeClass("fa-question-circle").addClass("fa-check-circle");
+        }
+        if ($("#step2-gc-sign-{{ TAB_INDEX_PLACEHOLDER }}").hasClass("fa-question-circle")) {
+          $("#step2-gc-sign-{{ TAB_INDEX_PLACEHOLDER }}").removeClass("fa-question-circle").addClass("fa-check-circle");
+        }
+        // check panel to show
+        if (self.is_ms() || self.is_ms2()) {
+          $("#add1spectrum-analyserData-MS-{{ TAB_INDEX_PLACEHOLDER }}").show();
+          $("#linkActivateStep3-ms-{{ TAB_INDEX_PLACEHOLDER }}").trigger('click');
+          // debug display
+          [
+            "add1spectrum-analyzserMS-sprayGazFlow-pos",
+            "add1spectrum-analyzserMS-sprayGazFlow-neg",
+            "add1spectrum-analyzserMS-vaporizerGazFlow-pos",
+            "add1spectrum-analyzserMS-vaporizerGazFlow-neg",
+            "add1spectrum-analyzserMS-vaporizerTemperature-pos",
+            "add1spectrum-analyzserMS-vaporizerTemperature-neg",
+            "add1spectrum-analyzserMS-sourceGazFlow-pos",
+            "add1spectrum-analyzserMS-sourceGazFlow-neg",
+            "add1spectrum-analyzserMS-ionTransferTubeTemperatureOrTransferCapillaryTemperature-pos",
+            "add1spectrum-analyzserMS-ionTransferTubeTemperatureOrTransferCapillaryTemperature-neg",
+            "add1spectrum-analyzserMS-highVoltageOrCoronaVoltage-pos",
+            "add1spectrum-analyzserMS-highVoltageOrCoronaVoltage-neg"
+          ].forEach((id) => {
+            var element = $(`#id-{{ TAB_INDEX_PLACEHOLDER }}`)
+            element.height(element.parent().children("span").height())
+          })
+          if ($("#step3-ms-sign-{{ TAB_INDEX_PLACEHOLDER }}").hasClass("fa-check-circle")) {
+            $("#step3-ms-sign-{{ TAB_INDEX_PLACEHOLDER }}").removeClass("fa-check-circle").addClass("fa-question-circle");
+          }
+          // MSMS only
+          $(self.prefix+".enable-if-ms").attr("disabled", !self.is_ms());
+          $(self.prefix+".enable-if-msms").attr("disabled", !self.is_ms2());
+        }
+        // avoid display bug
+        $("#add1spectrum-analyzer-ms-instrument-{{ TAB_INDEX_PLACEHOLDER }}").change();
+        break;
+      case 4:
+        // hide after step 4 / alt step 4
+        $("#add1spectrum-peaksData-MS-{{ TAB_INDEX_PLACEHOLDER }}").hide();
+        $("#add1spectrum-otherData-{{ TAB_INDEX_PLACEHOLDER }}").hide();
+        // step 3 ok 
+        if ($("#step3-ms-sign-{{ TAB_INDEX_PLACEHOLDER }}").hasClass("fa-question-circle")) {
+          $("#step3-ms-sign-{{ TAB_INDEX_PLACEHOLDER }}").removeClass("fa-question-circle").addClass("fa-check-circle");
+        }
+        if (self.is_ms() || self.is_ms2()) {
+          $("#add1spectrum-peaksData-MS-{{ TAB_INDEX_PLACEHOLDER }}").show();
+          $("#linkActivateStep4-ms-{{ TAB_INDEX_PLACEHOLDER }}").trigger("click");
+          if ($("#step4-ms-sign-{{ TAB_INDEX_PLACEHOLDER }}").hasClass("fa-check-circle")) {
+            $("#step4-ms-sign-{{ TAB_INDEX_PLACEHOLDER }}").removeClass("fa-check-circle").addClass("fa-question-circle");
+          }
+          // LC MS
+          if (!self.isMSpeaksInit) {
+            console.log(`self.is_mix(): ${self.is_mix()}`)
+            if (self.is_mix()) {
+              all_contexts.forEach((context, index) => {
+                if (context === null) {
+                  return;
+                }
+                context.handsontableMSpeaks(null) ;
+                context.updateLCMSspectraViewer() ;
+                context.isMSpeaksInit = true;
+                $(context.prefix+".add1spectrum-peaksMSForm-peaklist-reset").val("").change();
+              })
+            } else {
+              self.handsontableMSpeaks(null);
+              self.isMSpeaksInit = true;
+              $(self.prefix+".add1spectrum-peaksMSForm-peaklist-reset").val("").change();
+            }
+          }
+        }
+        // show ms tab
+        setTimeout(() => $("#container_MS_Peaks-{{ TAB_INDEX_PLACEHOLDER }}").trigger("click"), 250);
+        $("#add1spectrum-peaksMS-msLevel-{{ TAB_INDEX_PLACEHOLDER }}").change();
+        break;
+      case 5:
+        // hide after step 5 / alt step 5
+        $("#add1spectrum-otherData-{{ TAB_INDEX_PLACEHOLDER }}").hide();
+        // step 4 ok 
+        if ($("#step4-ms-sign-{{ TAB_INDEX_PLACEHOLDER }}").hasClass("fa-question-circle")) {
+          $("#step4-ms-sign-{{ TAB_INDEX_PLACEHOLDER }}").removeClass("fa-question-circle").addClass("fa-check-circle");
+        }
+        if ($("#step5sign-{{ TAB_INDEX_PLACEHOLDER }}").hasClass("fa-check-circle")) {
+          $("#step5sign-{{ TAB_INDEX_PLACEHOLDER }}").removeClass("fa-check-circle").addClass("fa-question-circle");
+        }
+        $("#add1spectrum-otherData-{{ TAB_INDEX_PLACEHOLDER }}").show();
+        $("#linkActivateStep5-{{ TAB_INDEX_PLACEHOLDER }}").trigger("click");
+        // reset step 6 button
+        self.checkIfEnableSubmit();
+        $("#import1SpectrumLoadingBare-{{ TAB_INDEX_PLACEHOLDER }}").hide();
+        $("#import1SpectrumResults-{{ TAB_INDEX_PLACEHOLDER }}").hide();
+        break;
+      case 6:
+        self.postOneSpectrumFrom();
+        self.cptPeakListTab++;
+        break;
+      case 7:
+      self.dumpOneSpectrumFrom();
+      break;
+    }
+  },
+
+  //USED HERE
+  resetElemColor: function(idElem) {
+
+    var self = this ;
+    if ($(`#${idElem}`).parent().hasClass("has-success")) {
+      $(`#${idElem}`).parent().removeClass("has-success") ;
+    }
+    if ($(`#${idElem}`).parent().hasClass("has-warning")) {
+      $(`#${idElem}`).parent().removeClass("has-warning") ;
+    }
+    if ($(`#${idElem}`).parent().hasClass("has-error")) {
+      $(`#${idElem}`).parent().removeClass("has-error") ;
+    }
+  },
+
+  //USED HERE
+  disableElem: function(idElem) {
+
+    var self = this ;
+    $(`#${idElem}`).prop("disabled", true) ;
+    $(`#${idElem}`).val("") ;
+    if ($(`#${idElem}`).hasClass("is-mandatory")) {
+      $(`#${idElem}`).removeClass("is-mandatory") ;
+    }
+  },
+
+  //USED HERE
+  enableElem: function(idElem) {
+
+    var self = this ;
+    $(`#${idElem}`).prop("disabled", false) ;
+    $(`#${idElem}`).parent().addClass("has-error") ;
+    if (!$(`#${idElem}`).hasClass("is-mandatory")) {
+      $(`#${idElem}`).addClass("is-mandatory") ;
+    }
+  },
+
+  //USED HERE
+  checkIfEnableSubmit: function() {
+
+    var self = this ;
+    var isBtnStep6OK = true;
+    $.each($(self.prefix+".add1spectrum-otherForm"), (id, elem) => {
+      if (self.is_error($(elem)) && $(elem).is(":visible")) {
+        isBtnStep6OK = false;
+      }
+    });
+    if (isBtnStep6OK) {
+      self.rm_class($("#btnSwitch-gotoStep6-{{ TAB_INDEX_PLACEHOLDER }}"), "btn-disabled") ;
+      self.set_class($("#btnSwitch-gotoStep6-{{ TAB_INDEX_PLACEHOLDER }}"), "btn-primary") ;
+      $("#btnSwitch-gotoStep6-{{ TAB_INDEX_PLACEHOLDER }}").prop("disabled", false);
+      self.rm_class($("#btnSwitch-gotoStep7-{{ TAB_INDEX_PLACEHOLDER }}"), "btn-disabled") ;
+      self.set_class($("#btnSwitch-gotoStep7-{{ TAB_INDEX_PLACEHOLDER }}"), "btn-primary") ;
+      $("#btnSwitch-gotoStep7-{{ TAB_INDEX_PLACEHOLDER }}").prop("disabled", false);
+    } else {
+      if (!$("#btnSwitch-gotoStep6-{{ TAB_INDEX_PLACEHOLDER }}").hasClass("btn-disabled")) {
+        $("#btnSwitch-gotoStep6-{{ TAB_INDEX_PLACEHOLDER }}").addClass("btn-disabled");
+      }
+      if ($("#btnSwitch-gotoStep6-{{ TAB_INDEX_PLACEHOLDER }}").hasClass("btn-primary")) {
+        $("#btnSwitch-gotoStep6-{{ TAB_INDEX_PLACEHOLDER }}").removeClass("btn-primary");
+      }
+      $("#btnSwitch-gotoStep6-{{ TAB_INDEX_PLACEHOLDER }}").prop("disabled", true);
+      if (!$("#btnSwitch-gotoStep7-{{ TAB_INDEX_PLACEHOLDER }}").hasClass("btn-disabled")) {
+        $("#btnSwitch-gotoStep7-{{ TAB_INDEX_PLACEHOLDER }}").addClass("btn-disabled");
+      }
+      if ($("#btnSwitch-gotoStep7-{{ TAB_INDEX_PLACEHOLDER }}").hasClass("btn-primary")) {
+        $("#btnSwitch-gotoStep7-{{ TAB_INDEX_PLACEHOLDER }}").removeClass("btn-primary");
+      }
+      $("#btnSwitch-gotoStep7-{{ TAB_INDEX_PLACEHOLDER }}").prop("disabled", true);
+    }
+  },
+
+  //USED IN HTML
+  addOneSpectrum: function(type) {
+
+    var self = this ;
+     // unlock
+    $(self.prefix+".add1spectrum-sampleForm").prop("disabled", false);
+    $(self.prefix+".add1spectrum-chromatoLCForm").prop("disabled", false);
+    $(self.prefix+".add1spectrum-analyzerMSForm").prop("disabled", false);
+    $(self.prefix+".add1spectrum-otherForm").prop("disabled", false);
+    $("#add1spectrum-chromatoLC-colConstructor-{{ TAB_INDEX_PLACEHOLDER }}").change();
+    // reset
+    self.isLC = false;
+    self.isGC = false;
+    self.isIC = false;
+    $("#alertBoxSubmitSpectrum-{{ TAB_INDEX_PLACEHOLDER }}").html("");
+    // hide in all steps
+    $(self.prefix+".opt-ms").hide();
+    $(self.prefix+".opt-msms").hide();
+    // hide step 2
+    $("#add1spectrum-chromatographyData-LC-{{ TAB_INDEX_PLACEHOLDER }}").hide();
+    $("#add1spectrum-chromatographyData-GC-{{ TAB_INDEX_PLACEHOLDER }}").hide();
+    // hide step 3
+    $("#add1spectrum-analyserData-MS-{{ TAB_INDEX_PLACEHOLDER }}").hide();
+    $(self.prefix+".add1spectrum-ionTrap").hide();
+    // hide step 4
+    $("#add1spectrum-peaksData-MS-{{ TAB_INDEX_PLACEHOLDER }}").hide();
+    // hide step 5
+    $("#add1spectrum-otherData-{{ TAB_INDEX_PLACEHOLDER }}").hide();
+    // reset field step 1
+    $("#add1spectrum-sample-type-{{ TAB_INDEX_PLACEHOLDER }}").val("");
+    $(self.prefix+".add1spectrum-sample-type-panel").hide();
+    $(self.prefix+".add1spectrum-sampleForm").val("");
+    $("#sample-bonus-display-{{ TAB_INDEX_PLACEHOLDER }}").html("");
+    // reset field step 2
+    $(self.prefix+".add1spectrum-chromatoLCForm").val("");
+    // reset field step 3
+    $(self.prefix+".add1spectrum-analyzerMSForm").val("");
+    // reset field step 4
+    // reset peak lists / all tabs
+    self.isSeparationFlowRateInit = false;
+    self.isMSpeaksInit = false;
+    $(self.prefix+".handsontable").html("");
+    // reset field step 5 => NO!
+    // set icon
+    $("#step0sign-{{ TAB_INDEX_PLACEHOLDER }}").removeClass("fa-question-circle").addClass("fa-check-circle");
+    if ($("#step1sign-{{ TAB_INDEX_PLACEHOLDER }}").hasClass("fa-check-circle")) {
+      $("#step1sign-{{ TAB_INDEX_PLACEHOLDER }}").removeClass("fa-check-circle").addClass("fa-question-circle");
+    }
+    // collapse step 0 / uncollaspe step 1
+    $("#linkActivateStep1-{{ TAB_INDEX_PLACEHOLDER }}").trigger("click");
+    // show step 1 content
+    $("#add1spectrum-sampleData-{{ TAB_INDEX_PLACEHOLDER }}").show();
+    switch(type) {
+    case 1:
+      // TODO GC-MS stuff
+      self.isGC = true;
+      break;
+    case 2:
+      // LC-MS stuff
+      self.isLC = true;
+      $(self.prefix+".opt-ms").show();
+      break;
+    case 5:
+      // LC-MSMS stuff
+      self.isLC = true;
+      $(self.prefix+".opt-ms").show();
+      $(self.prefix+".opt-msms").show();
+      break;
+    case 6:
+      // IC-MS stuff
+      self.isIC = true;
+      $(self.prefix+".opt-ms").show();
+      break;
+    case 7:
+      // IC-MSMS stuff
+      self.isIC = true;
+      $(self.prefix+".opt-ms").show();
+      $(self.prefix+".opt-msms").show();
+      break;
+    }
+    self.resetFromColors();
+    // reset json obj to submit form
+    self.jsonSpectrumType = null;
+    self.isJsonSpectrumTypeComplete = false;
+    self.jsonSample = null;
+    self.isJsonSampleComplete = false;
+    self.isJsonRCCaddedComplete = false;
+    self.jsonChromato = null;
+    self.isJsonChromatoComplete = false;
+    self.jsonAnalyzer = null;
+    self.isJsonAnalyzerComplete = false;
+    self.jsonPeaksList = [];
+    self.isJsonPeaksListComplete = false;
+    self.jsonOtherMetadata = null;
+    self.isJsonOtherMetadataComplete = false;
+    
+    self.cptPeakListTab = 0;
+    self.jsonAnalyzerAcquisition = [];
+    self.idMetadataMap = {}
+    self.listOfViewableSpectra = [];
+    
+    // spec MS
+    self.jsonMolIonization = null;
+    
+    // spec MSMS
+    self.jsonMolIonBeam = null;
+    
+    // try load cpd
+    if (self.inchikey !== null) {
+      self.loadJSCompound(self.inchikey);
+    }
+  },
+
+  //USED HERE
+  loadJSCompound: function(inchikey) {
+    var self = this ;
+    
+    $("#add1spectrum-sample-type-{{ TAB_INDEX_PLACEHOLDER }}").val("compound-ref");
+    $("#add1spectrum-sample-type-{{ TAB_INDEX_PLACEHOLDER }}").change();
+    $("#add1spectrum-sample-inchikey-{{ TAB_INDEX_PLACEHOLDER }}").val(inchikey);
+    $("#add1spectrum-sample-inchikey-{{ TAB_INDEX_PLACEHOLDER }}").change();
+    if (inchidata[inchikey] !== null) {
+      return (set_inchi_data(inchidata[inchikey]), {{ TAB_INDEX_PLACEHOLDER }}) ;
+    }
+    $.ajax({
+      type: "get",
+      url: "{{ PF_URL_PLACEHOLDER }}/webapp/get-cpd-data",
+      data: "inchikey="+inchikey,
+      dataType: "json",
+      success: function(data) {
+        if (data.success) {
+          set_inchi_data(data) ;
+        }
+      },
+      error : function(data) {
+      }
+    }).always(function() {
+    });
+  },
+
+  //USED HERE
+  handsontableSeparationFlowRate: function(data) {
+    var self = this ;
+
+    // reset
+    $("#container_LC_SFG-{{ TAB_INDEX_PLACEHOLDER }}").html("");
+    // init
+    var data_LC_SFG;
+    if (data==null) {
+      data_LC_SFG = [
+       [ "", "", "" ],
+       [ "", "", "" ],
+       [ "", "", "" ],
+       [ "", "", "" ],
+       [ "", "", "" ],
+       [ "", "", "" ],
+       [ "", "", "" ],
+       [ "", "", "" ],
+       [ "", "", "" ],
+     ];
+    } else {
+      data_LC_SFG = data;
+    }
+    
+    var container_LC_SFG = document.getElementById("container_LC_SFG-{{ TAB_INDEX_PLACEHOLDER }}");
+    self.hot_LC_SFG = new Handsontable(container_LC_SFG, {
+      data : data_LC_SFG,
+      minSpareRows : 1,
+      colHeaders : true,
+      colHeaders: ["time (min)", "solv. A (%)", "solv. B (%)"],
+      contextMenu : false
+    });
+    Handsontable.Dom.addEvent(document.body, "click", function(e) {
+      var element = e.target || e.srcElement;
+      if (element.nodeName == "BUTTON"&& element.name == "dump") {
+        var name = element.getAttribute("data-dump");
+        var instance = element.getAttribute("data-instance");
+        self.hot_LC_SFG = window[instance];
+        console.log("data of " + name, self.hot_LC_SFG.getData());
+      }
+    });
+    $("#container_LC_SFG table.htCore-{{ TAB_INDEX_PLACEHOLDER }}").css("width","100%");
+  },
+
+  //USED HERE
+  handsontableMSpeaks: function(data) {
+    console.log("handsontableMSpeaks")
+    console.log(data)
+    var self = this ;
+    var data_MS_Peaks ;
+    var container_MS_Peaks ;
+
+    if (data != null) {
+      data_MS_Peaks = data;
+    } else {
+      data_MS_Peaks = JSON.parse(JSON.stringify(self.DEFAULT_MS_PEAK_VALUES));
+    }
+    $("#container_MS_Peaks-{{ TAB_INDEX_PLACEHOLDER }}").html("");
+    container_MS_Peaks = document.getElementById(
+      "container_MS_Peaks-{{ TAB_INDEX_PLACEHOLDER }}"
+    );
+    var colHeaders = [
+      "m/z", "absolute intensity", "relative intensity (%)", "delta (ppm)",
+      "composition", "attribution", "Validated"
+    ]
+    var columns = [
+      {type: "numeric", format: "0.0000"},
+      {type: "numeric", format: "0.00"},
+      {type: "numeric", format: "0.00"},
+      {type: "numeric", format: "0.0000"},
+      {type: "text"},
+      {type: "text"},
+      {type: "checkbox"}
+    ] ;
+    if (self.is_ms2()) {
+      colHeaders.push("Parent ion") ;
+      columns.push({type: "checkbox"}) ;
+    }
+    self.hot_MS_Peaks = new Handsontable(container_MS_Peaks, {
+      data: data_MS_Peaks,
+      minSpareRows: 1,
+      colHeaders: true,
+      colHeaders: colHeaders,
+      contextMenu: false,
+      maxRows: data_MS_Peaks.length,
+      minRows: data_MS_Peaks.length,
+      columns: columns,
+      afterChange: function(changes) {
+        if (self.lock.precursor_ion) {
+          return ;
+        }
+        self.lock.precursor_ion = true ;
+        try {
+          changes?.forEach(([row, prop, old, value]) => {
+            var data ;
+            var precursor_ion ;
+
+            var data = self.hot_MS_Peaks.getData() ;
+            if (prop !== 7 || value !== true || data === undefined) {
+              return ;
+            }
+            for (var i = 0; i < data.length ; i += 1) {
+              data[i][7] = false ;
+            }
+            data[row][7] = true ;
+            precursor_ion = $(`#add1spectrum-peaksMS-msPrecursorIon-{{ TAB_INDEX_PLACEHOLDER }}`) ;
+            console.log(`setting preco ion to ${data[row][0]}`) ;
+            precursor_ion.val(data[row][0]) ;
+            precursor_ion.change() ;
+            self.hot_MS_Peaks.render() ;
+          })
+        } finally {
+          self.lock.precursor_ion = false ;
+        }
+      }
+    });
+    Handsontable.Dom.addEvent(document.body, "click", (e) => {
+      var element ;
+      var name ;
+      var instance ;
+
+      element = e.target || e.srcElement ;
+      if (element.nodeName == "BUTTON" && element.name == "dump") {
+        name = element.getAttribute("data-dump") ;
+        instance = element.getAttribute("data-instance") ;
+        self.hot_MS_Peaks = window[instance] ;
+        console.log("data of " + name, self.hot_MS_Peaks.getData()) ;
+      }
+    }) ;
+
+    $("#container_MS_Peaks-{{ TAB_INDEX_PLACEHOLDER }} table.htCore").css(
+      "width","100%"
+    ) ;
+    if (self.is_ms2()) {
+      setTimeout(() => self.select_precursor_ion(), 200) ;
+    }
+  },
+
+  change_tab: function() {
+    var self = this ;
+    setTimeout(() => self.auto_select_ion_parent(), 1000) ;
+  },
+
+  auto_select_ion_parent: function() {
+    var self = this ;
+    if (!self.a_ion_parent_is_selected()) {
+      setTimeout(() => self.select_precursor_ion(), 1000) ;
+    }
+  },
+
+  select_precursor_ion: function() {
+    var self = this ;
+    var data ;
+    var precuirsor_ion ;
+
+    if (self.hot_MS_Peaks == null) {
+      return setTimeout(() => self.select_precursor_ion(), 200) ;
+    }
+    console.log("Selecting ion preco for tab {{ TAB_INDEX_PLACEHOLDER }}")
+    data = self.hot_MS_Peaks.getData() ;
+    for (var i = 0 ; i < data.length ; i += 1) {
+      if (data[i][5] === "[M+H]+" || data[i][5] === "[M+H]-" || data[i][2] == 100.0) {
+          precursor_ion = $("#add1spectrum-peaksMS-msPrecursorIon-{{ TAB_INDEX_PLACEHOLDER }}") ;
+          precursor_ion.val(data[i][0]) ;
+          precursor_ion.change() ;
+          return ;
+      }
+    }
+  },
+
+  sync_precursor_ion: function() {
+    var self = this ;
+    var data ;
+
+    if (self.lock.precursor_ion || self.hot_MS_Peaks == undefined) {
+      return ;
+    }
+    self.lock.precursor_ion = true ;
+    console.log("Syncing precursor ion")
+    var val = $("#add1spectrum-peaksMS-msPrecursorIon-{{ TAB_INDEX_PLACEHOLDER }}").val() ;
+    var data = self.hot_MS_Peaks.getData() ;
+    for (var i = 0; i < data.length ; i += 1) {
+      if (Math.abs(data[i][0] - val) < 0.0001) {
+        for (var j = 0; j < data.length ; j += 1) {
+          data[j][7] = false ;
+        }
+        data[i][7] = true ;
+        self.hot_MS_Peaks.render() ;
+        return ;
+      }
+    }
+    self.lock.precursor_ion = false ;
+  },
+
+  // USED HERE
+  handsontableRefChemCpdAdded: function(data) {
+    var self = this ;
+    // reset
+    $("#container_RCC_ADDED-{{ TAB_INDEX_PLACEHOLDER }}").html("");
+    $("#sample-bonus-display-{{ TAB_INDEX_PLACEHOLDER }}").html("");
+    // init
+    var data_RCC_ADDED, colHeaderData, container_RCC_ADDED;
+
+    colHeaderData = [
+      {data: "common name", type: "text"},
+      {data: "<b>InChIKey</b>", type: "text"},
+      {data: "composition", renderer: lightgrayRenderer},
+      {data: "<b>concentration (&micro;g/ml)</b>", type: "text"},
+      {data: "exact mass", renderer: lightgrayRenderer},
+      {data: "(M+H)+ or (M-H)-", renderer: lightgrayRenderer}
+    ] ;
+    
+    if (data == null) {
+      data_RCC_ADDED = [
+        [ "", "", "","", "", "" ],
+        [ "", "", "","", "", "" ],
+        [ "", "", "","", "", "" ],
+        [ "", "", "","", "", "" ],
+        [ "", "", "","", "", "" ],
+        [ "", "", "","", "", "" ],
+        [ "", "", "","", "", "" ],
+        [ "", "", "","", "", "" ],
+        [ "", "", "","", "", "" ],
+        [ "", "", "","", "", "" ],
+        [ "", "", "","", "", "" ],
+        [ "", "", "","", "", "" ],
+      ];
+    } else {
+      container_RCC_ADDED = data;
+    }
+
+    container_RCC_ADDED = document.getElementById("container_RCC_ADDED-{{ TAB_INDEX_PLACEHOLDER }}");
+    self.hot_RCC_ADDED = new Handsontable(container_RCC_ADDED, {
+      data: data_RCC_ADDED,
+      minSpareRows : 1,
+      colHeaders : true,
+      colHeaders: [
+        "common name",
+        "<b>InChIKey</b>",
+        "composition",
+        "<b>concentration (&micro;g/ml)</b>",
+        "exact mass",
+        "(M+H)+ or (M-H)-"
+      ],
+      contextMenu : false,
+      columns: colHeaderData
+    });
+    function bindDumpButton_RCC_ADDED() {
+      Handsontable.Dom.addEvent(document.body, "click", (e) => {
+        var element = e.target || e.srcElement;
+        if (element.nodeName == "BUTTON"&& element.name == "dump") {
+          var name = element.getAttribute("data-dump");
+          var instance = element.getAttribute("data-instance");
+          self.hot_RCC_ADDED = window[instance];
+          console.log("data of " + name, self.hot_RCC_ADDED.getData());
+        }
+      });
+    }
+    bindDumpButton_RCC_ADDED();
+    $("#container_RCC_ADDED-{{ TAB_INDEX_PLACEHOLDER }} table.htCore").css("width","100%");
+    // celect cell
+    self.hot_RCC_ADDED.selectCell(0, 0);
+    // add select listener
+    self.hot_RCC_ADDED.addHook("afterSelection", (r, c) => self.hookSelection(r, c));
+  },
+
+  //USED HERE
+  hookSelection: function(r, c) {
+    var self = this ;
+    if (c == 0 || c == 1 || c == 2) 
+      self.pickChemicalCompound4Mix(r);
+  },
+
+  //USED HERE
+  postOneSpectrumFrom: function() {
+    var self = this ;
+    $("#import1SpectrumLoadingBare-{{ TAB_INDEX_PLACEHOLDER }}").show();
+
+    // II - form data -> json object
+    self.loadFomDataIntoJsonObjects();
+    // II.A - check if json object complete
+    var alertMsg = self.getFormErrorMessage();
+    
+    if (alertMsg != "") {
+      $("#alertBoxSubmitSpectrum-{{ TAB_INDEX_PLACEHOLDER }}").html(alertMsg);
+      $("#import1SpectrumLoadingBare-{{ TAB_INDEX_PLACEHOLDER }}").hide();
+      return false;
+    }
+    // all OK: lock!
+    // lock sample
+    $(self.prefix+".add1spectrum-sampleForm").prop("disabled", true);
+    // lock chromato
+    $(self.prefix+".add1spectrum-chromatoLCForm").prop("disabled", true);
+    if (!$("#container_LC_SFG-{{ TAB_INDEX_PLACEHOLDER }}").is(":empty")) {
+      self.hot_LC_SFG.updateSettings({
+        cells: function(row, col, prop) {
+          var cellProperties = {};
+          cellProperties.readOnly = true;
+          return cellProperties;
+        }
+      });
+    }
+    if (!$("#container_MS_Peaks-{{ TAB_INDEX_PLACEHOLDER }}").is(":empty")) {
+      self.hot_MS_Peaks.updateSettings({
+        cells: function(row, col, prop) {
+          var cellProperties = {};
+          cellProperties.readOnly = true;
+          return cellProperties;
+        }
+      });
+    }
+    if (!$("#container_RCC_ADDED-{{ TAB_INDEX_PLACEHOLDER }}").is(":empty")) {
+      self.hot_RCC_ADDED.updateSettings({
+        cells: function(row, col, prop) {
+          var cellProperties = {};
+          cellProperties.readOnly = true;
+          return cellProperties;
+        }
+      });
+      self.hot_RCC_ADDED.removeHook(
+        "afterSelection",
+        (r, c) => self.hookSelection(r, c)
+      );
+    }
+
+    // lock analyzer
+    $(self.prefix+".add1spectrum-analyzerMSForm").prop("disabled", true);
+    // lock other metadata field
+    $(self.prefix+".add1spectrum-otherForm").prop("disabled", true);
+    // lock switch btn
+    $("#btnSwitch-gotoStep2-{{ TAB_INDEX_PLACEHOLDER }}").prop("disabled", true);
+    $("#btnSwitch-gotoStep3-lc-{{ TAB_INDEX_PLACEHOLDER }}").prop("disabled", true);
+    $("#btnSwitch-gotoStep4-ms-{{ TAB_INDEX_PLACEHOLDER }}").prop("disabled", true);
+    self.postSpectrumToServer() ;
+  },
+
+  postSpectrumToServer: function(jsonData, tab_index) {
+    var self = this ;
+    var base_peakdata ;
+    var new_peakdata ;
+    var is_ms2 = self.is_ms2() ;
+
+    if (self.is_mix()) {
+      if ({{ TAB_INDEX_PLACEHOLDER }} != 1) {
+        return ;
+      }
+      jsonData = self.gatherJsonObjects() ;
+      all_mix_data = Object.assign({}, jsonData) ;
+      all_mix_data["peaklists"] = [] ;
+      base_peakdata = Object.assign({}, jsonData["peaklists"][0]) ;
+      all_contexts.forEach((context, index) => {
+        if (context === null) {
+          return;
+        }
+        new_peakdata = Object.assign({}, base_peakdata) ;
+        context.loadFomDataIntoJsonObjects()
+        if (is_ms2) {
+          new_peakdata["precursor_ion"] = context.jsonPeaksList["precursor_ion"] ;
+        }
+        new_peakdata["peaklist"] = context.jsonPeaksList["peaklist"] ;
+        all_mix_data["peaklists"].push(new_peakdata)
+      })
+    }
+    // II.B - rebuild json full object (with all metadata or just id if already in base)
+    if (jsonData == null) {
+      jsonData = self.gatherJsonObjects();
+    }
+    // II.C - add id metadata (if exist)
+    var json_array = [] ;
+    if (!tab_index) {
+      tab_index = {{ TAB_INDEX_PLACEHOLDER }} ;
+    }
+    json_array[tab_index-1] = jsonData ;
+    
+    // III - post json object
+    // III.A - success
+    self.sent_json = jsonData ;
+    console.warn(
+      "This data has been validated without going through the internal server!"
+    )
+    if ($("#step5sign-{{ TAB_INDEX_PLACEHOLDER }}").hasClass("fa-question-circle")) {
+      $("#step5sign-{{ TAB_INDEX_PLACEHOLDER }}").removeClass("fa-question-circle").addClass("fa-check-circle");
+    }
+    if ($("#step5sign-{{ TAB_INDEX_PLACEHOLDER }}").hasClass("fa-spinner")) {
+      $("#step5sign-{{ TAB_INDEX_PLACEHOLDER }}").removeClass("fa-spinner fa-spin").addClass("fa-check-circle");
+    }
+    $("#import1SpectrumLoadingBare-{{ TAB_INDEX_PLACEHOLDER }}").hide();
+    $("#alertBoxSubmitSpectrum-{{ TAB_INDEX_PLACEHOLDER }}").html(`
+      <div class="alert alert-success alert-dismissible" role="alert">
+        <button type="button" class="close" data-dismiss="alert">
+          <span aria-hidden="true">&times;</span>
+          <span class="sr-only">
+            <spring:message code="alert.close" text="Close" />
+          </span>
+        </button>
+        <strong>
+          <spring:message code="alert.strong.info" text="Success!" />
+        </strong> Spectrum ready to be sent!
+      </div>
+    `);
+    return true;
+  },
+
+  //USED HERE
+  loadFomDataIntoJsonObjects: function() {
+    var self = this ;
+    // I - Spectrum type
+    self.isJsonSpectrumTypeComplete = false ;
+    if (self.isGC && self.is_ms()) {
+      self.jsonSpectrumType = "gc-ms" ;
+    } else if (self.isLC && self.is_ms()) {
+      self.jsonSpectrumType = "lc-ms" ;
+    } else if (self.isLC && self.is_ms2()) {
+      self.jsonSpectrumType = "lc-msms" ;
+    } else if (self.isGC && self.is_ms()) {
+      self.jsonSpectrumType = "ic-ms" ;
+    } else if (self.isLC && self.is_ms()) {
+      self.jsonSpectrumType = "ic-msms" ;
+    }
+    if (self.jsonSpectrumType != null && self.jsonSpectrumType != "") {
+      self.isJsonSpectrumTypeComplete = true;
+    }
+    
+    // II - Sample
+    self.isJsonSampleComplete = true;
+    self.isJsonRCCaddedComplete = true;
+    self.jsonSample = {};
+
+    switch($("#add1spectrum-sample-type-{{ TAB_INDEX_PLACEHOLDER }}").val()) {
+    // II.A - chemical lib. compound
+    case "compound-ref":
+      if ($("#add1spectrum-sample-inchikey-{{ TAB_INDEX_PLACEHOLDER }}").val() == "") {
+        return false;
+      }
+      self.jsonSample["sample_type"] = "reference-chemical-compound";
+      self.jsonSample["inchikey"] = $("#add1spectrum-sample-inchikey-{{ TAB_INDEX_PLACEHOLDER }}").val();
+      self.jsonSample["concentration"] = $("#add1spectrum-sample-concentration-{{ TAB_INDEX_PLACEHOLDER }}").val();
+      if (self.is_ms()) {
+        self.jsonSample["solvent"] = $("#add1spectrum-sample-lcmsSolvent-{{ TAB_INDEX_PLACEHOLDER }}").val();
+      }
+      self.isJsonSampleComplete = true;
+      break;
+      // II.B - chemical lib. compound mix
+    case "compound-mix": 
+      // solvent
+      self.jsonSample["solvent"] = $("#add1spectrum-sample-mixSolvent-{{ TAB_INDEX_PLACEHOLDER }}").val();
+      // cpd added
+      self.jsonSample.inchikeys_list = self.getRCCADDED();
+      self.jsonSample.concentrations_list = self.getRCCADDEDConcentration();
+      if (self.jsonSample.inchikeys_list.length == 0 && !self.is_other_in_mix()) {
+        self.isJsonRCCaddedComplete = false;
+        console.log(`isJsonRCCaddedComplete: false`)
+        return false;
+      }
+      self.isJsonSampleComplete = true;
+      break;
+    default:
+      if (!self.is_other_in_mix()) {
+        return false;
+      } 
+    }
+
+    // III - Chromato
+    self.isJsonChromatoComplete = true;
+    self.jsonChromato = {};
+    
+    // III.A - no chromato
+    // nope?
+
+    // III.B - GC  
+    if (self.isGC) {
+      self.isJsonChromatoComplete = false;
+      // TODO
+    }
+
+    // III.C - LC
+    if (self.isLC) {
+      self.isJsonChromatoComplete = true;
+      self.jsonChromato = {};
+      // check error
+      $.each($(self.prefix+".add1spectrum-chromatoLCForm").parent(), function() {
+        if ($(this).hasClass("has-error"))
+          self.isJsonChromatoComplete = false;
+      });
+      if (
+        !self.isJsonChromatoComplete
+        && !self.is_other_in_mix()
+      ) {
+        console.log(`isJsonChromatoComplete: false`)
+        return false;
+      }
+      var id = `#add1spectrum-chromatoLC-method-{{ TAB_INDEX_PLACEHOLDER }}` ;
+      self.jsonChromato["method"] = $(`${id} option:selected`).text();
+      [
+        ["column_constructor", "colConstructor"],
+        ["column_constructor_other", "colConstructorOther"],
+        ["column_name", "colName"],
+        ["column_length", "colLength"],
+        ["column_diameter", "colDiameter"],
+        ["particule_size", "colParticuleSize"],
+        ["column_temperature", "colTemperature"],
+        ["mode", "LCMode"],
+        ["separation_flow_rate", "separationFlowRate"],
+        ["solvent_a", "separationSolvA"],
+        ["solvent_a_ph", "separationSolvApH"],
+        ["solvent_b", "separationSolvB"],
+        ["solvent_b_ph", "separationSolvBApH"]
+      ].forEach((field) => {
+        id = `#add1spectrum-chromatoLC-${field[1]}-{{ TAB_INDEX_PLACEHOLDER }}` ;
+        self.jsonChromato[field[0]] = $(id).val();
+      })
+      // fulfill json object
+      
+      jsonSFG = [];
+      var formatData = {
+        time: [],
+        solvent_a_percent: [],
+        solvent_b_percent: []
+      };
+      var uniq_times = [] ;
+      $.each(self.hot_LC_SFG.getData(), function() {
+        var time = this[0] ;
+        if (time != "" && time !== null) {
+          if (
+            !isNaN(time)
+            && !isNaN(this[1])
+            && !isNaN(this[2])
+            && ! (time in uniq_times)
+          ) {
+            formatData["time"].push(Number(time));
+            formatData["solvent_a_percent"].push(Number(this[1]));
+            formatData["solvent_b_percent"].push(Number(this[2]));
+            uniq_times.push(time) ;
+          }
+        }
+      });
+      self.jsonChromato.separation_flow_gradient = formatData;
+    }
+
+    // III.D - IC  
+    if (self.isIC) {
+      self.isJsonChromatoComplete = false;
+      // TODO
+    }
+
+    // IV - Analyzer
+    self.isJsonAnalyzerComplete = true;
+    self.isJsonAnalyzer = {};
+    // IV.A - MS
+    if (self.is_ms() || self.is_ms2()) {
+      self.isJsonAnalyzerComplete = true;
+      self.jsonAnalyzer = {};
+      // check error
+      $.each($(self.prefix+".add1spectrum-analyzerMSForm").parent(), function(){
+        if ($(this).hasClass("has-error"))
+          self.isJsonAnalyzerComplete = false;
+      });
+      if (
+        !self.isJsonAnalyzerComplete
+        && !self.is_other_in_mix()
+      ) {
+        console.log(`isJsonAnalyzerComplete: false`)
+        return false;
+      }
+      
+      // fulfill json object
+      self.jsonAnalyzer["instrument_name"] = $("#add1spectrum-analyzer-ms-instrument-{{ TAB_INDEX_PLACEHOLDER }}").val();
+      self.jsonAnalyzer["instrument_model"] = $("#add1spectrum-analyzer-ms-model-{{ TAB_INDEX_PLACEHOLDER }}").val();
+      self.jsonAnalyzer["instrument_brand"] = $("#add1spectrum-analyzer-ms-model-{{ TAB_INDEX_PLACEHOLDER }}").val();
+      self.jsonAnalyzer["ion_analyzer_type"] = $("#add1spectrum-analyzer-ms-ionAnalyzerType-{{ TAB_INDEX_PLACEHOLDER }}").val();
+      
+      if (self.is_ms2()) {
+        // MSMS ion BEAM or TRAP
+        self.jsonMolIonBeam = {}
+        var jsonIonTrapBeam = {
+          ion_gas: $("#add1spectrum-ionTrapBeam-ionGas-{{ TAB_INDEX_PLACEHOLDER }}").val(),
+          ion_pressure_value: $("#add1spectrum-ionTrapBeam-ionGasPressureValue-{{ TAB_INDEX_PLACEHOLDER }}").val(),
+          ion_pressure_unit: $("#add1spectrum-ionTrapBeam-ionGasPressureUnit-{{ TAB_INDEX_PLACEHOLDER }}").val()
+        } ;
+        var key = null ;
+        if ($("#add1spectrum-ionTrapBeam-type-{{ TAB_INDEX_PLACEHOLDER }}").val() == "trap") {
+          // sp
+          jsonIonTrapBeam["ion_freq_shift"] = $("#add1spectrum-ionTrapBeam-ionFrequencyShift-{{ TAB_INDEX_PLACEHOLDER }}").val();
+          jsonIonTrapBeam["ion_number"] = $("#add1spectrum-ionTrapBeam-ionNumber-{{ TAB_INDEX_PLACEHOLDER }}").val();
+          key = "ion_trap" ;
+        } else if ($("#add1spectrum-ionTrapBeam-type-{{ TAB_INDEX_PLACEHOLDER }}").val() == "beam") {
+          key = "ion_beam_storage" ;
+        }
+        if (key !== null) {
+          self.jsonMolIonBeam[key] = jsonIonTrapBeam;
+        }
+      }
+      
+      self.jsonMolIonization = {};
+      var json_mode ;
+      ["pos", "neg"].forEach((kind) => {
+        json_mode = {} ;
+        [
+          ["ionisation_method", "ionizationMethod"],
+          ["spray_gas_flow", "sprayGazFlow"],
+          ["vaporizer_gas_flow", "vaporizerGazFlow"],
+          ["vaporizer_temperature", "vaporizerTemperature"],
+          ["source_gas_flow", "sourceGazFlow"],
+          ["transfer_tube_or_capillary_temperature", "ionTransferTubeTemperatureOrTransferCapillaryTemperature"],
+          ["high_voltage", "highVoltageOrCoronaVoltage"]
+        ].forEach((field) => {
+          var id = `#add1spectrum-analyzserMS-${field[1]}-${kind}-{{ TAB_INDEX_PLACEHOLDER }}` ;
+          json_mode[field[0]] = $(id).val() ;
+        })
+        self.jsonMolIonization[`mode_${kind}`] = json_mode ;
+      })
+    }
+
+    // IV.B - NMR
+    if (self.is_ms() || self.is_ms2()) {
+      self.isJsonPeaksListComplete = false;
+      // init
+      var peaklist = [];
+      var peakdata = {};
+      var spectrumData = {};
+      // peaklist
+      var ms_peak_data = self.hot_MS_Peaks.getData();
+      $.each(ms_peak_data, function(index) {
+        var data = ms_peak_data[index] ;
+        var formatData = {};
+        if (
+          data[0] != ""
+          && !isNaN(data[0])
+            // && !isNaN(data[2])
+          && (data[6] === "true" || data[6] === true)
+        ) {
+          peaklist.push({
+            mz: Number(data[0]),
+            ri: Number(data[2]),
+            delta_ppm: Number(data[3]),
+            composition: (data[4]),
+            annotation: (data[5])
+          });
+          self.isJsonPeaksListComplete = true;
+        }
+      });
+      // peak list data
+      peakdata["scan_type"] = (
+        self.is_ms2() ? "ms2" : "ms"
+      );
+      peakdata["polarity"] = $("#add1spectrum-peaksMS-polarity-{{ TAB_INDEX_PLACEHOLDER }}").val();
+      peakdata["resolution"] = $("#add1spectrum-peaksMS-resolution-{{ TAB_INDEX_PLACEHOLDER }}").val();
+      peakdata["curation"] = $("#add1spectrum-peaksMS-curation-{{ TAB_INDEX_PLACEHOLDER }}").val();
+      peakdata["mz_from"] = $("#add1spectrum-peaksMS-rangeFrom-{{ TAB_INDEX_PLACEHOLDER }}").val();
+      peakdata["mz_to"] = $("#add1spectrum-peaksMS-rangeTo-{{ TAB_INDEX_PLACEHOLDER }}").val();
+      peakdata["retention_min_time_from"] = $("#add1spectrum-peaksMS-rtMinFrom-{{ TAB_INDEX_PLACEHOLDER }}").val();
+      peakdata["retention_min_time_to"] = $("#add1spectrum-peaksMS-rtMinTo-{{ TAB_INDEX_PLACEHOLDER }}").val();
+      peakdata["rt_solv_from"] = $("#add1spectrum-peaksMS-rtSolvFrom-{{ TAB_INDEX_PLACEHOLDER }}").val();
+      peakdata["rt_solv_to"] = $("#add1spectrum-peaksMS-rtSolvTo-{{ TAB_INDEX_PLACEHOLDER }}").val();
+      peakdata["resolution_FWHM"] = $("#add1spectrum-analyzer-ms-resolutionFWHM-{{ TAB_INDEX_PLACEHOLDER }}").val();
+      if (self.is_ms2()) {
+        var data = self.hot_MS_Peaks.getData() ;
+        if (data.length != 0) {
+          var selected_ion = self.get_selected_parent_ion_index() ;
+          if (selected_ion !== null) {
+            peakdata["precursor_ion"] = data[selected_ion][0] ;
+            peakdata["precursor_spectrum_id"] = null ;
+          } else {
+            peakdata["precursor_ion"] = self.get_selected_parent_ion_mz() ;
+            peakdata["precursor_spectrum_id"] = null ;
+          }
+        }
+      }
+      peakdata["peaklist"] = peaklist;
+      self.jsonPeaksList = peakdata;
+    }
+    
+    self.isJsonOtherMetadataComplete = true;
+    self.jsonOtherMetadata = {};
+    // check error
+    $.each($(self.prefix+".add1spectrum-otherForm").parent(), function(){
+      if ($(this).hasClass("has-error"))
+        self.isJsonOtherMetadataComplete = false;
+    });
+    if (!self.isJsonOtherMetadataComplete && !self.is_other_in_mix()) {
+      console.log(`isJsonOtherMetadataComplete: false`)
+      return false;
+    }
+    self.jsonOtherMetadata["data_authors"] =  $("#add1spectrum-other-author-{{ TAB_INDEX_PLACEHOLDER }}").val();
+    self.jsonOtherMetadata["data_validator"] =  $("#add1spectrum-other-validator-{{ TAB_INDEX_PLACEHOLDER }}").val();;
+    self.jsonOtherMetadata["acquisition_date"] =  $("#add1spectrum-other-date-{{ TAB_INDEX_PLACEHOLDER }}").val();
+    if (!self.jsonOtherMetadata["acquisition_date"]) {
+      self.jsonOtherMetadata["acquisition_date"] = null ;
+    }
+    self.jsonOtherMetadata["data_ownership"] =  $("#add1spectrum-other-owner-{{ TAB_INDEX_PLACEHOLDER }}").val();
+    self.jsonOtherMetadata["raw_file_name"] =  $("#add1spectrum-other-fileName-{{ TAB_INDEX_PLACEHOLDER }}").val();
+    self.jsonOtherMetadata["raw_file_size"] =  $("#add1spectrum-other-fileSize-{{ TAB_INDEX_PLACEHOLDER }}").val();
+    return true;
+  },
+
+  //USED HERE
+  getFormErrorMessage: function() {
+    var self = this ;
+    var alertMsg = "";
+    if (!self.isJsonSpectrumTypeComplete) {
+      alertMsg = `
+      <div class="alert alert-danger alert-dismissible" role="alert">
+        <button type="button" class="close" data-dismiss="alert">
+          <span aria-hidden="true">&times;</span>
+          <span class="sr-only">
+            <spring:message code="alert.close" text="Close" />
+          </span>
+        </button>
+        <strong>
+          <spring:message code="alert.strong.error" text="Error!" />
+        </strong> Error processing spectrum type!
+      </div>` ;
+    } else if (!self.isJsonSampleComplete) {
+      alertMsg = `
+      <div class="alert alert-danger alert-dismissible" role="alert">
+        <button type="button" class="close" data-dismiss="alert">
+          <span aria-hidden="true">&times;</span>
+          <span class="sr-only">
+            <spring:message code="alert.close" text="Close" />
+          </span>
+        </button>
+        <strong>
+          <spring:message code="alert.strong.error" text="Error!" />
+        </strong> Missing mandatory data into sample section!
+        <br />
+        <a
+          href="#"
+          onclick="$('#linkActivateStep1-{{ TAB_INDEX_PLACEHOLDER }}').trigger('click');"
+        >Go to this section</a>
+      </div>` ;
+    } else if (!self.isJsonRCCaddedComplete) {
+      alertMsg = `
+      <div class="alert alert-danger alert-dismissible" role="alert">
+        <button type="button" class="close" data-dismiss="alert">
+          <span aria-hidden="true">&times;</span>
+          <span class="sr-only">
+            <spring:message code="alert.close" text="Close" />
+          </span>
+        </button>
+        <strong>
+          <spring:message code="alert.strong.error" text="Error!" />
+        </strong> Pease enter at least ONE compound in mix into sample section!
+        <br />
+        <a
+          href="#"
+          onclick="$('#linkActivateStep1-{{ TAB_INDEX_PLACEHOLDER }}').trigger('click');"
+        >Go to this section</a>
+      </div>`;
+    } else if (!self.isJsonChromatoComplete) {
+      alertMsg = `
+      <div class="alert alert-danger alert-dismissible" role="alert">
+        <button type="button" class="close" data-dismiss="alert">
+          <span aria-hidden="true">&times;</span>
+          <span class="sr-only">
+            <spring:message code="alert.close" text="Close" />
+          </span>
+        </button>
+        <strong>
+          <spring:message code="alert.strong.error" text="Error!" />
+        </strong> Missing data in chromatography section!
+      ` ;
+      if (self.is_ms()) {
+        alertMsg += `
+        <br />
+        <a
+          href="#"
+          onclick="$('#linkActivateStep4-ms-{{ TAB_INDEX_PLACEHOLDER }}').trigger('click');"
+        >Go to this section</a>`;
+      }
+      alertMsg += ' </div>';
+    } else if (!self.isJsonPeaksListComplete) {
+      alertMsg = `
+      <div class="alert alert-danger alert-dismissible" role="alert">
+        <button type="button" class="close" data-dismiss="alert">
+          <span aria-hidden="true">&times;</span>
+          <span class="sr-only">
+            <spring:message code="alert.close" text="Close" />
+          </span>
+        </button>
+        <strong>
+          <spring:message code="alert.strong.error" text="Error!" />
+        </strong> Missing peaklist!
+      ` ;
+      if (self.is_ms()) {
+        alertMsg += `
+        <br />
+        <a
+          href="#"
+          onclick="$('#linkActivateStep4-ms-{{ TAB_INDEX_PLACEHOLDER }}').trigger('click');"
+        >Go to this section</a>`;
+      }
+      alertMsg += ' </div>';
+    } else if (self.is_mix() && self.is_ms2()) {
+      for (var i = 0 ; i < all_contexts.length ; i += 1) {
+        if (all_contexts[i] === null || all_contexts[i] === undefined) {
+          continue;
+        }
+        if (all_contexts[i].get_selected_parent_ion_index() === null) {
+          return alertMsg + `
+            <div class="alert alert-danger alert-dismissible" role="alert">
+              <button type="button" class="close" data-dismiss="alert">
+                <span aria-hidden="true">&times;</span>
+                <span class="sr-only">
+                  <spring:message code="alert.close" text="Close" />
+                </span>
+              </button>
+              <strong>
+                <spring:message code="alert.strong.error" text="Error!" />
+              </strong> Select precursor ion in all peak lists!
+            </div>
+          `
+        }
+      }
+    }
+    // TODO other
+    return alertMsg;
+  },
+
+  //USED HERE
+  gatherJsonObjects: function() {
+    var self = this ;
+    var jsonData = {};
+    if (self.is_mix()) {
+      jsonData["sample_type"] = "mix_of_reference_chemical_compounds" ;
+    } else {
+      jsonData["sample_type"] = "reference_chemical_compound" ;
+    }
+    jsonData["spectrum_type"] = self.jsonSpectrumType.toUpperCase().replaceAll("-", "");
+    jsonData["sample"] = self.jsonSample;
+    if (self.isLC) {
+      jsonData["chromatography"] = self.jsonChromato;
+    } else if (self.isGC) {
+      jsonData["chromatography"] = self.jsonChromato;
+    } else if (self.isIC) {
+      jsonData["chromatography"] = self.jsonChromato;
+    } 
+    if (self.is_ms()) {
+      jsonData["analyzer"] = self.jsonAnalyzer;
+      var molecule_ionization = self.jsonMolIonization;
+      jsonData["ionization_mode_positive"] = molecule_ionization["mode_pos"] ;
+      jsonData["ionization_mode_negative"] = molecule_ionization["mode_neg"] ;
+      jsonData["peaklists"] = [self.jsonPeaksList] ;
+    } else if (self.is_ms2()) {
+      jsonData["analyzer"] = self.jsonAnalyzer;
+      var molecule_ionization = self.jsonMolIonization;
+      jsonData["ionization_mode_positive"] = molecule_ionization["mode_pos"] ;
+      jsonData["ionization_mode_negative"] = molecule_ionization["mode_neg"] ;
+      if (self.jsonMolIonBeam != null) {
+        jsonData["ion_beam_storage"] = self.jsonMolIonBeam["ion_beam_storage"];
+      }
+      jsonData["peaklists"] = [self.jsonPeaksList] ;
+    }
+    jsonData["other_metadata"] = self.jsonOtherMetadata;
+    return jsonData;
+  },
+
+  //USED IN HTML
+  pickChemicalCompound: function() {
+    var self = this ;
+    self.singlePick = true;
+    $("#modalPickCompound-{{ TAB_INDEX_PLACEHOLDER }}").modal("show");
+    $("#add-one-cc-s1-value-{{ TAB_INDEX_PLACEHOLDER }}").focus();
+  },
+
+  //USED HERE
+  pickChemicalCompound4Mix: function(rowNumber) {
+    var self = this ;
+    self.singlePick = false;
+    self.multiPickLine = rowNumber;
+    $("#modalPickCompound-{{ TAB_INDEX_PLACEHOLDER }}").modal("show");
+    $("#add-one-cc-s1-value-{{ TAB_INDEX_PLACEHOLDER }}").focus();
+  },
+
+  //USED HERE
+  searchAjax: function() {
+    var self = this ;
+    var results ;
+    var rawQuery = $('#add-one-cc-s1-value-{{ TAB_INDEX_PLACEHOLDER }}').val();
+    if (rawQuery.length > 2) {
+      return [] ;
+    }
+    results = [] ;
+    $.ajax({ 
+        type: "post",
+        url: "{{ PF_URL_PLACEHOLDER }}/webapp/search",
+        dataType: "json",
+        async: false,
+        data: "query=" + $("#add-one-cc-s1-value-{{ TAB_INDEX_PLACEHOLDER }}").val(),
+        success: function(json) {
+          if (json.success) {
+            $.each(json.compoundNames, function(){
+              results.push(this.name) ;
+            }) ; 
+            $.each(json.compounds, function(){
+              if (this.inChIKey.indexOf(rawQuery)) {
+                results.push(this.inChIKey) ;
+              }
+            }) ;
+          }
+      },
+      error : function(xhr) {
+        self.subjects = [] ;
+        console.log(xhr) ;
+      }
+    }) ;
+    return results ;
+  },
+
+  //USED HERE
+  searchLocalCompound: function() {
+    var self = this ;
+    $("#load-step-1-{{ TAB_INDEX_PLACEHOLDER }}").show();
+    $.ajax({ 
+      type: "get",
+      url: "{{ PF_URL_PLACEHOLDER }}/rest/v2/compounds",
+      async: true,
+      data: "limit=1&query=" + $('#add-one-cc-s1-value-{{ TAB_INDEX_PLACEHOLDER }}').val() + "&query_filter=" + self.fitlerSearchLoadlCpd+"&token={{ PF_TOKEN_PLACEHOLDER }}",
+      success: function(data) {
+        data = data[0] ;
+        var id = parseInt(data["id"]) ;
+        var name = data["name"] ;
+        var inchikey = data["inchikey"] ;
+        var inchi = data["inchi"] ;
+        data = `
+    <div class="table-responsive">
+      <table id="tabPickCpd-{{ TAB_INDEX_PLACEHOLDER }}" class="table table-bordered table-hover table-striped tablesorter" style="cursor: pointer;">
+        <thead>
+          <tr>
+            <th class="header">Chemical Name <i class="fa fa-sort"></i></th>
+            <th class="header">Monoisotopic Mass <i class="fa fa-sort"></i></th>
+            <th class="header">Formula <i class="fa fa-sort"></i></th>
+            <th class="header" style="">Structure</th>
+          </tr>
+        </thead>
+        <tbody>
+          <tr class="success" onclick="loadCompoundInForm(${id}, '${inchikey}', '${inchi}', '${data["formula"]}', '${data["exactMass"]}' , 100);">
+            <td style="vertical-align: middle;">
+              <span id="cpt-load-name-${id}-{{ TAB_INDEX_PLACEHOLDER }}">${name}</span> 
+              <br><small style="white-space: nowrap;">${inchikey}</small>
+            </td>
+            <td style="vertical-align: middle;" class="compoundMass">${data["exactMass"]}</td>
+            <td style="vertical-align: middle;" class="compoundFormula">${data["formula"]}</sub></td>
+            <td><span class="avatar">
+              <img class="compoundSVG" src="{{ PF_URL_PLACEHOLDER }}/webapp/image/generic/${inchikey}" alt="${name}">
+              </span>
+            </td>
+          </tr>
+        </tbody>
+      </table>
+    <small><sup><b>*</b></sup>: Generic Compounds (abstract "flat" compound without (+) or (-) center).</small>
+    <` + "script" + ` type="text/javascript">
+    $("#tabPickCpd-{{ TAB_INDEX_PLACEHOLDER }}").tablesorter();
+    $.each($(self.prefix+".compoundFormula"), function(id, elem) {
+      var rawFromula = $(elem).text();
+      var formatedFormula = rawFromula;
+      try {
+        $.each($.unique( rawFromula.match(/\d+/g)), function(keyF, valF) {
+          var re = new RegExp(valF,"g");
+          formatedFormula = formatedFormula.replace(re, "<sub>" + valF + "</sub>");
+        });
+      } catch (e){}
+      formatedFormula = formatedFormula.replace("</sub><sub>", "");
+      $(elem).html(formatedFormula);
+    });
+    $.each($(self.prefix+".compoundMass"), function(id, elem) {
+      var exactMass = parseFloat( $(elem).text());
+      exactMass = roundNumber(exactMass,7)
+      $(elem).html(exactMass);
+    });
+    </` + "script" + `>
+
+      </div>
+    <` + "script" + ` type="text/javascript">
+    var listOfRefCompoundsMatch = null;
+
+    loadCompoundInForm = function(id, inchikey, inchi, composition, exactMass, type) {
+      if (ctx().modeEditSpectrum) {
+        var name = $("#cpt-load-name-" + id + "-{{ TAB_INDEX_PLACEHOLDER }}").html();
+        if (ctx().multiPickLine >= 0) {
+          ctx().hot_RCC_ADDED.setDataAtCell(ctx().multiPickLine, 0, name);
+
+          // restet form
+          setTimeout(function(){
+            $("#add-one-cc-s1-value-{{ TAB_INDEX_PLACEHOLDER }}").val("");
+            $("#ok-step-1-{{ TAB_INDEX_PLACEHOLDER }}").html("");
+          }, 200);
+          // img
+          var typeS = "chemical";
+          if (type == 100)
+            typeS = "generic";
+          else if (type == 101)
+            typeS = "chemical";
+          // '<img class="mixRCCadd'+ctx().multiPickLine+' compoundSVGZoom" src="{{ PF_URL_PLACEHOLDER }}/webapp/image/'+typeS+'/'+inchikey+'" alt="'+name+'">'
+          var currentCpt = { 
+              "name": name,
+              "type": typeS,
+              "concentration": "?",
+              "inchikey": inchikey
+          }; 
+          updatedCpdMixData[name] = currentCpt;
+        }
+        // display
+        $("#modalPickCompound-{{ TAB_INDEX_PLACEHOLDER }}").modal("hide");
+        $("#modalEditSpectrum-{{ TAB_INDEX_PLACEHOLDER }} .modal-dialog").show();
+        return;
+      } // else: add one spectrum
+      var name = $("#cpt-load-name-" + id + "-{{ TAB_INDEX_PLACEHOLDER }}").html();
+      if (ctx().singlePick) {
+        $("#add1spectrum-sample-inchikey-{{ TAB_INDEX_PLACEHOLDER }}").val(inchikey);
+        $("#add1spectrum-sample-inchikey-{{ TAB_INDEX_PLACEHOLDER }}").change();
+        $("#add1spectrum-sample-inchi-{{ TAB_INDEX_PLACEHOLDER }}").val(inchi);
+        $("#add1spectrum-sample-inchi-{{ TAB_INDEX_PLACEHOLDER }}").change();
+        $("#add1spectrum-sample-commonName-{{ TAB_INDEX_PLACEHOLDER }}").val(name);
+        $("#add1spectrum-sample-commonName-{{ TAB_INDEX_PLACEHOLDER }}").change();  
+
+        $("#importspectrum-sample-inchikey-{{ TAB_INDEX_PLACEHOLDER }}").val(inchikey);
+        $("#importspectrum-sample-inchikey-{{ TAB_INDEX_PLACEHOLDER }}").change();
+      } else if (ctx().multiPickLine >= 0) {
+        ctx().hot_RCC_ADDED.setDataAtCell(ctx().multiPickLine, 0, name);
+        ctx().hot_RCC_ADDED.setDataAtCell(ctx().multiPickLine, 1, inchikey);
+        ctx().hot_RCC_ADDED.setDataAtCell(ctx().multiPickLine, 2, composition);
+        ctx().hot_RCC_ADDED.setDataAtCell(ctx().multiPickLine, 4, exactMass);
+        // restet form
+        setTimeout(function(){
+          $("#add-one-cc-s1-value-{{ TAB_INDEX_PLACEHOLDER }}").val("");
+          $("#ok-step-1-{{ TAB_INDEX_PLACEHOLDER }}").html("");
+        }, 200);
+      }
+      var typeS = "chemical";
+      if (type == 100)
+        typeS = "generic";
+      else if (type == 101)
+        typeS = "chemical";
+      if (ctx().singlePick)
+        $("#sample-bonus-display-{{ TAB_INDEX_PLACEHOLDER }}").html('<img class="" src="{{ PF_URL_PLACEHOLDER }}/webapp/image/'+typeS+'/'+inchikey+'" alt="'+name+'">');
+      else {
+        // delete
+        $(ctx().prefix+"img.mixRCCadd"+ctx().multiPickLine).remove();
+        // add
+        $("#sample-bonus-display-{{ TAB_INDEX_PLACEHOLDER }}").append('<img class="mixRCCadd'+ctx().multiPickLine+' compoundSVGZoom" src="{{ PF_URL_PLACEHOLDER }}/webapp/image/'+typeS+'/'+inchikey+'" alt="'+name+'">');
+        $(ctx().prefix+"img.mixRCCadd"+ctx().multiPickLine+"").mouseenter(function() {
+          $(this).removeClass("compoundSVGZoom");
+        }).mouseleave(function() {
+          $(this).addClass("compoundSVGZoom");
+        });
+      }
+      $("#modalPickCompound-{{ TAB_INDEX_PLACEHOLDER }}").modal("hide");
+    }
+    </` + "script" + `></` + "div" + `>` ;
+        $("#ok-step-1-{{ TAB_INDEX_PLACEHOLDER }}").html(data);
+      },
+      error : function(xhr) {
+        // log
+        console.log(xhr);
+        // error
+        $("#ok-step-1-{{ TAB_INDEX_PLACEHOLDER }}").html("Error: could not process request.");
+      }
+    }).always(function() {
+      $("#load-step-1-{{ TAB_INDEX_PLACEHOLDER }}").hide();
+    });
+  },
+
+  //USED HERE
+  getRCCADDED: function() {
+    var self = this ;
+    jsonRCC_ADDED = [];
+    $.each(self.hot_RCC_ADDED.getData(), function(){
+      var formatData = {};
+      if ("<b>InChIKey</b>" in this && this["<b>InChIKey</b>"]!= undefined && this["<b>InChIKey</b>"] != "") {
+        jsonRCC_ADDED.push(this["<b>InChIKey</b>"]);
+      }
+    });
+    return jsonRCC_ADDED;
+  },
+
+  //USED HERE
+  getRCCADDEDConcentration: function() {
+    var self = this ;
+    jsonRCC_ADDED = [];
+    $.each(self.hot_RCC_ADDED.getData(), function(){
+      var formatData = {};
+      if ("<b>InChIKey</b>" in this && this["<b>InChIKey</b>"]!= undefined && this["<b>InChIKey</b>"] != "") {
+        jsonRCC_ADDED.push(this["<b>concentration (&micro;g/ml)</b>"]);
+      }
+    });
+    return jsonRCC_ADDED;
+  },
+
+  //USED IN HTML
+  clearLine: function() {
+    var self = this ;
+    // restet form
+    setTimeout(function(){
+      $("#add-one-cc-s1-value-{{ TAB_INDEX_PLACEHOLDER }}").val("");
+      $("#ok-step-1-{{ TAB_INDEX_PLACEHOLDER }}").html("");
+    }, 200);
+    $(self.prefix+"img.mixRCCadd"+self.multiPickLine).remove();
+    if (self.singlePick) {
+      $("#add1spectrum-sample-inchikey-{{ TAB_INDEX_PLACEHOLDER }}").val("");
+      $("#add1spectrum-sample-inchikey-{{ TAB_INDEX_PLACEHOLDER }}").change();
+      $("#add1spectrum-sample-inchi-{{ TAB_INDEX_PLACEHOLDER }}").val("");
+      $("#add1spectrum-sample-inchi-{{ TAB_INDEX_PLACEHOLDER }}").change();
+      $("#add1spectrum-sample-commonName-{{ TAB_INDEX_PLACEHOLDER }}").val("");
+      $("#add1spectrum-sample-commonName-{{ TAB_INDEX_PLACEHOLDER }}").change();
+      $("#sample-bonus-display-{{ TAB_INDEX_PLACEHOLDER }}").html("");
+    } else if (self.multiPickLine >= 0) {
+      for(var i = 0 ; i < 6 ; i += 1) {
+        self.hot_RCC_ADDED.setDataAtCell(self.multiPickLine, i, "");
+      }
+    }
+  },
+
+  exit: function() {
+    $.ajax({type: "get", url: "/quit", async: true, success: ()=>window.close()});
+  },
+
+} ;
+
+$.ajax({
+  type: "get",
+  url: "{{ PF_URL_PLACEHOLDER }}/webapp/get-cpd-data?token={{ PF_TOKEN_PLACEHOLDER }}",
+  data: "inchikey=" + "{{ INCHIKEY_PLACEHOLDER }}",
+  dataType: "json",
+  success: function(data) {
+    if (data.success) {
+      var self = context_{{ TAB_INDEX_PLACEHOLDER }} ;
+      console.log(`inchikey {{ INCHIKEY_PLACEHOLDER }} found!!`)
+      inchidata["{{ INCHIKEY_PLACEHOLDER }}"] = data ;
+      self.init() ;
+      self.fitlerSearchLoadlCpd = 5;
+      self.inchikey = null;
+      all_contexts[{{ TAB_INDEX_PLACEHOLDER }}] = self ;
+    } else {
+      no_success(
+        {{ TAB_INDEX_PLACEHOLDER }},
+        "{{ INCHIKEY_PLACEHOLDER }}",
+        {{ DEFAULT_DATA }}["name"]
+      ) ;
+      all_contexts[{{ TAB_INDEX_PLACEHOLDER }}] = null ;
+    }
+  },
+  error : function(data) {
+    no_success(
+      {{ TAB_INDEX_PLACEHOLDER }},
+      "{{ INCHIKEY_PLACEHOLDER }}",
+      {{ DEFAULT_DATA }}["name"]
+    ) ;
+    all_contexts[{{ TAB_INDEX_PLACEHOLDER }}] = null ;
+  }
+}).always(() => null);