What's wrong in my JS function? - javascript

I am optimizing a Java code to JS, but runs on Nashorn and do not own debug option. The input is val = "JPG ou PNG" and the output is "JPG ou PNG". Why does this happen? I need the output to be "jpg/png"
Function
function process(val) {
var cleaned = val.replaceAll("[•×\\tª°▪º⊗ fi ²●˚~ĩ`ũ]", "").trim().toLowerCase();
var out = [];
if (cleaned.contains("ou")) {
out = cleaned.split("ou");
}
else if (cleaned.contains("/")) {
out = cleaned.split("/");
}
else {
return cleaned;
}
for (var i = 0; i < out.length; i++) {
out[i] = out[i].trim();
}
return join(out, "/");
}

Three of your functions don't exist in javascript:
replaceAll(searchValue, newValue) in javascript is replace(searchValue, newValue)
contains(searchValue) in javascript is indexOf(searchValue) > -1
join(array, separator) in javascript is array.join(separator)
JSFIDDLE DEMO

Here's my solution:
function process(val) {
var cleaned = val.replace("[•×\\tª°▪º⊗ fi ²●˚~ĩ`ũ]", "").trim().toLowerCase();
var out = [];
if (cleaned.indexOf("ou") >= 0) {
out = cleaned.split("ou");
}
else if (cleaned.indexOf("/") >= 0) {
out = cleaned.split("/");
}
else {
return cleaned;
}
for (var i = 0; i < out.length; i++) {
out[i] = out[i].trim();
}
return join(out, "/");
}
Your logic was right, but strings in Javascript don't have 'replaceAll' and 'contains', so I replaced them with 'replace' and 'indexOf(x) >= 0'.
Also, you mentioned you don't have the option to debug in your environment, yet the function you provided is pretty standalone. This means you could easily copy it into another environment to test it in isolation.
For example, I was able to wrap this code in a HTML file then open it in my web browser (I had to implement my own 'join').
<html>
<body>
<script>
function join(val, divider) {
var out = "";
for(var i = 0; i < val.length; i++) {
if(out.length > 0) out += divider;
out += val[i];
}
return out;
}
function process(val) {
var cleaned = val.replace("[•×\\tª°▪º⊗ fi ²●˚~ĩ`ũ]", "").trim().toLowerCase();
var out = [];
if (cleaned.indexOf("ou") >= 0) {
out = cleaned.split("ou");
}
else if (cleaned.indexOf("/") >= 0) {
out = cleaned.split("/");
}
else {
return cleaned;
}
for (var i = 0; i < out.length; i++) {
out[i] = out[i].trim();
}
return join(out, "/");
}
var inval = "JPG ou PNG";
var outval = process(inval);
console.log(inval + " => " + outval);
</script>
</body>
</html>
I verified it works by opening up the console and seeing the output "JPG ou PNG => jpg/png".

Related

In Javascript function onLoadPopulate() is not working?

