Search by pressing the enter key on keyboard - javascript

Trying to also search by pressing enter key. Works with the button but for some reason the code i have for the key press is not working.
Javascript:
function displayMatches() {
const searchText = document.querySelector('.search').value;
const matchArray = findMatches(searchText, name);
const html = matchArray.map(place => {
const regex = new RegExp(searchText);
const nameName = place.name.replace(regex, `<span class="hl">${searchText}</span>`);
return `
<a href="${place.url}" target="_blank">
<li>
<span class="name">${nameName} <br> ${(place.price)}</span>
<img src="${place.imgurl}" alt="Drink Image" height="87.5" width="100">
</li>
</a>
`;
}).join('');
suggestions.innerHTML = html;
}
const suggestions = document.querySelector('.suggestions');
const searchBtn = document.querySelector('.btn-search');
searchBtn.addEventListener('click', displayMatches);
var input = document.getElementById('.search');
input.addEventListener("keyup", function(event) {
if (event.keyCode === 13) {
event.preventDefault();
document.getElementById('.btn-search').click();
}
});

In:
document.getElementById('.btn-search').click();
Are you sure .btn-search is a id property? Seems like a class property. You cannot get the element with getElementById if the "btn-search" isn't the id of the element.
And you don't need to set "." (class) or "#" (id) on the getElementById (getElementById it's only to get elements by id, so you don't need to tell the script the property type you searching).

As the user William Carneiro stated, the issue is the . character.
The function getElementById just receive the id, not a selector. Check documentation
Change this line:
var input = document.getElementById('.search');
With something like this:
var input = document.getElementById('search');
... or this:
var input = document.querySelector('#search');
Also, make sure that your element has id="search", it seems that probably you want to find an element with the class search instead.
var input = document.querySelector('.search');

I found this and I think it can helped you
JavaScript:
function myFunction(event) {
var x = event.keyCode;
if (x == 27) {
// 27 is the ESC key
alert ("You pressed the Escape key!");
}
}

Ok most of your code was working
A few things to note
When using query selector and calling a class use the class name with the dot'.search-btn'
When using getElementById remember there is no Dot 'search-btn'
Also I think I added an id in few places make sure your html tags have Id attributes to them before using getElementById i.e class='search-btn' id='search-btn' ...>
Other than that your code works
function displayMatches() {
const searchText = document.querySelector('.search').value;
// the rest of your code here
console.log("enter Worked Searching" );
}
const suggestions = document.querySelector('.suggestions');
const searchBtn = document.querySelector('.btn-search');
searchBtn.addEventListener('click', displayMatches);
var input = document.getElementById('search');
input.addEventListener("keyup", function(event) {
if (event.keyCode === 13) {
event.preventDefault();
document.getElementById('btn-search').click();
}
});
<input class="search" id = 'search'type="text" placeholder="Search Deals">
<input type='button' class='btn-search' value='search' id ='btn-search'>

Related

Javascript adding li element value to the empty list if it is not existing

