How to delete a specific value in a cookie - jquery - javascript

I am developing a shopping cart system, where the user can add or remove products to his or her basket.
I am storing 2 things for each product in the product cookie: product barcode and price.
My code so far looks like this:
var addToBasketHandler = $(".add-product");
var removeFromBasketHandler = $(".unselect");
var Basket = {
select: function (box, cookie) {
box.addClass("selected");
var ean = box.attr('ean');
var value = box.find($(".price strong")).html().replace(/[^0-9\.]/g, '');
if ($.cookie(cookie) == undefined) {
$.cookie(cookie, ean + "~" + value);
} else if ($.cookie(cookie).indexOf(ean) == -1) {
$.cookie(cookie, $.cookie(cookie) + "|" + ean + "~" + value);
}
},
deselect: function (box, cookie) {
box.removeClass("selected");
// code to delete the cookie value
}
};
$(document).ready(function () {
$(addToBasketHandler).click(function () {
var box = $(this).parents(".box-offer");
Basket.select(box, "productCookie");
});
$(removeFromBasketHandler).click(function () {
var box = $(this).parents(".box-offer");
Basket.deselect(box, "productCookie");
});
});
And after adding 3 products to my cart, my cookie looks like this:
productCookie = 9918430821007~12.00 | 7C9918430831006~3.00 | 7C7501031311309~50.30
Please help on how I could remove only the selected product from this cookie list above.
FYI I am using jquery + jquery cookie

Try
deselect: function (box, cookie) {
box.removeClass("selected");
var ean = box.attr('ean');
var value = box.find($(".price strong")).html().replace(/[^0-9\.]/g, '');
var val = ean + "~" + value; //value to be removed
if ($.cookie(cookie) !== undefined) {
var cookie_val = $.cookie(cookie);
if (cookie_val.indexOf(val) !== -1) { //check value present in cookie
var arr = cookie_val.replace(' ', '').split('|'); //remove spaces and split with |
var index = arr.indexOf(val);//get index of value to be deleted
arr.splice(index, 1); //remove value from array
$.cookie(cookie, arr.join(' | ')); //convert array to sting using join and set value to cookie
}
}
}

Related

Delete element from array when deleting record from localStorage

I have a localStorage object like this:
Key: jpxun
Value: [{"id":"0","name":"royal"},{"id":"1","name":"tippins"},{"id":"4","name":"leviosa"},{"id":"5","name":"vicious"}]
I have this JS to display output the localStorage:
var jpxun = JSON.parse(localStorage.getItem('jpxun')) || [];
if (jpxun) {
var jpxun_length = jpxun.length;
} else {
var jpxun_length = 0;
}
var hst = document.getElementById("usernames");
var MyUsernames = JSON.parse(localStorage.getItem("jpxun"));
if (jpxun_length > 0) {
// declare array to hold items for outputting later in plain text format
var plain_text_array = [];
for (var i = 0; i < MyUsernames.length; i++) {
var un1 = MyUsernames[i].name;
hst.innerHTML += "<li>" +"<a id="+MyUsernames[i].id + " href='#content' onclick='deleteById(this)'>x </a>" + un1 + "</li>";
// add word to plain text array
plain_text_array.push(un1);
}
}
Each element is outputted in a list item with an 'x' as a hyperlink so that it can be clicked and that element is deleted from localStorage.
This is the code to delete the item from localStorage:
var deleteById = function ( self ){
MyUsernames = MyUsernames.filter(function(elem) {
return elem.id !== self.id;
});
localStorage.setItem("jpxun",JSON.stringify(MyUsernames));
self.parentNode.parentNode.removeChild(self.parentNode);
}
That works fine.
Unfortunately I don't really understand how the code works in deleteById.
As that is the case, I am stuck on working out how to delete the corresponding record from plain_text_array when its value is deleted from localStorage.
I would try to find the text in the array thats includes that string 'id="item_id"':
plain_text_array = plain_text_array.filter(item => !item.includes(`id="${self.id}"`));
Just add it in the end of deleteById function.

Windows 8 Application Javascript and SQlite (Database is locked)

