Select In Stock Items - javascript

I'm creating a script to perform a click action to only select in-stock items. But I'm having a hard time selecting the content "Disponible"
HTML below:
<div class="top namePartPriceContainer">
<span id="InventoryStatus_OnlineStatus_691003" class="text inventoryStatus inv-status-3" itemprop="availability" href="https://schema.org/InStock" content="Disponible">In Stock
</span>
<div id="InventoryStatus_ShowLink_Section_691003" class="left available" style="display:none;">
<span class="text Select attributes to see availability">Select attributes to see availability
</span>
</div>
My JavaScript code:
var products = document.getElementById("dijit__WidgetBase_0");
var items = products.getElementsByTagName("li");
for (var i = 0; i < items.length; ++i) {
if(items[i].getElementsByTagName("span")[0].innerText === "In Stock"){
document.getElementById("productPageAdd2Cart").click();
}
}

getAttribute(); looks like the solution for you.
var content = document.getElementById('id').getAttribute('content');
and then:
if(content == 'Disponible') {
document.getElementById("productPageAdd2Cart").click();
}

Related

Repeating Popup IDs

I am pulling data from MySQL database and displaying user posted content on the page. A UserPost consists of data from 2 tables, UserTable and PostTable.
When querying from both tables I have the correct information displayed until I click the edit button. Then the queried data inside the popup always matches the first element of the query. I believe this is because the popup has an ID. I tried using PHP data to have multiple buttons with different IDs but I am still getting the same popup content correlating with the first queried data. I have highlighted the lines in question with "<-- PROBLEM HERE**********************************"
Thank you.
PHP Function Calling All User Posts
function homePosts($conn) {
$UserID = $_SESSION['UserID'];
$userPostSQL = "SELECT * FROM PostTable WHERE UserID = ? AND SectionID = 1 ORDER BY Date DESC";
$userPostSTMT = $conn->prepare($userPostSQL);
$userPostSTMT->bind_param("s", $UserID);
$userPostSTMT->execute();
$userPostRESULT = $userPostSTMT->get_result();
if (mysqli_num_rows($userPostRESULT) != 0) {
// User Posts Exist
while ($userPostROW = $userPostRESULT->fetch_assoc()) {
$userInfoSQL = "SELECT UserName, ProfilePicture FROM UserTable WHERE UserID = ?";
$userInfoSTMT = $conn->prepare($userInfoSQL);
$userInfoSTMT->bind_param("s", $UserID);
$userInfoSTMT->execute();
$userInfoRESULT = $userInfoSTMT->get_result();
if (mysqli_num_rows($userInfoRESULT) != 0) {
// User Info Exists
while ($userInfoROW = $userInfoRESULT->fetch_assoc()) {
$Date = $userPostROW['Date'];
$Text = $userPostROW['Text'];
$PostID = $userPostROW['PostID'];
$UserName = $userInfoROW['UserName'];
$ProfilePicture = $userInfoROW['ProfilePicture'];
echo '
<div class="popup" id="popup-'.$PostID.'"> <-- PROBLEM HERE $PostID remains the same throughout the loop**********************************
<div class="overlay"></div>
<div class="content">
<div class="close-btn" onclick="togglePopup()">×</div>
<h1>Edit Post</h1>
<p>'.$Text.'</p>
<p>This Post ID keeps the value of the first loop iteration'.$PostID.'</p>
</div>
</div>
<div class="postBox">
<img class="postprofilepicture" src="../profilepictures/'.$ProfilePicture.'">
<p class="postusername">'.$UserName.'<p>
<p class="posttime">'.date('M jS, Y h:ia',strtotime($Date)).'<p>
<p>'.$Text.'</p>
<p>This Post ID Changes through for every new row'.$PostID.'<p>
<br>
<div class="dropdown">
<button onclick="myFunction(this)" class="dropbtn">···</button>
<div Id="myDropdown" class="dropdown-content">
View
Like
Save
Edit
<button onclick="togglePopup()">Popup</button>
</div>
</div>
</div>
<br>
<script>
function togglePopup(){
document.getElementById("popup-'.$PostID.'").classList.toggle("active"); <-- PROBLEM HERE $PostID remains the same throughout the loop**********************************
}
function myFunction(e) {
e.parentNode.querySelector(".dropdown-content").classList.toggle("show")
}
window.onclick = function(event) {
if (!event.target.matches(".dropbtn")) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains("show")) {
openDropdown.classList.remove("show");
}
}
}
}
</script>
';
}
}
}
}
$userPostSTMT->free_result();
$userPostSTMT->close();
$userInfoSTMT->free_result();
$userInfoSTMT->close();
}
I needed to create a $Count variable that would assign a number for each post instead of using a random postid. I could then call element by classname using the count number to call an array of all the divs with a specific class name.
$Count = 0;
<div class="popup" class="popup">
<div class="overlay"></div>
<div class="content">
<div class="close-btn" onclick="togglePopup('.$PopCount.')">×</div>
<h1>Edit Post</h1>
<p>'.$Text.'</p>
<p>This Post ID keeps the value of the first loop iteration'.$PostID.'</p>
</div>
</div>
<div class="postBox">
<img class="postprofilepicture" src="../profilepictures/'.$ProfilePicture.'">
<p class="postusername">'.$UserName.'<p>
<p class="posttime">'.date('M jS, Y h:ia',strtotime($Date)).'<p>
<p>'.$Text.'</p>
<p>This Post ID Changes through for every new row'.$PostID.'<p>
<br>
<div class="dropdown">
<button onclick="myFunction(this)" class="dropbtn">···</button>
<div Id="myDropdown" class="dropdown-content">
View
Like
Show
Edit
<button onclick="togglePopup('.$PopCount.')">Popup</button>
</div>
</div>
</div>
<br>
<script>
function togglePopup(PopCount){
document.getElementsByClassName("popup")[PopCount].classList.toggle("active");
}
function myFunction(e) {
e.parentNode.querySelector(".dropdown-content").classList.toggle("show")
}
window.onclick = function(event) {
if (!event.target.matches(".dropbtn")) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains("show")) {
openDropdown.classList.remove("show");
}
}
}
}
</script>
';
$PopCount++;