I have a problem in Javascript.I am adding new list items to the 'ul' elements and this list is empty at first and I do not want to add same values twice. When I write the if statement I get the exception because my list is empty so the result return null.
How can I fix this this problem?
Thank you in advance...
Html Codes
<input type="text" id="the-filter" placeholder="Search For..." />
<div class="list-container">
<ul id="myList"></ul>
<button id="button">Click</button>
Javascript Codes
let newlist = document.querySelector("#myList");
const li = document.getElementsByClassName('list-group-item');
const button = document.getElementById("button");
const button.addEventListener('click' , listName);
const input = document.getElementById("the-filter");
function listName()
const inputVal = input.value;
for (i = 0; i < li.length; i++) {
if ((li[i].innerHTML.toLocaleLowerCase().includes(inputVal) && inputVal!="") ||
(li[i].innerHTML.toUpperCase().includes(inputVal) && inputVal!="")) {
let newItem = document.createElement("li");
li[i].classList.add("list-group-item");
let textnode = document.createTextNode(li[i].innerHTML.toLocaleLowerCase());
newItem.appendChild(textnode);
if((newlist.children[0].innerHTML.toLocaleLowerCase().includes(inputVal))){
newlist.insertBefore(newItem, newlist.childNodes[0]);
}
}
}
}
If I understood the task correct, you need to add items to the list by button click.
If same item exists (case insensitive), then nothing happens.
const list = document.querySelector("#myList");
const button = document.getElementById("button");
button.addEventListener("click", listName);
const input = document.getElementById("the-filter");
function listName() {
const inputVal = input.value;
const [...lis] = document.getElementsByClassName("list-group-item");
const same = lis.find((el) => el.textContent.toLowerCase() === inputVal.toLowerCase());
if (same) {
return;
}
let newItem = document.createElement("li");
newItem.classList.add("list-group-item");
newItem.textContent = inputVal;
list.appendChild(newItem)
}
<input type="text" id="the-filter" placeholder="Search For..." />
<div class="list-container">
<ul id="myList"></ul>
<button id="button">Click</button>
</div>
You're on the right track with event listeners and element creation, but your original code didn't quite seem to match your stated goal.
Here's a solution you might find useful, with some explanatory comments:
// Identifies some DOM elements
const
input = document.getElementById("my-input"),
newList = document.getElementById("my-list"),
items = document.getElementsByClassName('list-group-item'),
button = document.getElementById("my-button");
// Focuses input, and calls addItem on button-click
input.focus();
button.addEventListener('click', addItem);
// Defines the listener function
function addItem(){
// Trims whitespace and sets string to lowerCase
const inputTrimmedLower = input.value.trim().toLocaleLowerCase();
// Clears and refocuses input
input.value = "";
input.focus();
// Ignores empty input
if (!inputTrimmedLower) { return; }
// Ignores value if a list item matches it
for (const li of items) {
const liTrimmedLower = li.textContent.trim().toLocaleLowerCase();
if (liTrimmedLower === inputTrimmedLower) {
console.log(`${inputTrimmedLower} is already listed`);
return;
}
}
// If we got this far, we want to add the new item
let newItem = document.createElement("li");
newItem.classList.add("list-group-item");
newItem.append(inputTrimmedLower); // Keeps lowerCase, as your original code
newList.prepend(newItem); // More modern method than `insertBefore()`
}
<input id="my-input" />
<ul id="my-list"></ul>
<button id="my-button">Click</button>

The changes occurs briefly using keydown and then disappear

I want to append an li when the enter key is pressed using keydown. However, when I press the enter key the new li appears momentarily and then disappear.
How can I make it save the change or how can I fix the code?
var submitBtn = document.querySelector("input[type = 'submit'");
var enterTodo = document.querySelector("input[type = 'text']");
var todoList = document.querySelector("#todoList");
enterTodo.addEventListener('keydown', (event)=>{
if(event.which == 13){
var todo = enterTodo.value;
todoList.append("<li>" + todo + "</li>");
};
})
The reason why it was showing up and dissapearing almost immediately is because forms automatically refresh the page on submit. Which is why you have to use preventDefault in the onSubmit event.
I set up two working samples based on your code. In both, I went ahead and got your code to to append the proper li elements rather than the text `<li>${todo}</li>` to the todoList. I also made the enterTodo clear after being added to the list.
This uses the code about how you had it with the event listener on keydown, but it prevents the refresh.
var submitBtn = document.querySelector("input[type = 'submit'");
var enterTodo = document.querySelector("input[type = 'text']");
var todoList = document.querySelector("#todoList");
var form = document.querySelector("form");
form.onsubmit = (evt) => evt.preventDefault();
function addTodo() {
var todo = enterTodo.value;
var li = document.createElement('li');
li.textContent = todo;
todoList.appendChild(li);
enterTodo.value = "";
}
enterTodo.addEventListener('keydown', (event) => {
if (event.which == 13) {
addTodo();
};
})
<body>
<form>
<input type="text" onsubmit="" />
<input type="submit" />
<ul id="todoList"></ul>
</form>
</body>
This uses the from's onSubmit handler to perform the addition to the todoList instead of directly handling the enter key in the text input. This has the added benefit of also supporting the submit button click as well.
var submitBtn = document.querySelector("input[type = 'submit'");
var enterTodo = document.querySelector("input[type = 'text']");
var todoList = document.querySelector("#todoList");
var form = document.querySelector("form");
function addTodo() {
var todo = enterTodo.value;
var li = document.createElement('li');
li.textContent = todo;
todoList.appendChild(li);
enterTodo.value='';
}
form.onsubmit = (evt) => {evt.preventDefault();
addTodo();
}
<body>
<form>
<input type="text" onsubmit="" />
<input type="submit" />
<ul id="todoList"></ul>
</form>
</body>

