Javascript: Looping a Textarea list into an Array - javascript

I am trying to retrieve information typed into a Textarea element, load that into an array so that I can output a string. To be more specific, I have an excel sheet with a number, a name, and another number. i want to paste that list into the Textarea, populate an array and output messages custom to the array information per line. (So a message that would have the number, the name, and then another number, go to the next line and do a whole new message with the next three array indexes.)
I can create an array from the Textfield using a for loop and the split() method. Now how do I get Javascript to go to the next line and treat that as a new message and load the new indexes for my next message for as long as the length of the list?
this is my test script so far.
function resultFunction(){
var x = document.getElementById("statusForm");
var text = " ";
var i;
for (i = 0; i < x.length; i++){
text += x.elements[i].value;
}
var loadArray = text.split(",");
var loadID = loadArray[0];
var carrierID = loadArray[1];
var poID = loadArray[2];
console.log(loadArray);
console.log(loadArray.length);
document.getElementById("resultsArea").innerHTML = "Hello " + carrierID + ", <br />Please send me status on the following loads <br />" + loadID + " <br />Thank you!";
};

I think you have to read line by line from text area and split each line into values as you want.
For e.g
var lines = document.getElementById("statusForm").split('\n');
for (i = 0; i < lines .length; i++){
var text = x.elements[i].value;
var loadArray = text.split(",");
var loadID = loadArray[0];
var carrierID = loadArray[1];
document.getElementById("resultsArea").innerHTML = "Hello " + carrierID + ", <br />Please send me status on the following loads <br />" + loadID + " <br />Thank you!";
}
Similiar to the above it will work

Related