Pagination will show first page, but not second or third

I'm trying to set up pagination for some blog posts. It works with the first page, and I check my tests to see if the loop is actually populating the "postsToDisplay" array (which it does), but when I click the second-page button, nothing shows up. I can click the first-page button and it brings the first page of posts back up. For some reason, it won't push the new arrays to the page though.
I've tried adding and taking away tests to see what is working. The array is definitely being populated, and the loop is going through the correct "i" values just fine.
Here's some edited code to reproduce my problem:
//Use this as "scripts.js"
$(document).ready(function() {
var realBlog = document.getElementsByClassName("realBlog");
var postsPerPage = 2;
var $pagination = $(".pagination")
function showPage(page) {
$(realBlog).hide();
let postsToDisplay = [];
for (let i = 0; i < realBlog.length; i += 1) {
if (i >= page * postsPerPage && i <= page * postsPerPage + postsPerPage - 1) {
postsToDisplay.push(realBlog[i]);
console.log(i); //Test to see if the loop is running the correct numbers
$(postsToDisplay[i]).show();
}
}
console.log(postsToDisplay); //Test to see if the array is full
return postsToDisplay;
}
showPage(0);
function createPageNumbers() {
let createUl = document.createElement("ul");
createUl.className = "pageNumbers";
for (let i = 1; i <= Math.ceil(realBlog.length/2); i += 1) {
let createLi = document.createElement("li");
let createA = document.createElement("a");
createA.href = "#" + i;
createA.textContent = i;
createLi.className = "pageButton";
createLi.append(createA);
createUl.append(createLi);
$(".pagination").append(createUl);
createA.addEventListener("click", () => {
showPage(i-1);
});
}
}
createPageNumbers();
});
//Use this as index.html
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="scripts.js"></script>
</head>
<body>
<div class="container realBlog">
<h1 class="realBlogTitle threeDText">Title</h1>
<p class="entry"></p>
<div class="entryInfo">
<span class="tag1"></span>
<span class="tag2"></span>
<span class="date"></span>
<span class="time"></span>
</div>
<div class="borderBottom"></div>
</div>
<div class="container realBlog">
<h1 class="realBlogTitle threeDText">Title</h1>
<p class="entry"></p>
<div class="entryInfo">
<span class="tag1"></span>
<span class="tag2"></span>
<span class="date"></span>
<span class="time"></span>
</div>
<div class="borderBottom"></div>
</div>
<div class="container realBlog">
<h1 class="realBlogTitle threeDText">Title</h1>
<p class="entry"></p>
<div class="entryInfo">
<span class="tag1"></span>
<span class="tag2"></span>
<span class="date"></span>
<span class="time"></span>
</div>
<div class="borderBottom"></div>
</div>
<div class="pagination"></div>
</body>
</html>
Page 1 should show posts 1 and 2, page 2 should show post 3.
Alright, I found the answer, and of course, it's a silly mistake. I have this little snippet: $(postsToDisplay[i]).show();
I'm not sure why I'm trying to show each 'i' when I can just show the whole array... So the fix is $(postsToDisplay).show();

