Object with array in localstorage - javascript

I am trying to make an object with array, every object should have array of file names. I named the object as productid, which can have multiple file names. When the customer gives the productid, the file names must be displayed in the text area. I have the following code:
<!DOCTYPE html>
<html>
<title>W3.CSS</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://www.w3schools.com/lib/w3.css">
<script type="text/javascript">
var productid = []
var filename = []
function managerClick(){
console.log("manager", productid);
console.log("manager", filename);
productid.push(document.getElementById("productId").value);
filename.push(document.getElementById("names").value);
localStorage.setItem("filename", JSON.stringify(filename));
localStorage.setItem("productid", JSON.stringify(productid));
var result={}
productid.map(function(k){
result[k]=filename;
})
console.log(result);
document.getElementById('myTextarea').value = "";
document.getElementById('CustomerpId').value = "";
};
function customerClick(){
document.getElementById('myTextarea').value = "";
var CustomerpId = document.getElementById('CustomerpId').value;
var filenames = JSON.parse(localStorage.getItem("filename"));
var productIds= JSON.parse(localStorage.getItem("productid"));
var tempArr = [];
for(i=0; i< productIds.length; i++) {
if(productIds[i] == CustomerpId) {
tempArr.push(i);
}
}
for(i=0; i< tempArr.length; i++) {
document.getElementById('myTextarea').value += filenames[tempArr[i]] + ",";
}
};
</script>
<body>
<div class="w3-card-4 w3-margin" style="width:50%;">
<center>Manager</center>
<div class="w3-container">
Product Id: <input type="text" id="productId"><br></br>
File Name: <input type="text" id="names"><br></br>
<center><button class="w3-btn w3-dark-grey" onclick="managerClick()">Data Entered</button></center><br>
</div>
<center>Customer</center>
<div class="w3-container">
Product Id: <input type="text" id="CustomerpId"><br></br>
<center>
<button class="w3-btn w3-dark-grey" onclick="customerClick()">Click To get filename</button>
</center><br>
<textarea rows="4" cols="30" id="myTextarea"></textarea>
</div>
</div>
</body>
</html>
The issue with this code is that whenever I enter my productid in my customer section, the array of all file names is being displayed. I want to display only the array of a specific productid:
example: product1[ file1,file2,file3]
product2[ file1,file2,file3,file4]
product3[ file1]
the array in that product should be displayed, if a specific product is given then data in that product has to be displayed, the above code displays it like this:
inputs i gave 1 as productid "a,aa,aaa", 2as second productid and "b,bb,bbb" as file name. In my console a,aa,aaa and b,bb,bbb are been displayed in both the products i dont want this to happen. All a,aa,aaa should be in 1st product and all b,bb,bbb should be saved in 2nd product. Every product should display its own values.

Try this function:
function customerClick(){
document.getElementById('myTextarea').value = "";
var CustomerpId = document.getElementById('CustomerpId').value;
var filenames = JSON.parse(localStorage.getItem("filename"));
var productIds= JSON.parse(localStorage.getItem("productid"));
var tempArr = [];
for(i=0; i< productIds.length; i++) {
if(productIds[i] == CustomerpId) {
tempArr.push(i);
}
}
for(i=0; i< tempArr.length; i++) {
document.getElementById('myTextarea').value += filenames[tempArr[i]] + ",";
}
};
On Click of Get Field Name, You have to get id for which you want to show and then perform operations on productid array and filenames array.
EDIT : As per you mentioned in comments here is updated code:
function managerClick() {
var productid = document.getElementById("productId").value;
var filename = document.getElementById("names").value;
var oldItems = JSON.parse(localStorage.getItem(productid)) || [];
var newItem = filename;
oldItems.push(newItem);
localStorage.setItem(productid, JSON.stringify(oldItems));
}
function customerClick() {
document.getElementById('myTextarea').value = "";
var CustomerpId = document.getElementById('CustomerpId').value;
var productIds = JSON.parse(localStorage.getItem(CustomerpId));
for(i=0;i<productIds.length;i++) {
document.getElementById('myTextarea').value += productIds[i] + ",";
}
}
Hope this helps.

