Click to See Complete Forum and Search --> : export tool
vdubjunkie
02-05-2008, 09:47 AM
Hi all,
I've searched the web a bit, but I'm having a difficult time coming up with even a starting point. I have a page that is built via CGI, and I've used div tags to be able to allow the end user to show as much or as little of the page as they want. I now need to give them the ability to export this data to an excel spreadsheet, aka csv, but I want to be able to allow them to export only what it shown. The obvious choice to me is continue to use JS to differentiate, but I don't know how to access the actual text of the page.
Does anybody have any thoughts on where I can get started for this?
toicontien
02-05-2008, 02:15 PM
Can you post some sample HTML for us to work on? I would suggest using an HTML TABLE.
vdubjunkie
02-05-2008, 04:51 PM
I think I see what you are saying. The elements of a table can be referenced, right? So if inside of each of my "display toggle-able" div tags, I want all text I will need referencable to be inside table elements, right? I'll still take some suggestions on how to make this happen, as I can only partially see this solution at the moment.
Anyway, here is a sample of the output from my CGI page.
<script type="text/javascript" src="js/functions.js">
</script>
<form><input type="button" value="pass" onClick="toggleDisplay('pass')">
<input type="button" value="fail" onClick="toggleDisplay('fail')">
<input type="button" value="no match" onClick="toggleDisplay('nomatch')">
<input type="button" value="model" onClick="toggleDisplay('model_info')">
<input type="button" value="os" onClick="toggleDisplay('os_info')">
<input type="button" value="inventory" onClick="toggleDisplay('inv_info')">
</form>
<h1><center>server001</center></h1>
<div class="model_info" id="model_info">
<div id="heading">
<font size="+2">Server Model</font></div>
<div id="list">
<div id="list_item">Model</div><div id="list_value"> 7049</div>
<div id="list_item">Tag</div><div id="list_value"> XYZFK</div>
</div>
</div>
<div class="os_info" id="os_info">
<div id="heading">
<font size="+2">Operating System</font></div>
<div id="list">
<div id="list_item">Operating System</div><div id="list_value"><font title="5.2.3790">Windows 2003 Server</font></div>
<div id="list_item">Service Pack</div><div id="list_value"> </div>
</div>
</div>
<div class="inv_info" id="inventory">
<div id="heading">
<font size="+2">Server Inventory</font></div>
<div id="list">
<div class="nomatch"><div id="list_item">Software Y</div><div id="list_value">1.1.0</div>
</div>
<div class="fail"><div id="list_item"><b>bios</b></div><div id="list_value"><b>FKL</b></div></font></div>
<div class="nomatch"><div id="list_item">ALM</div><div id="list_value">1.40</div>
</div>
<div class="nomatch"><div id="list_item">Primary Backplane</div><div id="list_value">1.00</div>
</div>
<div class="nomatch"><div id="list_item">RADEON 7000 SERIES Driver</div><div id="list_value">6.14.10.6497</div>
</div>
<div class="nomatch"><div id="list_item">RAID Controller Driver</div><div id="list_value">7.41.5.27</div>
oh, and if you are wondering, part of my excessive use of div tags both helps with css and my toggle-able nature of the page.
magentaplacenta
02-05-2008, 05:25 PM
In your toggleDisplay function are you using display:none; to not show info or visibility:hidden; ?
It seems like if you're using display:none; then whatever is viewable in the web browser is all that would be exported?
vdubjunkie
02-05-2008, 07:33 PM
magenta,
correct on both accounts. I am using "display: none" and it will be only those items which remain "display: block" that I will want to be exported.
toicontien
02-05-2008, 08:23 PM
Your markup could use some big improvements.
1) The values for all Id attributes must be unique within the HTML document.
2) You're giving each list a unique class name, when one class name will suffice.
3) You've given each list a unique Id. That's all you need in order to style the list with CSS or identify it with JavaScript.
4) You have a major case of DIVitis. What you really have is tabular data, so use a table.
5) By properly using table headers and binding them with the table data cells, you get a markup structure that is both meaningful to you as a human, and to JavaScript as a document object model.
<h1>server001</h1>
<table cellpadding="4" cellspacing="3" border="1" class="dataTable" id="model_info">
<caption>Server Model</caption>
<thead>
<tr>
<th id="th_model_info_model">Model</th>
<th id="th_model_info_tag">Tag</th>
</tr>
</thead>
<tbody>
<tr>
<td headers="th_model_info_model">7049</td>
<td headers="th_model_info_tag">XYZFK</td>
</tr>
</tbody>
</table>
<table cellpadding="4" cellspacing="3" border="1" class="dataTable" id="os_info">
<caption>Operating System</caption>
<thead>
<tr>
<th id="th_os_info_name">Name</th>
<th id="th_os_info_version">Version</th>
<th id="th_os_info_sp">Service Pack</th>
</tr>
</thead>
<tbody>
<tr>
<td headers="th_os_info_name">Windows 2003 Server</td>
<td headers="th_os_info_version">v5.2.3790</td>
<td headers="th_os_info_sp">n/a</td>
</tr>
</tbody>
</table>
<table cellpadding="4" cellspacing="3" border="1" class="dataTable" id="inventory">
<caption>Server Inventory</caption>
<thead>
<tr>
<th id="th_inventory_device">Device Name</th>
<th id="th_inventory_version">Firmware Version</th>
</tr>
</thead>
<tbody>
<tr>
<td headers="th_inventory_device">Software Y</td>
<td headers="th_inventory_version">1.1.0</td>
</tr>
<tr>
<td headers="th_inventory_device">Bios</td>
<td headers="th_inventory_version">FKL</td>
</tr>
<tr>
<td headers="th_inventory_device">ALM</td>
<td headers="th_inventory_version">1.40</td>
</tr>
<tr>
<td headers="th_inventory_device">Primary Backplane</td>
<td headers="th_inventory_version">1.00</td>
</tr>
<tr>
<td headers="th_inventory_device">RADEON 7000 SERIES Driver</td>
<td headers="th_inventory_version">6.14.10.6497</td>
</tr>
<tr>
<td headers="th_inventory_device">RAID Controller Driver</td>
<td headers="th_inventory_version">7.41.5.27</td>
</tr>
</tbody>
</table>
Let's start with this markup, as it best describes the data on your page. And now that your data is properly marked up in tables, read up on the table document object model for some scripting tricks and techniques:
http://www.w3schools.com/htmldom/dom_obj_table.asp
http://www.w3schools.com/htmldom/dom_obj_tablerow.asp
http://www.w3schools.com/htmldom/dom_obj_tabledata.asp
vdubjunkie
02-06-2008, 11:28 AM
This is great information. I agree that my data is more of a tabular nature. I am running in to a glitch though. Since I am giving the end user the ability to turn on and off the visibility of each section, and all elements of each section individually based upon whether they passed,failed or didn't match a rule, when you do turn off and back on visibility of individual elements (or td's) of a table, when it redraws, it doesn't do so gracefully. I am now exploring the possibility I can still get the text I want from the DOM. Otherwise, I might have to explore how to set static table size definitions based upon the data filling the fields so that it won't redraw so poorly.
toicontien
02-06-2008, 01:49 PM
How are you turning the visibility on and off? For tables, if you use the display property, a "none" value of course hides the table and removes it from the document flow. A "block" value changes the display of the table from "table" to "block" and it acts like a DIV tag instead of a TABLE tag. When showing the table again, set the display property to an empty string: ""
function showHide(el) {
if (el.display == "") {
// Hide the element
el.display = "none";
} else {
// Show the element
el.display = "";
}
}
Did you read the pages about the table document object model that I linked to above? Once you have a DOM node reference to a table cell, you can use the non standard -- but universally supported -- innerHTML property to get the text in the table cell.
vdubjunkie
02-06-2008, 02:04 PM
Here is a snippet of my adjusted html using frames.
<table cellpadding="4" cellspacing="3" border="1" class="model_info">
<caption>Server Model</caption>
<thead>
<tr>
<th id="th_model_info_model">Model</th>
<th id="th_model_info_tag">Tag</th>
</tr>
</thead>
<tbody>
<tr class="nomatch">
<td headers="th_inventory_device">Software Y</td>
<td headers="th_inventory_version">1.7.0</td>
</tr>
Below is the method I'm using to toggle the display. Since I need to be able to toggle the display for many items which may not be consecutive, I'm using this nifty bit that I believe came from Ultimater..
function toggleDisplay()
{
var f = document.getElementsByClassName(arguments[0]);
for(var i=0;i<f.length;i++)
{
f[i].style.display = (f[i].style.display == 'none') ? 'block' : 'none';
}
}
document.getElementsByClassName = function(clsName)
{
var retVal = new Array();
var elements = document.getElementsByTagName("*");
for(var i=0;i<elements.length;i++)
{
if(elements[i].className.indexOf(" ") >= 0)
{
var classes = elements[i].className.split(" ");
for(var j=0;j<classes.length;j++)
{
if(classes[j] == clsName)
retVal.push(elements[i]);
}
}
else if(elements[i].className == clsName)
retVal.push(elements[i]);
}
return retVal;
}
I allow the end user to toggle off display based upon a class of "nomatch" as well as others.
I've begun now to sift through the table elements going after the "textContent" of them, and that is coming along acceptably, but I'm also wondering now, once I get my data all put together in a "csv format" how will I use javascript to provide that data as a savable file. I hope like heck I don't have to write it back to the server first. That would just be hokey!
Thanks once again for the help. I'm actually starting to feel like I get JS to a workable level.
toicontien
02-06-2008, 02:21 PM
Table tags are not block display by default. The toggleDisplay function toggles between "none" and "block" values. Change "block" to an empty string: "".
vdubjunkie
02-06-2008, 02:26 PM
well, im also changing display of other non table elements. perhaps I need to have a separate function for changing display of the table.
do you have any thoughts on how to save the data to a client side file once JS has parsed through and created it?
toicontien
02-06-2008, 02:28 PM
toggling between "none" and an empty string works for all elements, except if an element's display is set to none in a style sheet.
vdubjunkie
02-06-2008, 02:34 PM
oh hooray. that was exactly what I needed. Thanks so much. Now it's just a matter of getting the elements of the tables and creating my csv format, then figuring the best way to allow the user to save this data as a client side file.
:D
toicontien
02-06-2008, 03:21 PM
It will be easy to harvest the data from the tables, but the Web browser does not allow people to save files, lest you want them to use Internet Explorer and ActiveX.
To get the data from the tables, read up on the Table Document Object Model links I provided in one of my previous posts.
vdubjunkie
02-06-2008, 03:43 PM
Ok, thanks.
I found this wonderful site (http://developer.mozilla.org/en/docs/Category:DOM) for lots of great information, of which I found what I needed. Now I'm going through the debug phase where I realize that my loops fail once they run into I'm assuming a nonexistent value. It makes it a lot more fun when you finally get a clue how to debug and what is possible.
Sucks about the files. I guess I'll have to write a cgi that allows the data to be written to the server side. That stinks. I'll pretty much do whatever I can to avoid using MS tools.