Find specific line in CSV based on 2 values with Javascript - javascript

I am trying to search, find and fetch some data from a CSV file using HTML/PHP/Javascript.
I want to make a form with 2 dropdowns, one for the FROM Zone name and one for the TO Zone name, and use the Zone codes (102, 104, 105 etc) as values for the dropdown items.
After the user have selected the FROM and TO i want to display the single digit to the far right (col 5).
Example: User choose "Zone1" to "Zone4", then the number "4" should be returned.
FromZoneCode;FromZoneName;ToZoneCode;ToZoneName;Distance;;;;
101;zone1;101;zone1;1;;;;
101;zone1;104;zone4;4;;;;
101;zone1;105;zone5;5;;;;
104;zone4;101;zone1;4;;;;
104;zone4;105;zone5;2;;;;
104;zone4;104;zone4;1;;;;
I have tried to search for a solution for this but i cant seem to find the right info.

Worked out after a long time:
Don't know how you got the CSV data. In the following example, I got it by an ajax request.
No jQuery needed.
Created the dropdowns dynamically.
Set the variable delimeter to ; (or) , as required, because most CSV files contains CSV delimeter.
Give the names of the columns for which dropdowns to be created in the variables dropdownname1 and dropdownname2.
Give the name of the column to be displayed as result on chaning dropdowns in the variable resultname.
Create a <span> element with id="result" in the HTML to display the result.
Variable keys contains column names.
Variable values contains array of arrays as values.
var data = [];
$.ajax({
url:"/Users/Default/Downloads/test.csv",
type:"GET",
datatype:"csv",
success:function(response){
data = response.split(/\r\n/);
start();
}
});
//Logic starts here
//Initializations
var keys = [], values = [], delimiter = ";";
var dropdownname1 = "FromZoneName", dropdownname2 = "ToZoneName", resultname = "Distance";
var resultelem = document.getElementById("result");
//Functionalities
function createDropdown(field)
{
function createOption(option, isselected)
{
var optionelem = document.createElement("option");
optionelem.value=option;
optionelem.text=option;
optionelem.selected = isselected;
return optionelem;
}
var selectelem = document.createElement("select");
selectelem.setAttribute("id",field);
var insertedoptions = [];
for(var i=0;i<values.length;i++)
{
var option = values[i][keys.indexOf(field)];
if(insertedoptions.indexOf(option) == -1)
{
insertedoptions.push(option);
selectelem.appendChild(createOption(option));
}
}
selectelem.appendChild(createOption("",true));
return selectelem;
}
function start()
{
keys = data.splice(0,1)[0].split(delimiter);
values = [];
for(var i=0,n=data.length;i<n;i++)
{
values.push(data[i].split(delimiter));
}
var bodyelem = document.getElementsByTagName("body")[0];
bodyelem.appendChild(createDropdown(dropdownname1));
bodyelem.appendChild(createDropdown(dropdownname2));
document.getElementById(dropdownname1).addEventListener("change",displayData);
document.getElementById(dropdownname2).addEventListener("change",displayData);
}
function displayData()
{
var selectelem1 = document.getElementById(dropdownname1), selectelem2 = document.getElementById(dropdownname2);
var selectedvalue1 = selectelem1.value, selectedvalue2 = selectelem2.value;
for(var i=0,n=values.length;i<n;i++)
{
if(values[i][keys.indexOf(dropdownname1)] == selectedvalue1 && values[i][keys.indexOf(dropdownname2)] == selectedvalue2)
{
resultelem.innerHTML=values[i][keys.indexOf(resultname)];
break;
}
else
{
resultelem.innerHTML="";
}
}
}

Related

Google Apps Scripts - Add specific value to each row being processed in a loop

