Как загрузить данные из CSV-файла в поле формы? - PullRequest
0 голосов
/ 15 июня 2019

Я пытаюсь связать мою HTML-форму с моим CSV-файлом, чтобы заполнить поле формы автоматически. В зависимости от того, что пользователь выбирает в первом поле, второе поле должно автоматически заполняться соответствующим значением. когда пользователь начинает вводить данные в первом поле, поле ввода автоматически извлекает данные из CSV-файла для отображения доступных параметров. Опции появляются после того, как пользователь завершил написание 3 слов в поле.

Кроме того, чтобы избежать каких-либо проблем с CORS в коде, я добавил дополнительный URL-адрес в URL-адрес моего файла CSV, который делает его доступным для любого веб-приложения.

Мне удалось подготовить этот код с помощью примеров, доступных в Интернете. Тем не менее, мой код не работает должным образом. Я пытался решить эту проблему самостоятельно. Но я не знаю достаточно о кодировании.

Может кто-нибудь, пожалуйста, помогите мне решить эту проблему.

<script>
$(function() { function processData(allText) { var record_num = 2; 
// or however many elements there are in each row 
var allTextLines = allText.split(/\r\n|\n/); var lines = []; var headings = allTextLines.shift().split(','); while (allTextLines.length > 0) { var tobj = {}, entry; entry = allTextLines.shift().split(','); tobj['label'] = entry[0]; tobj['value'] = entry[1]; lines.push(tobj); } return lines; } 

// Storage for lists of CSV Data

 var lists = []; 

// Get the CSV Content
 $.get("https://cors-anywhere.herokuapp.com/www.coasilat.com/wp-content/uploads/2019/06/file.txt  ", function(data) { lists = processData(data); }); $("#species").autocomplete({ minLength: 3, source: lists, select: function(event, ui) { $("#species").val(ui.item.label); $("#identifiant").val(ui.item.value); return false; } }); });)
</script>
 <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
   <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
         
  <form> 
  <div class="ui-widget"> <label for="species">Species: </label> <input id="species"> <label for="identifiant">Identifiant: </label> <input id="identifiant" style="width: 6em;"> </div></form>

Ответы [ 2 ]

0 голосов
/ 15 июня 2019

Вот модифицированный ответ, работающий с автозаполнением jquery-ui.

Решение: $.get() - это асинхронная функция (данные недоступны при загрузке страницы),поэтому автозаполнение jquery-ui не работает с обновленным массивом lists[], поскольку оно (кажется, что оно) не работает с динамически генерируемыми данными .Таким образом, источник автозаполнения должен был быть обновлен вновь поступившими данными в функции обратного вызова $.get().

$("#species").autocomplete('option', 'source', lists) - это ключевая строка , поскольку он обновляет источник автозаполнения новыми данными.

// Only needed for working example
var myCSV = "Species,Identifiant\r\n";
myCSV += "Species A,320439\r\n";
myCSV += "Species B,349450\r\n";
myCSV += "Species C,43435904\r\n";
myCSV += "Species D,320440\r\n";
myCSV += "Species E,349451\r\n";
myCSV += "Species F,43435905\r\n";
console.log(myCSV);

