Implement shopping cart JavaScript - javascript

here what I am trying to do is when a user clicks the + button function should get called, it looks for the cookie shopping_cart. Then it tries to find the JSON with key 'item_qty', which is key-value pair of all the items in the cart. But the cart is not updating, moreover when clicked on + button is showing Unexpected token N in JSON at position 0
In browser console I am getting it as
"csrftoken=some_value; shopping_cart=None"
var updateCart = function (count) {
$('#cart-info').val($('#cart-info').val() + count);
};
var item_add = function (item_slug) {
var shopping_cart = JSON.parse($.cookie("shopping_cart"));
var item_slug = item_slug;
if(shopping_cart.hasOwnProperty('item_qty')){
item_qty_dict = shopping_cart['item_qty'];
if(item_qty_dict.hasOwnProperty(item_slug)){
var count_pre = item_qty_dict[item_slug];
item_qty_dict[item_slug] = count_pre + 1;
}
else {
item_qty_dict[item_slug] = 1;
shopping_cart['item_qty'] = item_qty_dict;
}
}
else {
shopping_cart = {}
shopping_cart['item_qty'] = {item_slug: 1};
}
$.cookie("shopping_cart", JSON.stringify(shopping_cart));
var temp= $.cookie('shopping_cart')
console.log(JSON.parse(temp));
};
var buttonPlus = $(".cart-qty-plus");
var incrementPlus = buttonPlus.click(function () {
var $n = $(this)
.parent(".qnty_chngr")
.find(".qty");
$n.val(Number($n.val()) + 1);
var product_slug = $(this).parent(".qnty_chngr").siblings('.product-slug').val();
console.log(product_slug);
updateCart(1);
item_add(product_slug);
});
HTML:
<div class="qnty_chngr">
<button class="cart-qty-plus" type="button" value="+">+</button>
<input type="text" name="qty" maxlength="12" value="1" class="input-text qty"/>
<button class="cart-qty-minus" type="button" value="-" title="Add less quantity">-</button>
</div>
<input type="hidden" class="product-slug" name="product_slug" value="{{ medicine.slug }}">
<div class="add_to_cart">
<button class="add_to_cart_txt" value="10"><span class="AddInfoBtn">Add </span></button>
</div>,

Seems in your cookie there is no valid JSON. None is not valid, it should be "None" (with quotes). Remove the cookie before testing.
Also if possible try using this library which works the way you expected.
https://github.com/js-cookie/js-cookie

Related

Updating an Object in LocalStorage Using JavaScript?