Related

Getting an Uncaught TypeError: Cannot set property 'onclick' of null with <script> at the end

I've looked at previous questions like this and cannot find the answer to my problem. I am working in javascript creating a checkout screen and I have two onclicks for two different html files but when I go to the html file for both it says that the other onclick is null. I have tried window.load and moving the script to the bottom of the
var cart = [];
var search = document.getElementById("addItem");
let placement = 0;
var cartElement = document.getElementById("showCart");
var cartTotal = document.getElementById("totalCart");
search.onclick = function(e) {
var userInput = document.getElementById("query").value;
var cartHTML = "";
e.preventDefault();
placement = 0;
for (i = 0; i < menu.length; i++) {
if (menu[i][0].includes(userInput)) {
cart.push(menu[i]);
placement++;
}
}
if (placement == 0) {
alert("Menu option not included. Please try again.");
}
cart.forEach((item, Order) => {
var cartItem = document.createElement("span");
cartItem.textContent = item[0] + " (" + item[1] + ")";
cartHTML += cartItem.outerHTML;
});
cartElement.innerHTML = cartHTML;
}
window.onload = function() {
var checkout = document.getElementById("addCartButton");
checkout.onclick = function(event) {
cart.forEach()
var cartTotalHTML = "";
event.preventDefault();
cart.forEach(Item, Order => {
var totalInCart = 0;
var writeCart = document.createElement("span");
totalInCart += Order[1];
});
writeCart.textContent = cartTotal += item[1];
cartTotalHTML = writeCart.outerHTML;
cartTotal.innerHTML = cartTotalHTML;
console.log(cartTotal);
}
}
<h3>Search for items in the menu below to add to cart</h3>
<form id="searchMenu">
<input type="search" id="query" name="q" placeholder="Search Menu..."></inpuut>
<input type = "Submit" name= "search" id="addItem" ></input>
</form>
<h4>Your cart: </h4>
<div class="Cart">
<div id="showCart"></div>
</div>
<script src="Script.js"></script>
<h4>Cart</h4>
<button id='addCartButton' class="Cart">Add Cart</button>
<div class="ShowCart">
<div id="totalCart"></div>
</div>
<script src="Script.js"></script>

childNode.remove() doesn't seem to be working