I write some simple app for windows 8 Metro UI with javascript. Because natural method from microsoft to use Sqlite with Javascript in Metro UI. I use 'doo' wrapper:
dooWrapper SQLite (github)
I create a method :
function addSomething(name) {
var dbPath = Windows.Storage.ApplicationData.current.localFolder.path + '\\a_db.sqlite';
SQLite3JS.openAsync(dbPath).then(function (db) {
return db.runAsync("INSERT INTO STH (nazwa) VALUES (:name)", { name: name }).
done(function () {
console.log('Add sth : ' + name);
db.close();
}, function (error) {
if (db) {
db.close();
}
console.log('ERROR Adding sth' + error.message);
})
});
}
I get error 'database is locked' I read about this error in documentation. But I have one question is other solution to add more rows without create 'insert' function with collections argument something like that : insert (array) ? I just want to use that function n-times without this error. That's possible?
Yes,it possible...i also got this error before....For that you just need to establish the database connection once...i have used this in my app and its working fine.
If there is no need of closing your db then then open database once like..
Add this code to default.js file
var myDatabase; //Global Variable
var dbPath = Windows.Storage.ApplicationData.current.localFolder.path + '\\db.sqlite';
//Create Table
SQLite3JS.openAsync(dbPath).then(function(db) {
myDatabase=db;
return db.runAsync('CREATE TABLE Item (name TEXT, price REAL, id INT PRIMARY KEY)');
});
Then you just need to use below code
// For Insert
return myDatabase.runAsync('INSERT INTO Item (name, price, id) VALUES ("'+ array[i].name+'", "48484", 1);
For array
var dbPromises = [];
var testArray = [];
//only for test purpose
//You can pass your array here directly
for (var a = 0; a < 300; a++) {
var obj = {
name: "Mango"+a,
price: 100+a,
id: a
};
testArray.push(obj);
}
for (var i = 0; i < testArray.length; i++) {
var query = 'INSERT OR REPLACE INTO Item (name, price, id) VALUES ("' + testArray[i].name + '",' + testArray[i].price + ',' + testArray[i].id + ')';
dbPromises.push(globalDatabase.allAsync(query));
}
WinJS.Promise.join(dbPromises).then(function () {
debugger;
}, function(err) {
debugger;
});
Above code is used only for less array size...bcz its taking too much time for insertion...
For fasst execution you should replace just below code
for (var i = 0; i < testArray.length; i++) {
var val = '("' + testArray[i].name + '",' + testArray[i].price + ',' + testArray[i].id + '),';
query = query + val;
if ((i + 1) % 300 == 0 || (i + 1) == testArray.length) {
query = query.replace(/,$/, "");
dbPromises.push(globalDatabase.allAsync(query));
query = 'INSERT OR REPLACE INTO Item (name, price, id) VALUES ';
}
}

Javascript SetTimeOut function Does Not Work Somehow

My system fatches data every 500 ms and my screen is full of html tables apart from each other . And every cell has unique key attribute. I am caching all of them anyway.
I have a global JavaScript object(_cellColorTimeouts) which contains settimeout functions for cellElements of tableRows that I mentioned above. After caching of cells, system creates timeout functions which is to wipe css out for spesific cell (in 3000ms).
In code block below uiElementKey_X and uiElementKey_Y are exact same but cached like are different. Adding unique suffix into table id makes them different. This proccess is done for row and cell items aswell.
example of _cellColorTimeouts data is
//array object keys are names of unique cell items.
_cellColorTimeouts = [uiElementKey_X_1, uiElementKey_X_2, uiElementKey_X_3,
uiElementKey_Y_1, uiElementKey_X_2, uiElementKey_Y_3];
.
. //does somethings to change cell colour
.
//after 3 seconds i need to clear css of this cell without looping the dom so i do it via cached dom.
if (_cellColorTimeouts.hasOwnProperty(uiElementKey) && _cellColorTimeouts[uiElementKey] != null) {
clearTimeout(_cellColorTimeouts[uiElementKey]);
_cellColorTimeouts[uiElementKey] = null;
}
_cellColorTimeouts[uiElementKey] = setTimeout(function () {
clearColourOfCell(cell);
}, 3000);
}
function clearColourOfCell(cell) {
cell.style.backgroundColor = cell.rowBGColour;
cell.style.color = "black";
_cellColorTimeouts[cell.uiElementKey] == null;
clearTimeout(_cellColorTimeouts[cell.uiElementKey]);
}
So the problem is settimeout function is not working for the first table but second is totally fine. I have checked is there any settimeout function return id from global, yes it has. For the first table somehow it does not work. I know this question is too unique for my case but any idea will be preciated?
---- EDIT ---- FULL FUNCTION UNCUT VERSION -----
function setWidgetData(widgetId, rowId, colId, value, colIndex) {
"use strict";
// check colIndex
if (colIndex === undefined || colIndex === null) {
colIndex = 0;
}
// loop on ui tables
var uiTables = _widgetUIElements[widgetId];
//var timeout;
for (var tableId in uiTables) {
var uiTable = uiTables[tableId];
var uiElementKey = tableId + "#" + rowId + "#" + colId + "#" + colIndex;
var cellCachedObject = uiTable[uiElementKey];
// check cell
if (cellCachedObject == undefined) {
//console.log("cell is undefined : " + "widgetId : " + widgetId + " - " + "rowId : " + rowId + " - " + "colId : " + colId + " - " + "colIndex : " + colIndex);
}
else {
// get cell
var cell = cellCachedObject["domElement"];
// set sell value
var cellValue = value;
// is value numeric? it means we will make some conversions on value
if (isNumeric(cellValue)) {
var canPaint = false;
// check cell entity
switch (cellCachedObject["entity"]) {
// date-time?
case "DATETIME":
// convert unix date time to readable date time
cellValue = new Date(fixDecimalSeparator(cellValue) * 1000);
cellValue = fixDateTimeDigits((cellValue.getDate())) + "/" + fixDateTimeDigits((cellValue.getMonth() + 1)) + " " + fixDateTimeDigits(cellValue.getHours()) + ":" + fixDateTimeDigits(cellValue.getMinutes());
break;
// date?
case "DATE":
// convert unix date time to readable date time
cellValue = new Date(fixDecimalSeparator(cellValue) * 1000);
cellValue = fixDateTimeDigits((cellValue.getDate())) + "/" + fixDateTimeDigits((cellValue.getMonth() + 1));
break;
// numeric?
case "NR":
// fix "," character in value
cellValue = fixDecimalSeparator(cellValue);
//just format the presicion
cellValue = number_format(cellValue, cellCachedObject["precision"], '.', ',');
canPaint = true;
break;
// other?
default:
// fix "," character in value
cellValue = fixDecimalSeparator(cellValue);
// if cell is number, no entity conversion
// entity convertion
cellValue = entityConverter(cellCachedObject["entity"], cellCachedObject["entityTo"], cellValue);
cellValue = new Number(cellValue).toFixed(cellCachedObject["precision"]);
// if widget currency is not USD. it means user selected currency from currency list or default user currency
if (cellCachedObject["isConvertable"]) {
// this scoop is not active with the new xml. if FOREX1 widget entity is RECIPCUR but never should not be
if (cellCachedObject["widgetIsFOREX1"]) {
cellValue = _currencyConverter.convertTrend(cellValue, cellCachedObject.currencyValueType, cellCachedObject["currencyTo"], cellCachedObject["rowId"], cellValue);
}
else {
cellValue = _currencyConverter.convert(cellValue, cellCachedObject["currency"], null, cellCachedObject["precision"]);
}
}
canPaint = true;
}
// if it is not date time
if (canPaint) {
// get current value of cell
var currentValue = cell.getAttribute("currentValue");
// check current value of cell make them coloured.
if (currentValue !== undefined) {
// new value is bigger than old value
var newVal = parseFloat(value);
var oldVal = parseFloat(currentValue);
var rowBGColour = cellCachedObject["rowBGColor"];
cell.rowBGColour = rowBGColour;
cell.uiElementKey = uiElementKey;
if (newVal > oldVal) {
//cell.css({ "background-color": "Green", "color": "White" });
cell.style.backgroundColor = "green";
cell.style.color = "white";
}
// new value is smaller than old value
if (newVal < oldVal) {
//cell.css({ "background-color": "Red", "color": "White" });
cell.style.backgroundColor = "red";
cell.style.color = "white";
}
if (_cellColorTimeouts.hasOwnProperty(uiElementKey) && _cellColorTimeouts[uiElementKey] != null) {
clearTimeout(_cellColorTimeouts[uiElementKey]);
_cellColorTimeouts[uiElementKey] = null;
}
_cellColorTimeouts[uiElementKey] = setTimeout(function () {
return function () {
clearColourOfCell(cell);
};
} (cell), 3000);
newVal = oldVal = rowBGColour = null;
}
currentValue = null;
}
canPaint = null;
// set new value as a current value
cell.setAttribute("currentValue", value);
}
cell.innerHTML = '';
cell.innerHTML = cellValue;
cellValue = null;
}
uiTable = uiElementKey = cellCachedObject = null;
}
uiTables = null;
}
You didn't post enough code for me to know for sure that this is the problem, but it's a good bet:
_cellColorTimeouts[uiElementKey] = setTimeout(function () {
return function() {
clearColourOfCell(cell);
};
}(cell), 3000);
By setting up the timeout handler like that, you ensure that the handler has its own private copy of that "cell" variable, so that no matter how "cell" is changed before the handler is finally invoked, that copy will retain the correct value.

