I don't understand this substring error - javascript

I noticed FireFox reports an error in my code, but can't understand what is wrong.
[13:36:02.868] TypeError: arr[i][0].substring is not a function # file:///home/asdf/Desktop/app/dic.js:10
Which seems to point to the ss variable line. AFAIK, I'm using it correctly (ie on the end of a string). Here the code snippet...
// quick array example...
var arr = [
["tammikuuta", "January"],
["helmikuuta", "February"],
["maaliskuuta", "March"]
];
function userInput(val){
var result = document.getElementById('result');
result.innerHTML = '';
if(val && val.length > 2){
for(var i = 0; i < arr.length; i++){
var ss = arr[i][0].substring(0,val.length); // ss (SubString) checks the number of characters currently typed
if(ss.toLowerCase() !== val.toLowerCase()){ // check substring against the user input
continue;
}
else { // display the output...
var res = arr[i][1];
var reg = eval('/'+val+'/i');
var found = arr[i][0].replace(reg, '<span class="r">$&<\/span>');
if(result.innerHTML.length > 0){
result.innerHTML += ',<br />';
}
result.innerHTML += found + '<b>' + ' > ' + '</b>' + '<span class="g">' + res + '<\/span>';
}
}
}
else {return;}
}
Please advice?
Edited: More code requested.

try this
var ss = arr[i][0].toString()
ss = ss.substring(0,val.length);

Related

how to decode string in javascript?

I am trying to decode my string using JavaScript. Here is my code on JSBin.
decordMessage('oppeeennnn','1234');
function decordMessage(m,k) {
var msg = m.split('');
var keysplit = k.split('');
var str ='';
var j =0
for (var i=0;i<msg.length;){
str += msg[i];
if(j < keysplit.length -2 &&i < keysplit.length && keysplit[j]){
i = i + parseInt(keysplit[j]);
j++;
}
console.log(i +"i")
console.log(str);
}
console.log("after");
console.log(str);
}
I make a function in which message and key is passed.
Expected output :: open
Actually string charters are repeated in input message (encrypted message) using key. So I need to decode the message.
You forgot to put a break in the else condition, that's why it was looping infinitely till it ran out of memory. Run it in a browser and the tab will crash:
decordMessage('oppeeennnn','1234');
function decordMessage(m,k) {
var msg = m.split('');
var keysplit = k.split('');
var str ='';
var j =0
for (var i=0;i<msg.length;){
str += msg[i];
if(j < keysplit.length &&i < keysplit.length && keysplit[j]){
i = i + parseInt(keysplit[j]);
j++;
}
else
break;
}
console.log("after");
console.log(str); // prints open
}
By the way, a better way to write the loop would be:
function decordMessage(m,k) {
var msg = m.split('');
var keysplit = k.split('');
var str = '';
var j = 0, i = 0;
while (j < keysplit.length
&& i < msg.length) {
str += msg[i];
i += parseInt(keysplit[j]);
j++;
}
console.log(str)
}
This may helps you.
decordMessage('oppeeennnn', '1234');
function decordMessage(m, k) {
var arr = m.split("");
uniqueArray = arr.filter(function(item, pos) {
return arr.indexOf(item) == pos;
});
console.log(uniqueArray.join(""));
}
Assuming encryption logic goes as 123456....
Sample here

Get the text from textarea line by line?