Issues with code for a simple on page search

I am trying to build a simple on page search that uses event listeners to look at a containers data and then hides that whole container if it doesn't have the required information.
So far I have:
// get search element
let searchInput = document.getElementById ('searchInput');
// add event listener
searchInput.addEventListener ('keyup', searchPage);
function searchPage(){
//search input detection
let searchValue = document.getElementById('searchInput').value;
//set parameters to search from
let parent = document.getElementById('product-container');
let child = parent.getElementsByTagName('span');
for(let i = 0;i < child.length;i++){
let a = child[i];
if(a.innerHTML.indexOf(searchValue) >= -1) {
child[i].parentNode.style.display = '';
} else {
child[i].parentNode.style.display = 'none';
};
};
};
But this only acts on the first product-container it finds, there are 5 such containers on the page.
How do I make this look through all containers, but hide the ones that don't contain any of the information typed in the search bar.
I am getting products from an API so using html replace to add to the following template:
<script id="template" type="text/template">
<div class="product">
<div class="product--header">{{ type }}</div>
<div class="product--image"><img src="../app/assets/images/no-image.png" alt="no image"> </div>
<div class="product--information" id="product--information">
<div class="product--title"><span>{{ name }}</span></div>
<!--This is just a place holder we would house the prices here if they were on the API -->
<div class="product--price">£55</div>
<div class="product--brand"><strong>Brand:</strong><span> {{ brand }}</span></div>
<div class="product--colour"><strong>Colour:</strong><span> {{ colour }}</span></div>
<div class="product--sizes">
<select>
<option value="" disabled selected>Select Size </option>
{{ options }}
</select>
</div>
<div class="product--description"><strong>Description:</strong><br><div class="product--description__content"><span> {{ description }} </span></div></div>
<div class="product--code"><strong>Product ID:</strong><span> {{ productid }}</span></div>
<div class="product--buttons">
<button class="btn--buy" aria-label="Add to Basket">Add to basket</button>
<button class="btn--save" aria-label="Save for Later">Save for later</button>
</div>
<button class="product--add-to-wishlist" aria-label="Add to Wishlist"><i class="fas fa-heart"></i></button>
</div>
</div>
</script>
The search box code is as follows:
<input type="text" name="search" id="searchInput" placeholder="Enter Search...">
and the code that the template goes into is:
<div id="product-container">
<div class="featured"></div>
<div class="products"></div>
</div>
Because you have multiple product containers, use document.getElementsByClassName() instead of document.getElementById() and provide product-container class as argument.
let searchInput = document.getElementsByClassName ('container');
You need to modify searchPage() method. Instead of using document to find searchValue and parent use this.
let searchValue = this.getElementsByClassName('searchInput')[0].value;
let parent = this.getElementsByClassName('container')[0];
Please, add HTML code.
EDIT: If I understand correctly you have one search input which will search multiple product containers. Here is one simple example, which you can easily apply to your problem.
HTML:
<input type="text" name="search" id="searchInput" placeholder="Enter Search...">
<div class="product-container">
<span class="product">Kiwi</span>
<p>Kiwi description</p>
</div>
<div class="product-container">
<span class="product">Banana</span>
<p>Banana description</p>
</div>
<div class="product-container">
<span class="product">Apple</span>
<p>Apple description</p>
</div>
JS:
let searchInput = document.getElementById ('searchInput');
searchInput.addEventListener ('keyup', searchPage);
function searchPage(){
let searchValue = this.value.toUpperCase();
let products = document.getElementsByClassName('product');
for(let i = 0; i < products.length; i++) {
console.log(products[i].innerHTML.toUpperCase());
if (products[i].innerHTML.toUpperCase().indexOf(searchValue) > -1)
products[i].parentNode.style.display = '';
else
products[i].parentNode.style.display = 'none';
};
};
CSS:
.product-container {
display: flex;
flex-direction: column;
margin-bottom: 10px;
background: grey;
}
.product-container span {
font-size: 20px;
}
.product {
display: block;
}
https://jsfiddle.net/gardelin/koc5eg6v/25/

