Im trying to define variable values from values inputted into an input textfield onkeyup. I've never done this before and cant find it on Google so was wondering if anybody had any idea on how to do this...
<input type="text" id="values" />
var numberone = "";
var numbertwo = "";
var numberthree = "";
Imagine the user types into the input box "thomas the tankengine" thomas would become 'var numberone'. 'the' would become number two and so on...
Is this possible?
You can split a string by spaces using the split() function
eg
var words = document.getElementById("values").value.split(' ');
var op1 = words[0];
...
Possible, but unwise and would require messing about with eval if you didn't want the variables to end up in the global scope.
Any time you variable variables can solve a problem, it can be better solved by using an array (for sequential data) or object (for named data).
This is exactly the sort of job that arrays are designed to handle.
var numbers = document.getElementById('values').value.split(' ');
console.log(numbers[0]);
console.log(numbers[1]);
console.log(numbers[2]);
How about saving each word in an index of an array so you can have a dynamic number of words:
var max_words = 3;
$('#values').on('keydown', function (event) {
if (event.keyCode == 32) {//32 == space key
var arr = $(this).val().split(' '),
len = max_words < arr.length ? max_words : arr.length,
out = [];
for (var i = 0; i < len; i++) {
out.push(arr[i]);
}
}
});
Here is a jsfiddle to demonstrate this code: http://jsfiddle.net/r8dXw/1/ (Note that the output is logged via console.log so check your console to see the output)
Related
I want to parse the following sort of string into key-value pairs in a Javascript object:
var stringVar = 'PLNC||0|EOR|<br>SUBD|Pines|1|EOR|<br>CITY|Fort Myers|1|EOR|<br>';
Each word of 4 capital letters (PLNC, SUBD, and CITY) is to be a key, while the word(s) in the immediately following pipe are to be the value (the first one, for PLNC, would be undefined, the one for SUBD would be 'Pines', the one for CITY would be 'Fort Myers').
Note that '|EOR|' immediately precedes every key-value pair.
What is the best way of doing this?
I just realised it's technically a csv format with interesting line endings. There are limitations to this in that your variable values cannot contain any | or < br> since they are the tokens which define the structure of the string. You could of course escape them.
var stringVar = 'PLNC||0|EOR|<br>SUBD|Pines|1|EOR|<br>CITY|Fort Myers|1|EOR|<br>';
function decodeString(str, variable_sep, line_endings)
{
var result = [];
var lines = str.split(line_endings);
for (var i=0; i<lines.length; i++) {
var line = lines[i];
var variables = line.split(variable_sep);
if (variables.length > 1) {
result[variables[0]] = variables[1];
}
}
return result;
}
var result = decodeString(stringVar, "|", "<br>");
console.log(result);
If you have underscore (and if you don't, then just try this out by opening up your console on their webpage, because they've got underscore included :)
then play around with it a bit. Here's a start for your journey:
_.compact(stringVar.split(/<br>|EOR|\|/))
Try
function parse(str) {
var str = str.replace(/<br>/gi);
console.log(str);
var arr = str.split('|');
var obj = {};
for (var i=0; i<arr.length; i=i+4) {
var key = arr[i] || '';
var val_1 = arr[i+1] || '';
var val_2 = arr[i+2] || '';
if(key) {
obj[key] = val_1 + ':' + val_2; //or similar
}
}
return obj;
}
DEMO
This will work on the particular data string in the question.
It will also work on other data string of the same general format, but relies on :
<br> being discardable before parsing
every record being a group of 4 string elements delineated by | (pipe)
first element of each record is the key
second and third elements combine to form the value
fourth element is discardable.
This may have been asked in the past but I couldnt find a suitable answer. What I am looking for is a method to extract parameters from an sql query such as below. The queries will always be an EXEC statement followed by the query name, and possible parameters.
Here is an example of what I may recieve
EXEC [dbo].[myProcedure] #Param1
This could also be as follows
EXEC [dbo].[myProcedure] #Param1, #Param2, #Param3
Those are the only types of queries that the input will take. As for why I am doing this, well thats another question all together, and I am pretty set on going down this route.
What I am looking for is to be able to take the above strings and produce an array of values such as
['#Param1','#Param2','#Param3',....]
I originally tried to just parese using a simple while statement but I seem to have huge issues there.
I hope this question makes sense,
Cheers,
Nico
[Edit]
Sorted this by using the following statement
function eParams(e) {
var i = e.indexOf('#');
if (i <= 0)
return;
e = e.substring(i);
var p = e.split(',');
var eList = [];
var s = '';
for (var i = 0, j = p.length - 1; i <= j; i++) {
var sP = p[i].trim();
if (sP.indexOf('#') < 0)
continue;
eList.push(sP);
}
}
var str = 'EXEC [dbo].[myProcedure] #Param1, #Param2, #Param3';
(str).match(/(#[^\s,]+)/g);
will return an array.
var s = "EXEC [dbo].[myProcedure] #Param1, #Param2, #Param3";
var i = s.indexOf('#');
var a = s.substr(i).split(/\s*,\s*/);
(error checking omitted)
I send a string from a server to the Firefox Browser in the format below:
"KEY:a1 VAL:123.45"
And this string can contain many such records.
Here is the code I have written:
var e;
var reply = request.responseText;
var txt = "", tab, key = "", val = "";
var x = reply.getElementsByTagName("KEY:");
for(i = 0; i < x.length; i++)
{
txt = x[i].childNodes[0].nodeValue; // "KEY:%c%c VAL:%.2F"
tab = txt.split(":");
key = "table_" + tab[1].substring(0,1);
val = tab[2];
e = document.getElementById(key);
e.innerHTML = val;
e.style.display = "block";
}
val displays "KEY:a1 VAL:123.45" instead of the expected "123.45" (and of course the key variable is also wrong, not matching a table cell, just picking the first one in the table).
I don't even know how to display the key and val values (document.write() and alert() do nothing and I don't see how to trace this code in Firefox).
Any idea, tip, correction, or code example is welcome but please don't recommend using any library, I want to do it with little code.
EDIT: from the two comments, I understand that there are two distinct ways to proceed: either using DOM objects and HTML tags, or using 'strings'. I would prefer to keep using the format above, so please guide me to a 'string' solution. Thanks!
You can use a simple regular expression to extract the information from the string:
var value = "KEY:a1 VAL:123.45",
pattern = /KEY:(\S+) VAL:(.+)$/g;
var result = pattern.exec(value);
// result[1] == 'a1'
// result[2] == '123.45'
In your case, you'd use request.responseText instead of value.
I have a problem like this Convert an HTML form field to a JSON object with inner objects but in to the other direction.
This is the JSON Object response from the server:
{
company : "ACME, INC.",
contact : {
firstname : "Daffy",
lastname : "Duck"
}
}
And this is the HTML form:
<form id="myform">
Company: <input type="text" name="company" />
First Name: <input type="text" name="contact.firstname" />
Last Name: <input type="text" name="contact.lastname" />
</form>
And this is the (pseudo)code:
var aFormFields;
for (var i = 0, iMax = aFormFields.length; i < iMax; i++) {
var sFieldName = aFormFields[i].getAttribute('name');
eval("sFieldValue = oResponse."+sFieldName);
}
Ok my solution works, but i looking for a good way to remove the evil eval from the code.
And the solution should also work for form fields with any count of dots in the field name.
Instead of:
eval("sFieldValue = oResponse."+sFieldName);
Use for single dotted fields:
sFieldValue = oResponse[sFieldName];
This will retrieve the value via its key.
Now if you need more than that you need to do the following:
Split sFieldName on .
Loop over that array and go down in oResponse till you reach the value that you desire
Code could look like this:
var node = oResponse, parts = sFieldName.split('.');
while(parts.length > 0) {
node = node[parts.shift()];
}
// node will now have the desired value
Further information on "Member Operators":
https://developer.mozilla.org/en/JavaScript/Reference/Operators/Member_Operators
This works for a single property:
sFieldValue = oResponse[sFieldName]
But it won't work for nested data like contact.firstname.
For that, split the name by dots, and use loop through each name:
var aFormFields;
for (var i = 0, iMax = aFormFields.length; i < iMax; i++) {
var aFieldNameParts = aFormFields[i].getAttribute('name').split(".");
var oFieldValue = oResponse;
for(var j=0; j<aFieldNameParts.length; j++) {
oFieldValue = oFieldValue[aFieldNameParts[j]];
}
var sFieldValue = oFieldValue;
}
Note: if a property does not exist, an error will occur. You might want to check whether oFieldValue[ aFieldNameParts[j] ] exists or not.
While it is possible, I wouldn't loop over the input fields, but over the JSON object:
function fillForm (form, data, prefix) {
prefix = prefix ? prefix + "." : "";
for (var x in data) {
if (typeof data[x] === "string") {
var input = form.elements[prefix + x];
if (input)
input.value = data[x];
} else
fillForm(form, data[x], prefix + x);
}
}
fillForm(document.getElementById("myform"), oResponse);
(untested)
Assuming your naming scheme is consistent, you can convert the dot-notation into subscripts. You'd have to split the field name on the period and iterate or recurse over the tokens, converting each into a subscript. Of course this assumes that oResponse always contains a value for every field.
for (var i = 0; i < aFormFields.length; i++) {
var sFieldName = aFormFields[i].getAttribute('name');
var tokens = sFieldName.split('.');
var cur = oResponse;
for (var j = 0; j < tokens.length; j++) {
cur = cur[tokens[j]];
}
sFieldValue = cur;
}
please treat this as a combination of answer and question :)
i am currently trying to get my server to jsonify the data that i get sent from a form just like you...
in my case the form will in the end create a json object with multiple subobjects that can have subobjects which can have... as well.
the depth is up to the user so i should be able to support infinite recursion.
my "solution" so far just feels wrong, but it correctly does the job,
the function getRequestBody gets fed a req.body object from expressjs,
this is basically an object with the following mapping:
{
"ridic-ulously-deep-subobject": "value",
"ridic-ulously-deep-subobject2": "value",
"ridic-ulously-deep2-subobject3": "value",
}
the following html is in use:
<form>
<input name="ridic-ulously-long-class-string" value="my value" />
</form>
and the javascript function (that should work genericly, feed it a req.body object like above and it will return a json object):
function getRequestBody(reqB){
var reqBody = {};
for(var keys in reqB) {
var keyArr = keys.split('-');
switch(keyArr.length){
case 1:
if(!reqBody[keyArr[0]]) reqBody[keyArr[0]] = {};
reqBody[keyArr[0]] = reqB[keys];
break;
case 2:
if(!reqBody[keyArr[0]]) reqBody[keyArr[0]] = {};
if(!reqBody[keyArr[0]][keyArr[1]]) reqBody[keyArr[0]][keyArr[1]] = {};
reqBody[keyArr[0]][keyArr[1]] = reqB[keys];
break;
case 3:
if(!reqBody[keyArr[0]]) reqBody[keyArr[0]] = {};
if(!reqBody[keyArr[0]][keyArr[1]]) reqBody[keyArr[0]][keyArr[1]] = {};
if(!reqBody[keyArr[0]][keyArr[1]][keyArr[2]]) reqBody[keyArr[0]][keyArr[1]][keyArr[2]] = {};
reqBody[keyArr[0]][keyArr[1]][keyArr[2]] = reqB[keys];
break;
case 4:
// ...
//and so on, always one line longer
}
return reqBody;
}
this just feels wrong and its only covering 5 levels of subobjects right now,
it might happen that an application has enough functionality to reach seven or even ten levels though.
this should be a common problem, but my search effort turned up nothing within 10 minutes,
which usually means that i am missing some keywords
or
that there is no viable solution [yet] (which i cant really imagine in this case).
is there someone out there who has imagination and logic sufficient enough to unspaghettify this or will i just have to expand this function with even more clutter to get me down to 10 possible sublevels?
i think that in the end it wont make a big difference performance wise,
but i would really like NOT to create this awful behemoth :D
have fun
jascha
Is there a way to create a dynamic array of strings on Javascript?
What I mean is, on a page the user can enter one number or thirty numbers, then he/she presses the OK button and the next page shows the array in the same order as it was entered, one element at a time.
Code is appreciated.
What I mean is, on a page the user can enter one number or thirty numbers, then he/she presses the OK button and the next page shows the array in the same order as it was entered, one element at a time.
Ok, so you need some user input first? There's a couple of methods of how to do that.
First is the prompt() function which displays a popup asking the user for some input.
Pros: easy. Cons: ugly, can't go back to edit easily.
Second is using html <input type="text"> fields.
Pros: can be styled, user can easily review and edit. Cons: a bit more coding needed.
For the prompt method, collecting your strings is a doddle:
var input = []; // initialise an empty array
var temp = '';
do {
temp = prompt("Enter a number. Press cancel or leave empty to finish.");
if (temp === "" || temp === null) {
break;
} else {
input.push(temp); // the array will dynamically grow
}
} while (1);
(Yeah it's not the prettiest loop, but it's late and I'm tired....)
The other method requires a bit more effort.
Put a single input field on the page.
Add an onfocus handler to it.
Check if there is another input element after this one, and if there is, check if it's empty.
If there is, don't do anything.
Otherwise, create a new input, put it after this one and apply the same handler to the new input.
When the user clicks OK, loop through all the <input>s on the page and store them into an array.
eg:
// if you put your dynamic text fields in a container it'll be easier to get them
var inputs = document.getElementById('inputArea').getElementsByTagName('input');
var input = [];
for (var i = 0, l = inputs.length; i < l; ++i) {
if (inputs[i].value.length) {
input.push(inputs[i].value);
}
}
After that, regardless of your method of collecting the input, you can print the numbers back on screen in a number of ways. A simple way would be like this:
var div = document.createElement('div');
for (var i = 0, l = input.length; i < l; ++i) {
div.innerHTML += input[i] + "<br />";
}
document.body.appendChild(div);
I've put this together so you can see it work at jsbin
Prompt method: http://jsbin.com/amefu
Inputs method: http://jsbin.com/iyoge
var junk=new Array();
junk.push('This is a string.');
Et cetera.
As far as I know, Javascript has dynamic arrays. You can add,delete and modify the elements on the fly.
var myArray = [1,2,3,4,5,6,7,8,9,10];
myArray.push(11);
document.writeln(myArray); // Gives 1,2,3,4,5,6,7,8,9,10,11
var myArray = [1,2,3,4,5,6,7,8,9,10];
var popped = myArray.pop();
document.writeln(myArray); // Gives 1,2,3,4,5,6,7,8,9
You can even add elements like
var myArray = new Array()
myArray[0] = 10
myArray[1] = 20
myArray[2] = 30
you can even change the values
myArray[2] = 40
Printing Order
If you want in the same order, this would suffice. Javascript prints the values in the order of key values. If you have inserted values in the array in monotonically increasing key values, then they will be printed in the same way unless you want to change the order.
Page Submission
If you are using JavaScript you don't even need to submit the values to the different page. You can even show the data on the same page by manipulating the DOM.
You can go with inserting data push, this is going to be doing in order
var arr = Array();
function arrAdd(value){
arr.push(value);
}
Here is an example. You enter a number (or whatever) in the textbox and press "add" to put it in the array. Then you press "show" to show the array items as elements.
<script type="text/javascript">
var arr = [];
function add() {
var inp = document.getElementById('num');
arr.push(inp.value);
inp.value = '';
}
function show() {
var html = '';
for (var i=0; i<arr.length; i++) {
html += '<div>' + arr[i] + '</div>';
}
var con = document.getElementById('container');
con.innerHTML = html;
}
</script>
<input type="text" id="num" />
<input type="button" onclick="add();" value="add" />
<br />
<input type="button" onclick="show();" value="show" />
<div id="container"></div>
The following code creates an Array object called myCars:
var myCars=new Array();
There are two ways of adding values to an array (you can add as many values as you need to define as many variables you require).
1:
var myCars=new Array();
myCars[0]="Saab";
myCars[1]="Volvo";
myCars[2]="BMW";
You could also pass an integer argument to control the array's size:
var myCars=new Array(3);
myCars[0]="Saab";
myCars[1]="Volvo";
myCars[2]="BMW";
2:
var myCars=new Array("Saab","Volvo","BMW");
Note: If you specify numbers or true/false values inside the array then the type of variables will be numeric or Boolean instead of string.
Access an Array
You can refer to a particular element in an array by referring to the name of the array and the index number. The index number starts at 0.
The following code line:
document.write(myCars[0]);
will result in the following output:
Saab
Modify Values in an Array
To modify a value in an existing array, just add a new value to the array with a specified index number:
myCars[0]="Opel";
Now, the following code line:
document.write(myCars[0]);
will result in the following output:
Opel
Please check http://jsfiddle.net/GEBrW/ for live test.
You can use similar method for dynamic arrays creation.
var i = 0;
var a = new Array();
a[i++] = i;
a[i++] = i;
a[i++] = i;
a[i++] = i;
a[i++] = i;
a[i++] = i;
a[i++] = i;
a[i++] = i;
The result:
a[0] = 1
a[1] = 2
a[2] = 3
a[3] = 4
a[4] = 5
a[5] = 6
a[6] = 7
a[7] = 8
Just initialize an array and push the element on the array.
It will automatic scale the array.
var a = [ ];
a.push('Some string'); console.log(a); // ['Some string']
a.push('another string'); console.log(a); // ['Some string', 'another string']
a.push('Some string'); console.log(a); // ['Some string', 'another string', 'Some string']