What would be the right syntax in jQuery

I have a jquery function which on submit event is generating an url.If one the parameter is not defined, adding to url should be skipped
var category =$("#prod_category").val();
var group =$("#prod_group")
window.location.href = "/page/" +
**//add to url if category is definned**
encodeURI(category) + "/" +
**//add to url if group is definned**
encodeURI(group) + "/" +
You can simply state if (category). If category has a value with a length greater than zero, this will return true.
var url = "/page/";
if (category){
url = url + encodeURI(category) + "/";
}
if (group){
url = url + encodeURI(group) + "/";
}
EDIT: When setting the values to category and group ensure you trim any whitespace that the element may be containing. For example:
var category = $.trim($("#prod_category").val());
You can do this by using $.grep:
var category = $.trim($("#prod_category").val());
var group = $.trim($("#prod_group").val());
window.location.href = '/page/' + $.grep([category, group], function(s) { return s != null && s.length }).join('/');
Try:
var category =$.trim( $("#prod_category").val() );
var group =$.trim( $("#prod_group").val() );
var urlVal = "/page/";
if( category !== "") {
urlVal += encodeURI(category);
}
if( group !== "") {
urlVal += encodeURI(group);
}
window.location.href = urlVal;
Use
if($.trim(category) != ''){
}
if($.trim(group) != ''){
}

