String array with key and value Remove already exist - javascript

I found some similar questions, but none helped me.
I have an array, and I am pushing items into it. I want to check if there is already an item then removes and add a new value.
I am doing this in the success of an ajax call,
var taxSplitUp = []; // my array
// ajax call here, in the success
for (var i in data.d) {
var ItemTaxAmt= data.d[i].ItemTaxAmt;
var TaxName = data.d[i].TaxName;
var idx = $.inArray(TaxName, taxSplitUp); // checks if already exist
if (idx == -1) {
var tx1 = '{"' + TaxName + '":"' + parseFloat(ItemTaxAmt).toFixed(2) + '"}';
taxSplitUp.push(tx1);
}
else {
taxSplitUp.splice(idx, 1); // removing
var t1 = taxSplitUp[TaxName]; // selecting the value from array
var tx1 = '{"' + TaxName + '":"' + parseFloat(ItemTaxAmt).toFixed(2) + parseFloat(t1).toFixed(2) + '"}';
taxSplitUp.push(tx1);
}
}
Here if the same key came, then I want to add the values together and want only one in the array, but the checking always returns false and adds another into the array.
please help.

$.inArray wont work with associative array. Try below solution
for (var i in data) {
var ItemTaxAmt= data[i].ItemTaxAmt;
var TaxName = data[i].TaxName;
console.log(TaxName);
$.map(taxSplitUp, function(item, index) {
if (item.TaxName == TaxName) {
item.ItemTaxAmt = ItemTaxAmt;
}else{
taxSplitUp.push({
'TaxName' :TaxName,
'ItemTaxAmt' : ItemTaxAmt
});
}
});
}
console.log(taxSplitUp);

Related

array.push() repeats same value

This is an object I tried to create to manage a list, but somethings wrong somewhere, whenever I used the list.addItem(); for the second or third time, all the values(array) in the list.list; changes to the finally added value(array).
var list = {
list : [],
eligible: function(item){
var status = true;
var dw = (item.w*item.h*item.l)/169;
if(dw > item.m){
status = true;
}else{
status = false;
}
return status;
},
addItem : function(item){
if(this.eligible(item)){
this.list.push(item);
console.log(this.list);
this.refresh();
alertify.success('Item Added to List');
}else{
alertify.warning('Item not eligible for Freight Calculation');
}
},
removeItem : function(item){
if(this.inList(item)){
var itemIndex = this.list.indexOf(item);
if(itemIndex > -1){
this.list.splice(itemIndex,1);
alertify.success('Item Removed from List');
this.refresh();
}
}else{
alertify.error('Item NOT in List');
}
},
inList: function(item){
var bool = false;
if (this.list.filter(function(e) { return e.id === item.id; }).length > 0) {
bool = true;
}else{
bool = false;
}
return bool;
},
findItem: function (id) {
for (var i = 0; i < this.list.length; i++) {
if (this.list[i].id === id) {
return this.list[i];
}
}
},
refresh: function(){
if(this.list.length > 0){
$('.items .table tbody').empty();
var itemNo = 0;
$.each( this.list, function( key, item ) {
$('.items .table tbody').append('</tr><tr><td>' + ++itemNo + '</td><td>' + item.qty + '</td><td>' + item.m + '</td><td>' + item.h + '</td><td>' + item.w + '</td><td>' + item.l + '</td><td><button data-item=\"' + item.id + '\" class=\"btn btn-remove btn-block\"><i class=\"far fa-minus-square\"></i></button></td><td>Price</td></tr>')
});
}else{
$('.items .table tbody').html('<tr><td colspan=\"8\" style=\"text-align:center;\"> No Items Added.</td></tr>')
}
}
};
I can't find whats wrong, maybe it's because I've been trying this all day. Btw I'm new to programming.
UPDATE: This is how i call the addItem:
var id=0; //just for reference
$('.btn-add-item').click(function(){
var item = [];
item.id = ++id;
item.qty = parseInt($('input[name=qty]').val());
item.m = parseFloat($('input[name=weight]').val()).toFixed(3);
item.w = parseFloat($('input[name=width]').val()).toFixed(2);
item.h = parseFloat($('input[name=height]').val()).toFixed(2);
item.l = parseFloat($('input[name=length]').val()).toFixed(2);
item.country = $('#countrySelect').val();
list.addItem(item);
});
In your click handler you are assigning each input element's value to the variable item as if item were an Object. Unfortunately, you've initialized item as an Array. You should initialize item as an Object. Then, your list Array will contain a list of Objects.
Change
var item = [];
To
var item = {};
Since you are new to programming, and Javascript is sort special in an odd way with this code, please let me explain why there was no error thrown to let you know this.
In JavaScript, Arrays are actually Objects. So assigning a value like you have (item.blah) actually places that property on the item Array Object as a property, but doesn't know your intent is to add the value to the list of Array elements. Javascript carries out what it believes is your intent.

