Related
I am making an hotel website as a hobby project but when trying to render the list items depending on the search query by hotels location.
Initially, I am rendering all hotels which I have stored in an array but when I search by location, let say I type "Stockholm", then I want to show all list items of hotels with location in Stockholm.
Right now I am only able to hide all list items when typing a location that matches an item.
Here is my code:
HTML:
<html>
<title>Kevs Hotel</title>
<link rel="stylesheet" type="text/css" href="Style/KevinsHotel.css">
<body>
<div class="header">
<h1>Kevs Hotel</h1>
<input type="search" id="locationSearch" name="location" placeholder="Location" onkeyup="searchBarFeatures()">
<input type="date" class="checkInTime" name="checkInDate" placeholder="Check in" required>
<input type="date" class="checkOutTime" name="checkOutDate" placeholder="Check out">
<input type="number" class="noOfGuests" name="NoOfGuests" placeholder="Guests">
<input type="submit" class="submitBtn" value="Search">
</div>
<ul id="hotelList">
<!-- <li id="hotelCard">
<h3 class="hotelName"></h3>
<p class="hotelLocation"></p>
<dfn class="hotelDescription"></dfn>
<b class="priceOfStay"></b><br>
<button onclick="openSelectedHotelModal()" class="selectHotelBtn">Select this hotel</button>
</li> -->
</ul>
<div id="hotelModal" class="selectedHotelModal">
<!-- <div id="modal-content">
<span class="closeModalBtn" onclick="closeSelectedModal()">⊠</span>
<h3 class="selectedHotelName"><b></b></h3>
<p class="selectedHotelLocation"></p>
<dfn class="selectedHotelDescription">The best hotel in Gothenburg. Its gör best</dfn>
<b class="selectedPriceOfStay">800 SEK</b><br>
</div> -->
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="Script/KevinsHotel.js"></script>
</body>
JavaScript/jQuery:
var hotels = [
{hotelName: 'Scandic Crown', location: 'Gothenburg', description: 'The best hotel in Gothenburg. Its gör best', price: 800},
{hotelName: 'Scandic Alvik', location: 'Stockholm', description: 'Stockholms finest hotel', price: 1200},
{hotelName: 'Scandic Triangeln', location: 'Malmö', description: 'One of the finest in Malmö, and with an amazing view of Malmö.', price: 1000},
{hotelName: 'City Hotel Avenyn', location: 'Gothenburg', description: 'Great and cosy hotel in middle of Gothenburg', price: 750},
{hotelName: 'Ice Hotel', location: 'Kiruna', description: 'The hotel that exists in the winter and looks like an igloo', price: 1250},
{hotelName: 'Gålö Camping', location: 'Haninge', description: 'A great excursion in Stockholm', price: 995}
];
var hotelListItem = document.getElementById('hotelCard');
var selectedHotelModal = document.getElementById("hotelModal"); //Get Modal
var searchInput = document.getElementById("locationSearch");
function searchBarFeatures(){
console.log(searchInput.value);
var locOccurence = hotels.filter((hot) => hot.location.toUpperCase() === searchInput.value.toUpperCase());
console.log("There are " + locOccurence.length + " hotels in " + searchInput.value);
for (let i = 0; i < hotels.length; i++) {
const hotel = hotels[i];
const hotelCard = ('<li id="hotelCard"><h3 class="hotelName">'
+ hotel.hotelName + '</h3>' +
'<p class="hotelLocation">' + hotel.location +
'</p><dfn class="hotelDescription">'+ hotel.description +
' <br></dfn><b class="priceOfStay">'+ hotel.price +'</b><br>' +
'<button onclick="openSelectedHotelModal()" class="selectHotelBtn">Select this hotel</button></li>');
if(searchInput.value.toUpperCase() === hotel.location.toUpperCase()){
console.log("The Location search input seems to match the hotel Location ;) ");
$(document).ready(function(){
var hotelList = $("#hotelList");
var hotCard = $("#hotelCard");
$(hotelList).hide(1000);
$(hotCard).filter('#hotelCard:nth-child(2) === ' + !searchInput.value + ' ').show(1000);
});
}
}
}
function hotelList() {
console.log(hotels.length);
console.log(searchInput.value);
for (let i = 0; i < hotels.length; i++) {
const hotel = hotels[i];
const hotelCard = ('<li id="hotelCard"><h3 class="hotelName">'
+ hotel.hotelName + '</h3>' +
'<p class="hotelLocation">' + hotel.location +
'</p><dfn class="hotelDescription">'+ hotel.description +
' <br></dfn><b class="priceOfStay">'+ hotel.price +'</b><br>' +
'<button onclick="openSelectedHotelModal()" class="selectHotelBtn">Select this hotel</button></li>');
$(document).ready(function(){
var hotelList = $("#hotelList");
hotelList.append(hotelCard);
});
}
}
window.onload = hotelList;
I really want to show the hotels which have its location which I am typing in the search bar, example if I type Stockholm I want to render all hotels with its location in Stockholm.
All help is appreciated.
Thank you in advance
You can loop through class i.e :.hotelLocation where location is there .Then , use $(this).text() to match it with the user input and if both are same use .show() to show that li tag .
Demo code :
var hotels = [{
hotelName: 'Scandic Crown',
location: 'Gothenburg',
description: 'The best hotel in Gothenburg. Its gör best',
price: 800
},
{
hotelName: 'Scandic Alvik',
location: 'Stockholm',
description: 'Stockholms finest hotel',
price: 1200
},
{
hotelName: 'Scandic Triangeln',
location: 'Malmö',
description: 'One of the finest in Malmö, and with an amazing view of Malmö.',
price: 1000
},
{
hotelName: 'City Hotel Avenyn',
location: 'Gothenburg',
description: 'Great and cosy hotel in middle of Gothenburg',
price: 750
},
{
hotelName: 'Ice Hotel',
location: 'Kiruna',
description: 'The hotel that exists in the winter and looks like an igloo',
price: 1250
},
{
hotelName: 'Gålö Camping',
location: 'Haninge',
description: 'A great excursion in Stockholm',
price: 995
}
];
var hotelListItem = document.getElementById('hotelCard');
var selectedHotelModal = document.getElementById("hotelModal"); //Get Modal
var searchInput = document.getElementById("locationSearch");
function searchBarFeatures() {
var hotelList = $("#hotelList");
hotelList.find("li").hide();//hide all li
//loop through list and find p tag where location is there
$("#hotelList").find(".hotelLocation").filter(function() {
//check if value matches
return $(this).text().toUpperCase().indexOf(searchInput.value.toUpperCase()) == 0;
}).parent().show(); //show
}
function hotelList() {
for (let i = 0; i < hotels.length; i++) {
const hotel = hotels[i];
const hotelCard = ('<li id="hotelCard"><h3 class="hotelName">' +
hotel.hotelName + '</h3>' +
'<p class="hotelLocation">' + hotel.location +
'</p><dfn class="hotelDescription">' + hotel.description +
' <br></dfn><b class="priceOfStay">' + hotel.price + '</b><br>' +
'<button onclick="openSelectedHotelModal()" class="selectHotelBtn">Select this hotel</button></li>');
$(document).ready(function() {
var hotelList = $("#hotelList");
hotelList.append(hotelCard);
});
}
}
window.onload = hotelList;
<body>
<div class="header">
<h1>Kevs Hotel</h1>
<input type="search" id="locationSearch" name="location" placeholder="Location" onkeyup="searchBarFeatures()">
<input type="date" class="checkInTime" name="checkInDate" placeholder="Check in" required>
<input type="date" class="checkOutTime" name="checkOutDate" placeholder="Check out">
<input type="number" class="noOfGuests" name="NoOfGuests" placeholder="Guests">
<input type="submit" class="submitBtn" value="Search">
</div>
<ul id="hotelList">
</ul>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
I have problem with anchor element and onclick attribute. The idea is that I have main function loadTableWithFilters that gets values from the pet data base and then draws a table with pets. The other functions are intended to change filters and call loadTableWithFilters function again. The problem that I have is with function calls from my html file.
This simply doesn't work
<li><a onclick="filterAllPets()">All Pets</a></li>
It gives me this error
Uncaught ReferenceError: filterAllPets is not defined
at HTMLAnchorElement.onclick
What I tried to do to solve this problem:
moved my <script> tags before </body>
changed function loadTableWithFilters ( petData ) to var loadTableWithFilters = function ( petData )
I know that I can give id to anchors and write some snippets like #id.onclick = function() but that's not the intention. I really don't understand why it doesn't work. Please explain it.
Code files
main.html
<!doctype html>
<html>
<head>
<title>~ Purfect Pets ~</title>
<link rel="stylesheet" href="css/normalize.css" />
<link rel="stylesheet" href="css/assignment4-theme.css" />
<link rel="stylesheet" href="css/a4-main.css" />
<!-- development css -->
<style>
table, td, th {
border: 1px solid black;
}
</style>
</head>
<body>
<header>
<div class="center">
<h1 class="app-title">
~ Purfect Pets ~
</h1>
</div>
</header>
<nav>
<div class="center">
<ul>
<li><a onclick="filterAllPets()">All Pets</a></li>
<li><span>|</span></li>
<li><a onclick="filterDog()">Dogs</a></li>
<li><a onclick="filterCat()">Cats</a></li>
<li><a onclick="filterBird()">Birds</a></li>
<li><span>|</span></li>
<li><a onclick="filter_zero_1()">< 1 year</a></li>
<li><a onclick="filter_1_3()">1 - 3 years</a></li>
<li><a onclick="filter_4_plus()">4+ years</a></li>
</ul>
</div>
</nav>
<section class="main center">
<table class="main-table-top">
<tbody>
<tr>
<th>Photo</th>
<th>Description</th>
</tr>
</tbody>
</table>
<div class="main-table-container">
<table class="main-table">
<tbody id="main-table-body">
<!-- tester -->
</tbody>
</table>
</div>
</section>
<footer>
<div class="center">
© 2017 Anton Elistratov
</div>
</footer>
<script src="js/data.js"></script>
<script src="js/a4-main.js"></script>
</body>
</html>
a4-main.js
//a4-main.js
window.onload = function() {
var filterType = ""; // sets the filter type to "" (will later be dog, cat or bird)
var filterAgeMin = 0; // sets the filter age min to 0 (for no minimum age filter)
var filterAgeMax = Number.MAX_VALUE; // sets the filter age max to the largest number possible (for no maximum age filter)
//
var loadTableWithFilters = function ( petData ){
var htmlRow = document.querySelector('#main-table-body');//getting my placeholder
htmlRow.innerHTML = "";//clearing
var i;//for loop increment
for (i = 0; i < petData.length; i++){
//$('#main-table-body tr td').append('<img src="' + petData[i].image.src + '"/>');
//getting image
if (petData[i].type === filterType || filterType === "" && petData[i].age >= filterAgeMin && petData[i].age <= filterAgeMax){
var image = document.createElement('img');
image.src = petData[i].image.src;
image.alt = petData[i].image.alt;
image.height = petData[i].image.height;
image.width = petData[i].image.width;
//getting name
var name = document.createElement('h4');
name.textContent = petData[i].name;
//getting description
var description = document.createElement('p');
description.innerHTML = petData[i].description;
//getting age
var age = document.createElement('span');
age.textContent = petData[i].age;
var type = petData[i].type;
//append('<li><img src="' + imgSrc[i] + '"/></li>');
var fullRow = document.createElement('tr');
var colLeft = document.createElement('td');
var colRight = document.createElement('td');
colLeft.appendChild(image);
colRight.appendChild(name);
colRight.appendChild(description);
colRight.appendChild(age);
//table assembly
fullRow.appendChild(colLeft);
fullRow.append(colRight);
htmlRow.appendChild(fullRow);
}
}//for (i = 0; i < petData.length; i++)
}
/* My filters */
//filters dogs
var filterDog = function () {
filterType = "dog";
loadTableWithFilters( petData );
}
//filters cats
var filterCat = function () {
filterType = "cat";
loadTableWithFilters( petData );
}
var filterBird = function () {
filterType = "bird";
loadTableWithFilters( petData );
}
//must be invoked when the user clicks "< 1 year"
var filter_zero_1 = function (){
filterAgeMin = 0;
filterAgeMax = 1;
loadTableWithFilters( petData );
}
//must be invoked when the user clicks "1 - 3 years"
var filter_1_3 = function (){
filterAgeMin = 1;
filterAgeMax = 3;
loadTableWithFilters( petData );
}
//must be invoked when the user clicks "4+ years"
var filter_4_plus = function () {
filterAgeMin = 4;
filterAgeMax = Number.MAX_VALUE;
loadTableWithFilters( petData );
}
/*This function simply sets the global filterType variable to "", the filterAgeMin variable to 0, the filterAgeMax variable to Number.MAX_VALUE and invokes the loadTableWithFilters function again to refresh the table. This function must be invoked when the user clicks "All Pets"*/
var filterAllPets = function () {
filterType = "";
filterAgeMin = 0;
filterAgeMax = Number.MAX_VALUE;
loadTableWithFilters( petData );
}
//function call
loadTableWithFilters( petData );
};//window.onload = function()
data.js
//data.js
var petData = [
{
image: { src: "https://scs.senecac.on.ca/~patrick.crawford/shared/winter-2017/web222/assignment4/pets/Bella.jpg", alt: "Bella", width: 120, height: 160 },
name: "Bella",
age: 0.5,
description: "<span>Bella</span> is a bright young pup who loves being around other dogs and doesn't mind the odd cat.<br />Her <span>favourite treat</span> is <span>bacon</span> - anything <span>bacon</span>.",
type: "dog"
}, {
image: { src: "https://scs.senecac.on.ca/~patrick.crawford/shared/winter-2017/web222/assignment4/pets/Buddy.jpg", alt: "Buddy", width: 120, height: 160 },
name: "Buddy",
age: 4,
description: "One of the most friendly dogs currently staying with us is <span>Buddy</span>.<br />He's a little older but has a <span>lot of love</span> to give.<br />His favourite activity is cuddling up and <span>watching a movie</span> with is owner.",
type: "dog"
}, {
image: { src: "https://scs.senecac.on.ca/~patrick.crawford/shared/winter-2017/web222/assignment4/pets/Charlie.jpg", alt: "Charlie", width: 120, height: 160 },
name: "Charlie",
age: 3,
description: "<span>Charlie</span> loves <span>spending time outdoors</span>. <br />He will chase anything that moves and will spend all day <span>playing fetch</span> in the park. <br />His favourite treat to eat is actually <span>broccoli</span> - crazy I know, but he loves it.",
type: "dog"
}, {
image: { src: "https://scs.senecac.on.ca/~patrick.crawford/shared/winter-2017/web222/assignment4/pets/Jasper.jpg", alt: "Jasper", width: 120, height: 160 },
name: "Jasper",
age: 2,
description: "<span>Jasper</span> is only 2 years (and 3 months) old, but he's already one of the smartest pups we've seen.<br /> He will recognize his <span>toys by name</span> and will always put them back in the toy box when asked.<br />He's the only dog we've seen that <span>tidies up after himself!</span>.",
type: "dog"
}, {
image: { src: "https://scs.senecac.on.ca/~patrick.crawford/shared/winter-2017/web222/assignment4/pets/Max.jpg", alt: "Max", width: 120, height: 160 },
name: "Max",
age: 5,
description: "Our little <span>Max</span> is always happy.<br />He loves to spend his time outdoors <span>playing fetch</span> and <span>going for jogs</span>.<br /> His favourite treats are <span>hot dogs</span> - any variety will do, but he loves Schneiders <span>Red Hots</span> the best.",
type: "dog"
}, {
image: { src: "https://scs.senecac.on.ca/~patrick.crawford/shared/winter-2017/web222/assignment4/pets/David.jpg", alt: "David", width: 120, height: 160 },
name: "David",
age: 0.5,
description: "<span>David</span> is our smallest kitten at only <span>6 months old</span>! <br />His favourite thing right now is <span>chasing his tail</span> and playing with <span>packing peanuts</span>.<br />He is full of love and will make a welcome addition to any home.",
type: "cat"
}, {
image: { src: "https://scs.senecac.on.ca/~patrick.crawford/shared/winter-2017/web222/assignment4/pets/Simba.jpg", alt: "Simba", width: 120, height: 160 },
name: "Simba",
age: 5,
description: "One of our oldest cats is <span>Simba</span>.<br /> He's over chasing things and is just looking for a nice place to <span>cuddle</span> - usually somebody's lap.<br /> He loves <span>Temptations</span> (any variety) and will <span>come running</span> from anywhere in the house if he suspects treats are on the way.",
type: "cat"
}, {
image: { src: "https://scs.senecac.on.ca/~patrick.crawford/shared/winter-2017/web222/assignment4/pets/Sparky.jpg", alt: "Sparky", width: 120, height: 160 },
name: "Sparky",
age: 2,
description: "<span>Sparky</span> is a very wild cat, but he's a <span>ton of fun</span>.<br />He would happily spend his days chasing <span>bugs</span> or <span>squirrels</span> outside or <span>playing with you</span> inside!<br /> His favourite treat is <span>cottage cheese</span> and will eat it straight from the container if you let him.",
type: "cat"
}, {
image: { src: "https://scs.senecac.on.ca/~patrick.crawford/shared/winter-2017/web222/assignment4/pets/Whiffles.jpg", alt: "Whiffles", width: 120, height: 160 },
name: "Whiffles",
age: 3,
description: "<span>Whiffles</span> is our first <span>hypoallergenic</span> cat.<br />She is very mellow and extremely friendly, making her the perfect indoor cat.<br />Her favourite treat is <span>Tuna</span> straight from the can - any variety.",
type: "cat"
}, {
image: { src: "https://scs.senecac.on.ca/~patrick.crawford/shared/winter-2017/web222/assignment4/pets/Widget.jpg", alt: "Widget", width: 120, height: 160 },
name: "Widget",
age: 1.5,
description: "One of our <span>youngest</span> cats is <span>Widget</span>. <br /> He's only 18 months old and still loves to run and jump and <span>chase his toys</span>.<br />His favourite food is <span>Salmon</span>, but he will always come running for any variety of <span>cat treats</span> (i.e. Temptations, Greenies, etc). ",
type: "cat"
}, {
image: { src: "https://scs.senecac.on.ca/~patrick.crawford/shared/winter-2017/web222/assignment4/pets/Augustus.jpg", alt: "Augustus", width: 120, height: 160 },
name: "Augustus",
age: 1.5,
description: "<span>Augustus</span> has been with us for just over <span>4 months</span>, and already we can see that he's <span>very friendly</span>.<br /> He will <span>chirp</span> and <span>chatter</span> whenever somebody enters the room. ",
type: "bird"
}, {
image: { src: "https://scs.senecac.on.ca/~patrick.crawford/shared/winter-2017/web222/assignment4/pets/Joanna.jpg", alt: "Joanna", width: 120, height: 160 },
name: "Joanna",
age: 0.5,
description: "One of our youngest birds is <span>Joanna</span>. She is only 6 months old, but is very active.<br /> She loves <span>flying outside</span> of her cage, but will never go far. Like all birds her age, she loves playing with the “<span>bird in the mirror</span>”.",
type: "bird"
}, {
image: { src: "https://scs.senecac.on.ca/~patrick.crawford/shared/winter-2017/web222/assignment4/pets/Jonathan.jpg", alt: "Jonathan", width: 120, height: 160 },
name: "Jonathan",
age: 3,
description: "<span>Jonathan</span> is one of our older birds, but is still very friendly and loves to <span>chirp and sing</span> in the morning.<br /> He loves taking <span>baths</span>, so as long as there's a <span>water bowl</span> in his cage, he'll be happy all day.",
type: "bird"
}, {
image: { src: "https://scs.senecac.on.ca/~patrick.crawford/shared/winter-2017/web222/assignment4/pets/Sammy.jpg", alt: "Sammy", width: 120, height: 160 },
name: "Sammy",
age: 2.5,
description: "<span>Sammy</span> is one of our older birds, but he's also the <span>smartest</span>. He is always trying to <span>mimic</span> whatever sounds are around him. He is also a very active bird, so be sure you are able to interact with him <span>multiple</span> times a day.<br />His favourite thing is when you <span>scratch</span> under his chin. ",
type: "bird"
}, {
image: { src: "https://scs.senecac.on.ca/~patrick.crawford/shared/winter-2017/web222/assignment4/pets/Suzette.jpg", alt: "Suzette", width: 120, height: 160 },
name: "Suzette",
age: 4,
description: "The oldest bird currently staying with us is <span>Suzette</span>. She's extremely <span>cuddly</span> and loves landing on people's glasses, collars, hats, or whatever she can get her little claws on, as long as she can be close. She's a great <span>companion</span> for anyone looking for a bird that will interact with them and remain <span>close by</span>.",
type: "bird"
}
];
Just remove it from window.load and it will work.
From this:
window.onload = function() {
var filterType = ""; // sets the filter type to "" (will later be dog, cat or bird)
var filterAgeMin = 0; // sets the filter age min to 0 (for no minimum age filter)
var filterAgeMax = Number.MAX_VALUE; // sets the filter age max to the largest number possible (for no maximum age filter)
//
var loadTableWithFilters = function(petData) {
var htmlRow = document.querySelector('#main-table-body'); //getting my placeholder
htmlRow.innerHTML = ""; //clearing
var i; //for loop increment
for (i = 0; i < petData.length; i++) {
//$('#main-table-body tr td').append('<img src="' + petData[i].image.src + '"/>');
//getting image
if (petData[i].type === filterType || filterType === "" && petData[i].age >= filterAgeMin && petData[i].age <= filterAgeMax) {
var image = document.createElement('img');
image.src = petData[i].image.src;
image.alt = petData[i].image.alt;
image.height = petData[i].image.height;
image.width = petData[i].image.width;
//getting name
var name = document.createElement('h4');
name.textContent = petData[i].name;
//getting description
var description = document.createElement('p');
description.innerHTML = petData[i].description;
//getting age
var age = document.createElement('span');
age.textContent = petData[i].age;
var type = petData[i].type;
//append('<li><img src="' + imgSrc[i] + '"/></li>');
var fullRow = document.createElement('tr');
var colLeft = document.createElement('td');
var colRight = document.createElement('td');
colLeft.appendChild(image);
colRight.appendChild(name);
colRight.appendChild(description);
colRight.appendChild(age);
//table assembly
fullRow.appendChild(colLeft);
fullRow.append(colRight);
htmlRow.appendChild(fullRow);
}
} //for (i = 0; i < petData.length; i++)
}
/* My filters */
//filters dogs
var filterDog = function() {
filterType = "dog";
loadTableWithFilters(petData);
}
//filters cats
var filterCat = function() {
filterType = "cat";
loadTableWithFilters(petData);
}
var filterBird = function() {
filterType = "bird";
loadTableWithFilters(petData);
}
//must be invoked when the user clicks "< 1 year"
var filter_zero_1 = function() {
filterAgeMin = 0;
filterAgeMax = 1;
loadTableWithFilters(petData);
}
//must be invoked when the user clicks "1 - 3 years"
var filter_1_3 = function() {
filterAgeMin = 1;
filterAgeMax = 3;
loadTableWithFilters(petData);
}
//must be invoked when the user clicks "4+ years"
var filter_4_plus = function() {
filterAgeMin = 4;
filterAgeMax = Number.MAX_VALUE;
loadTableWithFilters(petData);
}
/*This function simply sets the global filterType variable to "", the filterAgeMin variable to 0, the filterAgeMax variable to Number.MAX_VALUE and invokes the loadTableWithFilters function again to refresh the table. This function must be invoked when the user clicks "All Pets"*/
var filterAllPets = function() {
filterType = "";
filterAgeMin = 0;
filterAgeMax = Number.MAX_VALUE;
loadTableWithFilters(petData);
}
//function call
loadTableWithFilters(petData);
}; //window.onload = function()
to this:
var filterType = ""; // sets the filter type to "" (will later be dog, cat or bird)
var filterAgeMin = 0; // sets the filter age min to 0 (for no minimum age filter)
var filterAgeMax = Number.MAX_VALUE; // sets the filter age max to the largest number possible (for no maximum age filter)
//
var loadTableWithFilters = function(petData) {
var htmlRow = document.querySelector('#main-table-body'); //getting my placeholder
htmlRow.innerHTML = ""; //clearing
var i; //for loop increment
for (i = 0; i < petData.length; i++) {
//$('#main-table-body tr td').append('<img src="' + petData[i].image.src + '"/>');
//getting image
if (petData[i].type === filterType || filterType === "" && petData[i].age >= filterAgeMin && petData[i].age <= filterAgeMax) {
var image = document.createElement('img');
image.src = petData[i].image.src;
image.alt = petData[i].image.alt;
image.height = petData[i].image.height;
image.width = petData[i].image.width;
//getting name
var name = document.createElement('h4');
name.textContent = petData[i].name;
//getting description
var description = document.createElement('p');
description.innerHTML = petData[i].description;
//getting age
var age = document.createElement('span');
age.textContent = petData[i].age;
var type = petData[i].type;
//append('<li><img src="' + imgSrc[i] + '"/></li>');
var fullRow = document.createElement('tr');
var colLeft = document.createElement('td');
var colRight = document.createElement('td');
colLeft.appendChild(image);
colRight.appendChild(name);
colRight.appendChild(description);
colRight.appendChild(age);
//table assembly
fullRow.appendChild(colLeft);
fullRow.append(colRight);
htmlRow.appendChild(fullRow);
}
} //for (i = 0; i < petData.length; i++)
}
/* My filters */
//filters dogs
var filterDog = function() {
filterType = "dog";
loadTableWithFilters(petData);
}
//filters cats
var filterCat = function() {
filterType = "cat";
loadTableWithFilters(petData);
}
var filterBird = function() {
filterType = "bird";
loadTableWithFilters(petData);
}
//must be invoked when the user clicks "< 1 year"
var filter_zero_1 = function() {
filterAgeMin = 0;
filterAgeMax = 1;
loadTableWithFilters(petData);
}
//must be invoked when the user clicks "1 - 3 years"
var filter_1_3 = function() {
filterAgeMin = 1;
filterAgeMax = 3;
loadTableWithFilters(petData);
}
//must be invoked when the user clicks "4+ years"
var filter_4_plus = function() {
filterAgeMin = 4;
filterAgeMax = Number.MAX_VALUE;
loadTableWithFilters(petData);
}
/*This function simply sets the global filterType variable to "", the filterAgeMin variable to 0, the filterAgeMax variable to Number.MAX_VALUE and invokes the loadTableWithFilters function again to refresh the table. This function must be invoked when the user clicks "All Pets"*/
var filterAllPets = function() {
filterType = "";
filterAgeMin = 0;
filterAgeMax = Number.MAX_VALUE;
loadTableWithFilters(petData);
}
//function call
loadTableWithFilters(petData);
I've created a JSON file to call out the name of a list of beers to display ABV and country but I am unable to display the results on the webpage. I was able to get the select tag to drop down the list, but when selecting a beer, it will only show the selected results as "undefined."
Here is the JS code I have so far...
var $select = $("#beerListing");
var beer = Array();
var country = Array();
$.getJSON("data.json", function(data) {
$select.html('');
for (var i = 0; i < data['beer'].length; i++)
$select.append('<option id="' + data["beer"][i]['id'] + '">' + data["beer"][i]["beer_name"] + '</option>');
for (x in data) {
if (beer.indexOf(data[x].beer_name) < 0) {
var y = beer.length;
beer[y] = data[x].beer_name;
country[y] = data[x].brewery_country;
}
}
showBeerList();
});
function showBeerList() {
var select = document.getElementById('beerListing');
for (var i = 0; i < beer.length; i++) {
var obj = document.createElement("option");
obj.text = beer[i];
obj.value = i;
select.appendChild(obj);
}
}
function getBeerInfo(picked) {
if (picked == "Pick Your Poison...") {
location.reload();
} else {
document.getElementById("name").innerHTML = beer[picked];
document.getElementById("country").innerHTML = country[picked];
}
}
HTML:
<html>
<head></head>
<body>
<h1>LCBO API TESTING</h1>
<select name="beerlist" id="beerListing" class="form-control" onchange="getBeerInfo(this.value)">
</select>
<br>
<label>Name:</label>
<label id="name">--</label>
<br>
<label>Country:</label>
<label id="country">--</label>
<br>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script src="main.js"></script>
</body>
</html>
JSON List called data.json
{
"beer": [{
"beer_name": "Organic Devon Cider",
"brewery_name": "Luscombe Organic Drinks",
"beer_type": "Cider",
"beer_abv": "4.9",
"beer_ibu": "0",
"comment": "",
"venue_name": "The Anchor & Hope",
"venue_city": "London",
"venue_state": "Greater London",
"brewery_country": "England"
}, {
"beer_name": "Beer A",
"brewery_name": "Beer A",
"beer_type": "Cider",
"beer_abv": "4.9",
"beer_ibu": "0",
"comment": "",
"venue_name": "Beer",
"venue_city": "New York",
"venue_state": "New York",
"brewery_country": "USA"
}]
}
You seemed to be adding the options to the select element twice and using for-in which iterates properties, not entries in an array.
Below snippet will not work as requires external data source.
var $select = $("#beerListing") ;
var beer = Array();
var country = Array();
$.getJSON("data.json", function(data) {
$select.html('');
for (var i = 0; i < data.beer.length; i = i + 1) {
if (beer.indexOf(data.beer[i].beer_name) < 0) {
beer.push(data.beer[i].beer_name);
country.push(data.beer[i].brewery_country);
}
}
showBeerList();
}
function showBeerList() {
var select = document.getElementById('beerListing');
for (var i = 0; i < beer.length; i++) {
var obj = document.createElement("option");
obj.text = beer[i];
obj.value = i;
select.appendChild(obj);
}
}
function getBeerInfo(picked) {
if (picked == "Pick Your Poison...") {
location.reload();
}
else {
document.getElementById("name").innerHTML = beer[picked];
document.getElementById("country").innerHTML = country[picked];
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>LCBO API TESTING</h1>
<select name="beerlist" id="beerListing" class="form-control" onchange="getBeerInfo(this.value)">
</select>
<br>
<label>Name:</label>
<label id="name">--</label>
<br>
<label>Country:</label>
<label id="country">--</label>
<br>
I got it working here: https://jsfiddle.net/bu7pkb5f/1/
What are you doing with:
if (beer.indexOf(data[x].beer_name) < 0) {
var y = beer.length;
beer[y] = data[x].beer_name;
country[y] = data[x].brewery_country;
}
I don't understand it but it's creating a third item in the list after the two real beer entries are processed. I left it commented out in the fiddle so you can check it out for yourself.
So I will start with my needs. I have a task to create json output using nightwatch.js from the ul list where inside lists are few div elements with classes like name, surname... But really I can't think of any of solutions. Here is my html
<html>
<meta charset="utf-8">
<body>
<ul class="random">
<li class="list">
<div class="name">John</div>
<div class="surname">Lewis</div>
</li>
<li class="list odd">
<div class="name">Nick</div>
<div class="surname">Kyrgios</div>
</li>
</ul>
</body>
</html>
And here is my nightwatch.js script
'Test' : function(browser) {
function iterate(elements) {
elements.value.forEach(function(el) {
browser.elementIdText(el.ELEMENT, function(r) {
browser.elementIdAttribute(el.ELEMENT, 'class', function(att){
// output for json i guess
console.log(att.value + ' => ' + r.value)
})
});
});
}
browser
.url('http://url.com/nightwatch.php')
.waitForElementVisible('body', 8000)
.elements('css selector', 'ul li div', iterate)
.end();
}
Basically this will execute the following:
name => John
surname => Lewis
name => Nick
surname => Kyrgios
Output is a string for both...
And how can I make it like
[{name: "John", surname: "Lewis"}, {name: "Nick", surname: "Kyrgios"}]
This should work. You just need to keep track of the object and place it inside the array after list.
function iterate(elements) {
var objArr = [];
var obj = {};
elements.value.forEach(function(el, idx) {
browser.elementIdText(el.ELEMENT, function(r) {
browser.elementIdAttribute(el.ELEMENT, 'class', function(att){
if (obj.hasOwnProperty(att.value)) {
objArr.push(obj);
obj = {};
}
obj[att.value] = r.value;
});
});
if (idx === (elements.value.length-1)) {
objArr.push(obj);
console.log(objArr);
}
});
}
As with Will's solution, I used straight JavaScript. It does not appear that the nightwatch.js code for this provides any significant benefit. In addition, your question does not specify that only nightwatch.js should be used.
As opposed to Will, I have assumed that the class on your inner <div> elements could be arbitrary and that the arbitrary class should be used as the key/property on the object for that entry. Choosing to use this method vs. restricting it only to a name or surname property will depend on what your HTML really is, and how you want to handle classes which are not those two strings.
var theList = [];
var listItems = document.querySelectorAll('li');
for (var itemIndex=0,itemLength=listItems.length; itemIndex < itemLength; itemIndex++) {
var entry = {};
divs = listItems[itemIndex].querySelectorAll('div');
for (var divsIndex=0, divsLength=divs.length; divsIndex < divsLength; divsIndex++) {
entry[divs[divsIndex].className] = divs[divsIndex].textContent;
}
theList.push(entry);
}
outputJson = JSON.stringify(theList);
console.log(outputJson);
<html>
<meta charset="utf-8">
<body>
<ul class="random">
<li class="list">
<div class="name">John</div>
<div class="surname">Lewis</div>
</li>
<li class="list odd">
<div class="name">Nick</div>
<div class="surname">Kyrgios</div>
</li>
</ul>
</body>
</html>
What about something like this?
function iterate(elements) {
var jsonArray = [];
var jsonBuffer = "";
elements.value.forEach(function(el) {
browser.elementIdText(el.ELEMENT, function(r) {
browser.elementIdAttribute(el.ELEMENT, 'class', function(att){
// output for json i guess
if (att.value == 'name') {
jsonBuffer += "{" + att.value + ":" + "" + r.value + "" + ",";
}
else {
jsonBuffer += att.value + ":" + "" + r.value + "" + "}";
jsonArray.push(jsonBuffer);
jsonBuffer = "";
}
})
});
});
var jsonOutput = "[";
var i = 0;
jsonArray.forEach(function(el) {
if (i < jsonArray.length) {
jsonOutput += el + ",";
} else {
jsonOutput += el + "]";
}
i++;
}
}
I'm not familiar with Nightwatch, but you essentially loop through the elements and push them on to an array.
var results = [];
var entries = document.querySelectorAll('li');
for (var ix = 0; ix < entries.length; ix++) {
var name = entries[ix].querySelector('.name').innerText;
var surname = entries[ix].querySelector('.surname').innerText;
results.push({
name: name,
surname: surname
});
}
console.log(results);
<ul class="random">
<li class="list">
<div class="name">John</div>
<div class="surname">Lewis</div>
</li>
<li class="list odd">
<div class="name">Nick</div>
<div class="surname">Kyrgios</div>
</li>
</ul>
I have a colour picker on my website. Which works great, However i'm wanting to have multiple for multiple elements to be different colour e.g. one text pink and the bg blue.
This is the code i have have at the moment (which works but changes both boxes) i'm missing an id somewhere but im not sure where.
<div class="row">
<script type="text/javascript">
var hexText="123";
var colorList = [ '000000', '993300', '333300', '003300', '003366', '000066', '333399', '333333',
'660000', 'FF6633', '666633', '336633', '336666', '0066FF', '666699', '666666', 'CC3333', 'FF9933',
'99CC33', '669966', '66CCCC', '3366FF', '663366', '999999', 'CC66FF', 'FFCC33', 'FFFF66', '99FF66'];
var picker = $('#color-picker');
for (var i = 0; i < colorList.length; i++ ) {
picker.append('<li class="color-item" data-hex="' + '#' + colorList[i] + '" style="background-color:' + '#' + colorList[i] + ';"></li>');
}
$('body').click(function () {
picker.fadeOut(1);
});
$('.call-picker').click(function(event) {
event.stopPropagation();
picker.fadeIn(1);
picker.children('li').hover(function() {
var codeHex = $(this).data('hex');
$('.color-holder').css('background-color', codeHex);
$('#pickcolor').val(codeHex).trigger('change');
});
});
</script>
<div class="color-wrapper">
<p>Choose color for Header</p>
<!-- ng-model="eventData.header" This is to post the information in the color picker box into the json at the bottom to make it useable by the server. -->
<form name="test">
<input type="text" name="custom_color" ng-model="Data.headerColor" placeholder="#FFFFFF" id="pickcolor" class="call-picker">
</form>
<div class="color-holder call-picker"></div>
<div class="color-picker" id="color-picker" style="display: none"></div>
</div>
</div>
<div class="row">
<script type="text/javascript">
var hexText="123";
var colorList = [ '000000', '993300', '333300', '003300', '003366', '000066', '333399', '333333',
'660000', 'FF6633', '666633', '336633', '336666', '0066FF', '666699', '666666', 'CC3333', 'FF9933',
'99CC33', '669966', '66CCCC', '3366FF', '663366', '999999', 'CC66FF', 'FFCC33', 'FFFF66', '99FF66'];
var picker = $('#color-picker2');
for (var i = 0; i < colorList.length; i++ ) {
picker.append('<li class="color-item" data-hex="' + '#' + colorList[i] + '" style="background-color:' + '#' + colorList[i] + ';"></li>');
}
$('body').click(function () {
picker.fadeOut(1);
});
$('.call-picker2').click(function(event) {
event.stopPropagation();
picker.fadeIn(1);
picker.children('li').hover(function() {
var codeHex = $(this).data('hex');
$('.color-holder2').css('background-color', codeHex);
$('#pickcolor2').val(codeHex).trigger('change');
});
});
</script>
<div class="color-wrapper">
<p>Choose color for Header</p>
<!-- ng-model="eventData.header" This is to post the information in the color picker box into the json at the bottom to make it useable by the server. -->
<form name="test">
<input type="text" name="custom_color2" ng-model="Data.bodytextColor" placeholder="#FFFFFF" id="pickcolor2" class="call-picker2">
</form>
<div class="color-holder2 call-picker2"></div>
<div class="color-picker2" id="color-picker2" style="display: none"></div>
</div>
picker variable must change.
<script type="text/javascript">
var hexText="123";
var colorList = [ '000000', '993300', '333300', '003300', '003366', '000066', '333399', '333333',
'660000', 'FF6633', '666633', '336633', '336666', '0066FF', '666699', '666666', 'CC3333', 'FF9933',
'99CC33', '669966', '66CCCC', '3366FF', '663366', '999999', 'CC66FF', 'FFCC33', 'FFFF66', '99FF66'];
var picker2 = $('#color-picker2');
for (var i = 0; i < colorList.length; i++ ) {
picker2.append('<li class="color-item" data-hex="' + '#' + colorList[i] + '" style="background-color:' + '#' + colorList[i] + ';"></li>');
}
$('body').click(function () {
picker2.fadeOut(1);
});
$('.call-picker2').click(function(event) {
event.stopPropagation();
picker2.fadeIn(1);
picker2.children('li').hover(function() {
var codeHex = $(this).data('hex');
$('.color-holder2').css('background-color', codeHex);
$('#pickcolor2').val(codeHex).trigger('change');
});
});
</script>