I am creating a web app that uses the BLE web api. I made it so that when you press the scan button it scans for bluetooth devices and filters out all the ones that are not ESP's. Then it calculates the distance and pushes it into an array. I am able to make so that it can scan for the bluetooth devices, calculate distance and calculate your position. However it only works once. I think this is because of the eventlistener because it only scans when the advertisements are received. However I can not seem to figure out how to make it so that i can just scan multiple times and recalculate the data.
import * as trilateration from './trilateration.js';
import * as Utils from './utils.js';
import context from './context.js';
const beaconMapping = {
'ESP32_1': 0,
'ESP32_2': 1,
'ESP32_3': 2,
}
const DISTANCE_SCALAR = 1;
console.log("Init");
const devices = [];
const ids = [];
const beaconuuid = [];
const distances = [];
const SCAN_TIME = 10000;
//add beacons to trilatertion;
trilateration.addBeacon(0, trilateration.vector(10.1, 7.0));
trilateration.addBeacon(1, trilateration.vector(0, 0));
trilateration.addBeacon(2, trilateration.vector(10.1, 0));
document.getElementById("scan").onclick = scan;
async function scan() {
console.log("Scanning...");
let options = {
acceptAllAdvertisements: true,
acceptAllDevices: true,
};
try {
log("Requesting Bluetooth Scan with options: " + JSON.stringify(options));
const scan = await navigator.bluetooth.requestLEScan(options);
// set the length to 0
distances.length = 0;
log("Scan started with:");
log(" acceptAllAdvertisements: " + scan.acceptAllAdvertisements);
log(" active: " + scan.active);
log(" keepRepeatedDevices: " + scan.keepRepeatedDevices);
log(" filters: " + JSON.stringify(scan.filters));
navigator.bluetooth.addEventListener("advertisementreceived", (event) => {
let name = event.device.name;
if (name && name.startsWith("ESP32") && !ids.includes(event.device.id)) {
console.log("Found");
//console.log(event);
//add to device list if name starts with ESP32
console.log("adding");
const obj = {
device: event.device,
uuids: event.uuids,
rssi: event.rssi,
tx: event.txPower,
distance: calculateDistance(event.rssi, event.txPower) * DISTANCE_SCALAR,
};
console.log(obj);
console.log(obj.tx, obj.rssi, obj.distance, name);
devices.push(obj);
ids.push(event.device.id);
const beaconIndex = beaconMapping[event.device.name];
if (beaconIndex !== undefined) {
distances.push(obj.distance);
trilateration.setDistance(beaconIndex, obj.distance);
} else {
console.error("Name not found in mapping");
}
if (distances.length > 2) {
var pos = trilateration.calculatePosition();
console.log(pos);
console.log("Distqnces qrr length", distances.length)
console.log("X: " + pos.x + "; Y: " + pos.y);
context.fillRect(pos.x * 100, pos.y * 100, 20, 20);
}
showBeaconInfo(obj);
}
/* log('Advertisement received.');
log(' Device Name: ' + event.device.name);
log(' Device ID: ' + event.device.id);
log(' RSSI: ' + event.rssi);
log(' TX Power: ' + event.txPower);
log(' UUIDs: ' + event.uuids); */
});
setTimeout(stopScan, SCAN_TIME);
function stopScan() {
console.log("List of all devices detected:");
console.log(devices);
console.log(ids)
console.log(beaconuuid);
console.log(distances)
log("Stopping scan...");
scan.stop();
log("Stopped. scan.active = " + scan.active);
}
} catch (error) {
log("Argh! " + error);
}
}
function showBeaconInfo(obj) {
log(" Device Name: " + obj.device.name);
log(" Device ID: " + obj.device.id);
log(" RSSI: " + obj.rssi);
log(" TX Power: " + obj.tx);
log(" UUIDs: " + obj.uuids);
}
function log(c) {
console.log(c);
}
function calculateDistance(rssi, txPower) {
//original method
//Math.pow(10, (event.txPower - event.rssi) / (10 * 2))
//overwrite txPower
txPower = -59;
if (rssi == 0) {
return -1.0;
}
const ratio = rssi * 1.0 / txPower;
if (ratio < 1.0) {
return Math.pow(ratio, 10);
} else {
const distance = (0.89976) * Math.pow(ratio, 7.7095) + 0.111;
return distance;
}
}
/*trilateration.addBeacon(0, trilateration.vector(25, 63));
trilateration.addBeacon(1, trilateration.vector(0, 0));
trilateration.addBeacon(2, trilateration.vector(25, 31));
trilateration.setDistance(0, distances[0]);
trilateration.setDistance(1, distances[1]);
trilateration.setDistance(2, distances[2]);
var pos = trilateration.calculatePosition();
console.log("X: " + pos.x + "; Y: " + pos.y);*/
context.strokeRect(0, 0, 1300, 700);
drawBeacons()
function drawBeacons() {
context.fillStyle = "red"
Utils.fillCircle(1001, 700, 50)
Utils.fillCircle(0, 0, 50)
Utils.fillCircle(1001, 0, 50)
}
I tried to decode this code but I did not succeed:
var _0x147bb5 = _0xe0c4, _0x41852d = _0xe0c4, _0x39ac2c = _0xe0c4;
(function (_0x3c89e2, _0x4b3ebe) {
var _0x331330 = _0xe0c4, _0x279707 = _0xe0c4, _0x50917c = _0xe0c4, _0x489044 = _0x3c89e2();
while (!![]) {
try {
var _0x36e386 = -parseInt(_0x331330(0x133)) / 0x1 + -parseInt(_0x279707('0x12a')) / 0x2 + -parseInt(_0x331330(0x111)) / 0x3 + -parseInt(_0x331330(0x12f)) / 0x4 + parseInt(_0x279707('0x10a')) / 0x5 * (-parseInt(_0x279707('0xf1')) / 0x6) + -parseInt(_0x331330('0x109')) / 0x7 + parseInt(_0x331330(0xee)) / 0x8 * (parseInt(_0x279707(0x11a)) / 0x9);
if (_0x36e386 === _0x4b3ebe) break; else _0x489044['push'](_0x489044['shift']());
} catch (_0x108487) {
_0x489044['push'](_0x489044['shift']());
}
}
}(_0x5a9e, 0x7f5a2));
var s = _0x147bb5('0x12b') + _0x147bb5(0xdc) + _0x39ac2c('0x118') + '91', f = 0xb, l = lf(), message = _0x39ac2c('0x117') + _0x39ac2c('0xe7') + _0x39ac2c('0x108') + _0x147bb5('0xd4') + 'ot\x20' + _0x147bb5('0x104') + _0x41852d(0xd3) + _0x39ac2c('0x122') + _0x39ac2c('0xef') + _0x41852d(0x127) + _0x41852d('0x102') + _0x41852d('0xfb') + _0x147bb5(0xe2) + _0x39ac2c(0xf2) + _0x147bb5(0xe5) + _0x41852d(0xd6) + _0x39ac2c(0x125) + _0x41852d(0xff) + _0x147bb5(0xd7) + _0x41852d('0x110') + _0x39ac2c('0x11e') + _0x39ac2c(0xdd) + _0x41852d(0x107) + 'ea)';
function rtclickcheck(_0xf37bcd) {
var _0x5b07b6 = _0x39ac2c, _0x189d42 = _0x41852d, _0x158d5e = _0x147bb5;
if (navigator[_0x5b07b6(0xfd) + _0x189d42(0xf5) + 'e'] == _0x158d5e('0xe4') + _0x189d42(0xde) + 'pe' && _0xf37bcd[_0x5b07b6('0xfc') + 'ch'] == 0x3) return alert(message), ![];
if (navigator[_0x5b07b6(0xfd) + _0x189d42(0xf8) + _0x5b07b6('0x11d') + 'n'][_0x5b07b6('0xec') + _0x158d5e(0x128) + 'f'](_0x158d5e(0xe6) + 'E') != -0x1 && event[_0x189d42('0x126') + _0x158d5e('0x132')] == 0x2) return alert(message), ![];
} function _0x5a9e() {
var _0x521b96 = ['Thi', '7109872DszjuD', '4405xemFJj', 'deA', '//r', 'cre', 'hre', 'h=/', 're.', '1823784ZeLCWd', ';\x20p', 'etc', 'cap', 'cha', 'crt', 'Ooh', '794', 'TCS', '14494869UZdEDp', 'onm', 'erH', 'sio', 'com', 'ute', 'dli', 'men', 'py\x20', '_y=', 'tBy', 'uth', 'but', 'rot', 'exO', 'inn', '603236FmaGTN', '-11', 'exp', 'ous', 'toU', '2882436fEtPRL', 'dit', 'kie', 'ton', '1000745kgQiEE', '\x20Co', 's\x20N', 'hos', '//y', 'sto', 'len', 'pat', 'tri', '.ly', '350', '\x20(y', 'sca', 'gth', 'lin', 'rib', 'by\x20', 'Att', 'Net', 'ps:', 'MSI', '!!\x20', 'edo', 'ide', 'tna', '10;', 'ind', '/yu', '24DoydZk', '-\x20P', 'rCo', '4518TXMdnf', 'htt', 'N_f', 'Ele', 'Nam', 'and', 'get', 'Ver', 'ire', 'ati', 'ed\x20', 'whi', 'app', 'coo', 'eme', 'TML', 'ath', 'ect', 'sli', 'For', 'Tim', 'set', 'uid'];
_0x5a9e = function () {
return _0x521b96;
};
return _0x5a9e();
}
document[_0x147bb5(0x11b) + _0x147bb5('0x12d') + _0x147bb5('0xe8') + 'wn'] = rtclickcheck;
if (l == s && s[_0x147bb5(0xd8) + _0x147bb5('0xdf')] == f) {
var ceditf = document[_0x147bb5(0xf7) + _0x41852d(0xf4) + _0x39ac2c('0x121') + _0x147bb5(0x124) + 'Id'](_0x39ac2c(0x10d) + _0x147bb5('0x130') + _0x147bb5('0xe0') + 'k'), citf = document[_0x39ac2c(0xf7) + _0x147bb5('0xf4') + _0x39ac2c('0x121') + _0x39ac2c('0x124') + 'Id'](_0x39ac2c('0x116') + _0x39ac2c(0xe0) + 'k');
o();
var citdf = document[_0x41852d('0xf7') + _0x147bb5('0xf4') + _0x41852d(0x121) + _0x41852d('0x124') + 'Id'](_0x41852d('0x116') + _0x147bb5('0x120') + 'nk');
function checkLIC() {
var _0x4072d7 = _0x41852d, _0x264ab4 = _0x41852d, _0x1a0d97 = _0x147bb5;
if (cedit['inn' + _0x4072d7('0x11c') + _0x4072d7(0x100)][_0x1a0d97('0xd8') + _0x4072d7('0xdf')] === 0x0) return invalidLIC(), ![];
}
}
var cedit = document[_0x41852d(0xf7) + _0x39ac2c(0xf4) + _0x39ac2c(0x121) + _0x41852d('0x124') + 'Id'](_0x147bb5('0x10d') + _0x39ac2c(0x130) + _0x39ac2c(0xe0) + 'k');
function _0xe0c4(_0x488be0, _0x324154) {
var _0x5a9e88 = _0x5a9e();
return _0xe0c4 = function (_0xe0c4a8, _0x3812b4) {
_0xe0c4a8 = _0xe0c4a8 - 0xd3; var _0x1108f7 = _0x5a9e88[_0xe0c4a8];
return _0x1108f7;
}, _0xe0c4(_0x488be0, _0x324154);
}
!cedit && invalidLIC();
function o() {
_0x162858();
function _0x162858() {
var _0x139ac8 = _0xe0c4, _0x75417f = _0xe0c4, _0x15d340 = _0xe0c4, _0x5960f5 = new Date();
_0x5960f5[_0x139ac8(0x106) + _0x75417f('0x105') + 'e'](_0x5960f5[_0x75417f(0xf7) + _0x15d340(0x105) + 'e']() + 0x15180 * 0x3);
var _0x43eec0 = _0x75417f(0x12c) + _0x15d340(0xf9) + 's=' + _0x5960f5[_0x15d340('0x12e') + _0x139ac8(0x119) + _0x139ac8(0xda) + 'ng']();
document[_0x15d340('0xfe') + 'kie'] = _0x15d340(0x114) + _0x139ac8('0x123') + _0x15d340('0xeb') + _0x15d340('0xd9') + _0x75417f('0x10f') + ';', document[_0x75417f(0xfe) + _0x15d340('0x131')] = 'JSO' + _0x139ac8(0xf3) + _0x75417f('0x113') + 'h' + '=' + fetchon + ';' + _0x43eec0 + (_0x139ac8(0x112) + _0x15d340('0x101') + '=/'), window['loc' + _0x15d340(0xfa) + 'on'][_0x15d340('0x10e') + 'f'] = api;
}
}
function invalidLIC() { }
function checkLIC() {
var _0x4dac69 = _0x39ac2c, _0x55bc12 = _0x41852d, _0x4c895a = _0x147bb5;
if (cedit[_0x4dac69(0x129) + _0x4dac69('0x11c') + _0x4c895a(0x100)][_0x55bc12('0xd8') + _0x4dac69(0xdf)] === 0x0) return invalidLIC(), ![]; else {
if (cedit[_0x4c895a('0xf7') + _0x55bc12(0xe3) + _0x55bc12(0xe1) + _0x4c895a('0x11f')](_0x4dac69(0x10e) + 'f') !== _0x4c895a(0xf2) + _0x4c895a('0xe5') + _0x55bc12('0x10c') + 'ebr' + _0x4c895a('0xf6') + _0x4c895a(0xdb) + _0x55bc12('0xed') + _0x4c895a(0xe9) + 'a/') return invalidLIC(), ![];
}
}
checkLIC(),
setInterval(
function () {
checkLIC();
},
0x1388
);
function lf() {
var _0x5a8bac = _0x39ac2c, _0x505e9a = _0x147bb5, _0xd36b1d = _0x147bb5, _0x5b07b5 = location[_0x5a8bac(0xd5) + _0x505e9a('0xea') + 'me'][_0x5a8bac(0x103) + 'ce'](0x2)[_0x505e9a(0x103) + 'ce'](0x0, -0x2) + '24', _0x130606 = 0x0;
if (_0x5b07b5[_0x5a8bac('0xd8') + _0xd36b1d('0xdf')] == 0x0) return _0x130606;
for (i = 0x0; i < _0x5b07b5[_0x5a8bac('0xd8') + _0xd36b1d(0xdf)]; i++) {
char = _0x5b07b5[_0xd36b1d('0x115') + _0xd36b1d('0xf0') + _0xd36b1d(0x10b) + 't'](i), _0x130606 = (_0x130606 << 0x5) - _0x130606 + char, _0x130606 = _0x130606 & _0x130606;
}
return _0x130606;
}
https://jsfiddle.net/utpgLw06/
So My first approach is to use online tools, but none of them works. I also try to manually decode it by calling the function name console.log(_0x331330(0x133)) but it just shows strings that I don't understand. I also tried to decode those strings by using much hex at numerical decoders but none of them works. Anyone can help me, please?
I played a bit with this code:
The _Ox names are just variable names. You can make the code more readable by collecting all such distinct names and replace them with more readable names, like v1, v2, v3, ....
There are two variables referenced which are not defined, api and fetchon. I suppose that the page where this script runs, has defined them somewhere.
The first part of the script is harmless and just shuffles an array of strings, which is later used to obfuscate strings (often property names). You can execute it
The code that needs de-obfuscation is the code that gets/sets properties of window, document, nagivator, ...and other objects. You can get a long way by putting that part of the script in a template literal, and evaluating all those expressions that evaluate to a property name, or to a value assigned to a property.
Functions and immediate code are mixed. It helps to reorganise that a bit.
Some functions have local variables which are constants and have unique names. These can be moved to the global scope and can often be evaluated safely, so the rest of the function's code can be clarified inside a template literal (like explained above).
Any remaining variables (not evaluated), can be given more telling names by seeing how they are used.
Anyway, here is the result I got to:
function rtclickcheck(e) {
if (navigator.appName == "Netscape" && e.which == 3)
return alert("Ooh!! This Not For Copy - Protected by https://yuthemestore.com (yuidea)"), false;
if (navigator.appVersion.indexOf("MSIE") != -1 && event.button == 2)
return alert("Ooh!! This Not For Copy - Protected by https://yuthemestore.com (yuidea)"), false;
}
document.onmousedown = rtclickcheck;
function o() {
var date = new Date();
date.setTime(date.getTime() + 259200);
var expiration = "expires=" + date.toUTCString();
document.cookie = "cap_y=10;path=/;";
// fetchon and api must be defined?
document.cookie = "JSON_fetch=" + fetchon + ";" + expiration + "; path=/";
window.location.href = api;
}
function invalidLIC() { }
function checkLIC() {
if (cedit.innerHTML.length === 0)
return invalidLIC(), false;
else {
if (cedit.getAttribute("href") !== "https://rebrand.ly/yuidea/")
return invalidLIC(), false;
}
}
function lf() {
var decrypted = location.hostname.slice(2).slice(0, -2) + '24',
encrypted = 0;
if (decrypted.length == 0) return encrypted;
for (i = 0; i < decrypted.length; i++) {
char = decrypted.charCodeAt(i);
encrypted = (encrypted << 5) - encrypted + char;
encrypted = encrypted & encrypted;
}
return encrypted;
}
var l = lf();
var s = "-1135079491";
if (l == s && s.length == 11) {
var ceditf = document.getElementById("creditlink"),
citf = document.getElementById("crtlink");
o();
var citdf = document.getElementById("crtdlink");
function checkLIC() {
if (cedit.innerHTML.length === 0)
return invalidLIC(), false;
}
}
var cedit = document.getElementById("creditlink");
!cedit && invalidLIC();
checkLIC();
setInterval(checkLIC, 5000);
This code seems to do the following things:
Avoid that the user can view the source of the page with a right click
Obfuscates the current site's hostname through bitshifting and summing, and checks that the result has a certain value. I didn't try to find out what the original hostname would have to be to get a match.
Sets some variables like ceditf which are not used in this script, but maybe elsewhere
If the host matches, two cookies are set, and a navigation occurs (to whatever api has as URL)
Every 5 seconds checks the content of the element with id "creditlink".
If the contents of "creditlink" are not as expected it calls invalidLIC, but that function is empty -- I think that might have had code in a previous version of this script, but it was later removed.
I have a calendar component for blazor that wraps the Toast-UI JS Calendar. I have a need to customize the calendar and the API allows that, but through overriding functions in JS.
How can I construct some instructions in C# (I'm thinking some fluent builder pattern) that I can pass down via jsinterop that can then re-construct the "template" parameter JS code that I can pass into the Calendar constructor?
Can I send a JS function as string from c# to js via jsinterop? Use eval() or function()?
What are the options to do this or better ways?
e.g.
https://nhn.github.io/tui.calendar/latest/tutorial-example14-template-for-month
function getTimeTemplate(schedule, isAllDay) {
var html = [];
if (!isAllDay) {
html.push('<strong>' + moment(schedule.start.getTime()).format('HH:mm') + '</strong> ');
}
if (schedule.isPrivate) {
html.push('<span class="calendar-font-icon ic-lock-b"></span>');
html.push(' Private');
} else {
if (schedule.isReadOnly) {
html.push('<span class="calendar-font-icon ic-readonly-b"></span>');
} else if (schedule.recurrenceRule) {
html.push('<span class="calendar-font-icon ic-repeat-b"></span>');
} else if (schedule.attendees.length) {
html.push('<span class="calendar-font-icon ic-user-b"></span>');
} else if (schedule.location) {
html.push('<span class="calendar-font-icon ic-location-b"></span>');
}
html.push(' ' + schedule.title);
}
return html.join('');
}
function getGridTitleTemplate(type) {
var title = '';
switch(type) {
case 'milestone':
title = '<span class="tui-full-calendar-left-content">MILESTONE</span>';
break;
case 'task':
title = '<span class="tui-full-calendar-left-content">TASK</span>';
break;
case 'allday':
title = '<span class="tui-full-calendar-left-content">ALL DAY</span>';
break;
}
return title;
}
function getGridCategoryTemplate(category, schedule) {
var tpl;
switch(category) {
case 'milestone':
tpl = '<span class="calendar-font-icon ic-milestone-b"></span> <span style="background-color: ' + schedule.bgColor + '">' + schedule.title + '</span>';
break;
case 'task':
tpl = '#' + schedule.title;
break;
case 'allday':
tpl = getTimeTemplate(schedule, true);
break;
}
return tpl;
}
// register templates
var templates = {
milestone: function(schedule) {
return getGridCategoryTemplate('milestone', schedule);
},
milestoneTitle: function() {
return getGridTitleTemplate('milestone');
},
task: function(schedule) {
return getGridCategoryTemplate('task', schedule);
},
taskTitle: function() {
return getGridTitleTemplate('task');
},
allday: function(schedule) {
return getTimeTemplate(schedule, true);
},
alldayTitle: function() {
return getGridTitleTemplate('allday');
},
time: function(schedule) {
return getTimeTemplate(schedule, false);
},
goingDuration: function(schedule) {
return '<span class="calendar-icon ic-travel-time"></span>' + schedule.goingDuration + 'min.';
},
comingDuration: function(schedule) {
return '<span class="calendar-icon ic-travel-time"></span>' + schedule.comingDuration + 'min.';
},
monthMoreTitleDate: function(date, dayname) {
var day = date.split('.')[2];
return '<span class="tui-full-calendar-month-more-title-day">' + day + '</span> <span class="tui-full-calendar-month-more-title-day-label">' + dayname + '</span>';
},
monthMoreClose: function() {
return '<span class="tui-full-calendar-icon tui-full-calendar-ic-close"></span>';
},
monthGridHeader: function(dayModel) {
var date = parseInt(dayModel.date.split('-')[2], 10);
var classNames = ['tui-full-calendar-weekday-grid-date '];
if (dayModel.isToday) {
classNames.push('tui-full-calendar-weekday-grid-date-decorator');
}
return '<span class="' + classNames.join(' ') + '">' + date + '</span>';
},
monthGridHeaderExceed: function(hiddenSchedules) {
return '<span class="weekday-grid-more-schedules">+' + hiddenSchedules + '</span>';
},
monthGridFooter: function() {
return '';
},
monthGridFooterExceed: function(hiddenSchedules) {
return '';
},
monthDayname: function(model) {
return String(model.label).toLocaleUpperCase();
},
dayGridTitle: function(viewName) {
/*
* use another functions instead of 'dayGridTitle'
* milestoneTitle: function() {...}
* taskTitle: function() {...}
* alldayTitle: function() {...}
*/
return getGridTitleTemplate(viewName);
},
schedule: function(schedule) {
/*
* use another functions instead of 'schedule'
* milestone: function() {...}
* task: function() {...}
* allday: function() {...}
*/
return getGridCategoryTemplate(schedule.category, schedule);
}
};
var cal = new tui.Calendar('#calendar', {
defaultView: 'month',
template: templates
});
I have few problems with below code.Can anyone help?
The if (currentStatus!="undefined") block in getStatusUsingAjax methid is not working.
unable to get the control out of getStatusUsingAjax method
$(document).ready(
loadStatus()
);
function loadStatus(x) {
$('.a-IRR-table tr').each(function(i) {
var val = $(this).find("td").eq(0).text();
link = $(this).find("td").eq(0).find("a").attr("href");
linkTag = $(this).find("td").eq(0).find("a");
`if ((val !== "-") && (val !== "")) {
console.log("val is" + val);
if (verifyrequestArray(val)) {
console.log("inside second if");
} else {
console.log("inside else");
sleep(1.5 * 1000);
var updatedStatus2 = getStatusUsingAjax(val, link);
console.log("UpdatedStatus2 is " + updatedStatus2);
setTooltip(linkTag, updatedStatus2);
}
}
});
}
function verifyrequestArray(id) {
var newArray = requestArray.toString().split('-');
console.log("NewArray is :" + newArray);
for (i = 0; i < newArray.length; i++) {
// I'm looking for the index i, when the condition is true
if (newArray[i] === id) {
console.log("request id found" + newArray[i]);
break;
} else {
console.log("request id not found" + newArray[i]);
return false;
}
}
}
function getStatusUsingAjax(requestValue, currentlink) {
console.log("patch req: " + requestValue);
console.log("Link is " + currentlink);
var currentStatus;
GM_xmlhttpRequest({
method: "GET",
url: currentlink,
onload: function(response) {
if ($(response.responseText).find("#P16_STATUS2").size() === 1) {
currentStatus = $(response.responseText).find("#P16_STATUS2").text();
console.log("Current Status from #P16_STATUS2 is :" + currentStatus);
console.log("Final URL is " + response.finalUrl);
}
}
});
// console.log("Final URL is " +response.finalUrl);
if (currentStatus != "undefined") {
var pusharr = [requestValue + "-" + currentStatus];
requestArray.push(pusharr);
console.log("Updated Array is " + requestArray);
return currentStatus;
}
}
function setTooltip(currentTag, status2) {
console.log("in settooltip" + currentTag);
currentTag.attr("title", status2); //setting status a tooltip
}
Any clue where the error is?
fn getStatusUsingAjax is async, you can not get return value using:
var updatedStatus2 = getStatusUsingAjax(val, link);
You sholud create callback:
function getStatusUsingAjax(val, link, callback){
//...
// do not use return currentStatus, call calback fn instead
callback(currentStatus)
}
and call it using:
getStatusUsingAjax(val, link, function(updatedStatus2){
console.log("UpdatedStatus2 is " + updatedStatus2);
setTooltip(linkTag, updatedStatus2);
});
I'm trying to create a shopping cart that builds an array to send to a server. The part I'm having trouble figuring out is allowing for the user to change the quantity via an input field that updates the 'quantity' value in the basketItems array.
I may be going about this wrong, but hopefully one of you geniuses could help me out.
var basketItems = [
{ itemName:"Item 1", price:1.00, quantity:0 },
{ itemName:"Item 2", price:2.00, quantity:0 },
{ itemName:"Item 3", price:3.00, quantity:0 }
];
var basketItemsTotal = 0.00;
function CalcBasketTotal() {
for (i=0;i<basketItems.length;i++) {
if (basketItems[i].quantity > 0) {
basketItemsTotal = basketItems[i].price * basketItems[i].quantity;
}
}
}
function PopulateBasketItems() {
for (i=0;i<basketItems.length;i++) {
basketTable.innerHTML +=
'<tr><td>' + basketItems[i].itemName + '</td>' +
'<td>$' + basketItems[i].price + '</td>' +
'<td><input value="' + basketItems[i].quantity + '"></td>' +
'<td>$' + basketItems[i].price * basketItems[i].quantity + '</td></tr>';
}
}
BONUS: Eventually, I'm trying to make this script send the server this array along with the total, but first thing's first!
your broblem is here :
function CalcBasketTotal() {
for (i=0;i<basketItems.length;i++) {
if (basketItems[i].quantity > 0) {
basketItemsTotal = basketItems[i].price * basketItems[i].quantity;
}
}
}
fix: (replace = by += to total)
function CalcBasketTotal() {
for (i=0;i<basketItems.length;i++) {
if (basketItems[i].quantity > 0) {
basketItemsTotal += basketItems[i].price * basketItems[i].quantity;
}
}
}