Full url sharepoint item in Javascript

I'm trying to get the ContentTypeId of an item in sharepoint to get the full url of the item to get the binary of it and after send it to another plateform.
So here i put this code in element.xml to get the list ID and the document ids of the items i'm selecting, after this i send them to an ASPX page in a Sharepoint Dialog to define the destination of the items and after this in the postback, stream the binary and send it to the another platform. The problem is : To get the full url of my items i need ListId, ItemId and ContentTypeId.
Because i've found a code to stream the binary here :
How to Programatically Download files from sharepoint document library
And i need the full url of my items.
Any idea?
thanks
var iddocs ='';
var listId ='';
function geturl()
{
var context = SP.ClientContext.get_current();
this.web = context.get_web();
listId = SP.ListOperation.Selection.getSelectedList();
var list = this.web.get_lists().getById(listId);
var ok = false;
try
{
if ( SP.ListOperation.Selection.getSelectedItems(context) !== false)
{
var items = SP.ListOperation.Selection.getSelectedItems(context);
var url='listId:'+listId+ ' Number of selected items: ' + items.length ;
var i = 0;
if(items.length==0)
{
}else{
while( i != items.length )
{
url += ' Doc' + i + ': ' + items[i].id;
if(i>0){iddocs += '-'};
iddocs += items[i].id;
i++;
};
ok = true;
alert(url+' Id of clicked item:'+{ItemId});
};
};
}
catch(err)
{
};
return ok;
};
function OpenDialog(pidliste) {
var options = SP.UI.$create_DialogOptions();
options.width = 600;
options.height = 600;
options.title = 'Envoyer vers Nuxeo';
options.url ='/_Layouts/SPTest.CustomMenuItem/index.aspx?click={ItemId}';
if(pidliste){options.url += '&ids='+pidliste +'-'+ iddocs;};
options.dialogReturnValueCallback = Function.createDelegate(null, CloseCallback);
SP.UI.ModalDialog.showModalDialog(options);
}
function CloseCallback(result, target) {
if (result == SP.UI.DialogResult.OK) {
}
if (result == SP.UI.DialogResult.cancel) {
SP.UI.Notify.addNotification('Opération canceled', false, '', null);
}
}
if(geturl())
{
OpenDialog(listId);
}else{
alert('Please select an item');
};
I've found the solution. In fact, items can be reached via :
{SiteUrl}+{ItemUrl}
The download function is linked in my first Post. But it doesn't work for multiple items, with this method you can only reach the properties of the item you're selecting.
You have to note that if you want to access to a SP file, you have to set your request.credential via :
request.Credentials = System.Net.CredentialCache.DefaultCredentials;
which will take the current credential you're using.
Hope it helps.

Categories