How to get grand total of all input values in javascript if dynamically entered

I'm looking to acquire a grand total of all product input field values that are dynamically generated when a user clicks on either the plus or minus button which, for that, adds the total price for each product.
Any help is greatly appreciated. This is what I have so far:
JS
$(function() {
$('.service_product-item').each(function() {
var thisEl = $(this),
btnPlus = thisEl.find('.service_btn-plus'),
btnMinus = thisEl.find('.service_btn-minus'),
fieldQtt = thisEl.find('input[name="service-qt1"],input[name="service-qt2"]'),
itemPriceEl = thisEl.find('.service_item-price'),
price = itemPriceEl.data('price');
// Add Products & Products Price
btnPlus.on('click', function() {
qttValue = parseInt(fieldQtt.val());
fieldQtt.val(qttValue + 1);
itemPriceEl.html('$' + (qttValue + 1) * price);
});
// Subtract Products & Products Price
btnMinus.on('click', function() {
qttValue = parseInt(fieldQtt.val()) - 1;
var newQTT = (qttValue <= 0) ? 0 : qttValue;
fieldQtt.val(newQTT);
itemPriceEl.html('$' + newQTT * price);
});
});
});
HTML
<div class="service_products_and_services_wrapper">
<div class="service_product-items">
<div class="service_product-item">
<div class="service_item-wrap">
<img src="http://www.kinyu-z.net/data/wallpapers/27/796765.png" alt="QT1" title="" />
<div class="service_wrap-qtt">
<div class="service_wrap-qtt-field-qtt">
<input class="service_field-qtt" name="service-qt1" value="0" readonly="" />
</div>
<div class="service_wrap-qtt-minus-plus">
<div class="service_btn-cart-qtt service_btn-plus">+</div>
<div class="service_btn-cart-qtt service_btn-minus">-</div>
</div>
</div>
</div>
<div class="service_item-info">
<div class="service_item-title">QT1<br>
<span style="font-size: .7em; text-transform: none;">($5 per item)</span>
</div>
<div class="service_item-price" data-price="5">$0</div>
</div>
</div>
<div class="service_product-item">
<div class="service_item-wrap">
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRIuVn6ZXHwQiFC0IlB1N_CxbXo6-5x1A4yqspYsxUUb0Xjmu8L" alt="QT2" title="" />
<div class="service_wrap-qtt">
<div class="service_wrap-qtt-field-qtt">
<input class="service_field-qtt" name="service-qt2" value="0" readonly="" />
</div>
<div class="service_wrap-qtt-minus-plus">
<div class="service_btn-cart-qtt service_btn-plus">+</div>
<div class="service_btn-cart-qtt service_btn-minus">-</div>
</div>
</div>
</div>
<div class="service_item-info">
<div class="service_item-title">QT2<br>
<span style="font-size: .7em; text-transform: none;">($10 per item)</span>
</div>
<div class="service_item-price" data-price="10">$0</div>
</div>
</div>
</div>
<p style="margin-top: 40px;">Grand Total: $0</p>
</div>
and here is a DEMO
There are some issues with the problem statement. Main one is that you don't really have any model defined for your application and your html acts as a data model as well, and important data is scoped to the event handlers. Also it is not clear what is the initial state of that application. So I just modify your code a bit.
One simple approach just to show how it could be done is following:
have a global total
with each minus and plus update the value accordingly
https://jsfiddle.net/Lyxceu3s/43/
var total = 0;
$(function() {
$('.service_product-item').each(function() {
var thisEl = $(this),
btnPlus = thisEl.find('.service_btn-plus'),
btnMinus = thisEl.find('.service_btn-minus'),
fieldQtt = thisEl.find('input[name="service-qt1"],input[name="service-qt2"]'),
itemPriceEl = thisEl.find('.service_item-price'),
price = itemPriceEl.data('price');
// Add Products & Products Price
btnPlus.on('click', function() {
qttValue = parseInt(fieldQtt.val());
fieldQtt.val(qttValue + 1);
total = total + price;
itemPriceEl.html('$' + (qttValue + 1) * price);
$('#idGT').html(total);
});
// Subtract Products & Products Price
btnMinus.on('click', function() {
qttValue = parseInt(fieldQtt.val()) - 1;
if(qttValue >= 0){
total = total - price;
}
var newQTT = (qttValue <= 0) ? 0 : qttValue;
fieldQtt.val(newQTT);
itemPriceEl.html('$' + newQTT * price);
$('#idGT').html(total);
});
});
});
And that would also require a little modification to your html:
<p style="margin-top: 40px;">Grand Total: $<span id="idGT">0</span></p>
Note: that in case of a minus, you have to check that quantity is above or 0 before you conditionally reset it to 0.
As a general note, you might want to separate your models from your views. Check the following SO thread for a digest: "Hello World" in MVC Pattern
Updated the fiddle. Made few changes to it
Please take a look at it and let me know if thats what you are looking for.
https://jsfiddle.net/Lyxceu3s/35/
var firstTotal = $('input[name="service-qt2"]').val() * 10 ;
var secondTotal = $('input[name="service-qt1"]').val() * 5;
$('#grandTotal').html(firstTotal + secondTotal)

