alter array object property then save back to localStorage? - javascript

I'm doing a cart and I want to increment the qty if the item_id exising in localStorage.
<button data-item_id="1" data-item_name="cake" data-item_price="2 dollar">Add to cart</button>
Not sure why my below code doesn't work, it added a new object instead of increment the qty value.
$(function(){
$('button').click(function(){
var item_id = $(this).attr('data-item_id');
var item_name = $(this).attr('data-item_name');
var item_price = $(this).attr('data-item_price');
var arr = JSON.parse(localStorage.getItem('cart')) || [];
var obj = {};
if(arr.length === 0){ // first time insert
obj.item_id = item_id;
obj.item_name = item_name;
obj.item_price = item_price;
obj.item_qty = 1;
}else{
$(arr,function(i){
//doesn't work here
obj.item_qty[i] = parseInt(this.qty) + 1;
});
}
arr.push(obj);
localStorage.setItem('cart',JSON.stringify(arr));
});
});
debug for few hours couldn't solved.

Use {} instead of [] making the arr contain one object per item_id and each object will get 1 added to the qty each time it is called. There is no remove in this code
$(function(){
$('button').on("click",function(e){
var item_id = $(this).data("item_id");
var item_name = $(this).data("item_name");
var item_price = $(this).data("item_price");
var cart = JSON.parse(localStorage.getItem('cart')) || {};
var currentObj = cart[item_id];
if(currentObj){
currentObj.qty++; // increase the qty by one
}
else { // item_id had not been stored before, create it
cart[item_id]= {
"item_name" :item_name,
"item_price":item_price,
"item_qty" :1
}
}
localStorage.setItem('cart',JSON.stringify(cart));
});
});

Then you have to do like this:
$(function(){
$('button').click(function(){
var item_id = $(this).attr('data-item_id');
var item_name = $(this).attr('data-item_name');
var item_price = $(this).attr('data-item_price');
var arr = JSON.parse(localStorage.getItem('cart')) || [];
var obj = {};
obj.item_id = item_id;
obj.item_name = item_name;
obj.item_price = item_price;
obj.item_qty = 1;
detectchange = 'no';
$.each(arr,function(i){
if(this.item_id == obj.item_id){
this.item_qty = parseInt(this.item_qty) + 1; detectchange = 'yes'; }
});
if(detectchange =='no'){
arr.push(obj); }
localStorage.setItem('cart',JSON.stringify(arr));
});
});

Related

How add a filter in server script with query

i'm new in servicenow and I have to add this filter "document_id.number STARTS WITH BKNG"
as a query, how can i do in servicenow?
this is my code:
// only show 30 in header menu dropdown
var max = 30;
var t = data;
t.items = [];
t.count = 0;
var u = getMyApprovals();
// use record watchers to tell header when to update dropdown counts
t.record_watchers = [];
t.record_watchers.push({'table':'sysapproval_approver','filter':'approverIN' + u.toString() + '^state=requested'});
var z = new GlideRecord('sysapproval_approver');
z.addQuery("approver", u);
z.addQuery("state", "requested");
z.addQuery("document_id.number", "STARTSWITH", "BKNG")
z.orderByDesc('sys_updated_on');
z.setLimit(max);
z.query();
var link = {};
link.title = gs.getMessage('View all approvals');
link.type = 'link';
link.href = '?id=approvals';
link.items = [];
t.items.push(link);
while (z.next()) {
var a = {};
var rec = getRecordBeingApproved(z);
if (!rec.isValidRecord()) // nothing being approved - hmmm
continue;
a.short_description = rec.short_description + "";
if (rec.getRecordClassName() == "sc_request") {
var items = new GlideRecord("sc_req_item");
items.addQuery("request", rec.getUniqueValue());
items.query();
if (items.getRowCount() > 1)
a.short_description = items.getRowCount() + " requested items";
else if (items.getRowCount() == 1) {
items.next();
a.short_description = items.getValue("short_description");
}
}
$sp.getRecordValues(a, z, 'sys_id,sys_updated_on');
a.number = rec.getDisplayValue();
a.__table = z.getRecordClassName();
a.type = 'approval';
t.items.push(a);
t.count++;
}
function getRecordBeingApproved(gr) {
if (!gr.sysapproval.nil())
return gr.sysapproval.getRefRecord();
return gr.document_id.getRefRecord();
}
i tried doing z.addQuery ("document_id.number", "STARTSWITH", "BKNG")
but it doesn't works.
i don't know how to do.
You can't dot-walk the document_id field when using .addQuery() as it is not a reference filed. Instead, you can use the Approval for (sysapproval) reference field like so:
z.addQuery("sysapproval.number", "STARTSWITH", "BKNG");

