Convert multiline div text to table with Jquery - html

I have a comma separated value list with several lines, and want to create a table with four columns using jquery. I have created a jquery function, but I am unable to reproduce the
$(function(){
$('div').prepend('<table><thead><tr><th>Author</th><th>Title</th><th>Year</th><th>Status</th></tr></thead><tbody>');
$('div').html(function(){
var text = $(this).text();
var array = text.split(',');
var array2 = array[0].split('-');
var html = '<tr><td>'+ array2[0] + '</td><td>'+ array2[1] + '</td><td>' + array[1] + '</td><td>' + array[2] + '</td></tr>';
$(this).html(html);
})
$('div').append('</tbody></table>');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
author - book,2010,good
author2 - book2,2011,good
author3 - book3,2011,bad
author4 - book4,2012,average
author5 - book5,2009,bad
author6 - book6,2008,good
</div>
The expected output:
<table><thead><tr><th>Author</th><th>Title</th><th>Year</th><th>Status</th></tr></thead>
<tbody>
<tr><td>author</td><td>book</td><td>2010</td><td>good</td></tr>
<tr><td>author2</td><td>book2</td><td>2011</td><td>good</td></tr>
<tr><td>author3</td><td>book3</td><td>2011</td><td>bad</td></tr>
<tr><td>author4</td><td>book4</td><td>2012</td><td>average</td></tr>
<tr><td>author5</td><td>book5</td><td>2009</td><td>bad</td></tr>
<tr><td>author6</td><td>book6</td><td>2008</td><td>good</td></tr>
</tbody>
</table>
The Jquery code doesn't work as I expect, I am stuck with this.
Thank you!

Break this down into smaller tasks by first getting the data processed and then once you have that figured out build the html from there.
You are missing a key step in splitting the line breaks to get your initial rows strings using text.split('\n').
Once you get those rows then map each row to split the other characters to get a sub array of strings for each row. Since none of this processing requires using elements you can do it in a sandbox until you get to where you can take string input and log a final array to console.
Once you have a data array then build the table rows. Note in your append() process you can't append closing tags as you would in a code editor. When you append html into the dom it creates full elements so include all closing tags in that html string
Working example:
const $div = $('#myDiv')
// include the closing tags in the html string
const $table = $('<table><thead><tr><th>Author</th><th>Title</th><th>Year</th><th>Status</th></tr></thead><tbody></tbody></table>');
let txt = $div.text().trim();// trim to remove whitespace at each end
// split line breaks for rows array
let rows = txt.split('\n').map(s => {
// split the two parts
const [author, content] = s.split(' - ');
// return final sub array
return [author, ...content.split(',')]
});
// inspect your work so far
console.log('rows array',JSON.stringify(rows))
// now that dat works, insert into table
rows.forEach(row =>{
var $row = $('<tr>');
row.forEach(s=> $row.append($('<td>',{text:s})));
$table.find('tbody').append($row)
})
// finally insert the table
$('div').html($table)
td, th{ border: 1px solid #ccc}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="myDiv">
author - book,2010,good
author2 - book2,2011,good
author3 - book3,2011,bad
author4 - book4,2012,average
author5 - book5,2009,bad
author6 - book6,2008,good
</div>

Related

SSIS Script howto append text to end of each row in flat file?

I currently have a flat file with around 1million rows.
I need to add a text string to the end of each row in the file.
I've been trying to adapt the following code but not having any success :-
public void Main()
{
// TODO: Add your code here
var lines = System.IO.File.ReadAllLines(#"E:\SSISSource\Source\Source.txt");
foreach (string item in lines)
{
var str = item.Replace("\n", "~20221214\n");
var subitems = str.Split('\n');
foreach (var subitem in subitems)
{
// write the data back to the file
}
}
Dts.TaskResult = (int)ScriptResults.Success;
}
I can't seem to get the code to recognise the carriage return "\n" & am not sure howto write the row back to the file to replace the existing rather than add a new row. Or is the above code sending me down a rabbit hole & there is an easier method ??
Many thanks for any pointers &/or assistance.
Read all lines is likely getting rid of the \n in each record. So your replace won't work.
Simply append your string and use #billinKC's solution otherwise.
BONUS:
I think DateTime.Now.ToString("yyyyMMdd"); is what you are trying to append to each line
Thanks #billinKC & #KeithL
KeithL you were correct in that the \n was stripped off. So I used a slightly amended version of #billinKC's code to get what I wanted :-
string origFile = #"E:\SSISSource\Source\Sourcetxt";
string fixedFile = #"E:\SSISSource\Source\Source.fixed.txt";
// Make a blank file
System.IO.File.WriteAllText(fixedFile, "");
var lines = System.IO.File.ReadAllLines(#"E:\SSISSource\Source\Source.txt");
foreach (string item in lines)
{
var str = item + "~20221214\n";
System.IO.File.AppendAllText(fixedFile, str);
}
As an aside KeithL - thanks for the DateTime code however the text that I am appending is obtained from a header row in the source file which is being read into a variable in an earlier step.
I read your code as
For each line in the file, replace the existing newline character with ~20221214 newline
At that point, the value of str is what you need, just write that! Instead, you split based on the new line which gets you an array of values which could be fine but why do the extra operations?
string origFile = #"E:\SSISSource\Source\Sourcetxt";
string fixedFile = #"E:\SSISSource\Source\Source.fixed.txt";
// Make a blank file
System.IO.File.WriteAllText(fixedFile, "");
var lines = System.IO.File.ReadAllLines(#"E:\SSISSource\Source\Source.txt");
foreach (string item in lines)
{
var str = item.Replace("\n", "~20221214\n");
System.IO.File.AppendAllText(fixedFile, str);
}
Something like this ought to be what you're looking for.

How to define style attribute when html is in double quotes (as String)

My question is very straight forward. I am trying to put style attribute in a html which is in string format. Through a method i am passing html code in string format. And later i am suppose to add a css in that depending on the situation.
I tried:
"<div style='background-color: red'>'Some data'</div>" // didnt help
"<div style="background-color: red;">'Some data'</div>" // didnt help
In the end:
if(somethingMatches){
data = data.replace('something', "<mark style='background-color: red;'>" + 'something' + "</mark>")
}
Is there some way that i can pull it off...
This is one of the way:
var data = document.body.innerHTML;
data = data.replace(/something/g, "<mark style='background-color: red;'>" + 'something' + "</mark>");
document.body.innerHTML = data;
my name is something<br>
something is going on
If you want to replace all matching words then you should use Regular expression in JavaScript

how to get table cell value while Parsing with XPath, and the cell contain value like <19.00 OR >23.99

actually i need to parse a HTML table and that table contains HTML character, you can see in image.
i need each cell data with that special character also. Right now when i am parsing the table with XPath its ignore that cell and returns that cell value as empty.
Both Image attached here.
$table_head = $summary_nodes->childNodes->item(0);
$table_body = $summary_nodes->childNodes->item(1);
$head = [];
$body = [];
// print_r($table_head);
foreach($table_head->childNodes as $h_index => $h_node){
$head_temp = [];
foreach($h_node->childNodes as $cell_index => $cell){
$head_temp[] = trim($cell->nodeValue);
}
$head[] = $head_temp;
}
foreach($table_body->childNodes as $b_index => $b_node){
$body_temp = [];
// print_r($b_node);
foreach($b_node->childNodes as $cell_index => $cell){
print_r($cell);
$body_temp[] = trim($cell->nodeValue);
}
$body[] = $body_temp;
}
return ['table_ready'=>array_merge([$head[count($head)-1]], $body), 'headers'=> $head];
Hello friends I got answer for this, actually what is happening we are adding HTML entity inside our real data that's why while passing it's conflicting with HTML content and while parsing parser remove automatically that HTML entities so we have to make sure our real data does not have any HTML entities if we are using or if we need any entity which is similar to HTML entity please try to use they are HTML entity code.

Output from an array in html page

I am trying to output the contents of an array within an array to a small area on an HTML page. I can only get one dimensional arrays to output.
Simplified, the intended array has a number of properties, but am struggling to find the correct code to output an array nested inside an array.
Properties are;
ID(integer)
Location(string)
Postcode(String)
other properties may be added down the line.
To output the information I am using the following code (which I can only get to work on a single array - even if I change to using [i][x] )
document.write("<tr><td>ID " + i + " is:</td>");
document.write("<td>" + LocationArray[i] + "</td></tr>");
How do I correctly create an array capable of storing the information and then output a specific part of it? eg display the contents of LocationArray[2][3]
Is document.write an efficient method, or is there something better?
I put something together, that could help you. To answer your question at the end about creating an array 'the right way'; There are two possibilities:
Create an array with 'property'-based properties : var locationsArray = [{ID:123,Location:'blabla',Postalcode:'1234'}];
Create an array with string-keys : var locationsArray = [{'ID':123,'Location':'blabla','Postalcode':'1234'}];
In my example I used the first attempt.
To your second question: document.write just writes at the end of the document. If you want to write to a specific area of the website, create a container (for example) and give it an id. Then change the property innerHTML of the created container, as I did in my example.
HTML:
<div id="locations"></div>
<button onclick="printLocations()">Print Locations</button>
Javascript:
function printLocations() {
var locationsArray = [{
ID : 123,
Location : 'Candyland',
Postalcode : '1234'
}, {
ID : 456,
Location : 'Middle-Earth',
Postalcode : '4567'
}
];
var locationsHtml = '';
for (var index in locationsArray) {
locationsHtml += 'ID: ' + locationsArray[index].ID + ', ' +
'Location: ' + locationsArray[index].Location + ', ' +
'Postalcode: ' + locationsArray[index].Postalcode + '<br />';
}
console.log(locationsHtml);
document.getElementById('locations').innerHTML = locationsHtml;
}
If you just want to write a specific part of the array (in your example just one specific location) just use the index you want and access it the same way as in the for loop in my example:
var locationsHtml = locationsArray[1].ID + locationsArray[1].Location + etc...;
/*with string-keys: var locationsHtml = locationsArray[1]['ID'] + etc...;*/
document.getElementById('locations').innerHTML = locationsHtml;

Vertical html table without repeating th tags

I'm generating a table using xslt, but for this question I'll keep that side out of it, as it relates more to the actual generated structure of a html table.
What I do is make a vertical table as follows, which suits the layout needed for the data concerned that originated in a spreadsheet. Example is contrived for brevity, actual data fields contain lengthy strings and many more fields.
Title: something or rather bla bla
Description: very long desription
Field1: asdfasdfasdfsdfsd
Field2: asdfasfasdfasdfsdfjasdlfksdjaflk
Title: another title
Description: another description
Field1:
Field2: my previous field was blank but this one is not, anyways
etc.
The only way so far I found to generate such a html table is using repeating tags for every field and every record e.g.:
<tr><th>Title</th><td>something or rather bla bla</td></tr>
<tr><th>Description</th><td>very long desription</td></tr>
...
<tr><th>Title</th><td>another title</td></tr>
<tr><th>Description</th><td>another description</td></tr>
...
Of course this is semantically incorrect but produces correct visual layout. I need it to be semantically correct html, as that's the only sane way of later attaching a filtering javascript facility.
The following correct semantically produces an extremely wide table with a single set of field headers on the left:
<tr><th>Title</th><td>something or rather bla bla</td><td>another title</td></tr>
<tr><th>Description</th><td>very long desription</td><td>another description</td></tr>
...
So to summarise, need a html table (or other html structure) where it's one record under another (visually) with repeating field headers, but the field headers must not be repeated in actual code because that would wreck any record based filtering to be added later on.
Yo. Thanks for updating your question, and including some code. Typically you'd also post what you've tried to correct this issue - but I'm satisfied enough with this post.
Since you want the repeating headers in vertical layout (not something I've seen often, but I can understand the desire), you don't have to modify the HTML formatting, just use a bit more JavaScript to figure it out. I haven't gone through and checked to see if I'm doing things efficiently (I'm probably not, since there are so many loops), but in my testing the following can attach to a vertical table and filter using a couple variables to indicate how many rows there are in each entry.
Firstly, here's the HTML I'm testing this one with. Notice I have a div with the id of filters, and each of my filter inputs has a custom attribute named filter that matches the header of the rows they are supposed to filter:
<div id='filters'>
Title: <input filter='Title'><br>
Desc: <input filter='Description'>
</div>
<table>
<tr><th>Title</th><td>abcd</td></tr>
<tr><th>Description</th><td>efgh</td></tr>
<tr><th>Title</th><td>ijkl</td></tr>
<tr><th>Description</th><td>mnop</td></tr>
<tr><th>Title</th><td>ijkl</td></tr>
<tr><th>Description</th><td>mdep</td></tr>
<tr><th>Title</th><td>ijkl</td></tr>
<tr><th>Description</th><td>mnop</td></tr>
<tr><th>Title</th><td>ijkl</td></tr>
<tr><th>Description</th><td>mnop</td></tr>
</table>
Here are the variables I use at the start:
var filterTable = $('table');
var rowsPerEntry = 2;
var totalEntries = filterTable.find('tbody tr').size() / rowsPerEntry;
var currentEntryNumber = 1;
var currentRowInEntry = 0;
And this little loop will add a class for each entry (based on the rowsPerEntry as seen above) to group the rows together (this way all rows for an entry can be selected together with a class selector in jQuery):
filterTable.find('tbody tr').each(function(){
$(this).addClass('entry' + currentEntryNumber);
currentRowInEntry += 1;
if(currentRowInEntry == rowsPerEntry){
currentRowInEntry = 0;
currentEntryNumber += 1;
}
});
And the magic; on keyup for the filters run a loop through the total number of entries, then a nested loop through the filters to determine if that entry does not match either filter's input. If either field for the entry does not match the corresponding filter value, then we add the entry number to our hide array and move along. Once we've determined which entries should be hidden, we can show all of the entries, and hide the specific ones that should be hidden:
$('#filters input').keyup(function(){
var hide = [];
for(var i = 0; i < totalEntries; i++){
var entryNumber = i + 1;
if($.inArray(entryNumber, hide) == -1){
$('#filters input').each(function(){
var val = $(this).val().toLowerCase();
var fHeader = $(this).attr('filter');
var fRow = $('.entry' + entryNumber + ' th:contains(' + fHeader + ')').closest('tr');
if(fRow.find('td').text().toLowerCase().indexOf(val) == -1){
hide.push(entryNumber);
return false;
}
});
}
}
filterTable.find('tbody tr').show();
$.each(hide, function(k, v){
filterTable.find('.entry' + v).hide();
});
});
It's no masterpiece, but I hope it'll get you started down the right path.
Here's a fiddle too: https://jsfiddle.net/bzjyfejc/