function onLoadPopulate() {
var grid = $("#grid0");
var numberOfRecords = grid.getGridParam("records");
var dataFromGrid = grid.jqGrid('getGridParam', 'data');
var count=0;
var link;
if(numberOfRecords>0){
numberOfRecords=endNo;
count=begNo-1;
}
for ( ; count < numberOfRecords; count++) {
var program = dataFromGrid[count].program;
var programVal="";
var programs = program.replace(/\s/g,'').split(',');
for ( var i = 0; i< programs.length;i++) {
if (programs[i] == "FS") {
if (programVal == "") {
programVal = 'DOG';
} else {
programVal = programVal.concat(",DOG");
}
} else if (programs[i] == "TF") {
console.log("in TF");
if (programVal == "") {
programVal = 'CAT';
} else {
programVal = programVal.concat(",CAT");
}
}
grid.jqGrid('setCell', count + 1, 'program',
programVal);
}
}
TEST DATA:
program = FS, TF
result i'm getting : DOG but
the result i need : DOG,CAT
When it is doing else if Even if programs[i] = TF it is skipping if loop inside.
Can anyone help with this JavaScript function?
I can't figure it out what is wrong.
issue with input data consisted of special characters i used following replace and it worked
.replace(/[^a-z0-9,\s]/gi,'').replace(/[_\s]/g,'').split(',')

How do I fix the undefined result I keep getting from this?

So I'm doing the HackerRank superDigit challenge and even though I have the correct value for all the informal test cases, the Output box says that the result is undefined.
I'm not really getting what undefined is all about or how a variable with a value returns as undefined.
function superDigit(n, k) {
// Write your code here
var nArr = [];
for(let i = 0; i < n.length; i++)
{
nArr.push(n[i]);
}
console.log('nArr: ' + nArr);
var nComb = 0;
for(let i = 0; i < nArr.length; i++)
{
nComb += parseInt(nArr[i]);
}
console.log('nComb: ' + nComb);
var nMult = nComb *= k;
console.log('nMult: ' + nMult);
console.log('');
if(nMult < 10)
{
return nMult;
}
else
{
superDigit(nMult.toString(),1);
}
}
You probably want to return the superDigit result as well. So when calling superDigit recursively, add the return statement. I also cleaned up the console.log calls a bit so its more readable to me.
function superDigit(n, k) {
var nArr = [];
for(let i = 0; i < n.length; i++)
{
nArr.push(n[i]);
}
var nComb = 0;
for(let i = 0; i < nArr.length; i++)
{
nComb += parseInt(nArr[i]);
}
var nMult = nComb *= k;
console.log('nMult:', nMult, 'nArr:', nArr, 'nComb:', nComb);
if(nMult < 10)
{
return nMult;
}
else
{
return superDigit(nMult.toString(),1);
}
}
document.getElementById('result').innerText = superDigit("200", 20);
<html>
<body>
<p id="result"></p>
</body>
</html>

getElementsByClassName doesn't work on IE6. What am I doing wrong?

My script works on IE7, 8, 9, etc., Chrome, Firefox, Safari, etc. But when I run this on IE6, it doesn't work. It is a calculate function like a bet vs cash on bank = transfer.
What am I doing wrong?
Here's a working sample:
var a, p = document.getElementsByClassName("preAmount");
var mark = new Array();
$(function () {
$('input').each(function () {
$(this).keyup(function () {
var w = $(this).val(),
n = w.indexOf("."),
z = w.indexOf("0");
//allow 2 digit decimal
if (n > 0 && (w.length - n) > 3) {
$(this).val(parseFloat(w.substring(0, n) + w.substring(n, n + 3)));
}
//reset beginning with zero
if (z == 0) {
$(this).val(w * 1);
}
//set zero
if (isNaN(w) || w.length == 0) {
$(this).val("0");
}
calculateTotal($(this));
});
});
$(".enableOnInput").click(function () {
var submitValid = false;
if (mark.length > 0) {
for (k = 0; k < mark.length; k++) {
// if one of the mark in array is true, it's valid to submit
if (mark[k] == true) {
submitValid = true;
break;
};
}
}
if (submitValid) {
window.open("success.html", "_self");
} else {
alert('您尚未更新游戏平台转帐资金!\n\nYou have not alter transfer amount!');
}
});
$(".reset").click(function () {
a = document.getElementsByClassName('namount');
for (k = 0; k < a.length; k++) {
a[k].value = parseFloat(p[k].innerHTML, 10);
}
$('.balance-value').text($('.t-right-title-balance').text());
mark = new Array();
});
});
function cal() {
var ta = 0,
tp = 0,
tb = parseFloat($('.t-right-title-balance').text());
a = document.getElementsByClassName('namount');
for (j = 0; j < p.length; j++) {
var ttp, tta;
ttp = parseFloat(p[j].innerHTML);
tta = parseFloat(a[j].value);
tp += ttp;
ta += tta;
mark[j] = (ttp != tta); //set alter mark of each platform
}
return (tb + tp - ta);
}
function calculateTotal(src) {
var sumtable = src.closest('.sumtable');
sumtable.find('input').each(function () {
var preAmount = $(this).parent().parent().find('.preAmount').text();
var curAmount = this.value;
if (!isNaN(this.value) && this.value.length != 0) {
preAmount = parseFloat(preAmount);
curAmount = parseFloat(this.value);
var f = parseFloat($('.t-right-title-balance').text()).toFixed(2);
var transAmount = curAmount - preAmount;
if (curAmount < 0 || transAmount > f) {
this.value = preAmount;
$('.balance-value').text(f);
return;
} else {
var b = parseFloat($('.balance-value').text());
var tb = cal();
if (tb >= 0) {
$('.balance-value').text(tb.toFixed(2));
} else {
this.value = preAmount; //illegal rollback
$('.balance-value').text(tb.toFixed(2));
return;
}
}
}
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
I don't know to tag the correct answer, but this is what fixed it,
From: #Phil - I imagine you'd have a little trouble with document.getElementsByClassName (minimum IE support is v9). Use the jQuery selector instead, eg $('.namount')
According to W3C:
The getElementsByClassName() method is not supported in Internet Explorer 8 and earlier versions.
I'm pretty sure that's right.
<!DOCTYPE html>
<html>
<body>
<p class="demo">Test.</p>
<button onclick="myFunction()">Click me!</button>
<script>
function myFunction() {
document.getElementsByClassName('demo').innerHTMl = "Hallo!";
}
</script>
</body>
</html>
You can try this on Internet Explorer 6 or 5.

Profiling Javascript in PyV8

I have a JS codebase running within PyV8. Now I'd like to improve its performance, but there don't seem to be any hooks to enable the V8 profiler. In an older trunk version of PyV8 there are some options referencing the profiler but I don't find any documentation on it. Do you have any idea on how to profile in PyV8 without me having to rewrite the Python-to-JS wrapper?
Do you know of any JS-only-framework that uses monkey patching in order to generate a timing profile? It's not a big deal if there is some overhead involved - better than not having a profile at all.
At the end I've found the hint I needed in the book 'Pro Javascript Design Patterns': Use a closure together with func.apply to apply instrumentation on functions. Unfortunately, the JS way of decorating functions is not quite as clean as Python's - but hey, it works and I get the information I need to drill down into the code's performance characteristics.
profile.js
function mod_profiler() {
var profile_by_function_name = {};
var total_time = 0;
var time_counting_for_function = null;
function get_function_name(func) {
var result = func.toString();
result = result.substr('function '.length);
result = result.substr(0, result.indexOf('('));
return result;
}
function update_profile(function_name, elapsed_time) {
var profile = profile_by_function_name[function_name];
if (profile === undefined) {
profile = {calls:0, elapsed_time:0};
profile_by_function_name[function_name] = profile;
}
profile.calls += 1;
profile.elapsed_time += elapsed_time;
if (time_counting_for_function === function_name) {
total_time += elapsed_time;
}
}
function profile(func) {
function profiled() {
var function_name = get_function_name(func);
if (time_counting_for_function === null) {
time_counting_for_function = function_name;
}
var start_time = new Date().getTime()
var result = func.apply(undefined, arguments);
var elapsed_time = new Date().getTime() - start_time;
update_profile(function_name, elapsed_time);
if (time_counting_for_function === function_name) {
time_counting_for_function = null;
}
return result;
}
return profiled;
}
function get_formatted_result() {
function get_whitespace(length) {
var result = "";
for (var i = 0; i < length; i++) {
result += " ";
}
return result;
}
var function_names = Object.keys(profile_by_function_name);
var function_names_sorted_by_elapsed_time = function_names.sort(function (a,b) {
var elapsed_a = profile_by_function_name[a].elapsed_time;
var elapsed_b = profile_by_function_name[b].elapsed_time;
if (elapsed_a < elapsed_b) {
return 1;
}
if (elapsed_a > elapsed_b) {
return -1;
}
return 0;
});
var max_name_length = 0;
for (var i = 0; i < function_names_sorted_by_elapsed_time.length; i++) {
if (function_names_sorted_by_elapsed_time[i].length > max_name_length) {
max_name_length = function_names_sorted_by_elapsed_time[i].length;
}
}
var result = "\n" + get_whitespace(max_name_length) + " " + "#calls\telapsed\t% of total\n";
for (var i = 0; i < function_names_sorted_by_elapsed_time.length; i++) {
if (total_time === 0) {
break;
}
var function_name = function_names_sorted_by_elapsed_time[i];
var percentage_elapsed = profile_by_function_name[function_name].elapsed_time * 100 / total_time;
if (percentage_elapsed < 0.3) {
break;
}
result += function_name + ":" + get_whitespace(max_name_length - 1 - function_name.length) + profile_by_function_name[function_name].calls + "\t" + profile_by_function_name[function_name].elapsed_time + "\t" + percentage_elapsed.toFixed(2) + "\n";
}
result += "==========\n";
result += "total time accounted for [ms]: " + total_time;
return result;
}
return {
profile: profile,
get_formatted_result: get_formatted_result
}
}
my_module_1.js
function mod_1(profiler_param) {
var profiler = profiler_param;
function my_private_func() {
return "hello world2";
}
if (typeof(profiler) === 'object' && profiler !== null) {
render_user_menu = profiler.profile(render_user_menu);
} //private functions need the instrumentation to be added manually or else they're not included in the profiling.
function my_public_func1() {
return "hello world";
}
function my_public_func2(input1, input2) {
return my_private_func() + input1 + input2;
}
//public functions get the instrumentations automatically as long as they're called from outside the module
var public_function_by_names = {
my_public_func1: my_public_func1
my_public_func2: my_public_func2
}
var result = {};
var public_function_names = Object.keys(public_function_by_names);
for (var i = 0; i < public_function_names.length; i++) {
var func = public_function_by_names[public_function_names[i]];
if (typeof(profiler) === 'object' && profiler !== null) {
result[public_function_names[i]] = profiler.profile(func);
}
else {
result[public_function_names[i]] = func;
}
}
return result;
}
PyV8 side
with X4GEJSContext(extensions=['profile', 'my_module_1']) as ctx:
if self.enable_profiling == True:
ctx.eval("var profiler = mod_profiler();")
ctx.eval("var mod1 = mod_1(profiler);")
#note: you can pass profiler to as many modules as you want and they get instrumented together.
logging.info(ctx.eval("mod1.my_public_func_1() + mod1.my_public_func_2('a', 3);"))
logging.info(ctx.eval("profiler.get_formatted_result();"))
else:
ctx.eval("var mod1 = mod_1();") #it still works without the profiler
Output
"hello worldhelloworld2a3"
#calls elapsed % of total
my_public_func1: 1 31 50.00
my_public_func2: 1 31 50.00
my_private_func: 1 31 50.00
==========
total time accounted for [ms]: 62

Multiple click listeners - java script

I am working on a project that imports some javascript rules from a file myjs.js, which is called (on all the web page of the project) in the header.
This files manages the behavior of checkboxes, and in fact toggling the checks of every checkbox pairs. The problem is that in some case, this behavior is wrong but I can't change anything in this js file because it is too complex.
So, on some page, I decided to listen to the click event on some checkbox to correct the behavior : the problem is that there is a conflict of script and I can't trigger my script (put on this very page). How can I force it to make my java script listened first ?
In fact the checkbox are constructed by myjs.js, applying to the html sequece
<div class="left">
<input type="radio" name="isPubOk" id="pubOk" checked="checked" />
<label for="pubOk"><?php echo _("Oui"); ?></label>
</div>
<div class="left">
<input type ="radio" name="isPubNok" id="pubNok" checked="" />
<label for="pubNok"><?php echo _("Non"); ?></label>
</div>
Here's a sample of the js file :
function initCustomForms() {
getElements();
separateElements();
replaceRadios();
replaceCheckboxes();
replaceSelects();
// hide drop when scrolling or resizing window
if (window.addEventListener) {
window.addEventListener("scroll", hideActiveSelectDrop, false);
window.addEventListener("resize", hideActiveSelectDrop, false);
}
else if (window.attachEvent) {
window.attachEvent("onscroll", hideActiveSelectDrop);
window.attachEvent("onresize", hideActiveSelectDrop);
}
}
function refreshCustomForms() {
// remove prevously created elements
if(window.inputs) {
for(var i = 0; i < checkboxes.length; i++) {
if(checkboxes[i].checked) {checkboxes[i]._ca.className = "checkboxAreaChecked";}
else {checkboxes[i]._ca.className = "checkboxArea";}
}
for(var i = 0; i < radios.length; i++) {
if(radios[i].checked) {radios[i]._ra.className = "radioAreaChecked";}
else {radios[i]._ra.className = "radioArea";}
}
for(var i = 0; i < selects.length; i++) {
var newText = document.createElement('div');
if (selects[i].options[selects[i].selectedIndex].title.indexOf('image') != -1) {
newText.innerHTML = '<img src="'+selects[i].options[selects[i].selectedIndex].title+'" alt="" />';
newText.innerHTML += '<span>'+selects[i].options[selects[i].selectedIndex].text+'</span>';
} else {
newText.innerHTML = selects[i].options[selects[i].selectedIndex].text;
}
document.getElementById("mySelectText"+i).innerHTML = newText.innerHTML;
}
}
}
// getting all the required elements
function getElements() {
// remove prevously created elements
if(window.inputs) {
for(var i = 0; i < inputs.length; i++) {
inputs[i].className = inputs[i].className.replace('outtaHere','');
if(inputs[i]._ca) inputs[i]._ca.parentNode.removeChild(inputs[i]._ca);
else if(inputs[i]._ra) inputs[i]._ra.parentNode.removeChild(inputs[i]._ra);
}
for(i = 0; i < selects.length; i++) {
selects[i].replaced = null;
selects[i].className = selects[i].className.replace('outtaHere','');
selects[i]._optionsDiv._parent.parentNode.removeChild(selects[i]._optionsDiv._parent);
selects[i]._optionsDiv.parentNode.removeChild(selects[i]._optionsDiv);
}
}
// reset state
inputs = new Array();
selects = new Array();
labels = new Array();
radios = new Array();
radioLabels = new Array();
checkboxes = new Array();
checkboxLabels = new Array();
for (var nf = 0; nf < document.getElementsByTagName("form").length; nf++) {
if(document.forms[nf].className.indexOf("default") < 0) {
for(var nfi = 0; nfi < document.forms[nf].getElementsByTagName("input").length; nfi++) {inputs.push(document.forms[nf].getElementsByTagName("input")[nfi]);
}
for(var nfl = 0; nfl < document.forms[nf].getElementsByTagName("label").length; nfl++) {labels.push(document.forms[nf].getElementsByTagName("label")[nfl]);}
for(var nfs = 0; nfs < document.forms[nf].getElementsByTagName("select").length; nfs++) {selects.push(document.forms[nf].getElementsByTagName("select")[nfs]);}
}
}
}
// separating all the elements in their respective arrays
function separateElements() {
var r = 0; var c = 0; var t = 0; var rl = 0; var cl = 0; var tl = 0; var b = 0;
for (var q = 0; q < inputs.length; q++) {
if(inputs[q].type == "radio") {
radios[r] = inputs[q]; ++r;
for(var w = 0; w < labels.length; w++) {
if((inputs[q].id) && labels[w].htmlFor == inputs[q].id)
{
radioLabels[rl] = labels[w];
++rl;
}
}
}
if(inputs[q].type == "checkbox") {
checkboxes[c] = inputs[q]; ++c;
for(var w = 0; w < labels.length; w++) {
if((inputs[q].id) && (labels[w].htmlFor == inputs[q].id))
{
checkboxLabels[cl] = labels[w];
++cl;
}
}
}
}
}
//replacing radio buttons
function replaceRadios() {
for (var q = 0; q < radios.length; q++) {
radios[q].className += " outtaHere";
var radioArea = document.createElement("div");
if(radios[q].checked) {
radioArea.className = "radioAreaChecked";
}
else
{
radioArea.className = "radioArea";
}
radioArea.id = "myRadio" + q;
radios[q].parentNode.insertBefore(radioArea, radios[q]);
radios[q]._ra = radioArea;
radioArea.onclick = new Function('rechangeRadios('+q+')');
if (radioLabels[q]) {
if(radios[q].checked) {
radioLabels[q].className += "radioAreaCheckedLabel";
}
radioLabels[q].onclick = new Function('rechangeRadios('+q+')');
}
}
return true;
}
//checking radios
function checkRadios(who) {
var what = radios[who]._ra;
for(var q = 0; q < radios.length; q++) {
if((radios[q]._ra.className == "radioAreaChecked") && (radios[q]._ra.nextSibling.name == radios[who].name))
{
radios[q]._ra.className = "radioArea";
}
}
what.className = "radioAreaChecked";
}
//changing radios
function changeRadios(who) {
if(radios[who].checked) {
for(var q = 0; q < radios.length; q++) {
if(radios[q].name == radios[who].name) {
radios[q].checked = false;
}
radios[who].checked = true;
checkRadios(who);
}
}
}
//rechanging radios
function rechangeRadios(who) {
if(!radios[who].checked) {
for(var q = 0; q < radios.length; q++) {
if(radios[q].name == radios[who].name) {
radios[q].checked = false;
}
if(radioLabels[q]) {
radioLabels[q].className = radioLabels[q].className.replace("radioAreaCheckedLabel","");
}
}
radios[who].checked = true;
if(radioLabels[who] && radioLabels[who].className.indexOf("radioAreaCheckedLabel") < 0) {
radioLabels[who].className += " radioAreaCheckedLabel";
}
checkRadios(who);
if(window.$ && window.$.fn) {
$(radios[who]).trigger('change');
}
}
}
//replacing checkboxes
function replaceCheckboxes() {
if (replaceCheckBoxes == 0)
return;
for (var q = 0; q < checkboxes.length; q++) {
// checkboxes[q].className += " outtaHere";
var checkboxArea = document.createElement("div");
if(checkboxes[q].checked) {
checkboxArea.className = "checkboxAreaChecked";
if(checkboxLabels[q]) {
checkboxLabels[q].className += " checkboxAreaCheckedLabel"
}
}
else {
checkboxArea.className = "checkboxArea";
}
checkboxArea.id = "myCheckbox" + q;
checkboxes[q].parentNode.insertBefore(checkboxArea, checkboxes[q]);
checkboxes[q]._ca = checkboxArea;
checkboxArea.onclick = new Function('rechangeCheckboxes('+q+')');
if (checkboxLabels[q]) {
checkboxLabels[q].onclick = new Function('changeCheckboxes('+q+')');
}
checkboxes[q].onkeydown = checkEvent;
}
return true;
}
//checking checkboxes
function checkCheckboxes(who, action) {
var what = checkboxes[who]._ca;
if(action == true) {
what.className = "checkboxAreaChecked";
what.checked = true;
}
if(action == false) {
what.className = "checkboxArea";
what.checked = false;
}
if(checkboxLabels[who]) {
if(checkboxes[who].checked) {
if(checkboxLabels[who].className.indexOf("checkboxAreaCheckedLabel") < 0) {
checkboxLabels[who].className += " checkboxAreaCheckedLabel";
}
} else {
checkboxLabels[who].className = checkboxLabels[who].className.replace("checkboxAreaCheckedLabel", "");
}
}
}
//changing checkboxes
function changeCheckboxes(who) {
setTimeout(function(){
if(checkboxes[who].checked) {
checkCheckboxes(who, true);
} else {
checkCheckboxes(who, false);
}
},10);
}
Please see the jquery stopImmediatePropagation() function here: http://docs.jquery.com/Types/Event#event.stopImmediatePropagation.28.29
I believe this will achieve what you are looking to do.
Edit: With more detail I may be able to provide a better answer.
Edit 2: It appears that there is no guarantee'd order of execution in Javascript, so inline code may not run before dynamically added code. In addition this particular function may only work if the other handlers are added using jQuery.
Edit 3:
A quick and dirty fix would be to add
<script type="text/javascript">var executeHandlers = false;</script>
to the top of the one html file.
Then edit the javascript file such that the event handlers have
if (executeHandlers !== false) { ... do the logic you normally would here ... }
as the body
This would add one line to the html file that needs to be treated differently, and should not impact the execution on the other pages.
Please note that this is a quick and dirty fix, and there are better ways to do this. Working with the constraints of an existing .js file, and only one file that needs to be treated differently, this seems to be the fastest / easiest way to the desired outcome, not necessarily the best.

Categories

Resources