0

I am trying to link my HTML form with my csv file to populate form field automatically. Based on what user selects in first field, second field should be automatically filled with the appropriate value. when the user starts typing in the first field, the input field automatically pulls data from csv file to show available options. Options appear after user completes writing 3 words in the field.

Further, to avoid any CORS issue in code, I have added additional URL in my CSV file URL which makes it accessible by any web application.

I was able to prepare this code with the help of examples available on web. However, my code is not working properly. I tried to solve this problem on my own. But I don't know about coding enough.

Can anyone please help me to solve this problem.

<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 Answers 2

0

Here's the modified answer, working with jquery-ui autocomplete.

The solution: the $.get() is an asynchronous function (the data is not readily available on page load), so jquery-ui autocomplete didn't work with the updated lists[] array, because it (seems so that it) doesn't work with dynamically generated data. So the source of autocomplete had to be refreshed with the newly arrived data in the $.get()'s callback function.

$("#species").autocomplete('option', 'source', lists) - this is the key line, as it updates autocomplete's source with the new data.

// 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>

The processData() function didn't work as expected with the source you provided, so that had to be modified too.

Sign up to request clarification or add additional context in comments.

9 Comments

finally i got my answer with the help and efforts of just yours! YOU made my day great today. sorry for not providing proper details. it was my mistake. but definitely i will remember this thing before asking any further question in future. again thanks for your help...
can you please help me one more time. if total number of columns in csv file is 3 rather than 2 and i need to fetch all these 3 columns and have to now fill additional input field(+2 additional input fields as were earlier) than what changes i will have to made in this code???
Without an example I could only guess. If you can prepare a JSFiddle with the other CSV source you describe now, it could be solved. You could add that fiddle (the URL) in a comment.
check this JSFiddle " jsfiddle.net/dr06kzve " i have added new csv file link and third input field... along with " identifiant " input field, i need to prefill "name" input field also. thanks in advance
Here's a more flexible solution: jsfiddle.net/mukagergely/azy0cwj1/55. This jquery-ui autocomplete is not the best there's, so some attributes had to be taken as granted. (Like "species".)
|
0

My solution is a kinda' autocomplete - it's called typeahead.

I displayed the filtered list, so you see what's happening, but you can place that anywhere - in a dropdown below the input field, for example.

$(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>

2 Comments

thanks for your answer. but can you please edit your answer and make this code to run and appear like this example jsfiddle.net/Twisty/rnuudsap i can't see any option list which i can use to prefill second field....thanks in advance
Why haven't you provided the working example (JSFiddle) in your question? It took some effort to write a new solution - modifying the working example took like 5 minutes. Please, next time be more thorough with how you post a question! Try to give all the necessary information and resources to others on SO, so they can help effectively! (Have a look at my other answer, then).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.