I'm writing a google sheets add on that helps you track data as you play a game. In the sidebar, you can search for a monster in the game and after you hit the submit button the monster's stats, a list of what items they drop after a kill, and a link to the wiki is rendered on screen.
The problem I'm having is that when you search a new monster after having already searched for one, the old items from the drop section won't get removed. The other sections on stats and the wiki link will change, but instead of removing the old drop items, the new items just get added to the end of the list.
I've tried using parent.removeChild() and childNode.remove() and neither seem to do anything and I'm wondering if its because of how google apps script works.
Here is the html for the sidebar itself: note that include() is a custom function that google recommends you add to your script so you can import other files.
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<?!= include('Info sidebar styles'); ?>
</head>
<body>
<form id="monsters">
<input class="monsterInput" type="text"placeholder="Monster Name" name="monsterName" />
<input class="monsterInput" type="text" placeholder="Monster Level" name="monsterLvl" />
<button id="submit">Search</button>
</form>
<div id="output">
</div>
<?!= include('sidebar script'); ?>
</body>
</html>
Here's the code for sidebar script:
<script>
if (document.readyState == 'loading') {
document.addEventListener('DOMContentLoaded', ready)
} else {
ready()
}
function ready(){
// create the divs that are later filled with info
var output = document.getElementById("output");
var stats = document.createElement("div");
stats.id = "statsDiv";
var drops = document.createElement("div");
drops.id = 'dropDiv';
var list = document.createElement("div");
list.id = "dropList";
var wiki = document.createElement("div");
wiki.id = "wiki";
output.appendChild(stats);
output.appendChild(drops);
output.appendChild(wiki);
var index = 0;
// the onSuccess for the onClick eventHandler. data is an object returned from the function call below
function onSuccess(data) {
console.log(`first index ${index}`);
// if the submit button has already been pushed and added the droplist to the DOM, increase the index
if(drops.getElementsByClassName("dropItem")[0]){
index++;
console.log(`second index ${index}`);
};
console.log(index);
// get the stats
var hitpoints = data.hitpoints;
var attackarray = data["attack_type"]
var attackTypes = '';
var attack1 = attackarray[0];
var attack2 = attackarray[1];
var attack3 = attackarray[2];
var attack4 = attackarray[3];
if(attackarray.length === 1){
attackTypes = attack1;
} else if (attackarray.length === 2){
attackTypes = `${attack1}, ${attack2}`;
} else if (attackarray.length === 3){
attackTypes = `${attack1}, ${attack2}, ${attack3}`;
} else if (attackarray.length === 4){
attackTypes = `${attack1}, ${attack2}, ${attack2}, ${attack4}`;
}
var attLvl = data["attack_level"];
var defLvl = data["defence_level"];
var magicLvl = data["magic_level"];
var rangeLvl = data["ranged_level"];
var maxHit = data["max_hit"];
var aggro = '';
if(data.aggressive){
aggro = "Yes";
} else {
aggro = "No";
}
var speed = data["attack_speed"];
// put the stats into html form
var statsInner =
`<h2> Stats </h2>
<ul id="statsList">
<li>Hitpoints: ${hitpoints}</li>
<li>Attack Level: ${attLvl}</li>
<li>Defense Level: ${defLvl}</li>
<li>Magic Level: ${magicLvl}</li>
<li>Ranged Level: ${rangeLvl}</li>
<li>Attack Style: ${attackTypes} </li>
<li>Attack Speed: ${speed}</li>
<li>Max Hit: ${maxHit} </li>
<li>Aggressive? ${aggro} </li>
</ul>`;
stats.innerHTML = statsInner;
drops.innerHTML = '<h2>Drops</h2>';
// Put the wiki url into HTML
var wikiURL = data["wiki_url"];
var wikiInner = `<p>For more info check out this monsters page on the wiki, <a href=${wikiURL}>here</a>.</p>`;
wiki.innerHTML = wikiInner;
// get the drop information and put it in html form. make the data-id attribute of each object equal the value of index
data.drops.forEach(function (item) {
var name = item.name;
var quant = item.quantity;
var members = '';
if(item.members){
members = "(m)";
}
var nameQM = `${name} (x${quant}) ${members}`;
var rarity = (item.rarity) * 100;
var rare = rarity.toFixed(2);
var nameNode = document.createElement("div");
var itemList =
`<p>${nameQM}</p>
<br>
<p> Rarity: ${rare} percent </p>`;
nameNode.innerHTML = itemList;
nameNode.className = "dropItem";
nameNode.dataset.id = index;
list.appendChild(nameNode);
})
drops.appendChild(list);
// if the drop item has a data-id that doesn't match the current index, remove it from the DOM.
var dropArray = list.getElementsByClassName("dropItem");
for(var i = 0; i < dropArray.length; i++){
var item = dropArray[i];
if(item.dataset.id != index){
item.remove();
}
}
}
//add the event listener to the submit button. getMonsterData makes an API call, parses the data, and returns an object filled with the data we add to the DOM through the success handler
document.getElementById("submit").addEventListener("click", function (e) {
e.preventDefault();
var parent = e.target.parentElement;
var monsterName = parent.elements[0].value;
var monsterlvl = parent.elements[1].value;
google.script.run.withSuccessHandler(onSuccess).getMonsterData(monsterName, monsterlvl);
});
}
</script>

Adding an event listener to DOM elements pushed into an array

