I have this form which import transactions of the user. I enhance the form where user can preview the list of transactions they will be importing to their account.
Sample:
The above sample preview is for the QIF file format which I successfully done.
Now I'm trying to preview the OFX file format and I'm having difficulty to arrange it in a table and get the exact value.
Here are my codes:
<input type="file" name="transactions" id="id_transactions">
<div style="display:none;width:335px;" id="preview-box">
<h4 class="thin" class="black">Import Preview</h4>
<table class="simple-table responsive-table footable">
<thead>
<tr>
<th scope="col" width="10%"><small class="black">Date</small></th>
<th scope="col" width="10%"><small class="black">Amount</small></th>
<th scope="col" width="20%"><small class="black">Payee</small></th>
</tr>
</thead>
</table>
<div class="scrollable" style="height:100px">
<table class="simple-table responsive-table footable">
<tbody id="preview-table"></tbody>
</table>
</div><br/>
</div>
<script>
$('#id_transactions').change(function() {
var upload = document.getElementById('id_transactions')
var files = upload.files
if (files != undefined) {
var reader = new FileReader();
reader.onload = function(e) {
var extension = upload.value.split('.').pop().toLowerCase()
var lineSplit = e.target.result.split("\n");
var payee = ''
var date
var amount
var content = "";
var content1 = "";
var content2 = "";
if(extension == "qif"){
// for qif preview
}else if(extension == "ofx"){
$('#preview-box').show(500)
for(var i = 1; i < lineSplit.length; i++) {
//I'm stuck here....
}
}
$('#preview-table').html(content);
};
reader.readAsText(files.item(0));
}
});
</script>
sample.ofx
OFXHEADER:100
DATA:OFXSGML
VERSION:103
SECURITY:NONE
ENCODING:USASCII
CHARSET:1252
COMPRESSION:NONE
OLDFILEUID:NONE
NEWFILEUID:NONE
<OFX>
<SIGNONMSGSRSV1>
<SONRS>
<STATUS>
<CODE>0
<SEVERITY>INFO
</STATUS>
<DTSERVER>20071015021529.000[-8:PST]
<LANGUAGE>ENG
<DTACCTUP>19900101000000
<FI>
<ORG>MYBANK
<FID>01234
</FI>
</SONRS>
</SIGNONMSGSRSV1>
<BANKMSGSRSV1>
<STMTTRNRS>
<TRNUID>23382938
<STATUS>
<CODE>0
<SEVERITY>INFO
</STATUS>
<STMTRS>
<CURDEF>USD
<BANKACCTFROM>
<BANKID>987654321
<ACCTID>098-121
<ACCTTYPE>SAVINGS
</BANKACCTFROM>
<BANKTRANLIST>
<DTSTART>20070101
<DTEND>20071015
<STMTTRN>
<TRNTYPE>CREDIT
<DTPOSTED>20070315
<DTUSER>20070315
<TRNAMT>200.00
<FITID>980315001
<NAME>DEPOSIT
<MEMO>automatic deposit
</STMTTRN>
<STMTTRN>
<TRNTYPE>CREDIT
<DTPOSTED>20070329
<DTUSER>20070329
<TRNAMT>150.00
<FITID>980310001
<NAME>TRANSFER
<MEMO>Transfer from checking
</STMTTRN>
<STMTTRN>
<TRNTYPE>PAYMENT
<DTPOSTED>20070709
<DTUSER>20070709
<TRNAMT>-100.00
<FITID>980309001
<CHECKNUM>1025
<NAME>John Hancock
</STMTTRN>
</BANKTRANLIST>
<LEDGERBAL>
<BALAMT>5250.00
<DTASOF>20071015021529.000[-8:PST]
</LEDGERBAL>
<AVAILBAL>
<BALAMT>5250.00
<DTASOF>20071015021529.000[-8:PST]
</AVAILBAL>
</STMTRS>
</STMTTRNRS>
</BANKMSGSRSV1>
</OFX>
Anyone who already done this?
UPDATE:
Output:
You know what, this OFX file format looks a lot like an XML in the second part, with an empty line separating the two parts (correct me if I'm wrong, I don't know this format).
Inside the onload event listener, try something like this:
var ofxParts = e.result.split("\r?\n\r?\n"), ofxHeaders, ofxDocument;
ofxHeaders = JSON.parse("{"
+ ofxParts[0].replace(/(\w+) *: *(\w*)/g, "\"$1\": \"$2\"")
.replace(/\r?\n/g, ", ") + "}");
ofxDocument = new DOMParser().parseFromString(ofxParts[1]
.replace(/<(\w+)>(?!\n|\r\n)(.*)/g, "<$1>$2</$1>"));
Now you should have the OFX headers in a useful Javascript object like this:
ofxHeaders = {
"OFXHEADER": "100",
"DATA": "OFXSGML",
"VERSION": "103",
"SECURITY": "NONE",
"ENCODING": "USASCII",
"CHARSET": "1252",
"COMPRESSION": "NONE",
"OLDFILEUID": "NONE",
"NEWFILEUID": "NONE"
};
and you can crawl and select your OFX document with document.evaluate like any other XML.
This should all be available as far as you're using FileReader. Except IE10, which doesn't support document.evaluate. You'll have to create an ActiveXObject and use loadXML if you want to use XPath.
Or you can just use jQuery:
var $ofx = $.parseXML(ofxParts[1].replace(/<(\w+)>(?!\n|\r\n)(.*)/g, "<$1>$2</$1>"));
Edit: You can now create the rows of the table in this kind of way:
var $xfers = $ofx.find("STMTTRN");
content = $xfers.map(function(xf) {
var $xf = $(xf), date = $xf.find("DTPOSTED").text();
return "<tr><td>" + date.substring(4, 6) + "/" + date.substring(6)
+ "/" + date.substring(0, 4) + "<td></td>" + $xf.find("NAME").text()
+ "</td><td>" + $xf.find("TRNAMT").text() + "</td></tr>";
}).join("");
Related
please help me with my code. I tried display retrieved data in my html table using javascript, but nothing work. I am new in firebase, if it possible please anyone help me or give advice, I have already tried everything methods on stack (
The structure of my base looks like this,please check the image from the link below
/Notes/{Generated User Token}/{Generated Date}/{Generated Note ID}/Fields
My Html Code
<table style="width:100%" id="ex-table">
<tr id="tr">
<th>Name:</th>
</table>
Javascript
var database = firebase.database();
var uid = firebase.auth().uid; // Not working, How to get a path to Generated tokens?
var date = // How to get a path to "DateddMMyyyy" from a structure?
var notes = // How to get a path to "NoteXXXXXXX" from a structure?
database.ref().child('Notes' +token+ '/' +date+ '/' +notes+ '/' ).once('value').then(function(snapshot) {
if(snapshot.exists()){
var content = '';
snapshot.forEach(function(data){
var val = data.val();
content +='<tr>';
content += '<td>' + val.name + '</td>';
content += '</tr>';
});
$('#ex-table').append(content);
}
});
I do not know how to write a path to Generated Date "DateddMMyyyy" and Generated Note ID "NoteXXXXXXX"
I need only display end fields from structure. What should I edit in
my code?
Ps: For more details about Generated date, please check code from android studio "timeStamp = new SimpleDateFormat("ddMMyyyy").format(Calendar.getInstance().getTime());"
For getting the date formated id pass the input date to getDateId use it to construct the database.ref()
function getDateId(dt){
var date = new Date(dt);
var currentMonth = date.getMonth();
var currentDate = date.getDate();
if (currentMonth < 10) { currentMonth = '0' + currentMonth};
if (currentDate < 10) { currentMonth = '0' + currentDate};
return `Date${currentDate}${currentMonth}${date.getFullYear()}`
}
var inputDate = new Date();
var dateId = getDateId(inputDate);
console.log(dateId)
I am using ASP.NET MVC 4.0 and I am trying to show the image in a simple grid, but the grid appears blank. The image is saved in byte array format. I am getting the other column details but not the image.
Below is the complete controller code for saving the image in byte array format and displaying from database:-
public ActionResult Index()
{
return View();
}
public ActionResult Savedata(HttpPostedFileBase Image)
{
SaveImage obj = new SaveImage();
string result;
if (Image != null)
{
HttpPostedFileBase httpobj = Request.Files["Image"];
string[] Imagename = httpobj.FileName.Split('.');
obj.ImageName=Imagename[0];
using (Stream inputStream = Request.Files[0].InputStream) //File Stream which is Uploaded
{
MemoryStream memoryStream = inputStream as MemoryStream;
if (memoryStream == null)
{
memoryStream = new MemoryStream();
inputStream.CopyTo(memoryStream);
}
obj.ImagePic = memoryStream.ToArray();
}
var path = Path.GetFileNameWithoutExtension(Image.FileName) + DateTime.Now.ToString("ddMMyyhhmmss") + Path.GetExtension(Image.FileName);
result = path.Replace(" ", string.Empty);
var serversavepath = Path.Combine(Server.MapPath("~/DemoImages/") + result);
Image.SaveAs(serversavepath);
obj.ImageName= result;
entity.SaveImages.Add(obj);
entity.SaveChanges();
}
//return View("Index");
return Content("<script>alert('Data Successfully Submitted');location.href='../Home/Index';</script>");
}
public JsonResult BindGrid()
{
DataRow[] result;
var output = (from c in entity.SaveImages.AsEnumerable()
select new
{
ID = c.Id,
ImageName = c.ImageName,
//ImagePic = c.ImagePic,
ImagePic = Convert.ToBase64String(c.ImagePic)
}).ToList();
var data = new { result = output };
return Json(output, JsonRequestBehavior.AllowGet);
}
Here is my complete View code. I am using a single view.
<script type="text/javascript">
$(function () {
$.post("#Url.Content("~/Home/BindGrid")", null, function (data) { bindgrid(data); }, "Json");
});
</script>
<script type="text/javascript">
$(function save() {
debugger;
$("#btnSave").click(function () {
location.href = '#Url.Action("Savedata", "Home")';
});
});
function bindgrid(data) {
var body = "";
$("#Grid tbody").empty();
$.each(data.result, function (key, value) {
body += "<tr><td> " + value.ID + "</td>" +
"<td>" + value.ImageName + "</td>" +
"<td>" + value.ImagePic + "</td>" +
"<td> <a style='cursor:pointer' onclick=Edit(" + value.Id + ");>Edit</a> <a style='cursor:pointer' onclick=Delete(" + value.Id + ");>Delete</a></td></tr>";
});
$("#Grid tbody").append(body);
}
</script>
<div>
#using (Html.BeginForm("Savedata", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div>
<table>
<tr>
<td>
Upload Image
</td>
<td><input type="file" name="Image" id="Image" style="width:100%" /></td>
</tr>
</table>
</div>
<br/>
<div>
<input type="submit" value="save" id="btnSave" />
</div>
}
<div id="list" style="width: 997px; margin-right: 0px;">
<table id="Grid">
<thead>
<tr>
<th>
ID
</th>
<th>
IMAGE NAME
</th>
<th>
IMAGES
</th>
<th>
ACTION
</th>
</tr>
</thead>
<tbody>
#foreach (var item in entity.SaveImages)
{
<tr>
<td>#item.Id</td>
<td>#item.ImageName</td>
<td><img src="~/DemoImages/#item.ImagePic" width="100" height="100" /></td>
#*<td><img src="string.format("data:image/png;base64 {0}",base64data)"/></td>*#
</tr>
}
</tbody>
</table>
</div>
</div>
</body>
I want the grid to display the images with other column details.
Your server-side code seems a little bit confused. I don't know if this is the result of misunderstanding, or multiple different attempts to make it work, or what. But the thing which stands out is that you are saving the image both to the server's disk and to the database. I can't see a reason to do both. Normally it's more efficient to save the file directly to disk, and just write the path and filename to the database, so the file can be located later.
P.S. Also I can't understand why you sometimes used Request.Files["Image"]; when the file is already available via the Image variable. And it's strange to remove the extension from the filename when storing, because then you lose information about what kind of file it is (and you aren't storing the MIME type instead either). And you also try to give two different values to obj.ImageName on different lines. This makes no sense.
So all you'd really need is this, I think:
public ActionResult Savedata(HttpPostedFileBase Image)
{
SaveImage obj = new SaveImage();
string result;
if (Image != null)
{
obj.ImageName = Image.FileName;
string imageFolder = "~/DemoImages/";
var path = Path.GetFileNameWithoutExtension(Image.FileName) + DateTime.Now.ToString("ddMMyyhhmmss") + Path.GetExtension(Image.FileName);
result = path.Replace(" ", string.Empty);
var serversavepath = Path.Combine(Server.MapPath(imageFolder) + result);
Image.SaveAs(serversavepath);
obj.ImageName = imageFolder + result;
entity.SaveImages.Add(obj);
entity.SaveChanges();
}
return Content("<script>alert('Data Successfully Submitted');location.href='../Home/Index';</script>");
}
The BindGrid method will be pretty similar, just without the ImagePic field:
public JsonResult BindGrid()
{
DataRow[] result;
var output = (from c in entity.SaveImages.AsEnumerable()
select new
{
ID = c.Id,
ImageName = c.ImageName
}).ToList();
var data = new { result = output };
return Json(output, JsonRequestBehavior.AllowGet);
}
And then in the View, you would only need the following to display it (because the folder name is already in the ImageName field, so it's a ready-made relative URL):
<img src="#item.ImageName" width="100" height="100" />
you could create <img> tag inside td and set base64 string to src attribute.
<tbody>
#foreach (var item in entity.SaveImages)
{
<tr>
<td>#item.Id</td>
<td>#item.ImageName</td>
<td><img src="'data:image/jpg;base64,' + #item.ImagePic" width="100" height="100" /></td>
</tr>
}
</tbody>
I have a function where i can download my table data into csv. But the button function only works when i place it in my index.html page, while my table's on the subpage.html page. But somehow, my button in the index page is able to download my table data in that subpage.html when i navigate to there.
Index.html : The button here works
<body>
<header ng-include="'views/header.html'"></header>
<main ng-view></main>
<button type="button" id="btnDownload"> Download as CSV</button>
</body>
Subpage.html : If i place the button here it doesn't work
<div>
<table id="tabletodownload" ng-show="auditoriums === 'none'" style="border:1px solid #000;">
<tr> <th> Customer Name </th> <th> Order Value </th> <th> Ordered On </th> </tr>
<tr ng-repeat="audit in auditoriums| limitTo: 1 - auditoriums.length">
<td>{{audit.NAME}}</td>
<td>{{audit.ADDRESSBLOCKHOUSENUMBER}}</td>
<td>{{audit.ADDRESSPOSTALCODE}}</td>
<td>{{audit.ADDRESSSTREETNAME}}</td>
</tr>
</table>
<br />
</div>
<button type="button" id="btnDownload"> Download as CSV</button>
Javascript code to DL to csv :
$(function() {
$('#btnDownload').click(function() {
$("#tabletodownload").tableToCSV({
filename: 'CustomerList'
});
});
});
jQuery.fn.tableToCSV = function (options) {
var settings = $.extend({
filename: ""
}, options);
var clean_text = function (text) {
text = $.trim(text.replace(/"/g, '""'));
return '"' + text + '"';
};
$(this).each(function () {
var table = $(this);
var caption = settings.filename;
var title = [];
var rows = [];
$(this).find('tr').each(function () {
var data = [];
$(this).find('th').each(function () {
var text = clean_text($(this).text());
title.push(text);
});
$(this).find('td').each(function () {
var text = clean_text($(this).text());
data.push(text);
});
data = data.join(",");
rows.push(data);
});
title = title.join(",");
rows = rows.join("\n");
var csv = title + rows;
var uri = 'data:text/csv;charset=utf-8,' + encodeURIComponent(csv);
var download_link = document.createElement('a');
download_link.href = uri;
var ts = new Date().getTime();
if (caption == "") {
download_link.download = ts + ".csv";
} else {
download_link.download = caption + "-" + ts + ".csv";
}
document.body.appendChild(download_link);
download_link.click();
document.body.removeChild(download_link);
});
};
If the index.html and subpage.html are 2 different pages (and not an angularjs template or something like that) then it's probably because the code that is handling the button click and the rest of your function doesn't exist in the subpage.html.
quick and dirty
I assume you're not using any build tools. The simplest way is to move the button function to a script tag inside subpage.html
the angularjs way
I see you're using angularjs in the project. Manually attaching evenlisterens like a button click isn't the angularjs way of doing thing. You could easily move the functionality to your angular controller that control's that page and add a ng-click attribute to the button that calls that function. This way you're letting the framework decide when and hpw to attach the click event listener instead of managing that yourself.
Btw...
Using a framework like angular/react/vue most of the times makes jQuery unnecessary. In this case you could also use a library that made for amgularjs to make a csv from a table. jQuery is very DOM way of thinking while angular is more of a DATA way of thinking. In my opinion is that why it's better to not mix these things.
This might help you:
https://github.com/kollavarsham/ng-table-to-csv
I have the following code which is partially what my HTML page does.
<script>
function close() {
MainJavaScript();
}
function MainJavaScript()
{
//var strEntity = " ";
var strEntity = document.getElementById('Entity').value;
//Images setup by Entity
if (strEntity == "MGP")
{
document.getElementById('displayPic').src="http://mgp75.png";
}
else if (strEntity == "MPP")
{
document.getElementById('displayPic').src="http://mpp75.png";
}
else if (strEntity == "RSC")
{
document.getElementById('displayPic').src="http://rsc75.png";
}
else if (strEntity == "MSN")
{
document.getElementById('displayPic').src="http://msn75.png";
}
var strFirstName = "John";
var strLastName = "Doe";
var strSuffix = " ";
var strTitle = "DDS";
var strSecondaryTitle = " ";
var strDisplayName = strFirstName + " " + strLastName;
if (strTitle.trim() != '')
strDisplayName += ", " + strTitle;
if (strSuffix.trim() != '')
strDisplayName += ", " + strSuffix;
if (strSecondaryTitle.trim() !='')
strDisplayName += ", " + strSecondaryTitle;
document.getElementById('FullName').innerHTML = strDisplayName;
}
</script>
Submit
<table>
<tr>
<td width="55%">
<div class="first">
<div class="contact-info">
<h3><img id="displayPic" src="" alt=""></h3>
</div><!--// .contact-info -->
</div>
</td>
<td width="40%">
<div>
<h1><font color="#003893" face="Georgia">Cu Vi</font></h1>
<h2><span id="FullName"></span></h2>
</div>
</td>
</tr>
</table>
When I click the Submit button the displayPic and the FullName is replaced by the respective values using MainJavascript function. What I am looking to do is create a PDF from the output but unfortunately all the DLLs and method I found requires me to output a HTML file and then convert to a PDF but because it is using JavaScript, the source is always blank but the display is changed once the button is clicked.
How can I achieve what I am looking to do, is convert the output into a PDF?
You should look at Xep CloudFormatter. This library, jquery plugin, prints any html page. So, given your example, if I were to start with an HTML template like you have, and then with javascript/jquery I populate the html and then call xepOnline.Formatter.Format to render it, you will get back a beautiful PDF.
I simplified your code a bit, but here is a fiddle for you to explore:
http://jsfiddle.net/kstubs/56x6W/
function printMe() {
tryAtMain();
var imgLoad = imagesLoaded($('#displayPic')[0]);
imgLoad.on( 'always', function() {
xepOnline.Formatter.Format('print_me', {
pageMargin: ".25in"
});
});
}
function tryAtMain() {
// some pic
$('#displayPic').attr('src','http://lorempixel.com/output/abstract-q-c-370-222-1.jpg');
$('#FullName').html('Johnny Carson');
}
I apologize if this kind of question has already been asked but I have looked through "Related Questions" and I don't think anything in here matches with mine, so please bear with me as I try to present my problem and how am I going to go about this, so here I go.
Okay, I will refer you my screenshot. Two of my tables have been generated by using Javascript and one is static and I didn't comment out the tbody tags within a listModulesWithinScene table.
http://img852.imageshack.us/i/haildstabletable.jpg/ (click in the link to view the image)
Here's my cut-down version of my HTML code for those who are interested. I'm pretty much new to this website, even though I do lurk through here from search engine (Google).
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<link href='http://fonts.googleapis.com/css?family=Josefin+Sans:100,regular' rel='stylesheet'
type='text/css' />
<link href="cssHomeAutomaionInterface.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="Scripts/SwitchContent.js"></script>
<script type="text/javascript" src="Scripts/ScrollingImagesInHeader.js"></script>
<script type="text/javascript" src="Scripts/XMLReaderWriter.js"></script>
<script type="text/javascript" src="Scripts/Main.js"></script>
<script type="text/javascript" src="Scripts/PageSpecific/Home.js"></script>
</head>
<body>
<!-- ... -->
<div id="home" class="container">
<div id="menuHome" class="submenu">
</div>
<div id="contentHome" class="content">
<h1>Home Page</h1>
<div id="moduleListArea">
<table id="listModules" class="data">
<caption>Lights and Devices</caption>
<thead>
<tr>
<th style="width: 100px;">Module ID#</th>
<th>Module Name</th>
<th style="width: 60px;">Status</th>
<th style="width: 150px">Action</th>
</tr>
</thead>
<!--<tbody>
<tr style="color: Green;" title="Dimmer">
<th>AB.CD.EF</th>
<td>2x Floor Lamp</td>
<td>75%</td>
<td>
Toggle
<div style="float: right;">
<input style="width: 40px;" id="module1" value="75" />
Set
</div>
</td>
</tr>
<tr style="color: Blue;" title="Switch">
<th>AB.CD.EE</th>
<td>Bedside Fan</td>
<td>ON</td>
<td>
Toggle
</td>
</tr>
</tbody>-->
</table>
</div>
<div id="sceneListArea" style="width: 50%; float: left;">
<table id="listScenes" class="data">
<caption style="text-align: left;">Scenes</caption>
<thead>
<tr>
<th>Scene Name</th>
<th style="width: 80px">Action</th>
</tr>
</thead>
<!--<tbody>
<tr>
<td>Welcome Home</td>
<td>Toggle</td>
</tr>
<tr>
<td>All Lights Off</td>
<td>Toggle</td>
</tr>
</tbody>-->
</table>
</div>
<div id="modulesWithinSceneListArea"
style="width: 50%; float: right;">
<table id="listModulesWithinScene" class="data">
<caption style="text-align: right;">Lights and Devices Within Scene</caption>
<thead>
<tr>
<th style="width: 100px;">Module ID#</th>
<th>Scene Name</th>
<th style="width: 50px">Level</th>
</tr>
</thead>
<tbody>
<tr>
<th>1</th>
<td>2x Floor Lamp</td>
<td>50%</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- ... -->
</body>
</html>
</code>
Now, let me go ahead and describe my problem.
So anyway, I want to call a function that's in the part of the code:
// Create a new anchor tag and name it "List."
var a_set = document.createElement("a");
a_set.href = "javascript:ListAllModulesWithinScene(listScenes_row" + r +
"_toggle";<br />
a_set.id = "listScenes_row" + r + "_set";
a_set.appendChild(document.createTextNode("List"));
I want javascript:ListAllModulesWithinScene(...) that is inside quotes to call the function (ListAllModulesWithinScene(sceneName)) in PageSpecific/Home.js, but nothing happens if I click the List link; so far, it's not working. This is the function that I'm trying to call.
function ListAllModulesWithinScene(sceneName)
{alert("test");
/* The part of the code that I took out fills up the table with the list of modules
that are part of the scene, each module having different levels/settings. */
}
The expected result is that I want to see the alert message box just to make sure it works before I call out the code to generate the rows of data like say...
function ListAllModulesWithinScene(sceneName)
{
/*listModulesWithinScene = document.getElementById("listModulesWithinScene");
// Delete the tbody tag if it does not exist and create a enw tbody tag.
if(listModulesWithinScene.getElementsByTagName("tbody") != null)
listModulesWithinScene.removeChild("tbody");
var listModulesWithinScene_tBody = document.createElement("tbody");
var xmlRows = xmlObj.childNodes[2].getElementsByTagName("Scene");
for (var r = 0; r < xmlRows.length; r++)
{
if (xmlRows[r].getAttribute("name") == sceneName)
{
var moduleRow = xmlRows[r].getElementsByTagName("Module");
if (moduleRow.length > 0)
{
var row = document.createElement("tr");
for (var msr = 0; msr < moduleRow.length; msr++)
{
var moduleRow2 = xmlObj.childNodes[1].getElementsByTagName("Module");
for (var mr = 0; mr < xmlRow2.length; mr++)
{
if (moduleRow[mr].getAttribute("id") ==
xmlObj.childNodes[1].childNodes[mr].getAttribute("id"))
{
var td_id = document.createElement("th");
td_id.appendChild(
document.createTextNode(moduleRow.getAttribute("id")));
td_id.setAttribute("id", "listModulesFromScene_row" + r +
"_id");
row.appendChild(td_id);
var td_name = document.createElement("td");
td_name.appendChild(
document.createTextNode(moduleRow2.getAttribute("name")));
td_name.setAttribute("id", "listModulesFromScene_row" + r +
"_name");
row.appendChild(td_name);
var td_level = document.createElement("td");
td_level.appendChild(
document.createTextNode(moduleRow.getAttribute("level")));
td_level.setAttribute("id", "listModulesFromScene_row" + r +
"_level");
row.appendChild(td_level);
}
}
}
}
}
}
listModulesWithinScene_tBody.appendChild(row);
listModulesWithinScene.appendChild(listModulesWithinScene_tBody);*/
}
In order to help get a better ideal of how my tables are generated, I want to post my entire code. I could provide more details about my problem but that's all I can provide for now.
This is the XMLReaderWriter.js file that I currently have.
/*
When it comes to loading and saving an XML file, it helps to try to keep the XML file organized
and well-formed, so it's best to not to modify the XML file UNLESS you know what you're doing.
The structure of an XML file is as follows:
<?xml version="1.0" encoding="utf-8" ?>
<HomeAutomationInterface>
<Setup>
<Location longitude="" latitude="" />
</Setup>
<Modules>
<!-- The first row is an example. -->
<Module id="1" name="module name" level="ON" type="dimmer">
<!-- ... -->
</Modules>
<Scenes>
<!-- the first row is an example. It can contain multiple modules. -->
<scene name="Scene Name">
<module id="1" level="50">
<module id="2" level="60">
<!-- ... -->
</scene>
<!-- ... -->
</Scenes>
<Timers>
<!-- The following four rows are an example. For DST, sunrise and sunset
is dependent in longitude and latitude. How this works is this:
1. Go to this website and enter your address information.
http://stevemorse.org/jcal/latlon.php
2. Go here and enter your today's date, followed by longitude and latitude,
and time zone: http://www.weatherimages.org/latlonsun.html
3. You should get your information related to sunrise and sunset. It should
look like this:
Thursday
10 March 2011 Universal Time - 5h
SUN
Begin civil twilight 06:30
Sunrise 06:54
Sun transit 12:48
Sunset 18:42
End civil twilight 19:06
Now that's how you get your times for your sunruse and sunset.
-->
<timer name="Timer Name 1" type="regular">
<regular time="hour:minute:second:millisecond">
<module id="1" level="50">
<!-- ... -->
</regular>
</timer>
<timer name="Timer Name 2" type="regular">
<regular time="hour:minute:second:millisecond">
<scene name="Scene Name">
<!-- ... -->
</regular>
</timer>
<timer name="Timer Name 3" type="DST">
<DST occour="sunrise|sunset" offsetDir="later|sooner"
offset="hour:minute:second:millisecond">
<module id="1" level="75">
<!-- ... -->
</DST>
</timer>
<timer name="Timer Name 4" type="DST">
<DST occour="sunrise|sunset" offsetDir="later|sooner"
offset="hour:minute:second:millisecond">
<scene name="Scene Name">
<!-- ... -->
</DST>
</timer>
<!-- ... -->
</Timers>
</HomeAutomationInterface>
It's a long documentation, but it helps to understand what this XML structure is all about.
*/
// Not for Internet Explorer 6 or below.
var xmlDoc;
var xmlObj;
// For HTML tables (<table>)
var listModules;
var listScenes;
var listModulesWithinScene;
// For HTML text boxes
var inputLongitude;
var inputLatitude;
function LoadXML()
{
// ActiveXObject will have to be checked first to see if it's defined. Otherwise, if you
// try to check XMLHttpRequest first, even if Internet Explorer supports it, you will get
// "Access Denied" in Internet Explorer and perhaps not in Firefox.
if (window.ActiveXObject)
{
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;
xmlDoc.load("HomeAutomationInterface.xml");
PopulateFromXML();
}
else
{
// If this is the only code in this function, then you will need to put all your
// project in the server, since Internet Explorer has a "Same Origin Policy" which
// I believe that the open method with "GET" causes a problem in Internet Explorer
// but did not cause a problem in Firefox. In order to rectify the problem, the code
// inside if(window.ActiveXObject) makes use of ActiveX.
xmlDoc = new XMLHttpRequest();
xmlDoc.open("GET", "HomeAutomationInterface.xml", null)
xmlDoc.send(null);
if (xmlDoc.status == 200)
{
xmlDoc = xmlDoc.responseXML;
PopulateFromXML();
}
}
}
function PopulateFromXML()
{
listModules = document.getElementById(
"listModules").getElementsByTagName("tbody");
// Gather the text fields for location data.
inputLongitude = document.getElementById("inputLongitude")
inputLatitude = document.getElementById("inputLatitude")
// Firefox's DOM Parser treats whitespaces as text nodes, including
// line breaks.
removeWhitespace(xmlDoc.documentElement);
// Send the document's root element to the XML Object variable.
xmlObj = xmlDoc.documentElement;
// Perform the checks and populate the tables
// and any other elements that are needed.
if (xmlObj.tagName == "HomeAutomationInterface")
{
// Check to be sure the first node is the "Setup" node. It contains the
// location node.
if ((xmlObj.childNodes[0].tagName == "Setup") &&
(xmlObj.childNodes[0].childNodes[0].tagName == "Location"))
{
// Copy the data from one of the attributes to the respective text boxes.
inputLongitude.value = xmlObj.childNodes[0]
.childNodes[0].getAttribute("longitude");
inputLatitude.value = xmlObj.childNodes[0]
.childNodes[0].getAttribute("latitude");
}
// The second node within the root element is Modules node.
// This will be implemented.
if (xmlObj.childNodes[1].tagName == "Modules")
{
//TODO: Implement the XML-to-Table translation that gets info
// about modules.
listModules = document.getElementById("listModules");
var listModules_tBody = document.createElement("tbody");
var xmlRows = xmlObj.childNodes[1].getElementsByTagName("Module");
for (var r = 0; r < xmlRows.length; r++)
{
var xmlRow = xmlRows[r];
var row = document.createElement("tr");
var td_id = document.createElement("th");
td_id.appendChild(document.createTextNode(xmlRow.getAttribute("id")));
td_id.setAttribute("id", "listModules_row" + r + "_id");
row.appendChild(td_id);
var td_name = document.createElement("td");
td_name.appendChild(document.createTextNode(xmlRow.getAttribute("name")));
td_name.setAttribute("id", "listModules_row" + r + "_name");
row.appendChild(td_name);
var td_level = document.createElement("td");
td_level.appendChild(document.createTextNode(xmlRow.getAttribute("level")));
td_level.setAttribute("id", "listModules_row" + r + "_level");
row.appendChild(td_level);
if (xmlRow.getAttribute("type") == "dimmer")
{
row.style.color = "Green";
// Create a new table cell for a dimmer. This will include a toggle,
// a text box, and a set button.
var td_dimmer = document.createElement("td");
// Create a new anchor tag and, set the href to #, and name it "Toggle."
var a_toggle = document.createElement("a");
a_toggle.href = "#";
a_toggle.id = "listMoudles_row" + r + "_dimmer_toggle";
a_toggle.appendChild(document.createTextNode("Toggle"));
td_dimmer.appendChild(a_toggle);
// Create a new div element to hold a text box and a set button.
var div_floatright = document.createElement("div");
div_floatright.style.float = "right";
// Create a new text box and append it to the div element.
var input_level = document.createElement("input");
input_level.type = "text";
input_level.name = "listModules_row" + r + "_inputLevel";
input_level.id = "listModules_row" + r + "_inputLevel";
input_level.style.width = "40px";
div_floatright.appendChild(input_level);
// Create a new anchor tag, set the href to #, and name it "Set."
var a_set = document.createElement("a");
a_set.href = "#";
a_set.id = "listMoudles_row" + r + "_dimmer_set";
a_set.appendChild(document.createTextNode("Set"));
div_floatright.appendChild(a_set);
// Append the div element to the table cell.
td_dimmer.appendChild(div_floatright);
// Finally, append the table cell to the row.
row.appendChild(td_dimmer);
}
else if (xmlRow.getAttribute("type") == "switch")
{
row.style.color = "Blue";
// Create a new table cell for a dimmer. This will include a toggle,
// a text box, and a set button.
var td_switch = document.createElement("td");
// Create a new anchor tag and, set the href to #, and name it "Toggle."
var a_toggle = document.createElement("a");
a_toggle.href = "#";
a_toggle.id = "listMoudles_row" + r + "_dimmer_toggle";
a_toggle.appendChild(document.createTextNode("Toggle"));
td_switch.appendChild(a_toggle);
row.appendChild(td_switch);
}
else
{
row.style.color = "Black";
row.appendChild(document.createTextNode("No actions available."));
}
listModules_tBody.appendChild(row);
}
listModules.appendChild(listModules_tBody);
// Uncomment this code and run the example.
//alert(listModules_row0_name.textContent);
}
// The third node within the root element is Scenes node.
// You need modules in order for scenes to work.
// This will be implemented.
if (xmlObj.childNodes[2].tagName == "Scenes")
{
listScenes = document.getElementById("listScenes");
var listScenes_tBody = document.createElement("tbody");
var xmlRows = xmlObj.childNodes[2].getElementsByTagName("Scene");
for (var r = 0; r < xmlRows.length; r++)
{
var xmlRow = xmlRows[r];
var row = document.createElement("tr");
var td_name = document.createElement("td");
td_name.appendChild(document.createTextNode(xmlRow.getAttribute("name")));
td_name.setAttribute("id", "listScenes_row" + r + "_name");
row.appendChild(td_name);
row.appendChild(td_name);
var td_actions = document.createElement("td");
// Create a new anchor tag and name it "Toggle."
var a_toggle = document.createElement("a");
a_toggle.href = "#";
a_toggle.id = "listScenes_row" + r + "_toggle";
a_toggle.appendChild(document.createTextNode("Toggle"));
// Create a new anchor tag and name it "List."
var a_set = document.createElement("a");
a_set.href = "javascript:ListAllModulesWithinScene(listScenes_row" + r +
"_toggle";
a_set.id = "listScenes_row" + r + "_set";
a_set.appendChild(document.createTextNode("List"));
td_actions.appendChild(a_toggle);
td_actions.appendChild(a_set);
row.appendChild(td_actions);
listScenes_tBody.appendChild(row);
}
listScenes.appendChild(listScenes_tBody);
}
// The last element is the Timers node.
// This will either activate the scene or turn on, off,
// dim, brighten, or set the light level of the module if
// it is the light module or turn on or off the appliance
// module. This will be implemented.
if (xmlObj.childNodes[3].tagName == "Timers")
{
//TODO: Implement a XML-to-Table parser that parses the XML data
// from the timers tag into the timer table.
}
}
}
// I stumbled across http://www.agavegroup.com/?p=32 and I borrowed the code from
// http://stackoverflow.com/questions/2792951/firefox-domparser-problem
// It took me a week to debug all my code until I find out what's going on with Firefox's
// DOM Inspector.
function removeWhitespace(node)
{
for (var i = node.childNodes.length; i-- > 0; )
{
var child = node.childNodes[i];
if (child.nodeType === 3 && child.data.match(/^\s*$/))
node.removeChild(child);
if (child.nodeType === 1)
removeWhitespace(child);
}
}
And now as for my background information, I'm doing this as my project for COP2822 (Scripting for the Web), so it's only Javascript and not server-side, so I have endured a lot of pain, but was able to make it through, so my experience with Javascript is well worth it in the end. I did have some experience with Javascript before I take COP2822, though.
Welcome to SO. Considering you copy pasted your code
a_set.href = "javascript:ListAllModulesWithinScene(listScenes_row"
+ r + "_toggle)";//<br />
You had a weird br tag in the middle of your js code and you had a missing ) in the function call.
If you still have issues, post and I'll try to discuss. I suggest getting a browser or extension to your browser that supplies a javascript console. In my opinion it's invaluable to debugging.
i think you want quotes (escaped) around the sceneName parameter value:
a_set.href = "javascript:ListAllModulesWithinScene(\"listScenes_row" + r + "_toggle\")";