how to use dynamic variable in update.js shopify - javascript

I want yo use test variable in update.js but it shows error when I use as variable but when I pass this value directly it works
can someone please tell me how can use dynamic variable to change quantity of existing products in cart
I have updated my code It will allow user to add only 5 items more than 5 items will be removed It will create string which will look like this
32082238341235:0,39470423048307:0,32164693278835:0,32164693835891:1
and finally the all IDs and qunatity will be updated by update.js
I have got error in last step its shows
{"status":404,"message":"Cart Error","description":"Cannot find variant"}
when i try to update all products
jQuery.getJSON('/cart.js', function(cart) {
var items_new = cart.items;
var count = 0;
count = cart.item_count;
var item_to_remove = count - 5;
if (count > 5) {
var item_to_remove = count - 5;
var combine = ""
if (item_to_remove > 0) {
for (var i = 0; i < items_new.length; i++) {
if (count > 5) {
var c_id = items_new[i].variant_id;
var c_quantity = items_new[i].quantity;
if (c_quantity >= item_to_remove) {
var q = c_quantity - item_to_remove
var data_multiple = c_id + ":" + q + ",";
debugger;
count = count - item_to_remove;
console.log(data_multiple);
var combine = combine + data_multiple;
} else {
var data_single = c_id + ":" + 0 + ",";
count = count - c_quantity;
item_to_remove = item_to_remove - c_quantity
console.log(data_single)
var combine = combine + data_single;
}
}
}
console.log(combine.slice(0, -1));
var test = combine.slice(0, -1);
console.log({
updates: {
test
}
});
jQuery.post('/cart/update.js', {
updates: {
test
}
});
}
t._rerenderCart()
}
t.sidebarDrawer.open()
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

You need to store test as an object within parentheses {} and then pass to updates by using the spread ... operator.
var test = {39470423048307 : 0, 32164693278835 : 0, 32164693835891 : 1};
console.log({updates: {...test}});
jQuery.post('/cart/update.js', {updates:{...test}});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
In your updated code, you are passing a string to updates rather than an object. You should create an object from the data inside the for loop and pass that object to updates. See lines with // CHANGE HERE:
...
var combine = {};
if (item_to_remove > 0) {
for (var i = 0; i < items_new.length; i++) {
if (count > 5) {
var c_id = items_new[i].variant_id;
var c_quantity = items_new[i].quantity;
if (c_quantity >= item_to_remove) {
var q = c_quantity - item_to_remove;
// CHANGE HERE
combine[c_id] = q;
count = count - item_to_remove;
} else {
// CHANGE HERE
combine[c_id] = 0;
count = count - c_quantity;
item_to_remove = item_to_remove - c_quantity;
}
console.log(combine);
}
}
// CHANGE HERE
var test = combine;
console.log({
updates: test
});
jQuery.post('/cart/update.js', {
updates: test
});
...

Related

Looping error in Javascript with eventHandler

I have the following Javascript code within and HTML page. Its function is to display elements on the form based on the user pressing a + button and if the element is not needed then it removes it via the user pressing the - button. Currently its throwing an error "TypeError: docs[n]" is undefined after the following sequence of events:
Select button to add elements
Remove elements not needed
Add elements back (Error Thrown)
Any help would be most appreciated
`<script language="JavaScript">`
var idx = 0;
var d;
//Make getElementsByClassName work for all of IE revs
if (!document.getElementsByClassName) {
document.getElementsByClassName = function (cn) {
var rx = new RegExp("(?:^|\\s)" + cn+ "(?:$|\\s)");
var allT = document.getElementsByTagName("*"), allCN = [],ac="", i = 0, a;
while (a = allT[i=i+1]) {
ac=a.className;
if ( ac && ac.indexOf(cn) !==-1) {
if(ac===cn){ allCN[allCN.length] = a; continue; }
rx.test(ac) ? (allCN[allCN.length] = a) : 0;
}
}
return allCN;
}
}
function add_fields(e) {
// for some reason, adding the new fields wipes out existing values, so save and restore
var docs = document.getElementsByClassName("doc");
var revs = document.getElementsByClassName("rev");
++idx;
/* console.log("test " + idx); */
var saveDocs = new Array(idx);
var saveRevs = new Array(idx);
for (n=0; n < idx; n++) {
saveDocs[n] = docs[n].value; **//Error is thrown here**
saveRevs[n] = revs[n].value;
}
node = document.getElementById("content");
theNewRow = document.createElement("tr");
theNewCell = theNewRow.insertCell(0);
theNewCell.innerHTML = "Approver Name";
theNewCell.setAttribute("style","font-size: 12pt");
theNewCell1 = theNewRow.insertCell(1);
theNewCell1.innerHTML = "<input type='text' class='doc' style='width:180px;' id='docNum0'/>";
theNewCell1.setAttribute("style","padding-left: 10px");
theNewCell2 = theNewRow.insertCell(2);
theNewCell2.innerHTML = "Approver Email";
theNewCell2.setAttribute("style","font-size: 12pt");
theNewCell2.setAttribute("style","padding-left: 10px");
theNewCell3 = theNewRow.insertCell(3);
theNewCell3.innerHTML = "<input type='text' class='rev' style='width:180px;' id='rev0'/> <input class='minusThing' type='button' style='font-size:10px' value='- '/>";
theNewCell3.setAttribute("style","padding-left: 0px");
node.appendChild( theNewRow );
// restore old arrays and add the id tags to the fields just added
docs = document.getElementsByClassName("doc");
revs = document.getElementsByClassName("rev");
for (n=0; n < idx; n++) {
docs[n].value = saveDocs[n];
revs[n].value = saveRevs[n];
}
docs[idx].id = "docNum" + idx;
revs[idx].id = "rev" + idx;
}
//for Loop the entries
function myfunction() {
alert('Inside Function')
var values = "";
for (n=0; n <= idx; n++)
{
var doc = document.getElementById("docNum"+n).value;
var rev = document.getElementById("rev"+n).value;
//alert(doc+rev);
//Call VbScript Sub and pass value
PassValues(doc,rev);
```
If you've removed all the docs, document.getElementsByClassName("doc"); is going to return an empty array. If you're incrementing idx before your loop, the loop will execute once and try to access docs[0], which is undefined.

Javascript- Dynamic variable loop

I'm trying to reduce the amount of code I repeat.
Currently I have the below:
var item1H = $(".item-1").height();
var item1W = $(".item-1").height();
$(".item-1 .text").css('margin-left', -item1W/2);
$(".item-1 .text").css('margin-bottom', -item1H/2);
var item2H = $(".item-2").height();
var item2W = $(".item-2").height();
$(".item-2 .text").css('margin-left', -item2W/2);
$(".item-2 .text").css('margin-bottom', -item2H/2);
I'm looking to put this into a for loop where the variable number would count up to whatever number I needed it to stop.
You can make function like this and use whenever you want
toSetMargin(".item-2")
toSetMargin(".item-2")
function toSetMargin(objStr){
var widthTmp = $(objStr + ' .text').height();
var heightTmp = $(objStr + ' .text').height();
obj.css('margin-left', -widthTmp/2);
obj.css('margin-bottom', -heightTmp/2)
}
This code not impact any other code.
You could use $('[class^="item-"]') to get all the elements that have a class that starts with item-, and the loop over them
$('[class^="item-"]').each(function(){
var $elem = $(this);
var item1H = $elem.height();
var item1W = $elem.width();
$elem.find('.text').css({'margin-left': -item1W/2,'margin-bottom':-item1H/2});
});
Ooh boy, one of these problems. This should help (untested):
for(i=1;i<=STOPPING_NUMBER;i++){
window["item"+i+"H"] = $(".item-"+i).height();
window["item"+i+"W"] = $(".item-"+i).width(); //Was height, accident?
$(".item-"+i+" .text").css('margin-left', 0-window["item"+i+"W"]/2); //Hope this works lol
$(".item-"+i+" .text").css('margin-bottom', 0-window["item"+i+"H"]/2);
}
Guessing these lines:
var item1W = $(".item-1").height();
var item2W = $(".item-2").height();
Should have been:
var item1W = $(".item-1").width();
var item2W = $(".item-2").width();
You could do something like:
function setCSS(item,attr,val) {
$(item +" .text").css(attr, (val * -1)/2);
}
var i, max = 10;
for(i=1;i<=max;i++) {
setCSS(".item-"+ i,"margin-left",$(".item-"+ i).width());
setCSS(".item-"+ i,"margin-bottom",$(".item-"+ i).height());
}
Or something less flexible within the function:
function setCSS(item,w,h) {
$(item +" .text").css("margin-left", (w * -1)/2);
$(item +" .text").css("margin-bottom", (h * -1)/2);
}
var i, max = 10;
for(i=1;i<=max;i++) {
setCSS(".item-"+ i,$(".item-"+ i).width()),$(".item-"+ i).height());
}
Something like this should be pretty acceptible in your case, I guess:
for (var i = 1, len = someN; i < len; i++) {
var $item = $('.item-' + i);
$item.find('.text').css({
'margin-left': -$item.width() / 2,
'margin-bottom': -$item.height() / 2
});
}

Getting an infinite loop and can't see why - Javascript

I'm writing a simple little Connect 4 game and I'm running into an infinite loop on one of my functions:
var reds = 0;
var greens = 0;
function checkEmpty(div) {
var empty = false;
var clicked = $(div).attr('id');
console.log(clicked);
var idnum = parseInt(clicked.substr(6));
while (idnum < 43) {
idnum = idnum + 7;
}
console.log("idnum=" + idnum);
while (empty == false) {
for (var i = idnum; i > 0; i - 7) {
idnumStr = idnum.toString();
var checking = $('#square' + idnumStr);
var str = checking.attr('class');
empty = str.includes('empty');
console.log(empty);
var divToFill = checking;
}
}
return divToFill;
}
function addDisc(div) {
if (reds > greens) {
$(div).addClass('green');
greens++;
console.log("greens=" + greens);
} else {
$(div).addClass('red');
reds++;
console.log("reds=" + reds);
};
$(div).removeClass('empty');
}
$(function() {
var i = 1;
//add a numbered id to every game square
$('.game-square').each(function() {
$(this).attr('id', 'square' + i);
i++;
//add an on click event handler to every game square
//onclick functions
$(this).on('click', function() {
var divToFill = checkEmpty(this);
addDisc(divToFill);
})
})
})
Here is a link to the codepen http://codepen.io/Gobias___/pen/xOwNOd
If you click on one of the circles and watch the browser's console, you'll see that it returns true over 3000 times. I can't figure out what I've done that makes it do that. I want the code to stop as soon as it returns empty = true. empty starts out false because I only want the code to run on divs that do not already have class .green or .red.
Where am I going wrong here?
for (var i = idnum; i > 0; i - 7);
You do not change the i.
Do you want to decrement it by 7?
Change your for loop to the one shown below:
for (var i = idnum; i > 0; i -= 7) {
// ...
}
You also do not use loop variable in the loop body. Instead, you use idnum, I think this can be issue.
while (empty == false) {
for (var i = idnum; i > 0; i -= 7) {
idnumStr = i.toString(); // changed to i
var checking = $('#square' + idnumStr);
var str = checking.attr('class');
empty = str.includes('empty');
console.log(empty);
var divToFill = checking;
// and don't forget to stop, when found empty
if (empty) break;
}
}
I add break if empty found, because if we go to next iteration we will override empty variable with smallest i related value.
You can also wrap empty assignment with if (!empty) {empty = ...;} to prevent this override, but I assume you can just break, because:
I want the code to stop as soon as it returns empty = true
Offtop hint:
while (idnum < 43) {
idnum = idnum + 7;
}
can be easy replaced with: idnum = 42 + (idnum%7 || 7)
Change to this:
for (var i = idnum; i > 0; i = i - 7) {
You are not decrementing the i in your for loop
Building on what the others have posted You would want to change the value of empty inside the for loop. because obviously the string still checks the last string in the loop which would always return false.
while(empty==false){
for (var i = idnum; i > 0; i -= 7) {
// your other codes
if (!empty) {
empty = str.includes('empty');
}
}

How to update Firebase multiple times

so when trying to go through a loop that checks, updates, and posts data to my Firebase storage, it seems that whenever I try to use the Firebase.update(), then it messes with my for loop and it repeats incrementations or doesn't increment at all. Any advice?
My Code:
var j = 0;
var k = 0;
var l = 0;
var m = 0;
var setDict = {};
for(var h = 0; h < teamWinNames.length; h++)
{
console.log(j);
console.log(h);
console.log(meWinList[j]);
var tempRef = new Firebase("https://mycounter-app.firebaseio.com/user/" + username + "/championData");
var tempName = teamWinNames[h];
tempRef.once("value", function (teamWinSnapshot)
{
var exists = teamWinSnapshot.child(meWinList[j] + '/' + tempName).exists();
console.log(exists);
if(exists == true)
{
console.log("Here");
var tempVal = teamWinSnapshot.child(meWinList[j] + '/' + tempName).val();
console.log(tempVal);
//var tempValue = obj[tempname][tempchamp];
//console.log(tempValue);
}
else
{
setDict[tempName] = '1-0-0-0';
console.log(setDict);
}
});
if(h != 0 && (h+1)%4 == 0)
{
sendUpdate(setDict, meWinList[j], username);
setDict = {};
j++;
}
}
and the function that makes the update:
function sendUpdate(data, champ, username)
{
var tempRef = new Firebase("https://mycounter-app.firebaseio.com/user/" + username + "/championData");
tempRef.child(champ).update(data);
}
The problem is that you are getting your data in the for loop and also changing it inside the loop. This means that the data you are using in your loop changes with each iteration. And as an added bonus you get the effects of the asynchronous nature of firebase that can look something like this:
Get data (1)
Get data (2)
Update data (1)
Get data (3)
Update data (3)
Update data (2)
To prevent all this i suggest putting the for loop inside the tempRef.once function like this: (pseudo code)
tempRef.once{
Loop through data{
Change data
}
Update data
}
This means you only have to get the data once and update it once.

List to Jquery Datatable c#

I'm trying to make my List to fill my jquery Datatable but I'm unable to do so, at the moment im writing my list to a file to access it by datatable in my view-model is my approach the correct one?
This is my code:
List<string> list = new List<string>();
foreach (var item in db.Pos)
{
var total = 0;
decimal costo = 0;
for (int i = 1; i <= 31; i++)
{
var value = 0;
if (item.Fecha.Day == i) { value = item.Cantidad; costo = costo + item.Total; }
total += value;
}
list.Add(item.Descripcion);
list.Add(item.Pdv);
list.Add(item.Rid);
list.Add(((costo / (total + 1)).ToString("C")));
for (int i = 1; i <= 31; i++)
{
var value = 0;
list.Add(value.ToString());
int month = item.Fecha.Month;
if (item.Fecha.Day == i) { value = item.Cantidad; list.Add(value.ToString()); }
}
list.Add(total.ToString());
list.Add((((costo / (total + 1)) * total).ToString("C")));
}
var json = JsonConvert.SerializeObject(new List<object>() { list });
System.IO.File.WriteAllText(#"\path.txt", json);
And my Datatable Ajax Call:
$(document).ready(function () {
var table = $('#pftable_hdr').DataTable({
ajax: {
url: "/path.txt",
dataSrc: ""
},
scrollY: "500px",
scrollX: true,
scrollCollapse: true,
fixedColumns: {
leftColumns: 3
}
});
});
Part of my Txt File Output:
[["ENS FRUTAS","REST","CENAS","$26.50","0","1","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","1","$26.50","CAFE AMER ILIMIT","REST","CENAS","$11.50","0","1","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","1","$11.50","QUESADILLAS TRAD (2)","REST","CENAS","$25.50","0","1","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","1","$25.50"]]
How can I fill my Jquery datatable with my list? My text file should have [] before and after the $data but I can't make that happen only at the first of the file and in the end.
Your backend code should look something like this. By doing this it will build a JSON string that is looking like this: [["","",""...],["","",""...],["","",""...]]
List<List<string>> list = new List<List<string>>();
foreach (var item in db.Pos)
{
List<string> listItem = new List<string>();
var total = 0;
decimal costo = 0;
for (int i = 1; i <= 31; i++)
{
var value = 0;
if (item.Fecha.Day == i) { value = item.Cantidad; costo = costo + item.Total; }
total += value;
}
listItem.Add(item.Descripcion);
listItem.Add(item.Pdv);
listItem.Add(item.Rid);
listItem.Add(((costo / (total + 1)).ToString("C")));
for (int i = 1; i <= 31; i++)
{
var value = 0;
listItem.Add(value.ToString());
int month = item.Fecha.Month;
if (item.Fecha.Day == i) { value = item.Cantidad; listItem.Add(value.ToString()); }
}
listItem.Add(total.ToString());
listItem.Add((((costo / (total + 1)) * total).ToString("C")));
list.Add(listItem);
}
var json = JsonConvert.SerializeObject(list);
System.IO.File.WriteAllText(#"\path.txt", json);
Try like this
list.Add("[");
list.Add(item.Descripcion);
// rest code....
list.Add((((costo / (total + 1)) * total).ToString("C")));
list.Add("]");
Will this work for your case ? Let know your comment
var json = JsonConvert.SerializeObject(new List<object>() { list });
In the above line list is already an object, then why you are creating a new object and assigning "list" to that object.
Try like below,
var json = JsonConvert.SerializeObject(list);
This will provide you the required result

Categories

Resources