How to get bottom-level properties from array of objects inside another array of objects in JavaScript

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>VR train search</title>
<!--
Data provided by https://www.digitraffic.fi/, used under the following license:
Creative Commons Attribution 4.0 International (CC BY 4.0)
Search for train connections through the VR API
https://www.digitraffic.fi/rautatieliikenne/#reittiperusteinen-haku
-->
</head>
<body>
<h3>Train search</h3>
<form>
<p>Ignore the search fields, I have hard-coded the stations in this example to make the code shorter. Just click Search trains.</p>
<label>From:</label>
<input type="text" id="departure_station">
<label>To:</label>
<input type="text" id="arrival_station">
<label>Date (yyyy-mm-dd):</label>
<input type="text" id="departure_date">
<input type="button" value="Search trains" onclick="searchTrains()">
</form>
<div id="onscreen_text"></div>
<script type="text/javascript">
function searchTrains() {
var departure_station = "HKI";
var arrival_station = "TPE";
var departure_date = "2019-02-12";
var xmlhttp = new XMLHttpRequest();
var json;
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
json = xmlhttp.responseText;
listResults(json);
}
if (xmlhttp.readyState == 4 && xmlhttp.status == 404) {
document.getElementById("onscreen_text").innerHTML = "<p>No search results found in the VR API.</p>";
}
}
// Get the data from the API
xmlhttp.open(
"GET", "https://rata.digitraffic.fi/api/v1/live-trains/station/" + departure_station + "/" + arrival_station + "?" + "departure_date=" + departure_date + "&limit=10", true);
xmlhttp.send();
}
function listResults(json) {
var results = JSON.parse(json);
console.log(results); // testing
var text = ""; // testing
// filter results for only passenger trains
var passengerTrains = [];
function getPassengerTrains() {
for (var i = 0; i < results.length; i++) {
if (results[i].trainCategory == "Long-distance" || results[i].trainCategory == "Commuter") {
passengerTrains.push(results[i]);
text = text + results[i].trainNumber + "<br>"; // testing
}
}
}
getPassengerTrains();
console.log(passengerTrains); // testing
// Get the desired properties from the filtered trains
// https://stackoverflow.com/questions/37750309/find-object-by-property-in-an-array-of-javascript-objects-inside-another-array
var station = passengerTrains.map(item => item.timeTableRows.stationShortCode);
console.log(station); // but this returns an array full of undefined
// Loop through array of train objects
for (var i = 0; i < passengerTrains.length; i++) {
console.log(passengerTrains[i]); // this seems to give the right result
// Loop through each train object to get timeTableRows subarray
for (var train in passengerTrains[i]) {
// make a new array named timetable
var timetable = passengerTrains[i].timeTableRows;
console.log(timetable);
// but this prints the same array 13 times = as many times as there are properties in the train object
/* Commented out because it freezes my browser
// Loop through each object in the timetable subarray to get the desired properties
for (var j=0; j < timetable.length; j++) {
console.log(timetable[j]);
for (var row in timetable[j]) {
text = text + "<p>From/to: " + timetable[j].stationShortCode;
text = text + "<br>Time: " + timetable[j].scheduledTime;
text = text + "<br>Train stopping: " + timetable[j].trainStopping;
text = text + "<br>Departure/arrival: " + timetable[j].type + "</p>";
}
} */
}
document.getElementById("onscreen_text").innerHTML = text;
}
}
</script>
</body>
</html>
I'm fairly new at programming and this is my first question here. I'm stuck trying to figure out how to get to the bottom level of a multilevel nested array/object thing in JavaScript.
What I'm working with is a parsed JSON file of train schedules of the type returned by this public API:
https://rata.digitraffic.fi/api/v1/live-trains/station/HKI/TPE?departure_date=2019-02-12
The parsed result is an array of train objects with a subarray named timeTableRows full of objects with properties such as stationShortCode: "HKI", scheduledTime: "2019-02-12T05:04:00.000Z", etc. I want to get to these bottom-level properties.
Screenshot from console for clarity
I tried the answer given here:
Find object by property in an array of JavaScript objects inside another array
But I can't figure out how to make it work for me, since I don't need to find a certain index but only a property by a certain name, and my attempts only return "undefined". I'm not at all familiar with ES5, so I would appreciate some beginner-friendly examples.
I commented out the rest of the for loops, since they created an iterating monstrosity that froze my browser. Is there any way to get to the bottom level of this kind of structure without looping multiple times through everything?
js snippet removed
function fetchNestedObject(prop, obj) {
let keys = prop.split('.');
keys[0] = obj[keys[0]];
return keys.reduce((a, b) => a && a[b]);
}
Usage:
fetchNestedObject('v.a.d.0', {v: {a: {d: [1]}}})
You could use Ramda for this ,https://ramdajs.com/docs/#path.
This will give you the value to your desired property, by typing the path, so you could use it as follow:
R.map(train => {
train_id:train.trainNumber,
timeTableRows:R.path(["path","to","property"],train)
}, trains)
Thank you for the answers above, I will note them for later use, although they are too advanced for my current level of JS knowledge. Right now I managed to create a series of nesting for loops that seems to do what I want it to do, but I will be happy to receive further comments or improvements on this solution.
To summarize, the problem was extracting data four levels down from the properties of an object inside an array, which is inside another object inside the top-level array (a parsed JSON response).
// passengerTrains is the top-level array
for (var i = 0; i < passengerTrains.length; i++) {
var train = passengerTrains[i]; // each train is an object
//console.log(train);
var trainNumber = train.trainNumber;
//console.log(trainNumber);
// Loop through array of timeTableRows inside each train object
for (var j = 0; j < train.timeTableRows.length; j++) {
var row = train.timeTableRows[j]; // each row is an object
// console.log(row);
// Print out only the data that we want
// The variables dep and arr are defined elsewhere in the code
if (row.stationShortCode == dep && row.type == "DEPARTURE") {
text = text + "Train " + trainNumber + ": Departure from " + departure_station + " at " + row.scheduledTime + "<br>";
console.log("Train " + trainNumber + ": Departure from " + departure_station + " at " + row.scheduledTime);
}
if (row.stationShortCode == arr && row.type == "ARRIVAL") {
text = text + "Train " + trainNumber + ": Arrival at " + arrival_station + " at " + row.scheduledTime + "<br><br>";
console.log("Train " + trainNumber + ": Arrival at " + arrival_station + " at " + row.scheduledTime);
}
}
document.getElementById("onscreen_text").innerHTML = text;
}

adding style to items in an array

