I'm parsing a document that has a known repeating structure. There is a heading (1 line), a sub-heading(1 line), and a content area (unknown # of lines).
The format for each item in the document is shown below:
=========================
Head Text
=========================
SubHead Text
=========================
Content Text Line 1
Content Text Line 2
...
Content Text Line 8
I want to create an Array that contains an Object for each section.
Something like:
var item = [];
items[0] = {
head: "head1 text",
subHead: "subHead1 text",
content: "content1 text"};
items[1] = {
head: "head2 text",
subHead: "subHead2 text",
content: "content2 text"};
I am having trouble efficiently traversing the document and dynamically adding each Object into the Array. I get an error under section 2 telling me that "page is null or not an object".
var count = 0;
while( !stream.AtEndOfStream ){
page[count] = stream.ReadLine();
count++;
}
var item = [{}];
var section = 0;
var i = 0, k = 0;
while (i < page.length) {
if (~page[i].indexOf("=====")) {
if(section == 0) {
item[k].head = page[i+1];
section++;
} else
if (section == 1) {
item[k].subHead1 = page[i+1];
section++;
i++;
} else
if (section == 2) {
var j = i+1;
while(!~page[j].indexOf("=====")) {
item[k].content += page[j] + "\n";
j++;
}
section = 0;
k++;
}
}
i++;
}
Change this:
var item = [{}];
to this:
var item = [];
Next, change this:
if (~page[i].indexOf("=====")) {
to this:
if (~page[i].indexOf("=====")) {
item[k] = {};
I am not sure if that will work, but the basic idea is to create a blank array (var item = [];) and then add objects when needed (item[k] = {}). Previously you were trying to add properties to undefined objects.
page is null because it has not been declared, in your snippet at least.
Related
I need to display unique elements of already binded data in that html table by using JQuery or JavaScript. Displaying unique value means that mearging the cells having same value in the rows. The table data is dynamic but the structure is fix.
So, here is given table:
Here, I need to merge the Red colored cells as shown below.
And the required table is:
So, I need to achieve this cell merging through Jquery or javascript. As this table is created with HTML table and the data is already binded in it. By using this binded data I need to achieve the reqiured table. I need to merge more columns like this.
I have tried some coding but it is not working correctly. The code is:
jQuery('tr.tblRow').each(function(i, obj)
{
current_name = jQuery(obj).text();
var current_name_arr = current_name.split(/\t|\n| /);
/* check for repeated names */
if (current_name_arr[22] == last_selected_compNo)
{
jQuery("td.headingSpas:contains('" + current_name_arr[22] + "')").each(function(index, object)
{
if (index == 0)
{
/* check if already has rowspan attribtue */
row_span = jQuery(object).attr('rowspan') ? jQuery(object).attr('rowspan') : 1;
/* add one */
row_span++;
/* include the new rowspan number */
jQuery(object).prop('rowspan', row_span);
}
else if(index < 2)
{
/* delete the other first name cells */
jQuery(object).remove();
}
});
}
}
Please help me.
I have written my own solution for this problem. It work for me..
/*Merging rows Start (updated by Suraj)*/
/*Some changes are made in HTML table's body like adding 'id' property in each column of the table.*/
var row = 0;
var col = 0;
jQuery('tr.tblRow').each(function(n, obj) {
/*Getting the first row as text*/
current_name = jQuery(obj).text();
/*Splitting the above text value into an array using 'Regex' by '/t' and '/n'*/
var current_name_arr = current_name.split(/\t|\n/);
/*Now storing the element into an array for getting the values easily.*/
var current_name_arr1 = [];
var j = 0;
for(var i = 0; i < current_name_arr.length; i++) {
if(current_name_arr[i] == ""){}
else {
current_name_arr1[j] = current_name_arr[i];
j++;
}
}
/*Setting column*/
if(n == 0) {
col = current_name_arr1.length;
}
});
jQuery('tr.tblRow').each(function(n, obj) {
var ele = ""
var removingEle = "";
/*Merging the cells by spaning the cells and removing the duplicate cells*/
for(var l = 0; l < col - 1; l++) {
if(l == 4 || l == 5) {
continue;
}
/*Getting the element by id*/
ele = $("#pdtDetail" + row + l);
/*Getting the removing element by id*/
removingEle = $("#pdtDetail" + (row + 1) + l);
if(ele.text() == removingEle.text()) {
/* check if already has rowspan attribtue */
row_span = ele.attr('rowspan') ? ele.attr('rowspan') : 1;
/* add one */
row_span++;
/* include the new rowspan number */
ele.prop('rowspan', row_span);
/* delete the other first name cells */
removingEle.remove();
}
}
/*If element get matched then increasing row by two because we have to leave the just after commming row.*/
if(ele.text() == removingEle.text()) {
row = row + 2;
}
else {
row++;
}
});
/*Merging rows End*/
The Final Table looks like as:
say if I have csv file with :
Heading 1 , Heading 2 , Heading 3
Value 1 , Value2 , Value 3
All I want is to create a map that stores Heading 1 as a key and Heading 2 as value;
like map.set(value1 , value2)
How do I do this while I read the file in javascript ?
function processData(allText) {
var allTextLines = allText.split("\r");
for (var i=1; i<allTextLines.length; i++) {
var data = allTextLines[i].split(',');
console.log(data[0]);
map1.set(data[0] , data[1]);
}
}
so far I tried to do this . But it doesn't work. It doesn't read the file at all. Any help is appreciated.
Thanks
If you have a series of items separated by commas (,), the you can iterate the String and explode or split the items. This can be done with Vanilla JavaScript. The magic part is the for() loop; iterating it by 2 instead of by 1, which is most commonly seen.
$(function() {
var myString = "Header 1,Value 1,Header 2,Value 2,Header 3,Value 3";
var parts = myString.split(",");
var myData = {};
for (var i = 0; i < parts.length; i += 2) {
myData[parts[i]] = parts[i + 1];
}
console.log(myData);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
If your file has multiple lines, and the first line is Headers, for example:
Header 1,Header 2,Header 3
Value 1,Value 2,Value 3
Value 4,Value 5,Value 6
You'll have to treat it differently. When it's brought into JS, it will be one big String, and you will have to first split it by End Of Line (EOL). This will create an Array of Strings that must be iterated. You will want to make an Array of Keys and then a Matrix of Values.
Since the file is Local, you will need to first get the File from the User. This is discussed here: How to read data From *.CSV file using javascript? and here: Reading in a local csv file in javascript? You will have to determine the best method for yourself.
One way is to use a File Input. There are drawbacks and caveats due to security and browsers, but it might work.
$(function() {
var fileInput = $("#getFile");
function toObj(keys, vals) {
var obj = {};
for (var i = 0; i < keys.length; i++) {
obj[keys[i]] = vals[i];
}
return obj;
}
function stringToObject(str, header) {
if (header == undefined) {
header = false;
}
var lines = str.split("\n");
var k = [],
m = [];
if (header) {
k = lines.splice(0, 1);
k = k[0].split(",");
}
$.each(lines, function(i, el) {
if (el.length) {
m.push(el.split(","));
}
});
if (k.length) {
var r = [];
$.each(m, function(i, el) {
r.push(toObj(k, el));
});
return r;
} else {
return m;
}
}
function readFile() {
var reader = new FileReader();
reader.onload = function() {
var newData = stringToObject(reader.result, $("#header").prop("checked"));
console.log(newData);
$("#out").html("<pre>" + reader.result + "</pre>");
};
reader.readAsBinaryString(fileInput[0].files[0]);
};
fileInput.change(readFile);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="file input">
<input type="checkbox" id="header" checked="checked"> <label>CSV Header</label><br />
<input type="file" id="getFile" />
</div>
<div id="out"></div>
My script (is meant to) grab text from the a page (which works fine) and then splits it by by newline (\n) and puts each splitted string into an array called "dnaSequence"; from there it loops through each element in the array and if the string contains the character ">" it assigns that string to the "var header_name", else it pushes all other lines into a new array called "dnaSubseq". The original text looks something like this:
>header_1
gctagctagc
cgcgagcgagc
>header_2
gcgcatgcgac
When I execute the code it fails to alert on anything. Here is the code:
function loaderMy() {
var dnaSubseq = [];
var dnaSequence = [];
var header_name = "";
var splittedLines = document.getElementById("page-wrapper").innerText;
dnaSequence = splittedLines.split('\n');
for (var i = 0; i < dnaSequence.length; i++) {
if (dnaSequence[i].match(/>/)) {
header_name = dnaSequence[i];
alert(header_name);
}
else {
dnaSubseq.pushValues(dnaSequence[i]);
}
alert(dnaSubseq);
}
}
Change
dnaSubseq.pushValues(dnaSequence[i]);
To
dnaSubseq.push(dnaSequence[i]);
If it doesn't alert anything, that means you forgot to invoke the function :)
loaderMy();
http://jsfiddle.net/zszyg5qx/
Try this function
function loaderMy() {
var dnaSubseq = [];
var dnaSequence = [];
var header_name = "";
var splittedLines = document.getElementById("page-wrapper").innerText;
dnaSequence = splittedLines.split('\n');
for (var i = 0; i < dnaSequence.length; i++) {
if (dnaSequence[i].match(/>/)) {
header_name = dnaSequence[i];
alert(header_name);
}
else {
dnaSubseq.push(dnaSequence[i]);
}
alert(dnaSubseq);
}
}
Javascript (using jQuery):
var paragraphs = [
['This is my first paragraph content of the first array', 'This is my second paragraph content of the first array', 'This is my third paragraph content of the first array'],
['This is my first paragraph content of the second array', 'This is my second paragraph content of the second array', 'This is my third paragraph content of the second array']
],
text_box_value,
unused_paragraphs = null;
$(document).ready(function(){
$('input#text_box').keyup(function(){
text_box_value = $(this).val();
});
$('input#submit_button').click(function(){
if(unused_paragraphs === null) {
unused_paragraphs = paragraphs;
}
for(var i = 0; i < unused_paragraphs.length; i++) {
if(unused_paragraphs[i].length == 0)
unused_paragraphs[i] = paragraphs[i];
while(unused_paragraphs[i].length != 0) {
var rand = Math.floor(Math.random() * unused_paragraphs[i].length);
if(unused_paragraphs[i][rand].search(text_box_value) !== -1) {
$("#paragraphs_container").append('<p>' + unused_paragraphs[i][rand] + '</p>');
break;
}
unused_paragraphs[i].splice(rand, 1);
}
}
console.log(unused_paragraphs);
console.log(paragraphs);
});
});
My question is why when I use splice method on unused_paragraphs variable it also remove the value from the paragraphs variable
Later edit JSFiddle
javascript objects/array are stored by reference.
If you want a copy that's a trick:
if(typeof unused_paragraphs == "undefined") {
var unused_paragraphs = [];
for(var i = 0; i<paragraphs.length; i++) {
unused_paragraphs[i] = paragraphs[i].slice(0);
}
}
and
unused_paragraphs[i] = paragraphs[i].slice(0);
to copy the obect to new object..
try this..
var unused_paragraphs= jQuery.extend(true, {}, paragraphs);
here is just an example of copied objects.. check it out
http://jsfiddle.net/5ExKF/3/
This pertains within a BPM application called ProcessMaker but the logic and syntax should relatively be the same. I'm trying to
populate a grid (basically a table) from another serialized grid where the data has been passed to a hidden field.
The data passed to the hidden field is formatted as follows:
Ex:
{"1":{"id":"4332","product":"ball","price":"$5.00",”ordered":"On"}
The javascript example below found on processmaker's wiki unserializes the hidden field as an object and uses its information to populate a new grid named whatever it is. The example on processmaker's wiki uses the eval function but how would you convert this using the json.parse() function?
function populateGrid() {
var grd = getObject("newAccountsGrid");
//remove all existing rows in the grid (except the first one):
var i = Number_Rows_Grid("newAccountsGrid", "accId");
for (; i > 1; i--)
grd.deleteGridRow(i, true);
//The first row can't be deleted, so clear the fields in the first row:
for (i = 0; i < grd.aFields.length; i++)
getGridField("contactsGrid", 1, grd.aFields[i].sFieldName).value = "";
//unserialize the hidden field as an object:
var oAccounts = eval('(' + getField("sAccounts").value + ')');
if (typeof oAccounts == 'object') {
for (var rowNo in oAccounts) {
if (rowNo != 1)
grd.addGridRow();
getGridField('newAccountsGrid', rowNo, 'accId').href = oAccounts[rowNo]["accountId"];
getGridField('newAccountsGrid', rowNo, 'accName').href = oAccounts[rowNo]["accountName"];
getGridField('newAccountsGrid', rowNo, 'createDate').href = oAccounts[rowNo]["created"];
}
}
}
populateGrid(); //execute when the DynaForm loads
It would be as simple as:
var oAccounts = JSON.parse(getField("sAccounts").value);
eval("("+something+")") ⇒ JSON.parse(something)
Just a few lines above this example (ProcessMaker wiki), is a note where recommend using JSON.parse ().
Using your example, your code should be as follows:
function populateGrid() {
var grd = getObject("newAccountsGrid");
//remove all existing rows in the grid (except the first one):
var i = Number_Rows_Grid("newAccountsGrid", "accId");
for (; i > 1; i--)
grd.deleteGridRow(i, true);
//The first row can't be deleted, so clear the fields in the first row:
for (i = 0; i < grd.aFields.length; i++)
getGridField("contactsGrid", 1, grd.aFields[i].sFieldName).value = "";
//unserialize the hidden field as an object:
var oAccounts = JSON.parse(getField("sAccounts").value);
if (typeof oAccounts == 'object') {
for (var rowNo in oAccounts) {
if (rowNo != 1)
grd.addGridRow();
getGridField('newAccountsGrid', rowNo, 'accId').href = oAccounts[rowNo]["accountId"];
getGridField('newAccountsGrid', rowNo, 'accName').href = oAccounts[rowNo]["accountName"];
getGridField('newAccountsGrid', rowNo, 'createDate').href = oAccounts[rowNo]["created"];
}
}
}
populateGrid(); //execute when the DynaForm loads