Apologies for the poorly-worded question. It's my first question here!
I am trying to make an application whereby one can log the scores of players from any game and see the results at the end of the game (see the code snippet below).
So far, I have managed to push players and their scores (initially empty arrays) into the main array and thereby presented these players in a list (see below):
HTML
<h1>Score Keeper</h1>
<input type="text" placeholder="Enter Player's Name" id="enterPlayer">
<input type="submit" id="enterPlayerBtn" value="Enter Player">
<div>
<ul id="scoreConsole"></ul>
</div>
JavaScript
var players = [];
var enterPlayer = document.querySelector("#enterPlayer");
var enterPlayerBtn = document.querySelector("#enterPlayerBtn");
var scoreConsole = document.querySelector("#scoreConsole");
//PUSHES OBJECTS INTO ARRAYS OF PLAYERS
addPlayer = () => {
var entered = enterPlayer.value;
players.push(
{
player: entered,
score: []
}
);
enterPlayer.value = "";
}
//DISPLAYS PLAYERS ENTERED INTO ARRAY:
var i=0;
createdPlayers = () => {
var toAdd = document.createDocumentFragment();
var newLi = document.createElement("li");
newLi.className="each-player";
newLi.innerHTML = players[i].player + " " + "<input type='number' placeholder='enter score' class='enterScore'>" + "<input type='submit' class='submitScoreBtn'>";
toAdd.appendChild(newLi);
i++;
scoreConsole.appendChild(toAdd);
}
enterPlayerBtn.addEventListener("click", () => {
addPlayer();
createdPlayers();
});
This gives me a list with the players' names, inputs to enter scores and buttons to log the scores. So far, so good.
But...
I am just trying to get each button to work. As you can see above, I gave each submit button classes ("submitScoreBtn"). I'm at the stage where I want to make sure that my new buttons work. Here's my code so far:
var enterScore = document.querySelectorAll(".enterScore");
var submitScore = document.querySelectorAll(".submitScoreBtn");
for (var x = 0; x < submitScore.length; x++){
submitScore[x].addEventListener("click", () => {
alert("selected");
});
}
I initially was getting errors without adding a for loop. Now I don't get any errors, but I also don't get any alerts. I'm just not sure why these buttons do not work.
Please see the code snippet below.
var players = [];
var enterPlayer = document.querySelector("#enterPlayer");
var enterPlayerBtn = document.querySelector("#enterPlayerBtn");
var scoreConsole = document.querySelector("#scoreConsole");
//PUSHES OBJECTS INTO ARRAYS OF PLAYERS
addPlayer = () => {
var entered = enterPlayer.value;
players.push(
{
player: entered,
score: []
}
);
enterPlayer.value = "";
}
//DISPLAYS PLAYERS ENTERED INTO ARRAY:
var i=0;
createdPlayers = () => {
var toAdd = document.createDocumentFragment();
var newLi = document.createElement("li");
newLi.className="each-player";
newLi.innerHTML = players[i].player + " " + "<input type='number' placeholder='enter score' class='enterScore'>" + "<input type='submit' class='submitScoreBtn'>";
toAdd.appendChild(newLi);
i++;
scoreConsole.appendChild(toAdd);
}
enterPlayerBtn.addEventListener("click", () => {
addPlayer();
createdPlayers();
});
var enterScore = document.querySelectorAll(".enterScore");
var submitScore = document.querySelectorAll(".submitScoreBtn");
for (var x = 0; x < submitScore.length; x++){
submitScore[x].addEventListener("click", () => {
alert("selected");
});
}
<html>
<head>
<title>Score</title>
</head>
<body>
<h1>Score Keeper</h1>
<input type="text" placeholder="Enter Player's Name" id="enterPlayer">
<input type="submit" id="enterPlayerBtn" value="Enter Player">
<div>
<ul id="scoreConsole"></ul>
</div>
<script src="game.js"></script>
</body>
</html>
Being as you're dynamically creating the buttons, it might be easier to simply add the function to the button's onclick.
You can still access the event object from this click by sending it as a parameter, like:
<input type='submit' onclick='submitScoreClick(event)' class='submitScoreBtn'>
var players = [];
var enterPlayer = document.querySelector("#enterPlayer");
var enterPlayerBtn = document.querySelector("#enterPlayerBtn");
var scoreConsole = document.querySelector("#scoreConsole");
//PUSHES OBJECTS INTO ARRAYS OF PLAYERS
addPlayer = () => {
var entered = enterPlayer.value;
players.push(
{
player: entered,
score: []
}
);
enterPlayer.value = "";
}
//DISPLAYS PLAYERS ENTERED INTO ARRAY:
var i=0;
createdPlayers = () => {
var toAdd = document.createDocumentFragment();
var newLi = document.createElement("li");
newLi.className="each-player";
newLi.innerHTML = players[i].player + " " + "<input type='number' placeholder='enter score' class='enterScore'>" + "<input type='submit' onclick='submitScoreClick(event)' class='submitScoreBtn'>";
toAdd.appendChild(newLi);
i++;
scoreConsole.appendChild(toAdd);
}
enterPlayerBtn.addEventListener("click", () => {
addPlayer();
createdPlayers();
});
var enterScore = document.querySelectorAll(".enterScore");
var submitScore = document.querySelectorAll(".submitScoreBtn");
function submitScoreClick (e) {
alert("selected");
};
<html>
<head>
<title>Score</title>
</head>
<body>
<h1>Score Keeper</h1>
<input type="text" placeholder="Enter Player's Name" id="enterPlayer">
<input type="submit" id="enterPlayerBtn" value="Enter Player">
<div>
<ul id="scoreConsole"></ul>
</div>
<script src="game.js"></script>
</body>
</html>
At the point in time when this code is run:
for (var x = 0; x < players.length; x++){
submitScore[x].addEventListener("click", (event) => {
event.alert("selected");
});
}
players.length is equal to 0. So the code is essentially never executed.
remove the for loop and add this code
document.addEventListener('click', function (event) {
if ( event.target.classList.contains( 'submitScoreBtn' ) ) {
alert("selected");
}
}, false);
var players = [];
var enterPlayer = document.querySelector("#enterPlayer");
var enterPlayerBtn = document.querySelector("#enterPlayerBtn");
var scoreConsole = document.querySelector("#scoreConsole");
//PUSHES OBJECTS INTO ARRAYS OF PLAYERS
addPlayer = () => {
var entered = enterPlayer.value;
players.push({
player: entered,
score: []
});
enterPlayer.value = "";
}
//DISPLAYS PLAYERS ENTERED INTO ARRAY:
var i = 0;
createdPlayers = () => {
var toAdd = document.createDocumentFragment();
var newLi = document.createElement("li");
newLi.className = "each-player";
newLi.innerHTML = players[i].player + " " + "<input type='number' placeholder='enter score' class='enterScore'>" + "<input type='submit' class='submitScoreBtn'>";
toAdd.appendChild(newLi);
i++;
scoreConsole.appendChild(toAdd);
}
document.addEventListener('click', function(event) {
if (event.target.classList.contains('submitScoreBtn')) {
alert("selected");
}
}, false);
enterPlayerBtn.addEventListener("click", () => {
addPlayer();
createdPlayers();
});
var enterScore = document.querySelectorAll(".enterScore");
<html>
<head>
<title>Score</title>
</head>
<body>
<h1>Score Keeper</h1>
<input type="text" placeholder="Enter Player's Name" id="enterPlayer">
<input type="submit" id="enterPlayerBtn" value="Enter Player">
<div>
<ul id="scoreConsole"></ul>
</div>
<script src="game.js"></script>
</body>
</html>
The easiest solution is to use variables and createElement just like you do with toAdd. This way each created entry will remember its own inputs (local variables to the function), and you can use for example the score input variable in the click handler without confusion of which number input belongs to which entry.
I removed the class for the inputs because it's not needed to select them anymore, but you can still add some for styling for example. If you want to add classes to select them all, be sure to run querySelectorAll each time, so that added elements are actually selected.
var players = [];
var enterPlayer = document.querySelector("#enterPlayer");
var enterPlayerBtn = document.querySelector("#enterPlayerBtn");
var scoreConsole = document.querySelector("#scoreConsole");
//PUSHES OBJECTS INTO ARRAYS OF PLAYERS
var addPlayer = () => {
var entered = enterPlayer.value;
players.push(
{
player: entered,
score: []
}
);
enterPlayer.value = "";
}
//DISPLAYS PLAYERS ENTERED INTO ARRAY:
var i=0;
var createdPlayers = () => {
var toAdd = document.createDocumentFragment();
var newLi = document.createElement("li");
newLi.className="each-player";
newLi.innerHTML = players[i].player + " ";
var enterScore = document.createElement("input");
enterScore.type = 'number';
enterScore.placeholder = 'enter score';
var submitScore = document.createElement("input");
submitScore.type = 'submit';
submitScore.addEventListener("click", () => {
alert("selected score: " + enterScore.value);
});
newLi.appendChild(enterScore);
newLi.appendChild(submitScore);
toAdd.appendChild(newLi);
i++;
scoreConsole.appendChild(toAdd);
}
enterPlayerBtn.addEventListener("click", () => {
addPlayer();
createdPlayers();
});
<html>
<head>
<title>Score</title>
</head>
<body>
<h1>Score Keeper</h1>
<input type="text" placeholder="Enter Player's Name" id="enterPlayer">
<input type="submit" id="enterPlayerBtn" value="Enter Player">
<div>
<ul id="scoreConsole"></ul>
</div>
<script src="game.js"></script>
</body>
</html>