Filtering value in textarea in 'input' event

What I want is filtering user's input. Remove newline and limit its length.
I tried two methods.
https://jsfiddle.net/mj111/356yx1df/3/
html
<div>
<textarea id="text1" placeholder="write down"></textarea>
</div>
<div>
<textarea id="text2" placeholder="write down"></textarea>
</div>
script
document.getElementById('text1')
.addEventListener('input', function (evt) {
evt.preventDefault(); // prevent value change
const msg = evt.target.value.replace(/\n/g, '')
if (msg.length <= 10) {
document.getElementById('text1').value = msg
}
})
document.getElementById('text2')
.addEventListener('input', function (evt) {
const msg = evt.target.value.replace(/\n/g, '').slice(0, 10)
document.getElementById('text2').value = msg
})
First one is not working, because preventDefault is not working. As MDN doc says. 'input' event is not cancelable.
So, I tried second method; just overwrite textarea value.
I think there's a better way to do this. If anyone has a good idea, please answer.
use keyup event to limit length or you can just add maxlength manually to the HTML as an attribute. If you want to set it dynamically you can use Element.setAttribute. For preventing new lines you can prevent the return key, as long as it is not shift. You can still use replace to replace things you feel need replacing, a regular expression will most effectively get the job done.
var text = document.getElementsByTagName('textarea');
var text1 = text[0];
var text2 = text[1];
text1.addEventListener('keydown', function(event) {
let val = event.target.value;
let limit = 25;
// limit the value once you reach a particular length
if (val.length > 3) {
event.target.value = val.substr(0, limit)
};
// prevent new line by preventing enter key press
if (event.keyCode === 13 && !event.shiftKey) {
event.preventDefault();
alert('no new lines please');
return false;
}
// and you can filter with replace
})
<div>
<textarea id="text1" placeholder="write down"></textarea>
</div>
<div>
<textarea id="text2" placeholder="write down"></textarea>
</div>

Javascript push input into Array causes several arrays not one

