How to add a search function to my JavaScript? - javascript

I am developing a music player using JavaScript and I am trying to add a search bar to my page but every tutorial I have seen so far uses a list created in the HTML page, whereas I have created a list using JavaScript code like this:
const songs = [
"BlindingLights.mp3",
"Boyfriend.mp3",
"DontStartNow.mp3",
"Intentions.mp3",
"Physical"
]
const createSongList = () => {
const list = document.createElement('ol')
for(let i = 0; i<songs.length; i++){
const item = document.createElement('li')
item.appendChild(document.createTextNode(songs[i]))
list.appendChild(item)
}
return list
}
document.getElementById('songList').appendChild(createSongList())
Is there a way I can use the 'songs' array or to develop a search function? Any advice would be appreciated. Thanks! :)
Edit for clarity:
So I have an input tag on my html that I want to use for a search bar, then I want what the user types in to return any matching songs from the songs array. For example if they type in 'Bli' I want it to show the Blinding Lights song.
The code snippet above is how I am currently displaying a list of songs using the array.
This is my input tag:
<input type="text" name="searchBar" id="searchBar" placeholder="Search" onkeyup="searchBar()">

Assuming that you want to filter songs array from a search string, you can use this function :
const songs = [
"BlindingLights.mp3",
"Boyfriend.mp3",
"DontStartNow.mp3",
"Intentions.mp3",
"Physical"
];
const searchSong = (value) => {
return songs.filter(song => song.includes(value));
};
console.log(searchSong('B'));

Maybe you can create a new function search to Array.prototype to make it used more easily
Array.prototype.search = function (keyword) {
return this.filter(text => text.toLowerCase().includes(keyword.toLowerCase().trim()))
}
const songs = [
"BlindingLights.mp3",
"Boyfriend.mp6",
"DontStartNow.mp5",
"Intentions.mp3",
"Physical"
];
songs.search('phy ') // => ["Physical"]
songs.search(' MP3') // =>  ["BlindingLights.mp3", "Intentions.mp3"]

Related

Generate one HTML from API based on the object key language and language of page

I have an API request and I'm generating a HTML content from its data using .map();.
The issue I'm facing is that in the array of objects I have keys that are showing content in one language or another. I need to display specific keys in mapped HTML based on the language of the page.
Example of object key: keyAEN: 'content in EN' for English or keyAFR: 'contenu en français' for French.
My way of solving this isn't the DRY-est and there's some repeating code.
Please check below existing code and let me know what would be a better solution in this case. I would like to avoid generating a long HTML because of different language content in the keys.
// Find page language in URL
const findUrl = window.location.href;
const regex = /\.eu\/(\w{2})\//;
const match = regex.exec(findUrl);
const resultLangUrl = match && match[1];
let pageLang = resultLangUrl.toUpperCase();
let language = pageLang.includes("EN");
let pickContainer = document.querySelector('#container');
// deleting keys not coresponding to page language from the objects
//ex: page language is EN, delete all FR keys
if (pageLang === true) {
data.forEach(object => {
delete object['KeyAFR']
delete object['KeyBFR']
delete object['KeyCFR']
});
//generate html for EN
const generateHtmlEN = data.map(test => {
return `<p>${test.KeyAEN}</p>
<p>${test.KeyBEN}</p>
<p>${test.KeyCEN}</p>`
}).join('');
pickContainer.insertAdjacentHTML('afterbegin', generateHtmlEN);
} else {
data.forEach(object => {
delete object['KeyAEN']
delete object['KeyBEN']
delete object['KeyCEN']
});
//generate html for FR
const generateHtmlFR = data.map(test => {
return `<p>${test.KeyAFR}</p>
<p>${test.KeyBFR}</p>
<p>${test.KeyCFR}</p>`
}).join('');
pickContainer.insertAdjacentHTML('afterbegin', generateHtmlFR);
}

Using filter() method to filter array results by substring

I keep trying to pull the email addresses out of an array of links using filter by text. This is the code I tried that is not working. I'm sure I'm missing something simple, any ideas?
let links = Array.from(document.getElementsByTagName('a'));
let subset = links.filter(getEmails);
function getEmails(email) {
return subset.includes('#');
}
Filter doesn't work like that. The callback for the filter method gets each element.
function getEmailLinks() {
const links = Array.from(document.querySelectorAll('a'));
return links
.map((link) => link.href)
.filter((link) => link.includes('mailto'))
.map((link) => link.split(':')[1])
.filter((email) => email.includes('#'));
}
console.log(getEmailLinks());
mailto
mailto

