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
});
...
I am trying to make the outcome of a function appear in a element outside the script. Instead of the outcome I get an "undefined" message. It is probably just a matter of syntax, but I don't get it to work.
Here is what I did:
<html>
<head>
</head><body>
<table class="mytable">
<tr>
<p><span id="number1">1</span><span> + </span><span id="number2">2</span><span> = </span></p>
<p><span id="sr">here goes the range of solutions to select of</span></p>
<p><span id="quote">here goes the quote</span></p>
</table>
<form id="myForm">
<div id="display" style="height: 20px; width: 100%;"></div>
<script>
var plusorminus1 = Math.random() < 0.5 ? -1 : 1;
var plusorminus2 = Math.random() < 0.5 ? -1 : 1;
var plusorminus3 = Math.random() < 0.5 ? -1 : 1;
var plusorminus4 = Math.random() < 0.5 ? -1 : 1;
var plusorminus5 = Math.random() < 0.5 ? -1 : 1;
var plusorminus6 = Math.random() < 0.5 ? -1 : 1;
var plusorminus7 = Math.random() < 0.5 ? -1 : 1;
function sortfunction(a, b){
return (a - b)
}
var number1;
var number2;
number1 = Math.floor((Math.random() * 15) + 1);
number2 = Math.floor((Math.random() * 15) + 1);
document.getElementById("number1").innerHTML = number1;
document.getElementById("number2").innerHTML = number2;
var answer = parseInt(number1,10)+parseInt(number2,10);
var addarr = []
while(addarr.length < 7){
var randomnumber = Math.ceil(Math.random()*10)
if(addarr.indexOf(randomnumber) > -1) continue;
addarr[addarr.length] = randomnumber;
}
var var1 = answer;
var var2 = answer + (plusorminus1 * addarr[0]);
var var3 = answer + (plusorminus2 * addarr[1]);
var var4 = answer + (plusorminus3 * addarr[2]);
var var5 = answer + (plusorminus4 * addarr[3]);
var var6 = answer + (plusorminus5 * addarr[3]);
var var7 = answer + (plusorminus6 * addarr[3]);
var myarray=[var1,var2,var3,var4,var5,var6,var7];
myarray=myarray.sort(sortfunction);
for(var i = 0; i < myarray.length; i++)
{
var sr = (function(val) {
btn = document.createElement('button');
btn.data = val;
btn.innerHTML = val;
btn.addEventListener('click', checkAnswer);
document.body.appendChild(btn);
return btn.data = val;
})(myarray[i]);
document.getElementById("sr").innerHTML = sr; //only shows the last value in the array
}
function checkAnswer(evt) {
if (evt.target.data == answer) {
display.innerHTML = ("correct");
} else {
display.innerHTML = ("Not correct");
}
document.getElementById("quote").innerHTML = evt.target.data; //does not work
}
</script>
</FORM>
</body>
</html>
So, what I want is the following:
- show the range of answers to select from within the span above.
- show the answer (correct/not correct) in the span above.
Well, maybe it is possible to make the whole code more elegant, but these are my predominant problems here.
The reason you're getting undefined is that you never return anything from the function which is assigned to the variable sr (and subsequently set as the content of a div with that same id)
var sr = (function(val) {
btn = document.createElement('button');
btn.data = val;
btn.innerHTML = val;
btn.addEventListener('click', checkAnswer);
document.body.appendChild(btn);
})(myarray[i]);
document.getElementById("sr").innerHTML = sr;
sr has the value undefined --^
It is not clear what you meant to put as the innerHTML of the div with an id of sr.
You set the inner HTML to sr, which is the return value of the function:
var sr = (function(val) {
// ...
// nothing is returned
})(myarray[i]);
document.getElementById("sr").innerHTML = sr;
But this function doesn't return anything!
Make it return something using the return keyword.
var sr = (function(val) {
// ...
return "I <3 Stack Overflow";
})(myarray[i]);
How to ensure i have a dynamic increment of Alphabets in a new cell on left side, next to each cell in a row which is dynamically created based on the option chosen in Select. This newly generated alphabet will be considered as bullet points/serial number for that particular row's text box.
jsfiddle
js code
$(document).ready(function(){
var select = $("#Number_of_position"), table = $("#Positions_names");
for (var i = 1; i <= 100; i++){
select.append('<option value="'+i+'">'+i+'</option>');
}
select.change(function () {
var rows = '';
for (var i = 0; i < $(this).val(); i++) {
rows += "<tr><td><input type='text'></td></tr>";
}
table.html(rows);
});
});
html
<select id="Number_of_position">
</select> <table id="Positions_names">
</table>
This is essentially a base26 question, you can search for an implementation of this in javascript pretty easily - How to create a function that converts a Number to a Bijective Hexavigesimal?
alpha = "abcdefghijklmnopqrstuvwxyz";
function hex(a) {
// First figure out how many digits there are.
a += 1; // This line is funky
var c = 0;
var x = 1;
while (a >= x) {
c++;
a -= x;
x *= 26;
}
// Now you can do normal base conversion.
var s = "";
for (var i = 0; i < c; i++) {
s = alpha.charAt(a % 26) + s;
a = Math.floor(a/26);
}
return s;
}
So you can do
$(document).ready(function(){
var select = $("#Number_of_position"), table = $("#Positions_names");
for (var i = 1; i <= 100; i++){
select.append('<option value="'+i+'">'+i+'</option>');
}
select.change(function () {
var rows = '';
for (var i = 0; i < $(this).val(); i++) {
rows += "<tr><td>" + hex(i) + "</td><td><input type='text'></td></tr>";
}
table.html(rows);
});
});
Heres the example http://jsfiddle.net/v2ksyy7L/6/
And if you want it to be uppercase just do
hex(i).toUpperCase();
Also - this will work up to any number of rows that javascript can handle
if i have understood you correctly, that's maybe what you want:
http://jsfiddle.net/v2ksyy7L/3/
I have added an array for the alphabet:
var alphabet = "abcdefghijklmnopqrstuvwxyz".split("");
and then added the output to your "render" loop:
rows += "<tr><td>" + alphabet[i] + " <input type='text'></td></tr>";
I have found a pretty stuff for rating entries: http://www.fyneworks.com/jquery/star-rating/. It's good and easy. But I still need some more.
My code:
<div data-rating="4/5" class="entry"></div>
Desired function:
function init_rating(rate) { //... }
$(".entry").html( init_rating($(this).attr("data-rating")) );
Thanks much,
Here:
function init_rating(selector) {
var entry = $(selector);
var output = "";
var input = "<input name=\"star\" type=\"radio\" class=\"star\""
var checked = " checked=\"checked\"";
var close = "/>";
var params = entry.attr("data-rating").split("/", 2);
var rating = parseInt(params[0]);
var total = parseInt(params[1]);
for (var i = 0; i < total; i++) {
output += input;
if (i == rating - 1) output += checked;
output += close;
}
entry.html(output);
$('input[type=radio].star').rating();
}
init_rating(".entry");
fiddle: http://jsfiddle.net/qcxvW/20/
I don't have any trouble grabbing a list of elements and sorting them alphabetically, but I'm having difficulty understanding how to do it with a modulus.
### UPDATE ###
Here's the code working 'my way', however, I like the re-usability of the answer provided below more, so have accepted that answer.
<script type="text/javascript">
$(document).ready( function() {
$('.sectionList2').each( function() {
var oldList = $('li a', this),
columns = 4,
newList = [];
for( var start = 0; start < columns; start++){
for( var i = start; i < oldList.length; i += columns){
newList.push('<li>' + $(oldList[i]).text() + '</li>');
}
}
$(this).html(newList.join(''));
});
});
</script>
For example. Say I have the following unordered list:
<ul>
<li>Boots</li>
<li>Eyewear</li>
<li>Gloves</li>
<li>Heated Gear</li>
<li>Helmet Accessories</li>
<li>Helmets</li>
<li>Jackets</li>
<li>Mechanic's Wear</li>
<li>Pants</li>
<li>Protection</li>
<li>Rainwear</li>
<li>Random Apparel</li>
<li>Riding Suits</li>
<li>Riding Underwear</li>
<li>Socks</li>
<li>Vests</li>
</ul>
I have this list set to display in 4 columns with each li floated right. Visually this makes finding items in larger lists difficult. The output I need is this:
<ul>
<li>Boots</li>
<li>Helmet Accessories</li>
<li>Pants</li>
<li>Riding Suits</li>
<li>Eyewear</li>
<li>Helmets</li>
<li>Protection</li>
<li>Riding Underwear</li>
<li>Gloves</li>
<li>Jackets</li>
<li>Rainwear</li>
<li>Socks</li>
<li>Heated Gear</li>
<li>Mechanic's Wear</li>
<li>Random Apparel</li>
<li>Vests</li>
</ul>
What I'm looking for is a function that I can pass my array of list items and get my array returned, sorted alphabetically, with a modulus of choice; in this case 4.
Any help would be appreciated as I can find no documentation on the subject.
Alphabetize your list. This is already done, in your case, but if not:
function alphabetizeElements(a, b)
{
var aText = $(a).text();
var bText = $(b).text();
return aText > bText ? 1 : aText < bText ? -1 : 0;
}
var alphabetizedList = $("#myList li").sort(alphabetizeElements);
Store the alphabetized index of each element:
$.each(alphabetizedList, function(i)
{
$(this).data("alphaIndex", i);
});
Sort the alphabetized list by modulus first, then index:
function listColumnSortFn(columns)
{
return function(a, b)
{
var aIndex = $(a).data("alphaIndex");
var bIndex = $(b).data("alphaIndex");
return ((aIndex % columns) - (bIndex % columns)) || (aIndex - bIndex);
}
}
var columnSortedList = alphabetizedList.sort(listColumnSortFn(4));
Replace the list elements with your sorted elements:
$("#myList li").remove();
$("#myList").append(columnSortedList);
Here is the whole thing, all together:
function sortList(columns)
{
var alphabetizedList = $("#myList li").sort(alphabetizeElements);
$.each(alphabetizedList, function(i)
{
$(this).data("alphaIndex", i);
});
var columnSortedList = alphabetizedList.sort(listColumnSortFn(columns));
$("#myList li").remove();
$("#myList").append(columnSortedList);
}
function alphabetizeElements(a, b)
{
var aText = $(a).text();
var bText = $(b).text();
return aText > bText ? 1 : aText < bText ? -1 : 0;
}
function listColumnSortFn(columns)
{
return function(a, b)
{
var aIndex = $(a).data("alphaIndex");
var bIndex = $(b).data("alphaIndex");
return ((aIndex % columns) - (bIndex % columns)) || (aIndex - bIndex);
}
}
$(function()
{
sortList(4);
});
var columnify = function (a,n) {
var result = [];
for (var i = 0, lastIndex = a.length - 1; i < lastIndex; i++)
result.push(a[i * n % (lastIndex)]);
result[lastIndex] = a[lastIndex];
return result;
}
var products = ["Boots",
"Eyewear",
"Gloves",
"Heated Gear",
"Helmet Accessories",
"Helmets",
"Jackets",
"Mechanic's Wear",
"Pants",
"Protection",
"Rainwear",
"Random Apparel",
"Riding Suits",
"Riding Underwear",
"Socks",
"Vests",]
columnify(products, 4)
["Boots", "Helmet Accessories", "Pants", "Riding Suits", "Eyewear", "Helmets", "Protection", "Riding Underwear", "Gloves", "Jackets", "Rainwear", "Socks", "Heated Gear", "Mechanic's Wear", "Random Apparel", "Vests"]
Apply that function to the already sorted list, and then it will return a list of strings in the order (almost) that you want. Then add the list that was returned in order to the unordered list in the DOM.
Also, I haven't tested it with anything besides that list. So I'd do that if I were you. From what I see, it only works if the length of the list is a multiple of n. Not that great of a solution but it's late for me and I can't be bothered to come up with anything better.
EDIT: fixed the issue with the last element
See if this will work: http://jsfiddle.net/6xm9m/2
var newList = new Array();
var listItem = $('#list > li');
var mod = 4;
var colCount = Math.ceil(listItem.length / mod);
listItem.each(function(index) {
var newIndex = ((index % colCount) * mod) + Math.floor(index / colCount);
// $(this).text(newIndex);
newList[newIndex] = this;
});
$('#list').empty();
for(var i = 0; i < newList.length; i++){
$('#list').append(newList[i]);
}
Needs improvements, probably, but I'm not really sure how well this works at all.
Here you go. The code is surprisingly simple once you figure it out. I realize you are using jQuery but I'm not familiar enough with it to use its features. This is simple enough that maybe it's not necessary.
function pivotArray(arr, columns) {
var l = arr.length, out = [], ind = 0, i = 0;
for (; i < l; i += 1) {
out[ind] = arr[i];
ind += columns;
if (ind >= l) {
ind = ind % columns + 1;
}
}
return out;
}
And here's the test to prove it works (tested in Firefox 3.6.9, IE 6, Chrome 1.0.154.36):
<html>
<head>
<style type="text/css">
a.panelnum {
display:block;
float:left;
width:40px;
height:40px;
border:1px solid black;
text-align:center;
vertical-align:middle;
text-decoration:none;
font-size:2em;
}
</style>
</head>
<body onload="doit(17, 4);">
<div id="output" style="border:1px solid blue;">
</div>
<script type="text/javascript">
function pivotArray(arr, columns) {
var l = arr.length, out = [], ind = 0, i = 0;
for (; i < l; i += 1) {
out[ind] = arr[i];
ind += columns;
if (ind >= l) {
ind = ind % columns + 1;
}
}
return out;
}
function doit(size, columns) {
document.getElementById('output').innerHTML = 'starting';
var l = size;
var inp = [];
for (var i = 0; i < l; i += 1) {
inp[i] = i;
}
var result = pivotArray(inp, columns);
var str = '';
for (i = 0; i < l; i += 1) {
str += '<a class="panelnum">' + result[i] + '</a>';
}
var d = document.getElementById('output')
d.innerHTML = '<p>Some pre text</p>' + str + '<p style="clear:both;">and some post text</p>';
d.style.width = (columns * d.childNodes[1].offsetWidth + 2) + 'px';
}
</script>
</body>
</html>
One more thing: it might be useful to just move the elements around in-place. I almost had script for it but my script was running backwards (as if floats went from top to bottom first). If I get time I'll work on it and post the code.
P.S. Anyone want to give me pointers on why I had to add 2 to the width calculation for IE6? Wait... it's the borders of the div isn't it?