Edit - Updated JS code to display suggestions made in comments, still having issues.. Now the button <input id="edit" type="submit" value="Submit"> won't go to edit.html, instead it is returning action.html? It is nested inside of the editForm?
I have a simple form which I have managed to learn to submit, add, remove, and display bookings using the localStorage (thanks to those who helped on here!).
My last task is to amend a booking, I think I am almost there with it, but not sure how to call the indexes (excuse my jargon), to replace the values.
The form submits and the web address reads something like edit.html?OldFirstName=NewFirstName&OldLastName=NewLastName, however the values don't update in storage, and it throws an error saying
Uncaught TypeError: Cannot read property 'fname' of undefined`.
I expected this to happen as I know I am not finding the values correctly, but I can't figure out how I should be writing it out? My thought process was that it would be similar to the original submit function but with the [i] values for fname and lname?
Here's my JS code - if you need anything else from me let me know:
// ~~~ add bookings to localStorage
var bookings = localStorage.getItem("bookings");
$("#submit").click(function () {
bookings = (bookings) ? JSON.parse(bookings) : [];
var newBookings = {
fname: $('#fname').val(),
lname: $('#lname').val()
}
bookings.push(newBookings);
var json = JSON.stringify(bookings);
window.localStorage.setItem("bookings", json);
});
// ~~~ edit bookings in localStorage
$("#edit").click(function (e) {
e.preventDefault();
bookings = (bookings) ? JSON.parse(bookings) : [];
var parent_form = $('#editForm');
var fname = parent_form.find('.input:eq(0)').val();
var lname = parent_form.find('.input:eq(1)').val();
var newBookings = {
fname: fname,
lname: lname
}
bookings.push(newBookings);
var json = JSON.stringify(bookings);
window.localStorage.setItem("bookings", json);
});
// ~~~ display bookings in browser
function showBooking(i) {
var bookingResult = document.getElementById("result");
var ul = document.createElement("ul");
var bookingItems = JSON.parse(localStorage.getItem("bookings")) || [];
bookingResult.innerHTML = "";
for (let i = 0; i < bookingItems.length; i++) {
bookingResult.innerHTML += `<div class="card card-body bg-light m-4">
<h3>${bookingItems[i].fname + " " + bookingItems[i].lname}
<button onclick="deleteBooking(${i})" class="btn btn-danger text-light ">Delete</button>
<button onclick="editBooking(${i})" class="btn btn-danger text-light ">Edit</button>
</h3>
</div>`;
}
}
// ~~~ edit bookings in browser
function editBooking(i) {
var bookingResult = document.getElementById("editAppt");
var bookingItems = JSON.parse(localStorage.getItem("bookings")) || [];
bookingResult.innerHTML =
`<form id="editForm" name="editForm" onsubmit="return editForm(this)" class="col-sm-6">
<div class="row">
<input type="text" class="input" id="fname_${i}" placeholder="${bookingItems[i].fname}" name="${bookingItems[i].fname}" required>
<input type="text" id="lname_${i}" class="input" placeholder="${bookingItems[i].lname}" name="${bookingItems[i].lname}" required>
<input id="edit" type="submit" value="Submit">
</div>
</form>`;
}
// ~~~ delete bookings from localStorage
function deleteBooking(i){
var bookingItems = JSON.parse(localStorage.getItem("bookings"));
bookingItems.splice(i, 1);
localStorage.setItem("bookings", JSON.stringify(bookingItems));
showBooking();
}
// ~~~ form submit handlers
function setAction(form) {
form.action = "action.html";
}
function editForm(form) {
form.action = "edit.html";
}
I can see that the issue comes from this like :
$("#edit").click(function (i) {
You expect the click event to return an index but it's not, the i will represent the event object, so you may need to use $(this) to get the related inputs like :
$("#edit").click(function (e) {
var parent_form = $(this.form);
var fname = parent_form.find('.input:eq(0)').val();
var lname = parent_form.find('.input:eq(1)').val();
....
NOTE: The id must not be duplicated, so you need to avoid that, you may use prefix like:
<input type="text" class="input" id="fname_${i}" placeholder="${bookingItems[i].fname}" name="${bookingItems[i].fname}" required>
<input type="text" class="input" id="lname_${i}" placeholder="${bookingItems[i].lname}" name="${bookingItems[i].lname}" required>

Fill textbox from url query and call function

<input type="text" id="tnum" maxlength="50" placeholder="Enter Your Tracking ID" />
<input class="btn" type="button" value="TRACK" onclick="doTrack()" />
<div id="YQContainer"></div>
So basically, I have a page that can track packages for my customers. I want to be able to send them a link in their email that will automatically track their package from the link. ( they don't have to type in their tracking id and click track when they go to my tracking page )
example.com/track?tnum=3298439857
This is what i'm using to track packages.
https://www.17track.net/en/externalcall/single
The basic idea is as follows:
Wait for page to load
Parse the URL and extract needed query parameter
Set the value of the form element
Call the doTrack() function
// Handy function to parse the URL and get a map of the query parameters
function parseQueryParameters(url) {
var qp = {};
if (!url) {
return qp;
}
var queryString = url.split('?')[1];
if (!queryString) {
return qp;
}
return queryString.split('&')
.reduce(function(m, d) {
var splits = d.split('=');
var key = splits[0];
var value = splits[1];
if (key && value) {
m[key] = value;
}
return m;
}, qp);
}
//Wait for page to load
window.onload = function() {
//Extract tnum query parameter
var qp = parseQueryParameters(window.location.href);
//If no parameter is provided, do nothing
if (!qp.tnum) return;
//Set the value of the form element
document.getElementById("tnum").value = qp.tnum;
// Call doTrack
doTrack();
}
//Temporary doTrack function - remove when integrating ;)
function doTrack() {
console.log(document.getElementById("tnum").value)
}
<input type="text" id="tnum" maxlength="50" placeholder="Enter Your Tracking ID" />
<input class="btn" type="button" value="TRACK" onclick="doTrack()" />
<div id="YQContainer"></div>
<html>
<head>
<script>
function setURL(){
var dt_value = document.getElementById("tnum").value;
//just test here ..what is coming..
alert(dt_value );
var sjdurl = "example.com/track?tnum="+dt_value;
popup = window.open(sjdurl,"popup"," menubar =0,toolbar =0,location=0, height=900, width=1000");
popup.window.moveTo(950,150);
}
</script>
</head>
<body>
<input type="Text" id="tnum" maxlength="25" size="25"/>
<input type='button' onclick='setURL()' value='SUBMIT'>
</body>
</html>
function doTrack(tnum) {
var trackNumber = tnum;
window.open("example.com/track?tnum="+trackNumber);
}
$(".btn").on('click',function(e) {
e.preventDefault();
var tnum = $('#tnum').val();
if (tnum!="") {
doTrack(tnum);
} else {
return false;
}
});

stepUp(1) , stepDown(1) not working in IE

HTML5 stepUp(1) and stepDown(1) are not working in IE.
Here is my code:
<div class = "col-sm-3">
<div class = "waist">
<p class = "waist-measure" id="mens-bottom-waist">Waist</p>
<a class = "waist-plus btn" onclick="waistPlus()">+</a>
<a class = "waist-minus btn " onclick="waistMinus()">-</a>
</div>
</div>
<script>
function waistPlus() {
document.getElementById("waist").stepUp(1);
}
function waistPlus() {
document.getElementById("waist").stepDown(1);
}
</script>
The methods stepUp and stepDown are only defined on <input> elements with type="number". The element with id="waist" in your document isn't of that type, so the methods don't work.
The methods stepUp and stepDowm are not supported by IE.
You can achieve this by using this:
var my_value = 1;
function stepup(){
var cur_val = document.querySelector("#quantity").value;
if(cur_val == 1 || cur_val > 1){
//Parse Current Value to Int
my_value = (parseInt(cur_val) + 1);
document.querySelector("#quantity").value = my_value;
}
}
function stepdown(){
var cur_val = document.querySelector("#quantity").value;
if(cur_val > 1){
//Parse Current Value to Int
my_value = (parseInt(cur_val) - 1);
document.querySelector("#quantity").value = my_value;
}
}
<input type="number" id="quantity" autocomplete="off" step="1" value="1"/>
<button type="button" onclick="stepup();">StepUp</button>
<button type="button" onclick="stepdown();">StepDown</button>
Hope this will help

Trying to create a form with 2 "quantity" selectors using html, javascript

I am trying to create a quantity selector like what you would find in a grocery store website or in most e-commerce sites. (One with +1 and -1 buttons) I can make the first selector work but can't seem to get the second one to.
Here's the code and HTML I have so far:
function addNum1() {
var newValue = Number(ordernow.firstvalue.value);
newValue +=1;
ordernow.firstvalue.value = newValue;
}
function minusNum1() {
var subNum = Number(ordernow.firstvalue.value);
if (subNum > 0) {
subNum -= 1;
ordernow.firstvalue.value = subNum;
}
}
function addNum2() {
var newValue = Number(ordernow.firstvalue2.value);
newValue2 +=1;
ordernow.firstvalue2.value = newValue2;
}
function minusNum2() {
var subNum2 = Number(ordernow.firstvalue2.value);
if (subNum2 > 0) {
subNum2 -= 1;
ordernow.firstvalue2.value = subNum2;
}
};
<body>
<div class=container>
<form name="orderup" id="ordernow">
<p> Chicken &nbsp &nbsp $4.57</p>
Quantity<input type="button" id="firstminus" value="- 1" onclick="minusNum1()"/>
<input type="text" id="firstvalue" value="0"/>
<input type="button" id="firstadd" value="+1" onclick="addNum1()"/>
<p> Beef &nbsp &nbsp $3.32</p>
Quantity<input type="button" id="firstminus2" value="- 1" onclick="minusNum2()"/>
<input type="text" id="firstvalue2" value="0"/>
<input type="button" id="firstadd2" value="+1" onclick="addNum2()"/>
</form>
</div>
</body>
If you open your browser's development tools the console should show an error message. On Chrome I get:
Uncaught ReferenceError: newValue2 is not defined
This is because addNum2() declares newValue but then uses newValue2 on the next line.
function addNum2() {
var newValue = Number(ordernow.firstvalue2.value);
newValue2 +=1;
ordernow.firstvalue2.value = newValue2;
}
var newValue = Number(ordernow.firstvalue2.value);
newValue2 +=1;
You can use the same var name because you are in a different function scope.
Fix:
function addNum2() {
var newValue = Number(ordernow.firstvalue2.value);
newValue +=1;
ordernow.firstvalue2.value = newValue;
}
Always check for error messages in the console and run your javascript in the debugger when something is "mysteriously" not working.

What's the best way to update the input names when dynamically adding them to a form?

I'm trynig to come up with a clean and efficient way of handling form input names when dynamically adding more to the POST array.
For example, if I have the following form:
<fieldset>
<input type="text" name="users-0.firstname" />
<input type="text" name="users-0.lastname" />
</fieldset>
I then click an 'addmore' button which duplicates that HTML and adds it back into the document. Resulting in:
<fieldset>
<input type="text" name="users-0.firstname" />
<input type="text" name="users-0.lastname" />
</fieldset>
I'm trying to find the best way to increment that name index so I can use the data on the server. So far, I've been using the following code:
$('.addmore').click(function()
{
var $button = $(this);
var $fieldset = $button.prev('fieldset');
var $newset = $('<div class="new">' + $fieldset[0].innerHTML + '</div>');
$newset.insertBefore($button);
updatenames($newset, $('fieldset').length + 1);
});
function updatenames($set, newIndex)
{
/*
updates input names in the form of
set-index.name
set-index
*/
var findnametype = function(inputname)
{
if (inputname.indexOf('-') != -1 && inputname.indexOf('.') != -1)
{
var data1 = inputname.split('-');
var data2 = data1[1].split('.');
// [type, set, index]
return [1, data1[0], parseInt(data2[0])]
}
if (inputname.indexOf('-') != -1 && inputname.indexOf('.') == -1)
{
var data = inputname.split('-');
return [2, data[0], data[1]];
}
return false;
};
var type = findnametype($set.find('input:eq(0)')[0].name);
$set.find('input, select').each(function()
{
var $input = $(this);
var oldname = $input[0].name;
var newname = false;
switch (type[0])
{
case 1: newname = oldname.replace('-' + type[2], '-' + newIndex);
break;
case 2: newname = oldname.replace('-' + type[2], '-' + newIndex);
break;
}
$input[0].name = newname;
});
return type;
}
That updatenames function is a variation of what I've been using lately. In this case, I check to find the format of the input name. I then increment the index.
The incrementing, as you've probably noticed, happens in the DOM. As a 'part 2' to my question, I'd like to learn how to have that object returned for me to then insert into the DOM.
Something like:
$newset = updatenames($newset, $('fieldset').length +1);
$newset.insertBefore($button);
Your help is appreciated. Cheers.
Have you considered using array-based field names? You wouldn't have to alter those at all:
<input type="text" name="users.firstname[]" />
<input type="text" name="users.lastname[]" />
whether this works for you will of course depend on what you're going to do with the fields.
<script type="text/javascript">
$(document).ready(function () {
$('.addmore').click(function () {
var fieldset = $(this).prev('fieldset');
var newFieldset = fieldset.clone();
incrementFieldset(newFieldset);
newFieldset.insertBefore($(this));
});
});
function incrementFieldset(set) {
$(set).find('input').each(function () {
var oldName = $(this).attr('name');
var regex = /^(.*)-([0-9]+)\.(.*)$/;
var match = regex.exec(oldName);
var newName = match[1] + '-' + (parseInt(match[2]) + 1) + '.' + match[3];
$(this).attr('name', newName);
});
}
</script>
<fieldset>
<input type="text" name="users-0.firstname" />
<input type="text" name="users-0.lastname" />
</fieldset>
<input type="button" class="addmore" value="Add" />
<fieldset>
<input index=1 var=user prop=firstname />
<input index=1 var=user prop=lastname />
</fieldset>
<fieldset>
<input index=2 var=user prop=firstname />
<input index=2 var=user prop=lastname />
</fieldset>
before you submit your form
get the custom attributes and construct your 'name' attribute
[update]
its jsp but shouldn't be hard for u to convert to php
<%
for (int i = 0; i < 1000; i++) {
%>
<fieldset>
<input index=<%=i%> var=user prop=firstname />
<input index=<%=i%> var=user prop=lastname />
</fieldset>
<%
}
%>
for the js code
$('button').click(function(){
$('input').each(function(i, node){
var $node = $(node);
$node.attr('name', $node.attr('var') + $node.attr('index') + "."+ $node.attr('prop'))
});
});

Categories

Resources