HTML Code
<textarea id="test"></textarea>
<button id="button_test">Ok</button>
Javascript
$(document).ready(function()
{
$("#test").val("123e2oierhqwpoiefdhqwopidfhjcospid");
});
$("#button_test").on("click",function()
{
var as=document.getElementById("test").value;
console.log(as);
});
We can get the values from textarea line by line using val and split functions. But
Is it possible to get the value from textarea line by line for very long word?.In the example i need to get the output as 123e2oierhqwpoiefdhqwo and pidfhjcospid as separate values.
Jsfiddle link here
You can use something like this. This will insert line breaks into into the textarea.
Credits: https://stackoverflow.com/a/4722395/4645728
$(document).ready(function() {
$("#test").val("123e2oierhqwpoiefdhqwopidfhjcospid");
});
$("#button_test").on("click", function() {
ApplyLineBreaks("test");
var as = document.getElementById("test").value;
console.log(as);
});
//https://stackoverflow.com/a/4722395/4645728
function ApplyLineBreaks(strTextAreaId) {
var oTextarea = document.getElementById(strTextAreaId);
if (oTextarea.wrap) {
oTextarea.setAttribute("wrap", "off");
} else {
oTextarea.setAttribute("wrap", "off");
var newArea = oTextarea.cloneNode(true);
newArea.value = oTextarea.value;
oTextarea.parentNode.replaceChild(newArea, oTextarea);
oTextarea = newArea;
}
var strRawValue = oTextarea.value;
oTextarea.value = "";
var nEmptyWidth = oTextarea.scrollWidth;
var nLastWrappingIndex = -1;
for (var i = 0; i < strRawValue.length; i++) {
var curChar = strRawValue.charAt(i);
if (curChar == ' ' || curChar == '-' || curChar == '+')
nLastWrappingIndex = i;
oTextarea.value += curChar;
if (oTextarea.scrollWidth > nEmptyWidth) {
var buffer = "";
if (nLastWrappingIndex >= 0) {
for (var j = nLastWrappingIndex + 1; j < i; j++)
buffer += strRawValue.charAt(j);
nLastWrappingIndex = -1;
}
buffer += curChar;
oTextarea.value = oTextarea.value.substr(0, oTextarea.value.length - buffer.length);
oTextarea.value += "\n" + buffer;
}
}
oTextarea.setAttribute("wrap", "");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<textarea id="test"></textarea>
<button id="button_test">Ok</button>
Use .match(/pattern/g). As your OP ,pattern should start \w (Find a word character) and match string sequence {start,end}
$("#button_test").on("click",function()
{
var as=document.getElementById("test").value;
console.log(as.match(/(\w{1,22})/g));
});
If you made the textarea width fixed using css you could do this:
css
textarea { resize: vertical; }
javascript
$("#button_test").on("click",function(){
var as=document.getElementById("test").value;
var len = document.getElementById("test").cols;
var chunks = [];
for (var i = 0, charsLength = as.length; i < charsLength; i += len) {
chunks.push(as.substring(i, i + len));
}
console.log(chunks);
});
This is probly not the best way, but it works and i hope it could help you.
First thing, i found the textarea allow 8px for default fontsize charactere.
Exemple :
Textarea with 80px
=> Allow line with 10 char maximum, all other are overflow on new line.
From this you can do a simple function like this :
$("#button_test").on("click",function()
{
console.clear();
var length_area = $("#test").width();
var length_value = $("#test").val().length;
var index = Math.trunc(length_area/8);
var finalstr = $("#test").val().substring(0, index) + " " + $("#test").val().substring(index);
console.log(finalstr);
});
Here the JSFiddle
The <textarea> element has built in functionality to control where words wrap. The cols attribute can be set (either harded coded in the HTML or set with the .attr() method using jQuery). The attribute extends the text area horizontally and it also automatically wraps text at the set value.
Example jsFiddle
$("#test").val("123e2oierhqwpoiefdhqwopidfhjcospid");
var newString = $("#test").val().toString();
var splitString = parseInt($("#test").attr("cols"), 10) + 1;
var stringArray = [];
stringArray.push(newString);
var lineOne = stringArray[0].slice(0, splitString);
var lineTwo = stringArray[0].slice(splitString);
var lineBreakString = lineOne + "\n" + lineTwo;
console.log(lineTwo);
$('#test').after("<pre>" + lineBreakString + "</pre>");
$("#test").val("123e2oierhqwpoiefdhqwopidfhjcospid");
var newString = $("#test").val().toString();
var splitString = parseInt($("#test").attr("cols"), 10) + 1;
var stringArray = [];
stringArray.push(newString);
var lineOne = stringArray[0].slice(0, splitString);
var lineTwo = stringArray[0].slice(splitString);
var lineBreakString = lineOne + "\n" + lineTwo;
$('#test').after("<pre>" + lineBreakString + "</pre>");
//console.log(lineBreakString);
pre {
color: green;
background: #CCC;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<textarea id="test" cols='21'></textarea>
<button id="button_test">Ok</button>
The example addresses the specific question asked. If you want to deal with larger blocks of text, you should use the .each() method and for loops to iterate over each line break.
Documentation:
.slice()
textarea
.push()
.parseInt()
.attr()

replacing text that has url with an anchor with regex

var a = document.querySelectorAll('.post .content div');
var b = a[7].childNodes;
for(i=0;i<b.length;i++){
var exp = /(\b(https?|ftp|file):\/\/[\-A-Z0-9+&##\/%?=~_|!:,.;]*[\-A-Z0-9+&##\/%=~_|])/ig;
if(b[i].nodeType === 3){
var ahref = document.createElement('a');
ahref.className="easyBBurlFetch";
ahref.href=b[i].nodeValue.replace(exp,'$1');
ahref.innerText=b[i].nodeValue.replace(exp,'$1');
b[i].parentNode.insertBefore(ahref,b[i]);
b[i].parentNode.removeChild(b[i].nextSibling);
}
}
Someone gave me the answer as I had this code though it wasn't working correct. Though I have the issue now if my text is like so:
This is just a test so click here www.youtube.com which then becomes
www.youtube.com%20which%20then%20becomes
It doesn't event keep the first line of text, I just need to parse the url while keeping the surrounding text.
In need the output to save the actual surrounding text but parse the urls that are inside the text to html anchor tags <a> so that they can then be clickable and actually follow through to a real website and not have unnessarcy text inside it from what my user was writing about. Thank you
UPDATE
I've got closer to making this work-- But I'm having a problem with the first text in the string is saying Undefined I've been debugging this and can't seem to figure out why this is happening. Here is code
var a = document.querySelectorAll('.post');
var b = a[0].childNodes;
var textArray;
var ahref;
for (i = 0; i < b.length; i++) {
var exp = /(\b(https?|ftp|file):\/\/[\-A-Z0-9+&##\/%?=~_|!:,.;]*[\-A-Z0-9+&##\/%=~_|])/ig;
if (b[i].nodeType === 3) {
var newHTML;
textArray = b[i].textContent.split(" ");
for (var j = 0; j < textArray.length; j++) {
if (textArray[j] !== "" && validURL(textArray[j])) {
ahref = document.createElement('a');
ahref.href = (/^(http:\/\/|https:\/\/)/).test(textArray[j]) ? textArray[j] : "http://" + textArray[j];
ahref.innerText = textArray[j];
ahref.className = "easyURLparse";
textArray[j] = ahref;
}
newHTML+= textArray[j].outerHTML ? textArray[j].outerHTML + " " : textArray[j] + " ";
}
var div = document.createElement('div');
div.innerHTML = newHTML;
newHTML = "";
b[i].parentNode.insertBefore(div, b[i]);
b[i].parentNode.removeChild(b[i].nextSibling);
}
}
function validURL(str) {
var pattern = new RegExp("([a-zA-Z0-9]+://)?([a-zA-Z0-9_]+:[a-zA-Z0-9_]+#)?([a-zA-Z0-9.-]+\\.[A-Za-z]{2,4})(:[0-9]+)?(/.*)?");
if (!pattern.test(str)) {
return false;
} else {
return true;
}
}
Testing Code
Just need to figure out the undefined and why it's adding it
this regexp will do the job
exp = /href="(\b(https?|ftp|file):\/\/[\-A-Z0-9+&##\/%?=~_|!:,.;]*[\-A-Z0-9+&##\/%=~_|])"/ig;
var a = document.querySelectorAll('.post');
var b = a[0].childNodes;
var textArray;
var ahref;
for (i = 0; i < b.length; i++) {
var exp = /(\b(https?|ftp|file):\/\/[\-A-Z0-9+&##\/%?=~_|!:,.;]*[\-A-Z0-9+&##\/%=~_|])/ig;
if (b[i].nodeType === 3) {
var newHTML;
if (validURL(b[i].textContent)) {
textArray = b[i].textContent.split(" ");
for (var j = 0; j < textArray.length; j++) {
if (textArray[j] !== undefined && textArray[j] !== "" && validURL(textArray[j]) && textArray[j] !== null) {
ahref = document.createElement('a');
ahref.href = (/^(http:\/\/|https:\/\/)/).test(textArray[j]) ? textArray[j] : "http://" + textArray[j];
ahref.innerText = textArray[j];
ahref.className = "easyURLparse";
textArray[j] = ahref;
}
newHTML += textArray[j].outerHTML ? textArray[j].outerHTML + " " : textArray[j] + " ";
}
var div = document.createElement('div');
div.innerHTML = newHTML;
div.className = "easyDiv";
b[i].parentNode.insertBefore(div, b[i]);
b[i].parentNode.removeChild(b[i].nextSibling);
}
newHTML = "";
}
}
function validURL(str) {
var pattern = new RegExp("([a-zA-Z0-9]+://)?([a-zA-Z0-9_]+:[a-zA-Z0-9_]+#)?([a-zA-Z0-9.-]+\\.[A-Za-z]{2,4})(:[0-9]+)?(/.*)?");
if (!pattern.test(str)) {
return false;
} else {
return true;
}
}
By taking the textNodes and splitting them into an array I can then change the url into an html element. Then taking the array elements seeing if there is outerHTML or not then placing it in a new string and replacing that textNode now with a workable link.
Working example

JavaScript Tag Cloud with IBM Cognos - IE is null or not an object

I followed a tutorial/modified the code to get a javascript tag cloud working in IBM Cognos (BI software). The tag cloud works fine in FireFox but in Internet Explorer I get the error:
"Message: '1' is null or not an object"
The line of code where this is present is 225 which is:
var B = b[1].toLowerCase();
I have tried many different solutions that I have seen but have been unable to get this working correctly, the rest of the code is as follows:
<script>
// JavaScript Document
// ====================================
// params that might need changin.
// DON'T forget to include a drill url in the href section below (see ###) if you want this report to be drillable
var delimit = "|";
var subdelimit = "[]"; // change this as needed (ex: Smith, Michael[]$500,000.00|)
var labelColumnNumber = 0; // first column is 0
var valueColumnNumber = 1;
var columnCount = 2; // how many columns are there in the list?
// ====================================
/*
function formatCurrency(num) {
num = num.toString().replace(/\$|\,/g,'');
if(isNaN(num))
num = "0";
sign = (num == (num = Math.abs(num)));
num = Math.floor(num*100+0.50000000001);
cents = num%100;
num = Math.floor(num/100).toString();
if(cents<10)
cents = "0" + cents;
for (var i = 0; i < Math.floor((num.length-(1+i))/3); i++)
num = num.substring(0,num.length-(4*i+3))+','+ num.substring(num.length-(4*i+3));
return (((sign)?'':'-') + '$' + num + '.' + cents);
}
*/
function formatCurrency(num) {
num = num.toString().replace(/\$|\,/g,'');
if(isNaN(num))
num = "0";
for (var i = 0; i < Math.floor((num.length-(1+i))/3); i++)
num = num.substring(0,num.length-(4*i+3))+','+ num.substring(num.length-(4*i+3));
return ( num );
}
function filterNum(str) {
re = /\$|,|#|#|~|`|\%|\*|\^|\&|\(|\)|\+|\=|\[|\-|\_|\]|\[|\}|\{|\;|\:|\'|\"|\<|\>|\?|\||\\|\!|\$|/g;
// remove special characters like "$" and "," etc...
return str.replace(re, "");
}
table = document.getElementById("dg");
if ( table.style.visibility != 'hidden'){ //only for visible
/*alert('Visible');*/
tags = document.getElementById("dg").getElementsByTagName("SPAN");
txt = "";
var newText = "a";
for (var i=columnCount; i<tags.length; i++) {
/*
valu = filterNum(tags[i+valueColumnNumber].innerHTML);
txt += valu;
txt += subdelimit+tags[i+labelColumnNumber].innerHTML+delimit;
i = i+columnCount;
*/
if(i%2!=0){
var newValue = filterNum(tags[i].innerHTML);
}else var newName =tags[i].innerHTML;
if((i>2) & (i%2!=0)){
newText = newText+newValue+subdelimit+newName+delimit;
if(typeof newText != 'undefined'){
txt = newText;
txt = txt.substr(9);
/* alert(txt);*/
}
}
}
}/*else alert ('Hidden');*/
function getFontSize(min,max,val) {
return Math.round((150.0*(1.0+(1.5*val-max/2)/max)));
}
function generateCloud(txt) {
//var txt = "48.1[]Google|28.1[]Yahoo!|10.5[]Live/MSN|4.9[]Ask|5[]AOL";
var logarithmic = false;
var lines = txt.split(delimit);
var min = 10000000000;
var max = 0;
for(var i=0;i<lines.length;i++) {
var line = lines[i];
var data = line.split(subdelimit);
if(data.length != 2) {
lines.splice(i,1);
continue;
}
data[0] = parseFloat(data[0]);
lines[i] = data;
if(data[0] > max)
max = data[0];
if(data[0] < min)
min = data[0];
}lines.sort(function (a,b) {
var A = a[1].toLowerCase();
var B = b[1].toLowerCase();
return A>B ? 1 : (A<B ? -1 : 0);
});
var html = "<style type='text/css'>#jscloud a:hover { text-decoration: underline; }</style> <div id='jscloud'>";
if(logarithmic) {
max = Math.log(max);
min = Math.log(min);
}
for(var i=0;i<lines.length;i++) {
var val = lines[i][0];
if(logarithmic) val = Math.log(val);
var fsize = getFontSize(min,max,val);
dollar = formatCurrency(lines[i][0]);
html += " <a href='###Some drillthrough url which includes the param "+lines[i][1]+"' style='font-size:"+fsize+"%;' title='"+dollar+"'>"+lines[i][1]+"</a> ";
}
html += "</div>";
var cloud = document.getElementById("cloud");
cloud.innerHTML = html;
var cloudhtml = document.getElementById("cloudhtml");
cloudhtml.value = html;
}
function setClass(layer,cls) {
layer.setAttribute("class",cls);
layer.setAttribute("className",cls);
}
function show(display) {
var cloud = document.getElementById("cloud");
var cloudhtml = document.getElementById("cloudhtml");if(display == "cloud") {
setClass(cloud,"visible");
setClass(cloudhtml,"hidden");
}
else if(display == "html") {
setClass(cloud,"hidden");
setClass(cloudhtml,"visible");
}
}
generateCloud(txt);
</script>
Any help or explanations is much appreciated
Sorry, I'm not seeing where a[] and b[] are defined, is this done elsewhere? Firefox and IE may be responding differently to the problem of an undefined array.

getElementById in Firefox

This below mentioned code works perfect in Internet Explorer but not in Firefox... I get an error in line in Firefox:
document.getElementById("supplier_no").value= values_array[0];
that getElementById returns null. how to solve the problem?
var winName; //variable for the popup window
var g_return_destination = null ; //variable to track where the data gets sent back to.
Set the value in the original pages text box:
function f_set_home_value( as_Value ) {
if (document.getElementById(g_return_destination[0]).name == "netbank_supplier_name_info" ) {
//clear the old values
for (selnum = 1; selnum <= 5; selnum++) {
document.getElementById("expense_account"+selnum).value = "";
document.getElementById("expense_account_name"+selnum).value = "";
document.getElementById("expense_vat_flag"+selnum).value = "off";
document.getElementById("expense_vat_flag"+selnum).checked = "";
document.getElementById("expense_vat_amount"+selnum).value = "";
document.getElementById("expense_vat_code"+selnum).value = "";
document.getElementById("expense_period"+selnum).value = "";
document.getElementById("expense_date"+selnum).value = "";
if (selnum!=1) {//these are sometimes defaulted in, and in any case you will always have line1
document.getElementById("expense_more_dept"+selnum).value = "";
document.getElementById("expense_more_prj"+selnum).value = "";
document.getElementById("expense_more_subj"+selnum).value = "";
}
document.getElementById("expense_amount"+selnum).value = "";
}
var values_array = as_Value[0].split("!");
document.getElementById("supplier_no").value = values_array[0];
document.getElementById("supplier_bankAccount_no").value = values_array[1];
str = values_array[2] ;
str = str.split(";sp;").join(" ");
document.getElementById("default_expense_account").value = str;
document.getElementById("expense_account1").value = str;
document.getElementById("expense_more_sok1").disabled = false;
str = values_array[3] ;
str = str.split(";sp;").join(" ");
document.getElementById("payment_term").value = str;
strPeriod = calcPeriod(str,document.getElementById("due_date").value);
document.getElementById("expense_period1").value = (strPeriod);
strExpenseDate = calcExpenseDate(str,document.getElementById("due_date").value);
document.getElementById("expense_date1").value = (strExpenseDate);
str = values_array[4] ;
str = str.split(";sp;").join(" ");
document.getElementById("expense_account_name1").value = str;
str = values_array[5] ;
str = str.split(";sp;").join(" ");
document.getElementById("expense_vat_code1").value = str;
if (str == 0) {
document.getElementById("expense_vat_flag1").checked = '';
document.getElementById("expense_vat_flag1").disabled = true;
} else {
document.getElementById("expense_vat_flag1").checked = 'yes';
document.getElementById("expense_vat_flag1").value = 'on';
document.getElementById("expense_vat_flag1").disabled = false;
}
str = values_array[6] ;
str = str.split(";sp;").join(" ");
document.getElementById("supplier_name").value = str;
var str = values_array[7];
str = str.split(";sp;").join(" ");
str = str.split("&cr;").join("\r");
document.getElementById("netbank_supplier_name_info").value = str;
strx = justNumberNF(document.getElementById("amount").value);
document.all["expense_vat_amount1"].value = NetbankToDollarsAndCents(strx * (24/124)) ;
document.getElementById("amount").value = NetbankToDollarsAndCents(strx);
document.getElementById("expense_amount1").value = document.getElementById("amount").value;
document.getElementById("expense_amount2").value = '';
document.getElementById("expense_account2").value= '';
//document.getElementById("expense_vat_flag2").value= '';
document.getElementById("expense_vat_amount2").value= '';
document.getElementById("expense_amount3").value = '';
document.getElementById("expense_account3").value= '';
//.getElementById("expense_vat_flag3").value= '';
document.getElementById("expense_vat_amount3").value= '';
document.getElementById("expense_amount4").value = '';
document.getElementById("expense_account4").value= '';
//document.getElementById("expense_vat_flag4").value= '';
document.getElementById("expense_vat_amount4").value= '';
document.getElementById("expense_amount5").value = '';
document.getElementById("expense_account5").value= '';
//document.getElementById("expense_vat_flag5").value= '';
document.getElementById("expense_vat_amount5").value= '';
str = values_array[8] ;
str = str.split(";sp;").join(" ");
if (str=="2"){
document.frmName.ButtonSelPeriodisering1.disabled=false;
document.frmName.ButtonSelPeriodisering1.click();
}
winName.close();
}
}
Pass Data Back to the original window
function f_popup_return(as_Value) {
var l_return = new Array(1);
l_return[0] = as_Value;
f_set_home_value(l_return);
}
function justNumberNF(val){
val = (val==null) ? 0 : val;
// check if a number, otherwise try taking out non-number characters.
if (isNaN(val)) {
var newVal = parseFloat(val.replace(/[^\d\.\-]/g, '.'));
// check if still not a number. Might be undefined, '', etc., so just replace with 0.
return (isNaN(newVal) ? 0 : newVal);
}
// return 0 in place of infinite numbers.
else if (!isFinite(val)) { return 0; }
return val;
};
function NetbankToDollarsAndCents(n) {
var s = "" + Math.round(n * 100) / 100 ;
var i = s.indexOf('.') ;
if (i < 0) {return s + ",00" } ;
var t = s.substring(0, i + 1) + s.substring(i + 1, i + 3) ;
if (i + 2 == s.length) {t += "0"} ;
return t.replace('.',',') ;
}
1) I'd really recommend using jQuery for this sort of thing. You're basically defaulting a large set of elements to empty string, and instead of having to write all that, you could give all your input elements a bogus class name (such as 'inputClass') and then write the following code in jQuery:
$('.inputClass').val('');
And have all your elements get updated, regardless of their id (in fact, you wouldn't even need one!). The code you currently have is nigh unreadable, and would be painful to maintain.
2) Firefox and IE have a known 'quirk' - if your names are the element's name attribute, and not the elements id attribute, then IE will find it just fine with a getElementById call, whereas Firefox will not. Check to make sure those names are actually the id attribute on your elements.
I bring to you jQuery this can save you A LOT, it could be just as simple as
$("#form .fieldsclass").val("");

Categories