Jump to content

Javascript N00B trying to figure out error in table creation


PC Nametag

Recommended Posts

Hello, I'm new-ish to programming and Javascript in general (and new to this message board). I have some basic concepts down. I am building a script to create a table and I keep getting the following message when write the script and try to validate it:

 

 

uncaught exception:TypeError: this.Cells[argument] has no properties

Here is the code (minus the boring table contents)

new FPTable;

var myTable = new FPTable;

myTable.AddColumns(9293, 9293, 9293);

myTable.AddRows(21);

myTable.Rows[0].Cells[0].SetBorders("None");

myTable.Rows[0].CopyCells(0,1,2,3);

...

return myTable.MakeTags();

Do I need to make a set borders statement for all 21 rows? Surely there is an easier way to write it, but, as I said, I'm fairly new to this.

Any help I would appreciate it.

Link to comment
Share on other sites

You're creating a table with three columns:

myTable.AddColumns(9293, 9293, 9293);

Then you're trying to copy the cell from the first column (0) to the second, third, and fourth columns (1, 2, and 3):

myTable.Rows[0].CopyCells(0,1,2,3);

Obviously there is no fourth column/cell, so you get the error. (Note that, in JavaScript, like in most programming languages, you start counting at zero instead of at one.)

 

The fix is to copy only to valid columns:

myTable.Rows[0].CopyCells(0,1,2);

That will copy the first cell (0) to the second and third cells (1 and 2) in the row.

 

Do I need to make a set borders statement for all 21 rows? Surely there is an easier way to write it, but, as I said, I'm fairly new to this.

No, you don't need to repeat that statement 21 times. You probably don't need as much repetition as I'm imagining there is in your "boring table contents" either.

 

A good thing to keep in mind is that, if you find yourself repeating a lot of code, there's almost always a way to reduce it with a "for" loop.

 

So, you can always do something like this, after adding all the table rows and their data:

for (var r = 0; r < 21; r++)
{
   for (var c = 0; c < 3; c++)
   {
       myTable.Rows[r].Cells[c].SetBorders("Thin", "Black", "Top", "Bottom", "Left", "Right");
   }
}

There's very similar code in the "Money Table" rule in the Frodo Travel tutorial that gets installed with FusionPro through version 10.

 

That said, as I mentioned earlier, I'll bet that you can reduce the code that fills in the table rows and their data with a similar for loop. So instead of this:

myTable.AddRows(21);

I would call myTable.AddRow() in a loop that executes 21 times. It's hard to say exactly what you need to do, since I don't have the rest of the job, or even any idea what your data look like, but it's probably something like this:

var myTable = new FPTable;
myTable.AddColumns(9293, 9293, 9293);

for (var r = 1; r <= 21; r++)
{
   var row = myTable.AddRow();
   row.SetContents(Field("Name_" + r), Field("Address_" + r), Field("Phone_" + r));
   for (var c = 0; c < 3; c++)
       row.Cells[c].SetBorders("Thin", "Black", "Top", "Bottom", "Left", "Right");
}

return myTable.MakeTags();

Or, equivalently:

var myTable = new FPTable;
myTable.AddColumns(9293, 9293, 9293);

for (var r = 1; r <= 21; r++)
{
   var row = myTable.AddRow();
   row.Cells[0].SetBorders("Thin", "Black", "Top", "Bottom", "Left", "Right");
   row.CopyCells(0, 1, 2);
   row.SetContents(Field("Name_" + r), Field("Address_" + r), Field("Phone_" + r));
}

return myTable.MakeTags();

Of course, I could make much more specific suggestions if you were to collect up the template and post it here.

 

You can find a lot of similar examples here on this forum as well, such as:

http://forums.pti.com/showthread.php?t=5235

http://forums.pti.com/showthread.php?t=4411

http://forums.pti.com/showthread.php?t=5160

http://forums.pti.com/showpost.php?p=21703&postcount=2

http://forums.pti.com/showthread.php?t=3179

Link to comment
Share on other sites

I figured I biffed the code up somewhere. :):o. I also figured there was a for statement I could use. As I said, I'm quite new to this so I'm stumbling around as I learn.

 

 

What I will do is as soon as I am done making it and have it to a point where I need 'intervention', I'll post my results and I can see where I can simplify based on feedback. I do appreciate the input.

 

 

 

My end goal is to make agendas on the back side of name tags that consist of variable data. I am trying to learn how to do it so it cuts down on the labor with how we set it up currently. Once you see the template, you'll see what I mean.

 

 

I've decided to post the source doc template and the template I was attempting to set up for reference. The xls doc should point to both templates. The source is the original way (customer did want it upside down) and the template 2 pdf is where I was working through it.

 

 

I see how the for statement would make it easier. I think I get stuck on how each row of info would have something different in it. Would that be a if...then statement??