loop through selected checkboxes

In the checkboxes which pertains on the same class ,I'm using this function (not finished) tho loop and set a string
function estados() {
var query = "trucades.estat in(";
var checks = $('.estate_check:checked');
if (checks.length === 0) {
query = "not selected ";
} else {
//set the message here ...but only loops once
}
return query;
}
But checks only contains an object which contains the selected checkboxes but if I try to llop ,it only loops once ,because only contains this object
var ckbox = $('.my-checkbox:checked');
var str = "";
ckbox.each(function(){
str += $(this).attr('data-text') + ", ";
});
alert(str);
This fiddle helps you figure it out:
JSFiddle
Assuming you need to create query, You can use .map() along with .get() to create an array of selected values. then Array.join() can be used to create comma separated string.
function estados() {
var query = "trucades.estat in(";
var checks = $('.estate_check:checked');
if (checks.length === 0) {
query = "not selected ";
} else {
//Create an array of selected value
var selectedValue = checks.map(function () {
return $(this).val();
}).get();
query += selectedValue.join(',') + ')'
}
return query;
}
function estados() {
var query = "trucades.estat in(";
$('.estate_check:checked').each(function( index ) {
const val = $( this ).val()
console.log(index + ': ' + val);
query += val;
});
query += ')';
return query;
}

JavaScript - Function for finding text within a string