// Begin jQuery Code
$(function() {
  function processData(allText) {
    // var record_num = 2; // or however many elements there are in each row
    var allTextLines = allText.split(/\r\n|\n/);
    var lines = [];
    var headings = allTextLines.shift().split(',');
    while (allTextLines.length > 0) {
      var tobj = {},
        entry;
      entry = allTextLines.shift().split(',');
      /*
      Normally we'd read the headers into the object.
      Since we will be using Autocomplete, it's looking for an array of objects with 'label' and 'value' properties.
      tobj[headings[0]] = entry[0];
      tobj[headings[1]] = entry[1];
      */
      if (typeof entry[1] !== 'undefined') {
        let prefix = !entry[0].includes('Species') ? 'Species ' : ''
        tobj['label'] = prefix + entry[0];
        tobj['value'] = entry[1].trim();
        lines.push(tobj);
      }
    }
    return lines;
  }
  let lists = [];

  // For working example 
  // lists = processData(myCSV);
  // console.log('lists1', lists)

  // In your script you will get this content from the CSV File
  // Get the CSV Content
  $.get("https://cors-anywhere.herokuapp.com/www.coasilat.com/wp-content/uploads/2019/06/file.txt", function(data) {
    lists = processData(data);
    $("#species").autocomplete('option', 'source', lists)
    console.log('lists2', lists)
  });

  $("#species").autocomplete({
    minLength: 3,
    source: lists,
    focus: function(event, ui) {
      console.log(ui)
      $("#species").val(ui.item.label);
      return false;
    },
    select: function(event, ui) {
      $("#species").val(ui.item.label);
      $("#identifiant").val(ui.item.value);
      return false;
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" />
<div class="ui-widget">
  <label for="species">Species: </label>
  <input id="species">
  <label for="identifiant">Identifiant: </label>
  <input id="identifiant" style="width: 6em;">
</div>

Функция processData () не работала должным образом с указанным вами источником, поэтому ее также пришлось изменить.

0 голосов
/ 15 июня 2019

Мое решение - это своего рода автозаполнение - оно называется typeahead.

Я отобразил отфильтрованный список, чтобы вы могли видеть, что происходит, но вы можете разместить это где угодно - например, в раскрывающемся списке под полем ввода..

$(function() {
  // processing CSV data
  function processData(allText) {

    // splitting lines
    var allTextLines = allText.split(/\r\n|\n/);

    const speciesData = []
    // reading data into array, if it's not the first row (CSV header) AND
    // if it's not 'Species'
    let j = 0; // this will be the item's index
    for (let i = 0; i < allTextLines.length - 1; i++) {
      if (i !== 0 && allTextLines[i] !== 'Species') {
        const record = allTextLines[i].split(',')
        speciesData.push({
          label: record[0],
          value: record[1].trim(), // it has a lot of whitespace
          index: j // adding this, so we can keep track of items
        })
        j++; // incrementing index
      }
    }

    // returning processed data
    return speciesData;
  }

  // Storage for lists of processed CSV Data
  let lists = [];

  // Get the CSV Content
  $.get("https://cors-anywhere.herokuapp.com/www.coasilat.com/wp-content/uploads/2019/06/file.txt  ", function(data) {
    // making processed data availabel app-wide
    lists = processData(data);
    // filling the 'suggestions list' the first time
    suggestionListHtml(lists, $('.suggestions-container'))
  });

  // actions on input field input event
  // only the third param differs in filterSpecies()
  $('#species').on('input', function(e) {
    const filteredList = filterSpecies($(this).val(), lists, 'label')
    suggestionListHtml(filteredList, $('.suggestions-container'))
  })
  $('#identifiant').on('input', function(e) {
    const filteredList = filterSpecies($(this).val(), lists, 'value')
    suggestionListHtml(filteredList, $('.suggestions-container'))
  })

  // clicking on an item in the 'suggestions list' fills out the input fields
  $('.suggestions-container').on('click', '.suggestion', function(e) {
    const item = lists[$(this).attr('data-listindex')]
    $('#species').val(item.label)
    $('#identifiant').val(item.value)
  })

});

function suggestionListHtml(filteredList, container) {
  // creating HTML template for the 'suggestions list'
  let html = ''
  filteredList.forEach(item => {
    html += `<span class="suggestion" data-listindex="${item.index}">label: ${item.label} - value: ${item.value}</span>`
  })

  // modifying the displayed 'suggestions list'
  container
    .empty()
    .append(html)
}

// filtering the processed list
// @param substr - the text from the input field
// @param list - the list to be filtered
// @param attr - one of the keys in the processed list (label or value)
function filterSpecies(substr, list, attr) {
  // doing the actual filtering
  const filteredList = list.filter(item => {
    return item[attr].toLowerCase().includes(substr.toLowerCase())
  })
  return filteredList
}
.suggestions-container span {
  display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<form>
  <div class="ui-widget">
    <label for="species">Species: </label>
    <input id="species">
    <label for="identifiant">Identifiant: </label>
    <input id="identifiant" style="width: 6em;">
  </div>
  <div class="suggestions-container">

  </div>
</form>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...