https://codepen.io/abhilashn/pen/BRepQz
// JavaScript Document
var quiz = { "JS" : [
{
"id" : 1,
"question" : "Inside which HTML element do we put the JavaScript?",
"options" : [
{"a": "<script>", "b":"<javascript>", "c":"<scripting>", "d":"<js>"}
],
"answer":"<script>",
},
{
"id" : 2,
"question" : "What is the correct JavaScript syntax to change the content of the HTML element below.",
"options" : [
{"a": "document.getElementById('demo').innerHTML = 'Hello World!';",
"b":"document.getElementByName('p').innerHTML = 'Hello World!';",
"c":"document.getElement('p').innerHTML = 'Hello World!';",
"d":"#demo.innerHTML = 'Hello World!';"}
],
"answer":"a",
}
]
}
var score = 0;
var qno = 1;
var currentque = 0;
var totalque = quiz.JS.length;
displayQuiz = function(cque) {
currentque = cque;
$("#qid").html(this.qno);
//console.log(quiz.JS[currentque].options[0]);
$("#question").html(quiz.JS[currentque].question);
for (var key in quiz.JS[currentque].options[0]) {
if (quiz.JS[currentque].options[0].hasOwnProperty(key)) {
console.log(key + " -> " + quiz.JS[currentque].options[0][key]);
$("#question-options").append(
"<div class='form-check option-block'>" +
"<label class='form-check-label'>" +
"<input type='radio' class='form-check-input' name='option' id='q"+key+"' value='" + quiz.JS[currentque].options[0][key] + "'>" +
quiz.JS[currentque].options[0][key] +
"</label>"
);
}
}
}
checkAnswer = function(option) {
var answer = quiz.JS[currentque].answer;
option = option.replace(/\</g,"<") //for <
option = option.replace(/\>/g,">") //for >
if(option == quiz.JS[currentque].answer) {
score = score + 1;
}
}
changeQuestion = function(cque) {
currentque = currentque + cque;
displayQuiz(currentque);
}
$(document).ready(function() {
displayQuiz(0);
});
$('input[type=radio][name=option]').change(function() {
if (this.checked) {
checkAnswer(value);
}
});
$('#next').click(function() {
changeQuestion(1);
});
You need to modify your solution with these changes:
1) To update the question number when you click next
$("#qid").html(this.qno++);//<--Update question number
2) You need to clear the div so that next question's options could be shown. Just appending would keep on adding the options.
$("#question").html(quiz.JS[currentque].question);
$("#question-options").html("");//<--Clear previous question
3) Modify next button's click handler as shown below:
$('#next').click(function(e) {
e.preventDefault();
var quiz = {
"JS": [{
"id": 1,
"question": "Inside which HTML element do we put the JavaScript?",
"options": [{
"a": "<script>",
"b": "<javascript>",
"c": "<scripting>",
"d": "<js>"
}],
"answer": "<script>",
},
{
"id": 2,
"question": "What is the correct JavaScript syntax to change the content of the HTML element below.",
"options": [{
"a": "document.getElementById('demo').innerHTML = 'Hello World!';",
"b": "document.getElementByName('p').innerHTML = 'Hello World!';",
"c": "document.getElement('p').innerHTML = 'Hello World!';",
"d": "#demo.innerHTML = 'Hello World!';"
}],
"answer": "a",
}
]
}
var score = 0;
var qno = 1;
var currentque = 0;
var totalque = quiz.JS.length;
displayQuiz = function(cque) {
currentque = cque;
$("#qid").html(this.qno++);//<--Update question number
//console.log(quiz.JS[currentque].options[0]);
$("#question").html(quiz.JS[currentque].question);
$("#question-options").html("");//<--Clear previous question
for (var key in quiz.JS[currentque].options[0]) {
if (quiz.JS[currentque].options[0].hasOwnProperty(key)) {
$("#question-options").append(
"<div class='form-check option-block'>" +
"<label class='form-check-label'>" +
"<input type='radio' class='form-check-input' name='option' id='q" + key + "' value='" + quiz.JS[currentque].options[0][key] + "'>" +
quiz.JS[currentque].options[0][key] +
"</label>"
);
}
}
}
checkAnswer = function(option) {
var answer = quiz.JS[currentque].answer;
option = option.replace(/\</g, "<") //for <
option = option.replace(/\>/g, ">") //for >
if (option == quiz.JS[currentque].answer) {
score = score + 1;
}
}
changeQuestion = function(cque) {
currentque = currentque + cque;
displayQuiz(currentque);
}
$(document).ready(function() {
displayQuiz(0);
});
$('input[type=radio][name=option]').change(function() {
if (this.checked) {
checkAnswer(value);
}
});
$('#next').click(function(e) {
e.preventDefault();
changeQuestion(1);
});
.content {
margin-top: 54px;
}
.quiz-body {
margin-top: 50px;
padding-bottom: 50px;
}
.option-block-container {
margin-top: 20px;
}
.option-block {
padding: 10px;
background: aliceblue;
border: 1px solid #84c5fe;
margin-bottom: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav class="navbar navbar-toggleable-md navbar-inverse fixed-top bg-primary">
<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="#">JS Quiz</a>
<div class="collapse navbar-collapse" id="navbarCollapse">
<ul class="nav navbar-nav mr-auto"></ul>
</div>
</nav>
<div class="content">
<div class="container-fluid">
<div class="row">
<div class="col-sm-8">
<div class="quiz-body">
<form name="quizForm">
<fieldset class="form-group">
<h4><span id="qid">1.</span> <span id="question"></span></h4>
<div class="option-block-container" id="question-options">
</div>
<!-- End of option block -->
</fieldset>
<button name="next" id="next" class="btn btn-success">Next</button>
</form>
</div>
</div>
<!-- End of col-sm-8 -->
<div class="col-sm-4">
</div>
</div>
<!-- End of row -->
</div>
<!-- ENd of container fluid -->
</div>
<!-- End of content -->
Related
I have a basic add-to-cart that allows for adding and removing cart items using checkboxes.
I want to be able to pre-set some of the items to be in the cart by getting the item's id or data-wish attribute and adding it to the array for the items.
var wish = {
items: ["handbag", "backpack"]
};
How do I allow for items to be pre-selected so that they appear in the cart and the .my-wish-add button is :checked (for the icon's checked state animation).
// Wish Function
var wish = {
items: []
};
var update_product = function(product) {};
$(function() {
//Add to wish
var addToWish = function(product, qty) {
qty = qty || 1;
var wish = getWish();
var indexOfId = wish.items.findIndex(x => x.id == product.id);
if (indexOfId === -1) {
wish.items.push({
id: product.id,
img: product.img,
name: product.name,
location: product.location,
price: product.price
});
$parent = $("#" + product.id).closest(".items__cart");
$parent
.find(".wish-icon")
.addClass("active")
.attr("data-prefix", "fas");
} else {
wish.items[indexOfId].stock = Number(product.stock);
}
//Update popup wish
updateWish(wish);
};
//Remove from wish on id
var removeFromWish = function(id) {
var wish = getWish();
var wishIndex = wish.items.findIndex(x => x.id == id);
wish.items.splice(wishIndex, 1);
$parent = $("#" + id).closest(".items__cart");
$parent
.find(".wish-icon")
.first()
.removeClass("active")
.attr("data-prefix", "far");
//Update popup wish
updateWish(wish);
};
var getProductValues = function(element) {
var productId = $(element)
.closest(".items__cart")
.find(".item__tile")
.attr("id");
var productImg = $(element)
.closest(".items__cart")
.find(".item__img")
.attr("src");
var productName = $(element)
.closest(".items__cart")
.find(".item__title")
.html();
var productPrice = $(element)
.closest(".items__cart")
.find(".cost")
.html();
var productLocation = $(element)
.closest(".items__cart")
.find(".item__location")
.html();
var productTax = $(element)
.closest(".items__cart")
.find(".circle")
.html();
return {
id: productId,
img: productImg,
name: productName,
location: productLocation,
price: productPrice,
tax: productTax
};
};
$(".my-wish-add").on("change", function() {
var product = getProductValues(this);
if ($(this).is(":checked")) {
addToWish({
id: product.id,
img: product.img,
name: product.name,
location: product.location,
price: product.price,
tax: product.tax
});
} else {
removeFromWish(product.id);
}
});
//Update wish html to reflect changes
var updateWish = function(wish) {
$(".wishlist__items").html("");
for (var i = 0; i < wish.items.length; i++) {
$(".wishlist__items").append(
"<li class='wish__item'>" +
'<div class="wish__thumb">' +
"<img src='" +
wish.items[i].img +
"' />" +
"</div>" +
'<div class="wish__info">' +
'<div class="wish__header">' +
'<div class="wish-name">' +
wish.items[i].name +
"</div>" +
"</div>" +
' <div class="wish__value">' +
"<span>Price: </span> $ " +
wish.items[i].price +
"</div>" +
"</div>" +
'<div class="wish__remove">' +
'<label class="wish__label">' +
'<input type="checkbox" id="my-wish-remove' +
i +
'" class="my-wish-remove" aria-hidden="true">' +
"<i class='fas fa-heart'></i>" +
"</div>" +
"</div>"
);
(function() {
var currentIndex = i;
$("#my-wish-remove" + currentIndex).on("change", function() {
$(this)
.closest("li")
.hide(400);
setTimeout(function() {
wish.items[currentIndex].stock = "";
update_product(wish.items[currentIndex]);
$("#" + wish.items[currentIndex].id)
.parents()
.find($(".wish-btn > input"))
.prop("checked", false);
removeFromWish(wish.items[currentIndex].id);
}, 400);
});
})();
}
};
//Get Wish
var getWish = function() {
var myWish = wish;
return myWish;
};
});
.wish__item {
display: flex;
}
.my-wish-add {
font-family: "Font Awesome\ 5 Pro";
font-weight: 900;
color: #6394f8;
}
.wish-btn {
position: relative;
cursor: pointer;
}
.wish-btn input {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.wish-icon.active {
color: green;
}
.active i.fa.fa-wishlist__list {
color: #6394f8;
}
.my-wish-remove {
font-size: 20px;
cursor: pointer;
color: rgb(109, 109, 109);
}
.my-wish-remove:hover {
color: #464646;
}
.items__wish {
border: 1px solid;
width: 150px;
}
.wish__info {
flex: 1;
border: 2px solid;
}
.wish__thumb {
display: flex;
}
.wish__thumb img {
height: 30px;
}
.wish-main {
flex: 1;
}
img {
width: 50px;
}
.wishlist__list {
margin: 20px 0;
float: right;
background: #fff;
width: 320px;
position: absolute;
border: 2px solid;
border-radius: 3px;
padding: 20px;
right: 7.5%;
}
.wishlist__items li {
list-style: none;
}
.wishlist__list-empty img {
width: 100px;
}
<script src="https://pro.fontawesome.com/releases/v5.3.1/js/all.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div data-id="wishlist">
<div class="wishlist__list">
<ul class="wishlist__items">
</ul>
</div>
</div>
<div class='products'>
<div class="items__cart">
<div id='headphones' class='item__title item__tile' data-wish="headphones">Product 1</div>
<img class="item__img" src="https://www.iconasys.com/wp-content/uploads/2017/06/360-Product-Photography-White-Background-Acrylic-Riser-08.jpg">
<div>
<span>$</span>
<span class='cost'>500</span>
</div>
<label class="wish-btn">
<input type="checkbox" name="wish-check" class='my-wish-add'><i class="wish-icon far fa-heart"></i></input></label>
</div>
<div class="items__cart">
<div id='backpack' class='item__title item__tile' data-wish="backpack">Product 2</div>
<div>
<h4 class="count">200</h4>
</div>
<img class="item__img" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQoqpSgkG4AQDQOe33jI1NiW3GW2JSB-_v36aREsVyFQH55JFOJ">
<div>
<span>$</span>
<span class='cost'>460</span>
</div>
<label class="wish-btn">
<input type="checkbox" name="wish-check" class='my-wish-add'><i class="wish-icon far fa-heart"></i></label>
</div>
<div class="items__cart">
<div id='handbag' class='item__title item__tile' data-wish="handbag">Product 3</div>
<h4 class="count">400</h4>
<img class="item__img" src="https://qph.fs.quoracdn.net/main-qimg-de7d9680c4460296e461af9720a77d64">
<div>
<span>$</span>
<span class='cost'>212</span>
</div>
<label class="wish-btn">
<input type="checkbox" name="wish-check" class='my-wish-add'><i class="wish-icon far fa-heart"></i></label>
</div>
I'm unable to append a certain div to a modal when pulling in data using pnp and JavaScript.
The whole process explained:
Function DomyApiCalls - WORKS (Pulls in all the boxes with the titles)
Function filtering - WORKS (Filters the names in alphabetical order)
Function getModal - Doesn't work (I want it when a user clicks on a box, that the modal shows and just appends all the filesHtml to the .Modalbody class.
This is pulling in the page title, I need the folderName from below instead.
$(document).ready(function(){
DoMyApiCalls("boxWrap");
var current_title = $(document).attr('title'); //CURRENT_TITLE is supposed to be the "FolderName".
if(current_title == 'Acuvue') {
getModal("Acuvue");
}
});
function DoMyApiCalls(elementId) {
$.ajax({
url: "/bdm/business-development/_api/web/lists/GetByTitle('CompletedSubmissionTiles')/Items?$select=EncodedAbsUrl,Title,Line1,Line2,Hyperlink,TargetWindow,DescriptionHTMLOption,Line1,TileOrder&$orderby=Title asc",
type: "GET",
headers: {
"accept": "application/json; odata=verbose"
},
success: function (data) {
if (data.d.results) {
var object = data.d.results;
var Line1var;
for(var i = 0; i < object.length; i++)
{
if(object[i].Line1 != null) { // Covers 'undefined' as well
Line1var = "<div class='Line1'>" + object[i].Line1 + "</div>";
} else {
Line1var = "";
}
$('#' + elementId).append("<div class='col-md-4 box' data-toggle='modal' data-target='#modal"+object[i].TileOrder+"' id='TileBox"+object[i].TileOrder+"'><div id='titleBox' class='titleBox'><h1>" + object[i].Title + "</h1><div style='width:250px; height: 130px;background-color: white; border: 1px solid lightgrey;'><img style='width: auto; height: inherit; margin-left: auto; margin-right: auto; display: block;' src='" + object[i].EncodedAbsUrl + "' alt='" + object[i].Title +"'/></div></div></div>");
filtering(object[i].Title);
}
}
}
});
};
function filtering(title) {
var filter = "Name eq '" + title + "'";
$pnp.setup({
baseUrl: "/bdm/business-development/"
});
$pnp.sp.web.folders.getByName('Completed Submissions').folders.filter(filter).expand("Files").get().then(function(data){
});
}
function getModal(folderName) {
$pnp.setup({
baseUrl: "/bdm/business-development/Completed%20Submissions/"
});
$pnp.sp.web.getFolderByServerRelativeUrl("/bdm/business-development/Completed%20Submissions/" + folderName).files.orderBy("Name").get().then(function(f) {
var files = '';
$.each(f, function(index, value){
var filesHtml = "<div class='file'>" +
"<a target='_blank' href='" + value.ServerRelativeUrl + "?web=1'><img src='//PublishingImages/wordThumbSmall.png'/></a>" +
"<a target='_blank' href='" + value.ServerRelativeUrl + "?web=1'><p id='fileTitle'>" + value.Title + "</p></a>" +
"</div>";
files = files + filesHtml;
});
$(".Modalbody").append(files);
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="modal" class="modal fade" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><div id="x">×</div></button>
<h4 class="modal-title">
</h4>
</div>
<div class="modal-body">
<div class="FT-main-category" style="margin-top:0px;">
<div class="FT-main-header ms-WPBody"><strong><span style="color: white;">Files</span></strong></div>
<div class="Modalbody">
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
Instead of adding the item to the list using an add button and then removing the appended item using a remove button, how do I make them the same button (or input) so that if it is checked the item is appended to the list and if it is unchecked it is removed from the list?
I need the add and remove to be the same button so that I can remove the item from the list by either unchecking the item button OR the appended item's button.
// Wish Function
var wish = {
items: []
};
var update_product = function(product) {};
$(function() {
//Add to wish
var addToWish = function(product, qty) {
qty = qty || 1;
var wish = getWish();
var indexOfId = wish.items.findIndex(x => x.id == product.id);
if (indexOfId === -1) {
wish.items.push({
id: product.id,
img: product.img,
name: product.name,
});
$parent = $("#" + product.id).closest(".items__wish");
$parent
.find(".wish-icon")
.addClass("active")
.attr("data-prefix", "fas");
} else {
wish.items[indexOfId].qty++;
wish.items[indexOfId].stock = Number(product.stock);
}
//Update popup wish
updateWish(wish);
};
var getProductValues = function(element) {
var productId = $(element)
.closest(".items__wish")
.find(".item__tile")
.attr("id");
var productImg = $(element)
.closest(".items__wish")
.find(".item__img")
.attr("src");
var productName = $(element)
.closest(".items__wish")
.find(".item__title")
.html();
return {
id: productId,
img: productImg,
name: productName,
};
};
$(".my-wish-add").on("change", function() {
var product = getProductValues(this);
addToWish({
id: product.id,
img: product.img,
name: product.name,
});
});
//Update wish html to reflect changes
var updateWish = function(wish) {
//Add to shopping wish dropdown
$(".wishlist__items").html("");
for (var i = 0; i < wish.items.length; i++) {
$(".wishlist__items").append(
"<li>" +
'<div class="my-wish-item">' +
"<img src='" +
wish.items[i].img +
"' />" +
'<div class="wish-main">' +
'<div class="wish-name">' +
wish.items[i].name +
"</div>" +
'<div class="my-wish-remove-container">' +
'<input type="checkbox" id="my-wish-remove' +
i +
'" class="my-wish-remove" aria-hidden="true">' +
"<i class='fas fa-heart'></i>" +
"</div>"
);
//Remove from wish on id
var removeFromWish = function(id) {
var wish = getWish();
var wishIndex = wish.items.findIndex(x => x.id == id);
wish.items.splice(wishIndex, 1);
$parent = $("#" + id).closest(".items__wish");
$parent
.find(".wish-icon")
.first()
.removeClass("active")
.attr("data-prefix", "far");
//Update popup wish
updateWish(wish);
};
(function() {
var currentIndex = i;
$("#my-wish-remove" + currentIndex).on("change", function() {
$(this)
.closest("li")
.hide(400);
setTimeout(function() {
wish.items[currentIndex].stock = "";
update_product(wish.items[currentIndex]);
removeFromWish(wish.items[currentIndex].id);
}, 400);
});
})();
}
};
//Get Wish
var getWish = function() {
var myWish = wish;
return myWish;
};
});
body {
font-family: "Font Awesome\ 5 Pro";
font-weight: 900;
}
img {
width: 50px;
}
.wishlist__list {
position: absolute;
right: 0;
}
.wishlist__items li {
list-style: none;
}
<script src="https://pro.fontawesome.com/releases/v5.3.1/js/all.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div data-id="wishlist">
<div class="wishlist__list">
<ul class="wishlist__items">
</ul>
</div>
</div>
<div class='products'>
<div class="items__wish">
<div id='1' class='item__title item__tile'>Product 1</div>
<img class="item__img" src="https://www.iconasys.com/wp-content/uploads/2017/06/360-Product-Photography-White-Background-Acrylic-Riser-08.jpg">
<label class="wish-btn">
<input type="checkbox" name="wish-check" class='my-wish-add'><i class="wish-icon far fa-heart"></i></input></label>
</div>
<div class="items__wish">
<div id='2' class='item__title item__tile'>Product 2</div>
<img class="item__img" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQoqpSgkG4AQDQOe33jI1NiW3GW2JSB-_v36aREsVyFQH55JFOJ">
<label class="wish-btn">
<input type="checkbox" name="wish-check" class='my-wish-add'><i class="wish-icon far fa-heart"></i></input></label>
if your aim is only to manage wished list by checkboxes this code should be sufficient.
var addedProducts = [];
$(document).on('click', '.items__wish', function() {
var item = $(this);
var itemIndex = item.index();
if (item.parents('.wishlist__items').length > 0) {
itemIndex = parseInt(item.attr('data-index'))
}
if (item.find('.my-wish-add').prop('checked') && addedProducts.indexOf(itemIndex) < 0) {
if (item.parents('.wishlist__items').length == 0) {
item.clone().attr('data-index', itemIndex).appendTo($('.wishlist__items'))
addedProducts.push(itemIndex)
}
}
else if (item.find('.my-wish-add').prop('checked')==false && addedProducts.indexOf(itemIndex) >= 0) {
$('.products .items__wish').eq(itemIndex).find('.my-wish-add').prop('checked', false);
$('.wishlist__items .items__wish[data-index="' + itemIndex + '"]').remove();
addedProducts.splice( addedProducts.indexOf(itemIndex), 1 );
}
});
body {
font-family: "Font Awesome\ 5 Pro";
font-weight: 900;
}
img {
width: 50px;
}
.wishlist__list {
position: absolute;
right: 0;
}
.wishlist__items li {
list-style: none;
}
<script src="https://pro.fontawesome.com/releases/v5.3.1/js/all.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div data-id="wishlist">
<div class="wishlist__list">
<ul class="wishlist__items">
</ul>
</div>
</div>
<div class='products'>
<div class="items__wish">
<div id='1' class='item__title item__tile'>Product 1</div>
<img class="item__img" src="https://www.iconasys.com/wp-content/uploads/2017/06/360-Product-Photography-White-Background-Acrylic-Riser-08.jpg">
<label class="wish-btn">
<input type="checkbox" name="wish-check" class='my-wish-add'><i class="wish-icon far fa-heart"></i></input></label>
</div>
<div class="items__wish">
<div id='2' class='item__title item__tile'>Product 2</div>
<img class="item__img" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQoqpSgkG4AQDQOe33jI1NiW3GW2JSB-_v36aREsVyFQH55JFOJ">
<label class="wish-btn">
<input type="checkbox" name="wish-check" class='my-wish-add'><i class="wish-icon far fa-heart"></i></input></label>
Update: You may consider moving removeFromWish() to the same scope as addToWish() so that it is accessible to other functions.
You can use jquery to see if the checkbox is checked, then either append the item or remove the item from the list accordingly.
$(".my-wish-add").on("change", function() {
var product = getProductValues(this);
if ($(this).is(":checked")) {
addToWish({
id: product.id,
img: product.img,
name: product.name,
});
} else {
removeFromWish(product.id);
}
});
Making these two changes should be able to solve your problem. If you want to uncheck the checkbox upon removal of the list item, you can also try the following:
(function() {
var currentIndex = i;
$("#my-wish-remove" + currentIndex).on("change", function() {
$(this)
.closest("li")
.hide(400);
setTimeout(function() {
wish.items[currentIndex].stock = "";
update_product(wish.items[currentIndex]);
removeFromWish(wish.items[currentIndex].id);
// uncheck (productID - 1)th checkbox
$(".my-wish-add").eq(wish.items[currentIndex].id - 1).prop("checked", false);
}, 400);
});
})();
Unchecking a checkbox like this may not be very clear. I hope you get the basic idea and adapt this code so that it fits your style.
[Updated] Demo:
// Wish Function
var wish = {
items: []
};
var update_product = function(product) {};
$(function() {
//Add to wish
var addToWish = function(product, qty) {
qty = qty || 1;
var wish = getWish();
var indexOfId = wish.items.findIndex(x => x.id == product.id);
if (indexOfId === -1) {
wish.items.push({
id: product.id,
img: product.img,
name: product.name,
});
$parent = $("#" + product.id).closest(".items__wish");
$parent
.find(".wish-icon")
.addClass("active")
.attr("data-prefix", "fas");
} else {
wish.items[indexOfId].qty++;
wish.items[indexOfId].stock = Number(product.stock);
}
//Update popup wish
updateWish(wish);
};
//Remove from wish on id
var removeFromWish = function(id) {
var wish = getWish();
var wishIndex = wish.items.findIndex(x => x.id == id);
wish.items.splice(wishIndex, 1);
$parent = $("#" + id).closest(".items__wish");
$parent
.find(".wish-icon")
.first()
.removeClass("active")
.attr("data-prefix", "far");
//Update popup wish
updateWish(wish);
};
var getProductValues = function(element) {
var productId = $(element)
.closest(".items__wish")
.find(".item__tile")
.attr("id");
var productImg = $(element)
.closest(".items__wish")
.find(".item__img")
.attr("src");
var productName = $(element)
.closest(".items__wish")
.find(".item__title")
.html();
return {
id: productId,
img: productImg,
name: productName,
};
};
$(".my-wish-add").on("change", function() {
var product = getProductValues(this);
if ($(this).is(":checked")) {
addToWish({
id: product.id,
img: product.img,
name: product.name,
});
} else {
removeFromWish(product.id);
}
});
//Update wish html to reflect changes
var updateWish = function(wish) {
//Add to shopping wish dropdown
$(".wishlist__items").html("");
for (var i = 0; i < wish.items.length; i++) {
$(".wishlist__items").append(
"<li>" +
'<div class="my-wish-item">' +
"<img src='" +
wish.items[i].img +
"' />" +
'<div class="wish-main">' +
'<div class="wish-name">' +
wish.items[i].name +
"</div>" +
'<div class="my-wish-remove-container">' +
'<input type="checkbox" id="my-wish-remove' +
i +
'" class="my-wish-remove" aria-hidden="true">' +
"<i class='fas fa-heart'></i>" +
"</div>"
);
(function() {
var currentIndex = i;
$("#my-wish-remove" + currentIndex).on("change", function() {
$(this)
.closest("li")
.hide(400);
setTimeout(function() {
wish.items[currentIndex].stock = "";
update_product(wish.items[currentIndex]);
$(".my-wish-add").eq(wish.items[currentIndex].id - 1).prop("checked", false);
removeFromWish(wish.items[currentIndex].id);
}, 400);
});
})();
}
};
//Get Wish
var getWish = function() {
var myWish = wish;
return myWish;
};
});
body {
font-family: "Font Awesome\ 5 Pro";
font-weight: 900;
}
img {
width: 50px;
}
.wishlist__list {
position: absolute;
right: 0;
}
.wishlist__items li {
list-style: none;
}
<script src="https://pro.fontawesome.com/releases/v5.3.1/js/all.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div data-id="wishlist">
<div class="wishlist__list">
<ul class="wishlist__items">
</ul>
</div>
</div>
<div class='products'>
<div class="items__wish">
<div id='1' class='item__title item__tile'>Product 1</div>
<img class="item__img" src="https://www.iconasys.com/wp-content/uploads/2017/06/360-Product-Photography-White-Background-Acrylic-Riser-08.jpg">
<label class="wish-btn">
<input type="checkbox" name="wish-check" class='my-wish-add'><i class="wish-icon far fa-heart"></i></input></label>
</div>
<div class="items__wish">
<div id='2' class='item__title item__tile'>Product 2</div>
<img class="item__img" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQoqpSgkG4AQDQOe33jI1NiW3GW2JSB-_v36aREsVyFQH55JFOJ">
<label class="wish-btn">
<input type="checkbox" name="wish-check" class='my-wish-add'><i class="wish-icon far fa-heart"></i></input></label>
Here's a much cleaner implementation of the required functionality using buttons. You can just as easily change it to use checkboxes instead.
Pro-tip: While I understand you might have specific requirements, I'd recommend using a component based design approach and considering using pure JavaScript instead of third party libraries like jQuery.
$(function() {
$("li button").click(function(event) {
let targetList = '';
if ($(event.target).closest(".list").attr('id') === 'product-list') {
targetList = '#wish-list ul';
targetLabel = 'Remove';
} else {
targetList = '#product-list ul';
targetLabel = 'Add';
}
event.target.innerHTML = targetLabel;
$(event.target).closest("li").appendTo(targetList);
})
$("#btn-display-list").click(function() {
alert(JSON.stringify(getListInfo('#wish-list')));
})
});
function getListInfo(type) {
const list = [];
$(type + " li").each(function(i, target) {
list.push({
id: $(target).attr("id"),
img: $(target).find("img").attr("src"),
name: $(target).find("h4").html()
})
})
return list;
}
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
color: #ddd;
font-weight: lighter;
}
.container {
display: flex;
}
.list {
width: 50%;
}
ul {
padding: 0px;
}
li {
list-style-type: none;
}
li img,
li div {
display: inline-block;
margin-bottom: 10px;
vertical-align: top;
}
li img {
max-width: 70px;
}
li h4 {
margin: 0px;
}
h4,
h3 {
font-weight: lighter;
}
button {
background: #0084ff;
border: none;
border-radius: 5px;
padding: 8px 14px;
font-size: 15px;
color: #fff;
}
#banner-message.alt {
background: #0084ff;
color: #fff;
margin-top: 40px;
width: 200px;
}
#banner-message.alt button {
background: #fff;
color: #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div id="product-list" class="list">
<h3>Product Catalog</h3>
<ul>
<li id='prod-001'>
<img class="item__img" src="https://www.iconasys.com/wp-content/uploads/2017/06/360-Product-Photography-White-Background-Acrylic-Riser-08.jpg">
<div>
<h4>product 1</h4>
<button>Add</button>
</div>
</li>
<li id='prod-002'>
<img class="item__img" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQoqpSgkG4AQDQOe33jI1NiW3GW2JSB-_v36aREsVyFQH55JFOJ">
<div>
<h4>product 2</h4>
<button>Add</button>
</div>
</li>
</ul>
</div>
<div id="wish-list" class="list">
<h3>Wishlist</h3>
<ul>
</ul>
</div>
</div>
<hr/>
<button id="btn-display-list">Show Wishlist</button>
Pretty new to javascript and jquery so I don't know if it's possible, but here goes. I'm attempting to build a simple chatbot feature for a website. Basically you click the help button link, a chatbox appears with a prompt for input. User inputs and a response comes out accordingly. I've got all this working fine.
What I want is to change the text color or background color of the user:"text" or help:"text" which alternate between chatting. Once the chatbox fills with back and forth text it becomes more difficult to differentiate between user input and feedback. Ideally i'd like the background color of chatbox feedback to be a gray color while user remains white.
HTML
<ul class="nav nav-pills nav-justified">
<li role="presentation" class="dropdown">
<a id="helpBtn" class="dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">
Help<span class="caret"></span></a>
<ul class="dropdown-menu">
<div id="helpBox">
<span id="usrText"></span>
</div>
<input id="textarea" placeholder="Type Here" maxlength="15">
</ul>
</li>
</ul>
JS/jquery
$(function() {
$('#helpBtn').click(function() {
$(this).toggleClass('active');
$('#helpBox').toggle();
$('#textarea').toggle();
if ($(this).hasClass('active')) {
$('#usrText').html('');
$('#usrText').append('HelpBot: What can I help you with? ','<br />'+'Please type "sales", "info" or "contact" for information.','<br />');
}
});
});
$(function() {
$('#textarea').keydown(function() {
var text = $(this).val();
if (event.keyCode == 13) {
$(this).val('');
$('text').css({
"background":"blue",
"color":"red"
});
$('#usrText').append('User: '+text,'<br />');
}
else {
return;
}
if (matches(text)==1) {
$('#usrText').append('HelpBot: Todays sales are: ','<br />');
}
else if (matches(text)==2) {
$('#usrText').append('HelpBot: Find info here: ','<br />');
}
else if (matches(text)==3) {
$('#usrText').append('HelpBot: Call: or Email: ','<br />');
}
else {
$('#usrText').append('HelpBot: I did not understand that. ','<br />');
$('#usrText').append('Please type "sales", "info", or "contact". ','<br />');
}
return false;
$('#helpBox').scrollTop($('#helpBox').children().height());
});
});
function matches(text) {
var a1 = ['sales','sale','bargain'];
var a2 = ['info','information','411'];
var a3 = ['contact','number','email','phone'];
var split = text.split(" ");
if (a1.includes(text)) {
var match = a1.includes(text);
return 1;
}
else if (a2.includes(text)) {
var match2 = a2.includes(text);
return 2;
}
else if (a3.includes(text)) {
var match3 = a3.includes(text);
return 3;
}
}
Here's the jsfiddle for the program:
JSfiddle Chatbot
If I understood you well, you want to change background color of HelpBot message? If that is the case then just add <span style="background-color:lightgray;">Your Text</span> and do it like this:
$(function() {
$('#helpBtn').click(function() {
$(this).toggleClass('active');
$('#helpBox').toggle();
$('#textarea').toggle();
if ($(this).hasClass('active')) {
$('#usrText').html('');
$('#usrText').append('<span style="background-color:lightgray;">HelpBot: What can I help you with? </span>', '<br />' + '<span style="background-color:lightgray;">Please type "sales", "info" or "contact" for information.</span>', '<br />');
}
});
});
$(function() {
$('#textarea').keydown(function() {
var text = $(this).val();
if (event.keyCode == 13) {
$(this).val('');
$('text').css({
"background": "blue",
"color": "red"
});
$('#usrText').append('User: ' + text, '<br />');
} else {
return;
}
if (matches(text) == 1) {
$('#usrText').append('<span style="background-color:lightgray;">HelpBot: Todays sales are: </span>', '<br />');
} else if (matches(text) == 2) {
$('#usrText').append('<span style="background-color:lightgray;">HelpBot: Find info here: </span>', '<br />');
} else if (matches(text) == 3) {
$('#usrText').append('<span style="background-color:lightgray;">HelpBot: Please call: (555)555-5555.', '<br /></span>', '<span style="background-color:lightgray;">HelpBot: Or you can email us at: wookiesRus#weirdos.net</span>', '<br />');
} else {
$('#usrText').append('<span style="background-color:lightgray;">HelpBot: I did not understand that. </span>', '<br />');
$('#usrText').append('<span style="background-color:lightgray;">Please type "sales", "info", or "contact". </span>', '<br />');
}
return false;
$('#helpBox').scrollTop($('#helpBox').children().height());
});
});
function matches(text) {
var a1 = ['sales', 'sale', 'bargain'];
var a2 = ['info', 'information', '411'];
var a3 = ['contact', 'number', 'email', 'phone'];
var split = text.split(" ");
if (a1.includes(text)) {
var match = a1.includes(text);
return 1;
} else if (a2.includes(text)) {
var match2 = a2.includes(text);
return 2;
} else if (a3.includes(text)) {
var match3 = a3.includes(text);
return 3;
}
}
#helpBtn {
color: black;
text-decoration: none;
}
#helpBox {
width: 100%;
height: 250px;
background-color: white;
overflow-y: auto;
display: none;
z-index: 1000;
}
#textarea {
position: absolute;
width: 100%;
margin-top: -23px;
display: none;
}
#usrText {
line-height: 1.4;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<ul class="nav nav-pills nav-justified">
<li role="presentation" class="dropdown">
<a id="helpBtn" class="dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">
Help<span class="caret"></span></a>
<ul class="dropdown-menu">
<div id="helpBox">
<span id="usrText"></span>
</div>
<input id="textarea" placeholder="Type Here" maxlength="15">
</ul>
</li>
I was trying to iterate the 'streamers' array by the variable showindex but failed,it just shows the first element "monstercat" and last element "amazhs" of the array, using debug in chrome and showindex in the displayResult function always is 0 and 9, can't figure out why. Any ideas?
var streamers = ['monstercat', 'sivhd', 'cryaotic', 'nightblue3', 'picoca_lol', 'freecodecamp', 'trick2g', 'riotgamesbrazil', 'riotgames', 'amazhs'];
$(document).ready(function() {
var logo = "";
var channelName = "";
var showindex = 0;
streamers.forEach(function(streamer, index) {
showindex = index;
$.ajax({
type: 'GET',
jsonp: "callback",
url: 'https://api.twitch.tv/kraken/streams/' + streamer,
headers: {
'Client-ID': 'd50b88uvtwlhdfrqi3vj3k1hm3izkyx'
},
success: displayResult
});
});
function displayResult(data) {
var outstring = "";
if (data.stream !== null) {
channelName = data.stream.channel.display_name;
logo = data.stream.channel.logo;
} else {
logo = "https://placeholdit.imgix.net/~text?txtsize=6&txt=50%C3%9750&w=50&h=50";
channelName = streamers[showindex];
}
outstring +=
"<li class='streamer'>" +
"<img class='streamer-icon' src='" + logo + "'/>" +
"<p class='streamer-name'>" +
"<a href='http://twitch.tv/" + channelName + "' target='_blank'>" + channelName + "</a></p>" +
"<span class='streamer-status'>" +
"<i class='fa fa-exclamation'></i></span></li>"
$("#showBox").append(outstring);
}
});
ul {
padding: 0;
margin: 0;
}
.tab-content {
border: 1px solid #ddd;
border-top: none;
}
.streamer {
list-style-type: none;
padding: 10px;
}
.streamer-icon {
width: 50px;
}
.streamer-name {
display: inline-block;
margin-left: 10px;
}
.streamer-status {
float: right;
padding-top: 15px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<div class="container">
<div class="row col-md-4 col-md-offset-4">
<ul class="nav nav-tabs" role="tablist">
<li class="active">all
</li>
<li>online
</li>
<li>offline
</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="all">
<ul id="showBox">
</ul>
</div>
<div class="tab-pane" id="online">
<ul></ul>
</div>
<div class="tab-pane" id="offline">
<ul></ul>
</div>
</div>
</div>
</div>
It's because the calls are all happening at the same time so instantly showindex = 9 a way around this would be to do the incrementation in displayResult though it could still go wrong (but it's less likely).
You probably could change your code entirely to make it use promises which would be a lot safer.
var streamers = ['monstercat', 'sivhd', 'cryaotic', 'nightblue3', 'picoca_lol', 'freecodecamp', 'trick2g', 'riotgamesbrazil', 'riotgames', 'amazhs'];
$(document).ready(function() {
var logo = "";
var channelName = "";
var showindex = 0;
streamers.forEach(function(streamer, index) {
$.ajax({
type: 'GET',
jsonp: "callback",
url: 'https://api.twitch.tv/kraken/streams/' + streamer,
headers: {
'Client-ID': 'd50b88uvtwlhdfrqi3vj3k1hm3izkyx'
},
success: displayResult
});
});
function displayResult(data) {
var outstring = "";
if (data.stream !== null) {
channelName = data.stream.channel.display_name;
logo = data.stream.channel.logo;
} else {
logo = "https://placeholdit.imgix.net/~text?txtsize=6&txt=50%C3%9750&w=50&h=50";
channelName = streamers[showindex];
}
outstring +=
"<li class='streamer'>" +
"<img class='streamer-icon' src='" + logo + "'/>" +
"<p class='streamer-name'>" +
"<a href='http://twitch.tv/" + channelName + "' target='_blank'>" + channelName + "</a></p>" +
"<span class='streamer-status'>" +
"<i class='fa fa-exclamation'></i></span></li>"
$("#showBox").append(outstring);
showindex++;
}
});
ul {
padding: 0;
margin: 0;
}
.tab-content {
border: 1px solid #ddd;
border-top: none;
}
.streamer {
list-style-type: none;
padding: 10px;
}
.streamer-icon {
width: 50px;
}
.streamer-name {
display: inline-block;
margin-left: 10px;
}
.streamer-status {
float: right;
padding-top: 15px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<div class="container">
<div class="row col-md-4 col-md-offset-4">
<ul class="nav nav-tabs" role="tablist">
<li class="active">all
</li>
<li>online
</li>
<li>offline
</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="all">
<ul id="showBox">
</ul>
</div>
<div class="tab-pane" id="online">
<ul></ul>
</div>
<div class="tab-pane" id="offline">
<ul></ul>
</div>
</div>
</div>
</div>
Here's another way to do it, it doesn't use foreach but iterates through the array another way. This way is a bit slower but means it doesn't get ahead of itself (you can actually see each one pop in)
var streamers = ['monstercat', 'sivhd', 'cryaotic', 'nightblue3', 'picoca_lol', 'freecodecamp', 'trick2g', 'riotgamesbrazil', 'riotgames', 'amazhs'];
$(document).ready(function() {
var logo = "";
var channelName = "";
var showindex = 0;
//Work out if there are any streamers left in the array
function calcStreamers() {
if (showindex < (streamers.length - 1)) {
//if there are add 1 and go get it
showindex++;
streamersGet();
} else {
//if not just stop
return false
}
};
//The get function
function streamersGet() {
$.ajax({
type: 'GET',
jsonp: "callback",
url: 'https://api.twitch.tv/kraken/streams/' + streamers[showindex],
headers: {
'Client-ID': 'd50b88uvtwlhdfrqi3vj3k1hm3izkyx'
},
success: displayResult
});
};
function displayResult(data) {
var outstring = "";
if (data.stream !== null) {
channelName = data.stream.channel.display_name;
logo = data.stream.channel.logo;
} else {
logo = "https://placeholdit.imgix.net/~text?txtsize=6&txt=50%C3%9750&w=50&h=50";
channelName = streamers[showindex];
}
outstring +=
"<li class='streamer'>" +
"<img class='streamer-icon' src='" + logo + "'/>" +
"<p class='streamer-name'>" +
"<a href='http://twitch.tv/" + channelName + "' target='_blank'>" + channelName + "</a></p>" +
"<span class='streamer-status'>" +
"<i class='fa fa-exclamation'></i></span></li>"
$("#showBox").append(outstring);
//Once the data has been added to the page go and check if there are more to add
calcStreamers();
}
//Initally start by getting the first result
streamersGet();
});
ul {
padding: 0;
margin: 0;
}
.tab-content {
border: 1px solid #ddd;
border-top: none;
}
.streamer {
list-style-type: none;
padding: 10px;
}
.streamer-icon {
width: 50px;
}
.streamer-name {
display: inline-block;
margin-left: 10px;
}
.streamer-status {
float: right;
padding-top: 15px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<div class="container">
<div class="row col-md-4 col-md-offset-4">
<ul class="nav nav-tabs" role="tablist">
<li class="active">all
</li>
<li>online
</li>
<li>offline
</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="all">
<ul id="showBox">
</ul>
</div>
<div class="tab-pane" id="online">
<ul></ul>
</div>
<div class="tab-pane" id="offline">
<ul></ul>
</div>
</div>
</div>
</div>
You wanted to iterate through the array correct?
var streamers = ['monstercat', 'sivhd', 'cryaotic', 'nightblue3', 'picoca_lol', 'freecodecamp', 'trick2g', 'riotgamesbrazil', 'riotgames', 'amazhs'];
$(document).ready(function() {
$(streamers).each(function(index, streamer){
console.log(streamer+" "+index);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>