so I want to write a function that takes leads from a source sheet, and then, sends them to another sheet (the destsheet) if they haven't been sent yet. The difference between a lead that has been sent and a lead that hasn't been is that a lead sent should have "yes" in column K (column 10)
I have managed to get the first part working (sending leads from a sheet to another) but for some reason, I can't get the script to add "yes" when a lead is sent to the other sheet. As you can see below, I've tried adding "values[i][tstCol] = "yes";" in several different spots, but it's not working.
Any ideas of what I'm doing wrong? Thanks!
function newLeads() {
var sourceSheet = SpreadsheetApp.openById('ID').getSheetByName('SHEETNAME');
var destSheet = SpreadsheetApp.openById('ID').getSheetByName('SHEETNAME');
var values = sourceSheet.getDataRange().getDisplayValues();
var finalValues=[];
var columns = String("0,1,2,3,4,5,6,7,8").split(','); //only want these columns
var tstCol = 10;
for (var i=0;i<values.length;i++) {
var newValues=[];
//values[i][tstCol] = "yes";
if (values[i][tstCol] != "yes") {
//values[i][tstCol] = "yes";
for (var j=0;j<columns.length;j++) {
//values[i][tstCol] = "yes";
newValues.push(values[i][columns[j]]);
}
finalValues.push(newValues);
}
}
destSheet.getRange(destSheet.getLastRow() + 1, 1, finalValues.length, finalValues[0].length).setValues(finalValues);
}
Take a look at this.
function newLeads() {
try {
var sourceSheet = SpreadsheetApp.openById('ID').getSheetByName('SHEETNAME');
var destSheet = SpreadsheetApp.openById('ID').getSheetByName('SHEETNAME');
var values = sourceSheet.getDataRange().getDisplayValues();
var finalValues=[];
var columns = String("0,1,2,3,4,5,6,7,8").split(','); //only want these columns
var tstCol = 10;
for (var i=0;i<values.length;i++) {
var newValues=[];
if (values[i][tstCol] != "yes") {
values[i][tstCol] = "yes"; // is this where you want to set to yes
for (var j=0;j<columns.length;j++) {
newValues.push(values[i][columns[j]]);
}
finalValues.push(newValues);
}
values[i] = [values[i][tstCol]]; // this would extract column tstCol
}
destSheet.getRange(destSheet.getLastRow() + 1, 1, finalValues.length, finalValues[0].length).setValues(finalValues);
sourceSheet.getRange(1,tstCol+1,values.length,1).setValues(values);
}
catch(err) {
console.log(err);
}
}
Explanation:
The try block is used to see if an error occurs during the block between try and catch; if an error occurs, the catch(err) block is executed and the error is being displayed.
The values array is an array of rows [[1,2,3,4],[5,6,7,8],...] which I converted it to an array [[1],[2],[3]...] of a single column of the spreadsheet type in order to use the setValues(values) method.
Reference link:
Apps Script setValues().

How to make my Array to be empty again and reusable for my Edit Text Function

Newbie here.. I was making an expense note app(just a noob app). I have this button function on which when I select one table row.. It will be deleted and the table row input text value will return to the input bar text area(name, date, amount, remarks). I was happy when it work.
But it only work once.
Because when I select different table row data. It will be deleted but the same "first input data value" will always return to the input text bar..
It seems the first table data are being saved in the empty array function that can be reuse again. What I am hoping for is when I use the empty array function it will be empty again to be use in another different table row data.
I am using array methods but failed or my If statement is wrong. Hopefully you can answer this :) thanks
document
.getElementById("editSelection")
.addEventListener("click", editSelection);
function editSelection() {
var editName = [];
var editDate = [];
var editAmount = [];
var editRemarks = [];
let selectedRows = document.getElementsByClassName("selected-row ");
while (selectedRows.length > 0) {
editName.push(cell0.innerText);
editDate.push(cell1.innerText);
editAmount.push(cell2.innerText);
editRemarks.push(cell3.innerText);
selectedRows[0].parentNode.removeChild(selectedRows[0]);
var name = document.getElementById("inputName");
name.value = editName.join("\n");
var date = document.getElementById("inputDate");
date.value = editDate.join("\n");
var amount = document.getElementById("inputAmount");
amount.value = editAmount.join("\n");
var remarks = document.getElementById("inputRemarks");
remarks.value = editRemarks.join("\n");
}
if (name || date || amount || remarks) {
editName.splice([0], editName.length);
editDate.splice([0], editDate.length);
editAmount.splice([0], editAmount.length);
editRemarks.splice([0], editRemarks.length);
}
}
If you define an empty array
var editName = [];
and fill it with values you can empty it again with
editName = [];

Push links generated to Google SpreadSheet in JS (Google AppScripts)