Get variables from URL and convert to array

I need to retrieve variables from an URL.
I use this found function:
function getParams(str) {
var match = str.replace(/%5B/g, '[').replace(/%5D/g, ']').match(/[^=&?]+\s*=\s*[^&#]*/g);
var obj = {};
for ( var i = match.length; i--; ) {
var spl = match[i].split("=");
var name = spl[0].replace("[]", "");
var value = spl[1];
obj[name] = obj[name] || [];
obj[name].push(value);
}
return obj;
}
var urlexample = "http://www.test.it/payments/?idCliente=9&idPagamenti%5B%5D=27&idPagamenti%5B%5D=26"
var me = getParams(stringa);
The output is:
{"idPagamenti":["26","27"],"idCliente":["9"]}
But idCliente is always NOT an array, so i'd like to retrieve:
{"idPagamenti":["26","27"],"idCliente": 9 }
This is the fiddle example
function getParams(str) {
var match = str.replace(/%5B/g, '[').replace(/%5D/g, ']').match(/[^=&?]+\s*=\s*[^&#]*/g);
var obj = {};
for ( var i = match.length; i--; ) {
var spl = match[i].split("=");
var name = spl[0].replace("[]", "");
var value = spl[1];
obj[name] = obj[name] || [];
obj[name].push(value);
}
return obj;
}
var stringa = "http://www.test.it/payments/?idCliente=9&idPagamenti%5B%5D=27&idPagamenti%5B%5D=26"
var me = getParams(stringa);
$(document).ready(function(){
alert("testing");
console.log(me);
$(".a").html(JSON.stringify(me));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="a">
</div>
Someone can help me to modify code?
I think your facing a real paradigm problem. Why idCliente wouldn't be an array but idPagamenti would be. You should have all array or none but not both. getParams() function can make this choice for you and you should probably change the way you are working with this.
Anyway, here is a getParams() function that replace any single-valued array to a value. Note that if you have only one idPagamenti in your URI, you will also have a single value for idPagamenti instead of an array.
function getParams(str) {
var match = str.replace(/%5B/g, '[').replace(/%5D/g, ']').match(/[^=&?]+\s*=\s*[^&#]*/g);
var obj = {};
for ( var i = match.length; i--; ) {
var spl = match[i].split("=");
var name = spl[0].replace("[]", "");
var value = spl[1];
obj[name] = obj[name] || [];
obj[name].push(value);
}
Object.keys(obj).forEach(key => {
if (obj[key].length === 1) {
obj[key] = obj[key][0];
}
})
return obj;
}
var urlexample = "http://www.test.it/payments/?idCliente=9&idPagamenti%5B%5D=27&idPagamenti%5B%5D=26"
var me = getParams(stringa);
If you know that you will always get ids as parameters, you can also add a parseInt() for each parameter by replacing var value = spl[1]; with var value = parseInt(spl[1], 10);

Calling an array item into another array

I faced the following functions (or method I don't what is right name of the ):
function getRowArray($scope, object, i){
i = i + 1;
var item = {};
var data = [];
var id = -1;
if ($scope.selectedType !== undefined) {
id = $scope.selectedType.id;
}
var rating = getRating($scope, object, id);
item['name'] = $scope.objectInfo[object]['name'];
item['objectId'] = rating.objectId;
item['hideRating'] = parseInt($scope.objectInfo[object].hideControls) & 1;
item['addInfo'] = rating.addInfo;
item['rating'] = rating.value;
item['ratingId'] = rating.id;
for (var i in $scope.objectInfo[object].childs) {
if ($scope.objectInfo[object].childs[i] == object){
continue;
}
data.push(getRowArray($scope, $scope.objectInfo[object].childs[i], i));
}
item['data'] = data;
return item;
}
and
function getTypeRow($scope, oobject, otype){
var item = {};
var data = [];
var rating = getRating($scope, oobject.id, otype.id);
item['name'] = otype.name;
item['objectId'] = rating.objectId;
item['typeId'] = rating.typeId;
item['ratingId'] = rating.id;
item['addInfo'] = rating.addInfo;
item['rating'] = rating.value;
// item['hideRating'] = parseInt($scope.objectInfo[object].hideControls);
return item;
}
I want to use the hideRating item from the first one in the second, I tried and added the commented line but I got an error it says the object is undifined, is it wrong like that or am I missing something ? thanks in advance
object is undefined because it wasn't initialized; it's not specified in the parameter list for the function getTypeRow. The oobject in the parameter list should be corrected to object:
// Correct 'oobject' to 'object'
function getTypeRow($scope, object, otype){
var item = {};
var data = [];
// Correct 'oobject' to 'object'
var rating = getRating($scope, oobject.id, otype.id);
...
}

how can i make this jsonArray form?

I want to get this (four keys & values in one object):
[{"sms":"Y","email":"Y","phone":"Y","oto":"Y"},{"sms":"N","email":"N","phone":"N","oto":"N"}]
but this is result :
[{"sms":"Y"},{"email":"Y"},{"phone":"Y"},{"oto":"Y"},{"sms":"N"},{"email":"N"},{"phone":"N"},{"oto":"N"}]
here is my code:
var chkObj = {};
var chkArray = [];
var cntchk = 1;
$("tbody input").each(function(idx){
var Nm = $(this).attr("name");
this.checked ? chkObj[Nm] = 'Y' : chkObj[Nm] = 'N';
cntchk++;
if(cntchk = 4){
chkArray.push(chkObj);
chkObj = {};
cntchk = 1;
}
});
Can you please show us the form as well? This gives a limited scope to answer.
But If i guess right, you have a form wherein you have the following fields sms, email, phone, and then oto, right?
So what you have to do is, instead of doing it for each input, you have to do it once for the four inputs.
Meaning that you have to set chkObj['sms'], chkObj['email'], chkObj['phone'], and then chkObj['oto'] and then do chkArray.push(chkObj).
You missed the second equals sign in this expression:
if(cntchk = 4){, so instead of comparison there is an assignment. Change this to if(cntchk == 4){
You have missed one "=" sign in if condition.
try this:
var chkObj = {};
var chkArray = [];
var cntchk = 1;
$("tbody input").each(function(idx){
var Nm = $(this).attr("name");
this.checked ? chkObj[Nm] = 'Y' : chkObj[Nm] = 'N';
cntchk++;
if(cntchk **==** 4){
chkArray.push(chkObj);
chkObj = {};
cntchk = 1;
}
});

How do I iterate over an IndexedDB objectStore using a condition on a non-key property?

I have a select box that I want to populate automatically with values from a objectStore, for that I need to iterate it like this: "Select COL1 from TABLE where COL2 = 'myvalue'",
this is my code:
var db;
var req = indexedDB.open("DB");
req.onsuccess = function (e) {
db = req.result;
var tran = db.transaction("store");
var singleKeyRange = IDBKeyRange.only("myvalue"); //the value I want to reach from COL2
tran.objectStore("store").openCursor(singleKeyRange).onsuccess = function(e) {
var cursor = e.target.result;
if (cursor) {
var opt = document.getElementById("selectbox");
var option = document.createElement("option");
var optionText=document.createTextNode(cursor.value.COL1); //the matching values in COL1
option.appendChild(optionText);
opt.appendChild(option);
cursor.continue();
}
}
};
I have all my values correctly indexed in the objectStore, just don't now how to reach values through others values.
Here is an example in which items are searched on non-indexed column, you need to go through all items and compare the values and add them to list, after that you can return the result set.
function SearchItems( keyPath, value, requestNo, callback){
var initOpenReq = indexedDB.open(baseName);
initOpenReq.onsuccess = function() {
var db = initOpenReq.result;
var transaction = db.transaction(objectStoreName, 'readonly');
var objectStore = transaction.objectStore(objectStoreName);
var cursorRequest = objectStore.openCursor();
var agregate = [];
cursorRequest.onsuccess = function (event){
if (event.target.result){
if(event.target.result.value[keyPath] && event.target.result.value[keyPath] == value){ //compare values
agregate.push(event.target.result.value);
}
event.target.result['continue']();
}
};
transaction.oncomplete = function (event) {
callback(agregate); // return items
};
}
}
This is an example with an index.
var db;
var req = indexedDB.open("DB", 2);
// Creating the index
req.onupgradeneeded = function (e){
var trans = e.target.transaction;
var obj = trans.objectStore("store");
obj.createIndex("indexname", "keypath") // keypath is the propertyname you want the index on. for Ex. {Name: "x", Age:5 }; If you want to filter on Name, keypath = Name
}
req.onsuccess = function (e) {
db = req.result;
var tran = db.transaction("store");
var singleKeyRange = IDBKeyRange.only("myvalue"); //the value I want to reach from COL2
var objectStore = tran.objectStore("store");
var opt = document.getElementById("selectbox");
objectStore.index("indexname").openCursor(singleKeyRange).onsuccess =
function(e){
var cursor = e.target.result;
if (cursor) {
var option = document.createElement("option");
var optionText=document.createTextNode(cursor.value.COL1); //the matching values in COL1
option.appendChild(optionText);
opt.appendChild(option);
cursor.continue();
}
}
};

Categories