I have a function that I use to pass over a table field name and its value. Depending on the name of the field, it either returns the contents as a link or it does not.
// Given a field name, check to see if its in our output. If so, return the formatted link
function createLink(field, val) {
var output = {
'ntid': 'https://web.internal/profile/' + val,
'email': 'mailTo:' + val
};
var i, key, keys = Object.keys(output);
for ( i = 0; i < keys.length; ++i ) {
key = keys[i];
if(field.toLowerCase() == key){
return ''+val+'';
}
}
return val;
}
Usage:
createLink('email', 'bob#stuff.com')
// returns bob#stuff.com
This also works for NTID. The issue I am having though is there are some field names that contain my values in the output such as Sup Email or Sup NTID and those are not transformed correctly.
Expected Result:
createLink('sup email', 'bob2#stuff2.com')
// returns bob#stuff.com
The Question:
How can I tweak my function to see if my field exists in the output array at all, even if it's not an exact match?
Change your function to
function createLink(field, val) {
var output = {
'ntid': 'https://web.internal/profile/' + val,
'email': 'mailTo:' + val
};
var i, key, keys = Object.keys(output);
for (i = 0; i < keys.length; ++i) {
key = keys[i];
if ((field.toLowerCase()).includes(key)) {
return '' + val + '';
}
}
return val;
}
console.log(createLink('sup email', 'bob2#stuff2.com') )
Notice the code if ((field.toLowerCase()).includes(key)) {
This will check for your key substring in the string
What you're implementing is the Strategy Pattern. The Strategy Pattern relies on some form of behaviour-switching depending on the inputs to the method. In your case, that switching is based on the first argument.
What you don't want to do is what your questions asks how to do. You don't want to assume every field name in your application which contains "email" or some other string is guaranteed to be an email address, handled by the same strategy.
Create a table of field names and strategies to use for the display of each of these fields; and use an "enum-ish" object as the definition of the strategies.
function create_link(field, val) {
const strategy = create_link.Field_Strategies[field];
if (typeof strategy === 'undefined') {
console.log("Using default strategy");
return val;
}
console.log("Using " + strategy);
switch (strategy) {
case create_link.Strategies.EMAIL:
return '' + val + '';
case create_link.Strategies.NTID:
return '<a href="https://web.internal/profile/' +
val + '" target="_blank">' + val + '</a>';
case create_link.Strategies.SOME_FIELD:
return '<a href="http://example.com/some/path/' +
encodeURIComponent(val) +
'" target="_blank">' + val + '</a>';
}
}
create_link.Strategies = {
EMAIL: "email strategy",
NTID: "ntid strategy",
SOME_FIELD: "somefield strategy"
};
create_link.Field_Strategies = {
"Sup email": create_link.Strategies.EMAIL,
"E-mail": create_link.Strategies.EMAIL,
"Email": create_link.Strategies.EMAIL,
"NTID": create_link.Strategies.NTID,
"Foobar baz": create_link.Strategies.SOME_FIELD
};
console.log(create_link("foo","foofoofoo"));
console.log(create_link("Sup email","supervisor#example.com"));
console.log(create_link("E-mail","foo#example.com"));
console.log(create_link("Email","bar#example.com"));
console.log(create_link("NTID","10983409509734"));
console.log(create_link("Foobar baz","Aleph null"));
You could use String.prototype.indexOf.
The indexOf() method returns the index within the calling String object of the first occurrence of the specified value...Returns -1 if the value is not found.
So your code would then look like:
// Given a field name, check to see if its in our output. If so, return the formatted link
function createLink(field, val) {
var output = {
'ntid': 'https://web.internal/profile/' + val,
'email': 'mailTo:' + val
};
var i, key, keys = Object.keys(output);
for ( i = 0; i < keys.length; ++i ) {
key = keys[i];
if(field.toLowerCase().indexOf(key) >= 0){ //CHANGE HERE
return ''+val+'';
}
}
return val;
}

JSON return value to global variable

Simply my code looks like this:
var thevariable = 0;
For(){
//somecode using thevariable
$.getJSON('',{},function(e){
//success and i want to set the returned value from php to my variable to use it in the forloop
thevariable = e.result;
});
}
my main problem that the variable value stays "0", during the whole For loop, while i only want it to be "0" at the first loop, then it takes the result returned from PHP to use it on for loop.
here it my real code if you need to take a look:
var orderinvoice = 0;
for(var i=0; i<table.rows.length; i++){
var ordername = table.rows[i].cells[5].innerText;
var orderqty = ((table.rows[i].cells[1].innerText).replace(/\,/g,'')).replace(/Qty /g,'');
var orderprice = (table.rows[i].cells[2].innerText).replace(/\$/g,'');
var ordertype = table.rows[i].cells[3].innerText;
var orderlink = table.rows[i].cells[4].innerText;
$.getJSON('orderprocess.php', {'invoice': orderinvoice, 'pay_email': email, 'ord_name': ordername, 'ord_qty': orderqty, 'ord_price': orderprice, 'ord_type': ordertype, 'ord_link': orderlink}, function(e) {
console.log();
document.getElementById("result").innerText= document.getElementById("result").innerText + "Order #"+e.result+" Created Successfully ";
document.getElementById("invoker").innerText = ""+e.invoice;
orderinvoice = e.invoice;
if(i+1 == table.rows.length){
document.getElementById("result").innerText= document.getElementById("result").innerText + "With invoice #" + e.invoice;
}
});
in a loop block, before one ajax complete other one will be run and this's javascript natural treatment. For your case you can call a function at the end of success event. Do something like this:
var i = 0;
doSt();
function doSt() {
var orderinvoice = 0;
var ordername = table.rows[i].cells[5].innerText;
var orderqty = ((table.rows[i].cells[1].innerText).replace(/\,/g, '')).replace(/Qty /g, '');
var orderprice = (table.rows[i].cells[2].innerText).replace(/\$/g, '');
var ordertype = table.rows[i].cells[3].innerText;
var orderlink = table.rows[i].cells[4].innerText;
$.getJSON('orderprocess.php', { 'invoice': orderinvoice, 'pay_email': email, 'ord_name': ordername, 'ord_qty': orderqty, 'ord_price': orderprice, 'ord_type': ordertype, 'ord_link': orderlink }, function(e) {
console.log();
document.getElementById("result").innerText = document.getElementById("result").innerText + "Order #" + e.result + " Created Successfully ";
document.getElementById("invoker").innerText = "" + e.invoice;
orderinvoice = e.invoice;
if (i + 1 == table.rows.length) {
document.getElementById("result").innerText = document.getElementById("result").innerText + "With invoice #" + e.invoice;
}
i++;
if (i < table.rows.length) doSt();
});
}
I think you need a recursive function that always deals with the first element in your rows array and then splices it off and calls itself. For example, something like this:
function getStuff(rows, results) {
if (rows.length > 0) {
var ordername = rows[0].cells[5].innerText;
$.getJSON('orderprocess.php', { 'ord_name': ordername }, function (e) {
// do some stuff
results.push('aggregate some things here?');
rows.splice(0, 1);
return getStuff(rows, results);
});
} else {
return results;
}
}
When the array is spent, results will be returned with whatever aggregate you wanted at the end of the cycle. Then, you can do as you please with the results. I think you can also manipulate the DOM inside the function as you see fit if that makes more sense. Hope this helps.

Hide all content exception made when URL parameter is used

I want to hide my website content exception made when ?token_code=12345678 is used in URL. This is the code that's not working correctly, it hides website but never shows it:
I'm calling script by www.example.com/?authtoken=12345678
So when that parameter is included in URL it should show website. But it's not displaying it. It's only hiding it.
PS. I'm using cookies to remember "token" :)
HTML:
<body data-token="12345678"> </body>
JS:
//setCookie and readCookie
function SetCookie(e, t, n) {
var r = new Date;
var i = new Date;
if (n == null || n == 0) n = 1;
i.setTime(r.getTime() + 36e5 * 24 * n);
document.cookie = e + "=" + escape(t) + ";expires=" + i.toGMTString()
}
function ReadCookie(e) {
var t = " " + document.cookie;
var n = t.indexOf(" " + e + "=");
if (n == -1) n = t.indexOf(";" + e + "=");
if (n == -1 || e == "") return "";
var r = t.indexOf(";", n + 1);
if (r == -1) r = t.length;
return unescape(t.substring(n + e.length + 2, r))
}
function DeleteCookie(name) {
document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
}
//capitalzies string
function capitalize(str) {
var first = str.charAt(0).toUpperCase();
str = str.replace(/^.{1}/, first);
return str;
}
// get's the GET paramters like so --> $_GET('var1');
function getVar(variable) {
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split("=");
if (pair[0] == variable) {
return pair[1];
}
}
return (false);
}
// Checks for one of TWO access short codes
// includeOnly && excludeOnly
// If includeOnly is not NULL, then ONLY include
// categories mentioned in that varaible.
// Also, cookie the data, that it's saved.
// Of course, if anyone re-visits the site, and
// re-writes the GET paramter, it'd delete all
// previous data in the cookie.
var token_code = ["authtoken", "excludeOnly"];
var asc = ""; //this is used to select the CURRENT access short code
var tokenValues = [];
//first check if there are ANY get params.
if (getVar(token_code[0]) != false) {
//before writing the inlcude only, delete EXCLUDE only
DeleteCookie(token_code[1]);
SetCookie(token_code[0], getVar(token_code[0]));
}
if (getVar(token_code[1]) != false) {
//before writing the EXCLUDE only, delete include only
DeleteCookie(token_code[0]);
SetCookie(token_code[1], getVar(token_code[1]));
}
//Try and reaad the cookie (there should be a cookie named "includeOnly" or "excludeOnly -- both from token_code)
//includeOnly is present?
if (ReadCookie(token_code[0]).toString().length > 0) {
//defines what the user wants to do. Exlcude or include? when token_code[0] it's include!
asc = token_code[0];
var tokens = ReadCookie(asc).toString();
tokenValues = decodeURIComponent(tokens).split(',');
//loop through each category.
//hide every category and it's children
$("[data-token]").hide();
$.each(tokenValues, function (index, value) {
//show every category, and it's childen, for the values
$("[data-token='" + value + "']").show();
});
}
//excludeOnly is present?
if (ReadCookie(token_code[1]).toString().length > 0) {
//defines what the user wants to do. Exlcude or include? when token_code[0] it's include!
asc = token_code[1];
var tokens = ReadCookie(asc).toString();
tokenValues = decodeURIComponent(tokens).split(',');
//loop through each category.
//hide every category and it's children
$("[data-token]").show();
$.each(tokenValues, function (index, value) {
//show every category, and it's childen, for the values
$("[data-token='" + value + "']").hide();
});
}
is there an easier way to do this?
In the bottom of your code, were the comment says to show, it runs .hide().
Could that be a problem?
//show every category, and it's childen, for the values
$("[data-token='" + value + "']").hide();

Categories

Resources