Uncaught TypeError: Cannot set property 'status' of undefined at HTMLInputElement.updateData JSON Javasscript

I have this code which seems to work perfectly fine till I add the last line. To the best of my knowledge the last line too has no mistake but I keep getting the error
firstProjectDifferent_style.html?_ijt=gs7id9qc5jeql1hvnl2cgn56i4:38 Uncaught TypeError: Cannot set property 'status' of undefined
at HTMLInputElement.updateData
Below is the entire code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JSON Excercise</title>
</head>
<body>
<h1>Learn JSON</h1>
<div id="output">
<ul id="taskList">
</ul>
</div>
<script type="text/javascript">
var data = '[{"info":"Cut Grass","status":false},{"info":"Clean Room","status":true},' +
'{"info":"Go to Gyn","status":true},{"info":"Make Dinner Late","status":false}]';
var dataJSON = JSON.parse(data);
var output = document.getElementById("output");
var taskList = document.querySelector("#taskList");
for (var key in dataJSON){
var status = dataJSON[key].status?"checked":"";
var html = "<li>"+ dataJSON[key].info + "<input type='checkbox' value='" + dataJSON[key].info + "'" + status +"></li>";
taskList.innerHTML += html
}
addEvent();
function addEvent() {
var checkBoxes = document.querySelectorAll("#taskList li input[type='checkbox']");
for (var index in checkBoxes){
checkBoxes[index].onchange = updateData;
}
}
function updateData() {
var key = event.target.value;
console.log(key, event.target.checked);
dataJSON[key].status = event.target.checked; //This line is causing the problem
}
</script>
</body>
</html>
Your first issue is in this lines:
function updateData() {
var key = event.target.value;
Change to (the parameter is required):
function updateData(event) {
var key = event.target.value;
Second, you cannot access an array of object like this:
dataJSON[key]
Another issue is your taskList: i canged it to document.querySelector('#taskList')
I would suggest to use .filter().
The working code may be:
var data = '[{"info":"Cut Grass","status":false},{"info":"Clean Room","status":true},' +
'{"info":"Go to Gyn","status":true},{"info":"Make Dinner Late","status":false}]';
var dataJSON = JSON.parse(data);
var output = document.getElementById("output");
var taskList = document.querySelector("#taskList");
for (var key in dataJSON){
var status = dataJSON[key].status?"checked":"";
var html = "<li>"+ dataJSON[key].info + "<input type='checkbox' value='" + dataJSON[key].info + "'" + status +"></li>";
document.querySelector('#taskList').innerHTML += html;
}
addEvent();
function addEvent() {
var checkBoxes = document.querySelectorAll("#taskList li input[type='checkbox']");
for (var index in checkBoxes){
checkBoxes[index].onchange = updateData;
}
}
function updateData(event) {
var key = event.target.value;
dataJSON.filter(function(a, b) {
return a.info == key;
})[0].status = event.target.checked;
console.log(key, event.target.checked);
}
<h1>Learn JSON</h1>
<div id="output">
<ul id="taskList">
</ul>
</div>

Find matched letter from each word in javascript array

I have an array in javascript like that :
var books = ['spring','last night','sweet heart','the sky','tomorrow'] ;
I have textarea
<textarea id="text" name="textpreview" class="text"></textarea>
So what I want is when I enter letter s then I will get two suggestions books just the first word not the second word I mean not sky Just spring and sweet heart .
I will get two spans
<textarea id="text" name="textpreview" class="text"></textarea>
<span>spring</span>
<span>sweet heart</span>
If I type again after s the p letter like sp in textarea then I will get just spring
<textarea id="text" name="textpreview" class="text"></textarea>
<span>spring</span>
and so on .
If I type n I will get nothing.
If I type t I will get tomorrow and the sky
Hope it can be done . Thanks for your support .
This help you :
<html>
<head>
<title></title>
</head>
<body>
<textarea id="text" name="textpreview" class="text"></textarea>
<p id="x"></p>
<script>
var x = document.getElementById("x");
var books = ['spring','last night','sweet heart','last night','the sky','tomorrow','tomorrow'];
var txt = document.getElementById("text");
txt.onkeyup = function(event) {
var str = "";
var arr = [];
var index = (txt.value).indexOf("#");
if(index !== -1 && (txt.value).substr(index + 1).length > 0) {
var value = (txt.value).substr(index + 1);
value = value.replace(/[\.\+\*\\\?]/g,'\\$&');
var patt = new RegExp("^" + value);
for(var i=0; i<books.length; i++) {
if(patt.test(books[i]) && arr.indexOf(books[i]) === -1) {
arr.push(books[i]);
}
}
}
if (arr.length < 1 )
x.innerHTML = "";
else {
for(var i=0; i<arr.length; i++)
str+=arr[i]+"<br>";
x.innerHTML = str;
}
}
</script>
</body>
</html>
This problem consists of two parts: Reading and writing your input/output from/to the DOM, and filtering your array books.
The reading and writing part should be easy, there are plenty of guides on how to achieve this.
To filter the books array, JavaScript offers a number of helpful functions:
var books = ['spring','last night','sweet heart','the sky','tomorrow'];
var input = 'S';
var result = books.filter(function(book) {
return book.toLowerCase().indexOf(input.toLowerCase()) === 0;
}).slice(0, 2);
console.log(result); // ['spring', 'sweet heart']
#TimoSta is correct that this is a two-part problem.
I expanded on his code a bit using angular to display the results in the DOM.
http://jsfiddle.net/kcmg9cae/
HTML:
<div ng-controller="MyCtrl">
<textarea id="text" name="textpreview" class="text" ng-model="startsWith"></textarea>
<span ng-repeat="book in sortedBooks()">{{ book }}</span>
</div>
Javascript:
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.books = ['spring','last night','sweet heart','the sky','tomorrow'];
$scope.sortedBooks = function () {
var sortedBooks = [];
for (var i = 0; i < $scope.books.length; i++){
if ($scope.books[i].toLowerCase().indexOf($scope.startsWith.toLowerCase()) === 0)
sortedBooks.push($scope.books[i]);
}
return sortedBooks;
}
}

Categories