I am doing a madlibs-type program. Prompts ask for words, which are then added to a string. I would like the words used from the prompts to be underlined when they are displayed with the rest of the string. I have created an array with all the prompts. Now, I just need to know how to run through that array and change the text-decoration to "underline". I know I need to use a for-loop through the array, but not sure of how to approach it.
What is the best way to make this happen?
HTML:
<body>
<div id = "story-space">
</div>
<script src = "madlibs.js"></script>
</body>
JS:
var prompt1 = prompt("Enter a animal.");
var prompt2 = prompt("Enter a city.");
var prompt3 = prompt("Enter an activity.");
var prompts = [prompt1, prompt2, prompt3, prompt4];
var text = "There was once was a " + prompt1 + " from " + prompt2 + " who liked to " + prompt3 + "."
document.getElementById("story-space").innerHTML = text;
Why can you add the html style like this
var text = "There was once was a <span style='text-decoration:underline'>" + prompt1 + "</span> from <span style='text-decoration:underline'>" + prompt2 + "</span> who liked to <span style='text-decoration:underline'>" + prompt3 + "</span>."
one simple way you can do it it as follows, note that you need to check for empty strings returned from prompt though, which is not handled in this answer,
var questions = ['an animal', 'a city', 'an activity'],
answers = [];
// create source string with placeholders that
// can be replaced with values in from prompts
var sourceText = "There was once was a {0} from {1} who liked to {2}."
//loop thru questions array and store answers in 'answers' variable
for (var q = 0; q < questions.length; q++) {
//create answer as span element
var question = questions[q],
answer = '<span style="text-decoration:underline;">';
answer += prompt('Enter ' + question);
answer +='</span>';
//update source text's 'qth' placeholder with answer
sourceText = sourceText.replace( new RegExp( "\\{" + q + "\\}", "g" ), function() {
return answer;
});
}
//update the target element's innerHTML
document.getElementById("story-space").innerHTML = sourceText;
You can try something like this by mapping all the prompts with an underline class.
var prompt1 = prompt("Enter a animal.");
var prompt2 = prompt("Enter a city.");
var prompt3 = prompt("Enter an activity.");
var prompts = [prompt1, prompt2, prompt3];
prompts = prompts.map(prompt => `<span class="underline">${prompt}</span>`)
var text = "There was once was a " + prompts[0] + " from " + prompts[1] + " who liked to " + prompts[1] + "."
document.getElementById("story-space").innerHTML = text;
.underline {
text-decoration: underline;
}
<div id = "story-space">
</div>
You can also try something like below where you just provide the pre-text for your prompt and let the Map and Reduce do the rest of the job for you.
let textPromptMap = new Map();
textPromptMap.set("There was once was a ", prompt("Enter a animal."))
textPromptMap.set(" from ", prompt("Enter a city."))
textPromptMap.set(" who liked to ", prompt("Enter an activity."))
const text = [...textPromptMap.keys()]
.reduce((a, b) =>
`${a}${b}<span class="underline">${textPromptMap.get(b)}</span>`, ""
)
document.getElementById("story-space").innerHTML = text;
.underline {
text-decoration: underline;
}
<div id = "story-space">
</div>

How to find a particular value in a string in js