This is a follow up to my question, seen here
I am trying to write that when a user enters in their name (string) into the field and hits enter, it pushes it into an array. It works, kinda. But I get an error when I try it one and then it produces multiple arrays when I try it another. I don't want to use jQuery.
Here is the HTML
<input type="text"
class="theplayer pre"
name="Player"
id="bind"
placeholder="Enter Names"
/>
<button type="button" id="thego" class="pre enterteam" value="click">Go</button>
Here is my js that works but it creates multiple arrays instead of pushing everything into one array (because the nextElementSibling is not called, I know this, see next block
let namesOfPlayers = [];
let currentValue = document.getElementById("bind").value;
let button = currentValue.nextElementSibling;
document.addEventListener('keypress', function (e) {
const key = e.which || e.keyCode;
if (key === 13) {
namesOfPlayers.push(currentValue);
console.log('namesOfPlayers', namesOfPlayers);
}
});
Here is my js that throws an error (I don't want to use jQuery)
I want that when a user hits enter or clicks the button that the string is submitted and added into the empty array. I can't for the life of me figure out how to make that work.
Thanks for your help!
You fetch the value of the input too soon. You should fetch it only when the button is clicked, not before.
Secondly, the button does not have a keypress event, nor a keyCode associated with it. You need to listen to the click event.
So do this:
let namesOfPlayers = [];
let input = document.getElementById("bind");
let button = input.nextElementSibling;
button.addEventListener('click', function (e) {
namesOfPlayers.push(input.value);
console.log('namesOfPlayers', namesOfPlayers);
});
<input type="text"
class="theplayer pre"
name="Player"
id="bind"
placeholder="Enter Names" />
<button type="button" id="thego" class="pre enterteam" value="click">Go</button>
Try this code, i added a click (for the button) and keypress (for the text input) events
so if you click enter when you focus on the text input the text in the input will be in the array.
and the same will happen if you click "Go" button
let namesOfPlayers = [];
let currentElement = document.getElementById("bind");
let button = currentElement.nextElementSibling;
let addPlayer = () => {
namesOfPlayers.push(currentElement.value);
console.log(namesOfPlayers); // Just for testing
}
currentElement.addEventListener('keypress', function (e) {
if (e.which === 13 || e.keyCode === 13) {
addPlayer();
}
});
button.addEventListener('click', addPlayer);
<input type="text"
class="theplayer pre"
name="Player"
id="bind"
placeholder="Enter Names"
/>
<button type="button" id="thego" class="pre enterteam" value="click">Go</button>
CurrentValue is defined outside of the event listener, so it only gets called once, on initialisation. That's why the push call only injects empty strings. Also, the button doesn't do anything because it doesn't have a listener.
Here's the updated code:
let namesOfPlayers = [];
// It's better to get the button by id instead of getting it by a previous child.
// This is because it might cause some unexpected behaviour if someone changed the HTML.
const button = document.getElementById("thego");
button.addEventListener('click', function (e) {
addItemToArray(namesOfPlayers);
});
document.addEventListener('keypress', function (e) {
const key = e.which || e.keyCode;
if (key === 13) {
addItemToArray(namesOfPlayers);
}
});
function addItemToArray(namesOfPlayers) {
const currentValue = document.getElementById("bind").value;
namesOfPlayers.push(currentValue);
console.log('namesOfPlayers', namesOfPlayers);
}
https://fiddle.jshell.net/4k4a9m6y/
But, you're better off with a form to improve performance.
let namesOfPlayers = [];
const form = document.getElementById("form");
form.addEventListener('submit', function (e) {
const currentValue = document.getElementById("bind").value;
namesOfPlayers.push(currentValue);
console.log('namesOfPlayers', namesOfPlayers);
});
<form id="form"
action="javascript:void(0);">
<input type="text"
class="theplayer pre"
name="Player"
id="bind"
placeholder="Enter Names"
/>
<button type="submit" id="thego" class="pre enterteam" value="click">Go</button>
</form>
https://fiddle.jshell.net/4k4a9m6y/2/

Set input value with text in link with javascript

I have an input field <input type="text" name="input">.
I also have some links:
<div>
first link
second link
...
</div>
I want to let the user click on a link and set the value of the input with the value in the link.
I guess I should do something like:
const input = document.getElementById('input');
document.getElementsByTagName('a').forEach(function () {
this.onclick = function () {
input.value = this.innerHTML();
}
});
but I know that document.getElementsByTagName('a') doesn't return an array, so it's not possible, and I am not sure if this is the right approach.
getElementsByTagName() returns an HTMLCollection.
The usage as per the docs:
The HTMLCollection interface represents a generic collection (array-like object similar to arguments) of elements (in document order) and offers methods and properties for selecting from the list.
// document.forms is an HTMLCollection
elem1 = document.forms[0];
elem2 = document.forms.item(0);
alert(elem1 === elem2); // shows: "true"
This means that you should be able to treat your result like an array (including using .length).
Firstly, Dom lists are not normal array's, so forEach won't work.
Secondly, innerHTML is not function, it's property..
The [].slice.call, can be used to convert into a normal array.
Try this below. ->
const input = document.getElementById('input');
[].slice.call(document.getElementsByTagName('a')).
forEach(function (e) {
e.onclick = function (evt) {
evt.preventDefault();
input.value = this.innerHTML;
}
});
<div>
first link
second link
</div>
<input id="input" type="text">
Try this below:
https://jsfiddle.net/7h1a3p4x/5/
var el = document.getElementsByClassName("link");
for (var i = 0; i < el.length; i++) {
el[i].addEventListener('click', sendData, false);
}
function sendData() {
var input = document.getElementById("myinput");
input.value = this.innerHTML;
}
<input id="myinput" type="text" name="name" />
<div>
<a class="link" href="#">LINK 1</a>
<a class="link" href="#">LINK 2</a>
</div>

Categories