How to keep track of the id number in an object when you iterate and add another object to it

I want to add another object to my exiting object but i doesn't get the value as others object have instead it gets a text, I tried a easy solution but didn't work, here is that i'm facing:
ConsoleLog Image
So instead of the key long I want to keep the numbers as they started from 0, but I don't know how?
Here is what I've tried:
const addToWatchlist = (movie) => {
const long = movies.length;
const data = {...movies, long: movie};
setMovies(movies)
ps: I'm using React.
const addToWatchlist = (movie) => {
movies.push(movie)
setMovies(movies)

Searching Array of Objects with two search values

so I am trying to make an app that has two search criterias. The front-end app basically fetches data and you have two search bars to filter out the incoming data.
One search is by name and the other is by school name, the tricky part is that the either of the search also takes into account if there is some value in the other search parameter.
For example, if you search for "California University" and "Bob", you should get only Bobs that go to California University to render on the screen. But it seems like right now my DOM only renders the most recent search Ive made. What is the best way to go about a filter that filters both student name and school name using an event listener (keyup) on the search inputs?
searchByNameInput.addEventListener("keyup", (e) => {
const filterNameArray = studentArray.filter((student) => {
// code here to filter students with this name and render it on DOM
}
}
searchBySchoolName.addEventListener("keyup", (e) => {
//filters students who go to this school and render it on DOM
}
}
Write a single filtering function that checks both inputs, and call it from both event listeners.
function filterStudents() {
const nameFilter = searchByNameInput.value;
const schoolFilter = searchBySchoolName.value;
const filterArray = studentArray.filter(student =>
(nameFilter == '' || student.name.includes(nameFilter) &&
(schoolFilter == '' || student.school.includes(schoolFilter))
}
searchByNameInput.addEventListener("keyup", filterStudents);
searchBySchoolNameInput.addEventListener("keyup", filterStudents);
first filter your object and please try it include() method instead of filter().
as a above example
here filterData is my new filtered object and stu_data is my array.
get all search value from search input.
Example:-
var filterData = stu_data.filter((stu_filter) => {
return (stu_filter.firstname.toLowerCase().includes(filter) ||
stu_filter.lastname.toLowerCase().includes(filter))})
I hope this is help for you!
happy coding :)

How to search for multiple words on a HTML page using JavaScript?

Right now my code is looking for the words 'Cheese' or 'Bread' within a specific webpage, and if it finds either word it should display an alert. However, it only displays the alert if the first word is found (cheese). Any suggestions on how to fix it so that it will successfully look for more than one word?
var array = Array.from(document.getElementsByClassName('wide-content-host'))
.find(el => el.innerText.includes('Cheese', 'Bread'));
if (array){
alert("Word found!")
}
This is an obvious change, but we could put an OR operator inside of the statement to signify both of them, like so:
let array = Array.from(document.getElementsByClassName('wide-content-host'))
.find(el => el.innerText.includes('Cheese') || el.innerText.includes('Bread'));
if (array) alert('Word found!');
You could also do it a more elegant way, like so:
const conditions = ['Cheese', 'Bread'];
const array = Array.from(document.getElementsByClassName('wide-content-host'));
const results = array.find((el) => conditions.some(nEl => el.innerText.includes(nEl)));
if (results) alert('Word found!');
This one works by grabbing the array from the 'wide-content-host' class name, then looping through that array with another loop that is looping through the values of the conditions array. With all of these loops working together, it will check whether or not the elements include the conditions.
** Edit **
In order to make the methods work without case-sensitivity, you would need to make the search cases lowercase e.g. 'cheese' and 'bread', and you would need to make the strings that you are searching through completely lowercase also.
Here are the examples for case-insensitivity:
let array = Array.from(document.getElementsByClassName('wide-content-host'))
.find(el => el.innerText.toLowerCase().includes('Cheese') || el.innerText.toLowerCase().includes('Bread'));
if (array) alert('Word found!');
or
const conditions = ['cheese', 'bread'];
const array = Array.from(document.getElementsByClassName('wide-content-host'));
const results = array.find((el) => conditions.some(nEl => el.innerText.toLowerCase().includes(nEl)));
if (results) alert('Word found!');
This can be done with regular expressions
let elem = document.querySelector("section");
let entries = elem.innerHTML.match(/(cheese)|(bread)/gi);
if (entries.length > 0) {
alert(`Words were found: ${entries}`);
}
<section>
<p>Cheese Bread</p>
<p>cheeSE BREAD</p>
</section>

Categories