I am using a script to automate form generation.
It basically loops over a list of elements, since each of them should have a different forms link.
How can I store the links generated corresponding to each group in a google spreadsheet?
I would like to have a spreadsheet in this way:
Group Link
138 https://docs.google.com/forms/idForm138
139 https://docs.google.com/forms/idForm139
Here's my code:
var lista_url=[]
var group=[137, 138, 139]
function createForm(group) {
// create & name Form
var item = "Speaker Information Form";
var form = FormApp.create(item)
.setTitle(item);
// single line text field
item = group;
form.addTextItem()
.setTitle(item)
.setRequired(true);
// multi-line "text area"
item = "Short biography (4-6 sentences)";
form.addParagraphTextItem()
.setTitle(item)
.setRequired(true);
// radiobuttons
item = "Handout format";
var choices = ["1-Pager", "Stapled", "Soft copy (PDF)", "none"];
form.addMultipleChoiceItem()
.setTitle(item)
.setChoiceValues(choices)
.setRequired(true);
// (multiple choice) checkboxes
item = "Microphone preference (if any)";
choices = ["wireless/lapel", "handheld", "podium/stand"];
form.addCheckboxItem()
.setTitle(item)
.setChoiceValues(choices);
var url_form= Logger.log('Published URL: ' + form.getPublishedUrl());
Logger.log('Group: '+group)
lista_url.push(url_form)
}
function generate_Form_links(group){
group.forEach(function(item, index){
console.log(item, index)
createForm(item)
}
}
generate_Form_links(group)
EDIT:
Implementing this raises this error: TypeError: infoArray.join is not a function
function excelformat(lista_url) {
var result_table = lista_url
var lineArray = [];
result_table.forEach(function(infoArray, index) {
var line = infoArray.join(" \t");
lineArray.push(index == 0 ? line : line);
});
var csvContent = lineArray.join("\r\n");
var excel_file = document.createElement('a');
excel_file.setAttribute('href', 'data:application/vnd.ms-excel;charset=utf-8,' + encodeURIComponent(csvContent));
excel_file.setAttribute('download', 'Visitor_History.xls');
document.body.appendChild(excel_file);
excel_file.click();
document.body.removeChild(excel_file);
}
excelformat(lista_url)
Not sure if I understand your task correctly. So, if you have the two arrays: group and links you can add their content in spreadsheet this way:
var group = [138, 139];
var links = ['https://docs.google.com/forms/idForm138','https://docs.google.com/forms/idForm139'];
function save_arrays_to_spreadsheet(group, links) {
var ss = SpreadsheetApp.openById(ss_id); // <-- put the spreadsheet ID here
var sheet = ss.getSheets()[0]; // let it be a first sheet
for (var i in group) sheet.appendRow([group[i], links[i]]); // add a row
}
And I don't understand what this function in your code is doing:
function generate_Form_links(group){
for (var group=0; group<=group.length ; group=i++){
createForm(group) //call our function for each value in list
}
}
It gets group (an array?) and converts it into zero var group = 0, and then there appears the variable i, etc. It all looks like an error to me.
Probably, I don't know, there should be:
function generate_Form_links(group) {
for (var i=0; i<=group.length; i++) { createForm(group[i]) }
}

Dynamic namedRange, Trying to print only cells with data in them

function readNamedRange() {
var app = SpreadsheetApp;
var activeSheet = app.getActiveSpreadsheet().getActiveSheet();
var listDown = activeSheet.getRange("listDown");
var result = activeSheet.getRange("listDown").getValues();
}
In the above code, my active sheet contains a namedRange which has the entire B column set to the namedRange called listDown. Cells B1 to B10 have data 1 through 10 in them.
I am trying to print only data cells with values in them using both for loop and an if statement inside it.
I have tried the following logic given below:
for(var i=0; i <result.length; i++){
if(result.length[i] != "" && result.length[i] != undefined ){
console.log(result);
}else{
console.log("namedRange is empty");
}
}
My above logic is not complete and I am unable to understand how to do it.
I believe your goal as follows.
You want to show the values of cells except for the empty cells at the log.
For this, how about this modification?
Modification points:
listDown is not used in your script.
The value retrieved by getValues() is 2 dimensional array. And your range is one column.
In this case, each value can be retrieved by result[i][0].
In your script, result.length[i] always becomes undefined.
At console.log(result), all values of result is shown.
In your case, result[i][0] != "" can be used for the if statement.
When above points are reflected to your script, it becomes as follows.
Modified script:
function readNamedRange() {
var activeSheet = SpreadsheetApp.getActiveSheet();
var result = activeSheet.getRange("listDown").getValues();
for (var i = 0; i < result.length; i++) {
if (result[i][0] != "") { // Modified
console.log(result[i][0]); // Modified
} else {
console.log("namedRange is empty");
}
}
}
References:
getValues()
Array
Added:
You want to show the values of only cells except for the empty cells.
For this, how about the following modified script?
The script in else was removed.
In order to reduce the process cost, var end = activeSheet.getLastRow() is used for the for loop.
Modified script:
function readNamedRange() {
var activeSheet = SpreadsheetApp.getActiveSheet();
var result = activeSheet.getRange("listDown").getValues();
var end = activeSheet.getLastRow();
for (var i = 0; i < end; i++) {
if (result[i][0] != "") {
console.log(result[i][0]);
}
}
}

restructure CSV data to create correct format in JSON

I'm working with some CSV data. Right now the CSV has a column called 'characteristic' which is one of three types, and a column called 'value', which contains the numerical value for the characteristic.
I'd like to change the structure of the data so that the columns are the characteristics themselves, and the values fall directly under those columns.
Here are screenshots of the tables, for clarity:
Currently:
What I'd like:
I changed things manually to give an example. The actual table I'll need to change is thousands of lines, so I'm hoping I can do this programmatically in some way.
The reason I need to restructure is that I need to transform the CSV to JSON, and the JSON needs to look like this:
[
{
"country":"afghanistan",
"iso3":"afg",
"first_indicator":3,
"second_indicator":5,
"third_indicator":3
},
{
"country":"united states",
"iso3":"usa",
"first_indicator":8,
"second_indicator":6,
"third_indicator":7
},
{
"country":"china",
"iso3":"chn",
"first_indicator":6,
"second_indicator":0.7,
"third_indicator":2
}
]
So - is there any way to take my CSV as it is now (first screenshot), and transform it to the JSON I want, without doing it all manually?
I've done a lot of searching, and I think maybe I just don't know what to search for. Ideally I would use javascript for this, but any suggestions welcome.
Thank you.
I made a JSFiddle for you, something like this should be what you want.
JavaScript
function Country(name, short){
this["country"] = name;
this["iso3"] = short;
}
function getCountryByName(name) {
for(var i = 0; i < countries.length; i++){
var country = countries[i];
if(country["country"] == name){
return country;
}
}
return null;
}
var csv = "country,shortname,characteristics,value\nafghanistan,afg,first_characteristic,3\nunited states,usa,first_characteristic,8\nchina,chn,first_characteristic,6\nafghanistan,afg,second_characteristic,5\nunited states,usa,second_characteristic,6\nchina,chn,second_characteristic,0.7\nafghanistan,afg,third_characteristic,3\nunited states,usa,third_characteristic,7\nchina,chn,third_characteristic,2"
var rows = csv.split("\n");
var countries = [];
if(rows.length > 0){
var header = rows[0];
var columns = header.split(",");
var countryIndex = columns.indexOf("country");
var shortnameIndex = columns.indexOf("shortname");
var characteristicsIndex = columns.indexOf("characteristics");
var valueIndex = columns.indexOf("value");
for(var i = 1; i < rows.length; i++) {
var row = rows[i];
var columns = row.split(",");
var name = columns[countryIndex];
var short = columns[shortnameIndex];
var characteristic = columns[characteristicsIndex];
var value = columns[valueIndex];
var country = getCountryByName(name);
if(!country){
country = new Country(name, short);
countries.push(country);
}
country[characteristic.replace("characteristic", "indicator")] = +value;
}
}
console.log(countries);
console.log(JSON.stringify(countries));
Output from the last line is this:
[{"country":"afghanistan","iso3":"afg","first_indicator":"3","second_indicator":"5","third_indicator":"3"},
{"country":"united states","iso3":"usa","first_indicator":"8","second_indicator":"6","third_indicator":"7"},
{"country":"china","iso3":"chn","first_indicator":"6","second_indicator":"0.7","third_indicator":"2"}]
My suggestion is to convert the CSV to JSON first. You can use an online tool.
When you have the JSON you can write a Javascript code to modify the JSON in the format you want.

Categories

Resources