I have a data like this,
var str = "#data time #city";
My goal is to make this as
var str = <a src="www.test/data">#data</a> time <a src="www.test/city">city</a>
I mean in my string where ever I found # its next value i.e data should be set as a param to the link www.test/{{param}} and should be surrounded with a link.Can any one suggest help.Thanks.
For this case, the String.replace() function will help you:
var str = "#data time #city"
str = str.replace(/#(\S+)/g, '#$1')
output.textContent = str
clickable.innerHTML = str
#output { font-family: courier }
<div id="output"></div>
<div id="clickable"></div>
The following code converts you data to the expected output.
The document.write(..) are for debug.
var data='#data time #city';
var hashtags = data.match(/#\S+/g);
document.write('before: ' + data + '</br>');
for (j = 0; j < hashtags.length; j++) {
// remove # from hashtag
var tag = hashtags[j].substring(1, hashtags[j].length);
// create the link
var link = '< a src="www.test/' + tag + '>#' + tag + '< / a > ';
// replace hashtag with link
data=data.replace(hashtags[j], link);
}
document.write('after: ' + data);

why is only the last item is showing and not all of them

I am using the code below to call a php page that displays all the products and then parse them and display them on the string. This was working fine last week displaying all the results however now it has seem to have broken and only displays the last results from the database and after several days and painful hour staring at my screen i am starting to go mad and could do with some help.
function display(results) {
article = document.getElementById("homeArticle");
item = '';
for (var i = 0; i < results.length; i++){
var item = results[i];
var name = item.P_NAME;
var description = item.P_DESCRIPTION;
var price = item.P_PRICE;
// next I add to the string that we want to place on the page
item = '<section id="homePageSection"> <p>Name:' + name + '</p><p>Description:' + description + '</p><p>Price:' + price + '</p></section>';
};
article.innerHTML = item;
}
function getItems() {
var xhr = new XMLHttpRequest();
xhr.onload = function() {
var results = JSON.parse(this.responseText);
display(results.rows);
};
xhr.open("GET", "displayData.php");
xhr.send();
}
window.addEventListener("load", getItems);
if anyone could have any pointers that would help massively thank you!
You needed two variables. One that you use to build up the html string and one to hold each item from the results array.
Change your code to this:
function display(results) {
article = document.getElementById("homeArticle");
var html = '';
for (var i = 0; i < results.length; i++){
var item = results[i];
var name = item.P_NAME;
var description = item.P_DESCRIPTION;
var price = item.P_PRICE;
// next I add to the string that we want to place on the page
html += '<section id="homePageSection"> <p>Name:' + name + '</p><p>Description:' + description + '</p><p>Price:' + price + '</p></section>';
};
article.innerHTML = html;
}
That way you will append the html strings rather than overwrite the prior one.
Also consider making sure that each html element has a unique id, you could do this by appending i to the id e.g.
html += '<section id="homePageSection-'+i+'"> <p>Name:' + name + '</p><p>Description:' + description + '</p><p>Price:' + price + '</p></section>';
Concat the item string, and don't use duplicate IDs, but classes instead:
item += '<section class="homePageSection"> <p>Name:' + name + '</p><p>Description:' + description + '</p><p>Price:' + price + '</p></section>';
What you were doing is overwriting item on each iteration, which I why you only get the last one.
UPDATE
Forgot to provide the code for that last sentence I wrote. To avoid overwriting it, either use a different variable (as in the other answer), or simply assign the values directly without creating unnecessary variables, like this:
for (var i = 0; i < results.length; i++){
item += '<section class="homePageSection"> <p>Name:' +
results[i].P_NAME +
'</p><p>Description:' +
results[i].P_DESCRIPTION +
'</p><p>Price:' +
results[i].P_PRICE +
'</p></section>';
}

Running Display in textarea - JavaScript

I was wondering how to keep outputs saved in the textarea box..
I'm writing a javascript program to translate english words to pig latin, so hello would be ellhay.
Anyways, say I type in "are" and in the textarea it translates it to "reaay" and then I type in "hello" (translation "ellohay") the textarea should output "ellohay" and "reaay" under it
I've tried this (edit now trying with array called outputs):
function printLatinWord() {
<!--
var outputs = new Array();
var input = document.form.english.value;
var lowercase = input.toLowerCase();
var fininput = lowercase.split (" ");
var output = "";
for (i = 0; i < fininput.length; i++) {
var result = fininput[i];
output += result.substring (1, result.length) + result.substring(0,1) + "ay ";
document.form.piglat.value = output + "\n";
var j = 0;
output = outputs[j];
j++;
}
/*
var newtext = "\n";
document.form.piglat.value = newtext + document.form.piglat.value;
//trying to keep running display of conversions
var newtext = ("\n");
output += newtext;*/
}
Basically nothing new happens with
At the end the var newtext is supposed to be where the outputs are stored.. but I'm not sure exactly how to get the values from the textarea and keep them there to be displayed under new outputs, if that makes sense.
document.form.piglat.value += newtext; appends newtext to the existing value. If you want it prepended instead, use
document.form.piglat.value = newtext + document.form.piglat.value;

Categories

Resources