Unable to disable `<li>` elements by setting `disable` property to `true`

I'm trying to make the rest of my chat room app disabled while a modal is open. I've been using element.disable = true to disable the buttons and this has worked. I have a ul where each li is the name of a chat room that is clickable and opens up its respective chat room in another container. I'm trying to disable the lis using the same disable.true method. I'm using a for loop to iterate through the array of lis, but it isn't working.
I used console.log to view the variable with the array stored in it (var lis) as well as the console.log(lis.length). The console shows that the array has a length of 5 but returns lis.length as 0.
Would be much appreciated if someone could tell me what I'm doing incorrectly.
HTML:
<div class"home-template" id="home">
<div class="rooms-container">
<h1 class="app-title">Bloc Chat</h1>
<ul id="rooms-list">
<li class="room-item" id="room-item" ng-repeat="chat in home.chatRooms">
{{ chat.$value }}
</li>
</ul>
<button class="btn btn-warning" id="new-room-button" type="button" ng-click="home.open()">New room</button>
<button class="btn btn-warning" id="delete-cookies-button" type="button" ng-click="home.deleteCookies()">Delete Cookie for testing</button>
</div>
<div class="messages-container">
<h1 class="current-room" ng-bind="home.activeRoom"></h1>
<ul class="messages-list">
<li class="message-bubble" ng-repeat="message in home.messages">
<div class="username">{{ message.username }}</div>
<div class="sentAt">{{ message.sentAt }}</div>
<div class="content">{{ message.content }}</div>
</li>
</ul>
</div>
</div>
JavaScript in a home controller:
home.cookieDisplay = $cookies.get('blocChatCurrentUser');
var modals = document.getElementsByClassName('modal');
var lis = document.getElementsByClassName('room-item');
var newButton = document.getElementById('new-room-button');
var delButton = document.getElementById('delete-cookies-button');
if (modals.length === 0) {
newButton.disabled = false;
delButton.disabled = false;
for (var i = 0; i < lis.length; i++) {
lis[i].disabled.false;
}
} else if (modals.length !== 0) {
newButton.disabled = true;
delButton.disabled = true;
for (var i = 0; i < lis.length; i++) {
// lis[i].setAttribute('display', 'none');
lis[i].disabled.true;
}
}
Here's what my console looks like:
You can't disable the li itself.
You can either disable the anchor tag (a) in it for example like this (refernece):
document.getElementById("tab_c").childNodes[0].onclick = function() {return false;};​
Or you can set pointer-events:noneas it has been done using CSS (reference):
.disabled {
pointer-events:none; //This makes it not clickable
opacity:0.6; //This grays it out to look disabled
}

Categories