agenda.zip

Edited by PC Nametag
adding additional info
Link to comment
Share on other sites

Ah, thanks for posting the template and the data. This gives me a much better idea of what you're doing.

 

And yes, you are definitely on the right track of making things easier for yourself in the long run by using a table instead of trying to manually create and populate 30 different frames. As Obi-Wan once said, you've taken your first step into a larger world.

I see how the for statement would make it easier. I think I get stuck on how each row of info would have something different in it. Would that be a if...then statement??

Well, sure, this is variable data after all, so obviously each row is different.

 

The example in my previous post, which was just guessing about what you were trying to do, assumed that you have a series (array) of data fields with consecutive numeric suffixes, such as Name_1, Name_2, Name_3, Address_1, Address_2, Address_3, etc.

 

As I suspected, your actual data is set up in much the same way, with fields time1, time2, time3, etc., and roomname1, roomname2, roomname3, and so on. And for the most part, that's how the rows of the table go, with time1 and room1 in one row, time2 and room2 in the next row, etc. But, you have some other things mixed in there that don't quite follow that pattern, so the code has to account for that. Therefore, in this case, with the way the data is structured, I'm not sure there's a super-easy "for" loop to reduce all of your logic to.

 

...

 

That said, I would consider a data format that's more generic, so that you could have a simpler loop in the rule, and potentially re-use this entire template.

 

One feature in particular that I think you could really benefit from is the multi-line record feature. This allows you to have basically a row in the Excel file for each row in the table, which makes the table code almost trivial.

 

I've taken the liberty of transposing the first two records of your data file into a multi-line format, and reworking the table code to read it, along with a bit of extra formatting. See the attached files.

 

I think this kind of data format is much more flexible, and will enable you to use more generic table code instead of re-writing the code for each new type of event/agenda/tag.

 

Note that, with this kind of format, you can use the same single data file to contain both the name and other info on the front side of each name tag AND the multi-line data for the agenda on the back. I've added a "name" field (column) to the Excel file; you can add any columns you need for other per-nametag data, with the values on the first line of each multi-line record. (Note also that the name field is also the "trigger" field, specified on the next-to-last step of the Data Source Wizard, so that a new record is denoted when that row in the Excel file has a non-empty value in that name column.)

multi-line.zip

Edited by Dan Korn
Link to comment
Share on other sites

Wow. My brain just melted like that guy's face does in Raiders of the Lost Ark

Hah, no mortal can face my JavaScript code! :D

Any chance you could point me in the direction of a step-by-step walk through of setting something like that up?

Yeah, I'm not sure such a walkthrough exists for "something like [this]" in general. The best way to organize the data depends on what you're doing with it.

 

To some extent, it's a matter of having some experience with how variable data works in general, and understanding what the different ways are that data can be abstracted and structured, and knowing how FusionPro works more specifically. Studying how this example I've put together works is probably a good starting point. Working on more jobs will give you more of a feel for what kinds of repetitive tasks and data structures can be better automated and reduced via abstraction (which is kind of a summation of why computers and programs exist in the first place).

 

But here's basically what I did: I copied the first row of your data in Excel to a new sheet, and split it up into one row per event. Then I went into the template in Acrobat, and the Data Wizard, and chose the new data file, and checked the "Multi-line records" box, and then set the "Start a new record when field" condition. Then I went into the rule and added the call to FusionPro.GetMultiLineRecords(), and used the returned object to iterate the lines (rows) in the record to output to the table.

 

Initially, I didn't have the first part of the code in the for loop that puts the Day field value onto a separate line, so the code was simpler. Without any formatting, it's essentially just this:

var myTable = new FPTable;
myTable.AddColumns(9293, 9293, 9293); 

var XDF = FusionPro.GetMultiLineRecords();
for (var r = 1; r <= XDF.recordCount; r++)
{
   var row = myTable.AddRow();
   row.SetContents(TaggedFromRaw(XDF.GetFieldValue(r, "time")),
                   TaggedFromRaw(XDF.GetFieldValue(r, "event")),
                   TaggedFromRaw(XDF.GetFieldValue(r, "roomname")));
}

return myTable.MakeTags();

You can see this same basic pattern in several examples on this forum by searching for "FusionPro GetMultiLineRecords FPTable" in your favorite search engine, or with this search.

 

This is what I was talking about in my previous post, that by using multi-line records, you basically have a row in the Excel file for each row in the table, which makes the table code almost trivial.

 

Then I added the other code to add a row for each new date, as that value changes. The idea is that we remember the day we're on in the dayName variable, outside the loop, then when we find a row where the Day column value is non-empty and different from the one we're remembering (if (day && day != dayName)), we put it into its own row and then remember the new value.

 

Finally, I added some code for formatting (setting margins, alignment, etc.). That's pretty much the walkthrough!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...