Jump to content

How might I make this multi-line work?


dmp

Recommended Posts

Hi there,

I need some help with making the multi-line work, I was hoping there was a drag & drop option but I guess it's not so simple haha.

 

 

I have a page with 4 membership cards on it that I need to populate. I have a list with 1 to many lines for each record. There is at least one Head of Household (HOH) and there may or may not be any dependents (DEP) in the HOH or DEP column.

There is a member ID that I've setup to be the multi-line identifier when I imported the list.

 

 

What I would like to do, is have the address of the HOH be in all 4 ID card spots, (which Is easy enough) and then have the HOH name be in the first ID card, and subsequent dependents be in the other 3 cards. If there is no other dependents then it would be blank(name) and just have the address of the HOH. If there are more than 4 lines for a record, I'd like it to just ignore the rest for that member (members only get 4 max cards)

 

 

I'll attach some mock data. PS. I'm a total n00b at writing code T.T

Sample List.zip

Link to comment
Share on other sites

What I would like to do, is have the address of the HOH be in all 4 ID card spots, (which Is easy enough) and then have the HOH name be in the first ID card, and subsequent dependents be in the other 3 cards. If there is no other dependents then it would be blank(name) and just have the address of the HOH. If there are more than 4 lines for a record, I'd like it to just ignore the rest for that member (members only get 4 max cards)

Yeah, this is a lot to try to parse. A picture might be worth a thousand words here. Could you attach an example of what you want the output to look like? Or better yet, the template you have so far?

Link to comment
Share on other sites

Hi Dan,

Thanks for taking a look at this!

Here's the FP document along with that sample data.

I've got the 4 ID card spots laid out with the top left one being the Head of Household(HOH) name/address for the actual mailing portion. Then the other 3 are using the address & member number which should be the same as the HOH in all 4 spots.

The kicker is that they want the dependents(DEP) name (if any) to populate the top right, then bottom left, then bottom right ID cards above the address. And when there is no DEP, to not have any name and just leave the address/member number there.

 

 

There's also a salutation on the bottom third of the page that is just "Dear <HOH>:"

 

 

 

I hope this makes it clearer, thanks again for your help!

- Mike

test.zip

Link to comment
Share on other sites

Hi Dan,

I saw some code you mentioned in another thread about the multi-line. I tried using that (added a column: FullName) and I have it so it suppresses the boxes if it's not being used, but I don't know how to actually make the boxes display the 2nd, 3rd, etc.. line of the record group.

 

 

I have this as an OnRecordStart:

FindTextFrame("Box0").suppress = true; 
FindTextFrame("Box1").suppress = true;
FindTextFrame("Box2").suppress = true;

//FusionPro.Composition.composeThisRecord = FieldChanged("MEMBER");
var data = FusionPro.GetMultiLineRecords();

for (var r = 1; r <= data.recordCount; r++)
{
   FindTextFrame("Box" + (r - 1)).suppress = false;
   FusionPro.Composition.AddVariable("FullName" + r, data.GetFieldValue(r, "FullName"));
}

 

 

So with this I can see the boxes showing up or not, but they always display the first line of the record instead of each consecutive one. I'm guessing I need to somehow make a rule that says FullName1 = first line, FullName2 = 2nd line etc.?

 

 

Cheers,

Mike

 

 

Javascript Rocks!

Link to comment
Share on other sites

I have this as an OnRecordStart:

FindTextFrame("Box0").suppress = true; 
FindTextFrame("Box1").suppress = true;
FindTextFrame("Box2").suppress = true;

//FusionPro.Composition.composeThisRecord = FieldChanged("MEMBER");
var data = FusionPro.GetMultiLineRecords();

for (var r = 1; r <= data.recordCount; r++)
{
   FindTextFrame("Box" + (r - 1)).suppress = false;
   FusionPro.Composition.AddVariable("FullName" + r, data.GetFieldValue(r, "FullName"));
}

So with this I can see the boxes showing up or not, but they always display the first line of the record instead of each consecutive one. I'm guessing I need to somehow make a rule that says FullName1 = first line, FullName2 = 2nd line etc.?

Well, I don't have the version of the data file with the "FullName" field. But you don't really need to add that to use multi-line records. You also don't need the variable injection with FusionPro.Composition.AddVariable. It's really not as complicated as all that. Let's start over.

 

The simplest way to output the sub-records from a multi-line record is to call FusionPro.GetMultiLineRecords() and iterate its records, like you're doing, but instead of injecting variables in OnRecordStart, you can just output each record onto a separate line of text from a regular Text rule, something like this:

var result = "";
var data = FusionPro.GetMultiLineRecords();
for (var r = 1; r <= data.recordCount; r++)
   result += data.GetFieldValue(r, "First") + " " + data.GetFieldValue(r, "Last") + "\n";

return result;

If I just put that code into a regular old text rule, and put that rule into a text frame, I get all the sub-records for each primary multi-line record. Obviously you can get any other data fields you want with more calls to data.GetFieldValue().

 

(If you've previously used external data files, and the code for iterating the sub-records in a multi-line record looks similar to how you iterating an XDF, that is absolutely by design.)

 

Now, just outputting lines of text isn't really interesting. The usual use case for multi-line records is to put each line into a table. There are several examples of that here on the forum, including:

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

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

http://forums.pti.com/showpost.php?p=20390&postcount=3

 

Modifying the logic from that last one to your data, you can do this:

var table = new FPTable();
table.AddColumns(5000,8000,3000,3000,4000,10000,10000,4000,5000,8000);
var header = table.AddRow();
header.Type = 'Header';
header.CopyCells(0,1,2,3,4,5,6,7,8);
header.SetContents("first","last","m","d","year","address","city","state","zip","phone");

var data = FusionPro.GetMultiLineRecords();
for (var rec = 1; rec <= data.recordCount; rec++)
{
 function ExField(str) { return TaggedTextFromRaw(data.GetFieldValue(rec, str)); }
 var content = ["first","last","month","day","year","address 1","city","state","zip","phone"].map(ExField);
 var row = table.AddRow();
 row.SetContents.apply(row, content);
}
return table.MakeTags();

And that will output a table with the lines from each record. It's obviously rudimentary, but you should get the idea.

 

Now, that's not really what you want to do. You want each sub-record's data in its own frame. So there you will have to either inject multiple variables for each frame, or set each frame's content, or use a repeatable component. You were kind of on the right track toward that with naming each frame. I named the frames Box1, Box2, Box3, and Box4, and did this in OnRecordStart:

var data = FusionPro.GetMultiLineRecords();
for (var rec = 1; rec <= 4; rec++)
{
   function ExField(str) { return TaggedTextFromRaw(data.GetFieldValue(rec, str)); }

   var text = "";
   if (rec <= data.recordCount)
   {
       text = ExField("FIRST") + " " + ExField("LAST") + '<p>' + ExField("ADDRESS 1")  + '<p>' + 
               ExField("CITY") + ", " + ExField("STATE") + " " + ExField("ZIP");
   }

   FindTextFrame("Box" + rec).content = text;
}

And I think that yields pretty much the result you want.

 

Like I said, you could also leverage a repeatable component or a Formatted Text Resource to do this, but unless there's something more complicated about how you're outputting the text in each box, building up the text in the rule like I'm doing is the simplest solution.

 

I've attached my version of the template which demonstrates all this.

test id cards-Dan.pdf

Link to comment
Share on other sites

OK I think I'm making progress. I got the names to show up. Now I'm having trouble with the VOID box, where I want to do the opposite:Show void when there are no records over an ID Card instead of leaving it blank.

 

 

I don't think it quite works the same way, so maybe there is a way to show VOID in a box when there's no 4th, 3rd, or 2nd record.

 

 

Here's what I have so far attached.

I added a column VOID in case I need to somehow grab that text instead of some kind of Return text "VOID". ugh sorry I"m not good at this.

 

 

Anyone have an idea? I'm almost there T.T

FP Export.zip

Link to comment
Share on other sites

OK I think I'm making progress. I got the names to show up. Now I'm having trouble with the VOID box, where I want to do the opposite:Show void when there are no records over an ID Card instead of leaving it blank.

Change this line in the last code block in my previous post:

    var text = "";

to this:

    var text = "VOID";

Link to comment
Share on other sites

  • 1 year later...

Hello,

 

 

I have a further question in regards to using this functionality. If the phone number in the data file is given in multiple formats or sometimes not in any format and just as a set of numbers (123.456.7890 or 123456789) how would you add that functionality to the code you showed above to choose a specific format style...

for (var rec = 1; rec <= data.recordCount; rec++)
{
 function ExField(str) { return TaggedTextFromRaw(data.GetFieldValue(rec, str)); }
 var content = ["first","last","month","day","year","address 1","city","state","zip","phone"].map(ExField);
 var row = table.AddRow();
 row.SetContents.apply(row, content);
}

I've tried changing the entry values in the "var content" statement from "phone" to Rule("FormatPhone") but that causes FusionPro to reply back that that field cannot be found.

 

 

Thank you.

.

Link to comment
Share on other sites

Hi David! Great to hear from you.

If the phone number in the data file is given in multiple formats or sometimes not in any format and just as a set of numbers (123.456.7890 or 123456789) how would you add that functionality to the code you showed above to choose a specific format style...

So I'm going to give three different answers, for three different versions of FusionPro.

 

First off, I can tease that the upcoming FusionPro 11.1 release will have a whole new set of Form (XML Template) rules, which will let you make a table like this, from multi-line data, with all kinds of variations for formatting the data (phone numbers, dates, currency, etc.) and the table itself (borders, shading, etc.) without needing to write a single line of JavaScript. It's a very cool new feature, which I will post more about when 11.1 is released.

 

Now, in the current FusionPro 11.0 release, modifying the code you have to add the phone formatting for that column is pretty easy:

for (var rec = 1; rec <= data.recordCount; rec++)
{
 function ExField(str) { return TaggedTextFromRaw(data.GetFieldValue(rec, str)); }
 var content = ["first","last","month","day","year","address 1","city","state","zip"].map(ExField);
 content.push(FormatPhoneNumber(ExField("PHONE"), '-'));
 var row = table.AddRow();
 row.SetContents.apply(row, content);
}

 

In versions before FP 11, there's no standalone FormatPhoneNumber function, so you need to make a version of the "Change phone format Rule" XML Template, convert it to JavaScript, and copy-and-paste the logic from there into a new function, which I would put into the JavaScript Globals, then call that function instead of FormatPhoneNumber.

Link to comment
Share on other sites

Hi Dan, it's nice to be heard! :p

 

I get your answer to my question and it seems rather straight forward. However I have one further angle to account for ... what if the phone number is to show up in the "middle" of the table and not as the last entry. Say its Name, Address, Phone, Month, Day, Year, etc... Can I then just add each item as a .push statement into the array "content" instead of all at once?

for (var rec = 1; rec <= data.recordCount; rec++)
{
 function ExField(str) { return TaggedTextFromRaw(data.GetFieldValue(rec, str)); }
 var content = [];
 content.push(ExField("first"));
 content.push(ExField("last"));
 content.push(ExField("address 1"));
 content.push(ExField("city"));
 content.push(ExField("state"));
 content.push(ExField("zip"));
 content.push(FormatPhoneNumber(ExField("PHONE"), '-'));
 content.push(ExField("month"));
 content.push(ExField("day"));
 content.push(ExField("year"));
 var row = table.AddRow();
 row.SetContents.apply(row, content);
}

I'm sure that there may be a better (i.e. more elegant) way of doing it ... but would this work?

Stay safe everyone.

Link to comment
Share on other sites

Can I then just add each item as a .push statement into the array "content" instead of all at once?

Sure, that's the same as:

for (var rec = 1; rec <= data.recordCount; rec++)
{
 function ExField(str) { return TaggedTextFromRaw(data.GetFieldValue(rec, str)); }
 var content = [
   ExField("first"),
   ExField("last"),
   ExField("address 1"),
   ExField("city"),
   ExField("state"),
   ExField("zip"),
   FormatPhoneNumber(ExField("PHONE"), '-'),
   ExField("month"),
   ExField("day"),
   ExField("year")
 ];
 var row = table.AddRow();
 row.SetContents.apply(row, content);
}

Which is the same as:

for (var rec = 1; rec <= data.recordCount; rec++)
{
 function ExField(str) { return TaggedTextFromRaw(data.GetFieldValue(rec, str)); }
 var row = table.AddRow();
 row.SetContents(
   ExField("first"),
   ExField("last"),
   ExField("address 1"),
   ExField("city"),
   ExField("state"),
   ExField("zip"),
   FormatPhoneNumber(ExField("PHONE"), '-'),
   ExField("month"),
   ExField("day"),
   ExField("year")
 );
}

In my previous post, I was using the array and the Function.apply method just to be able to use Array.map to avoid calling that ExField function repeatedly (following the DRY Principle).

 

I suppose a way to keep the succintness of what I wrote before, with this one override case, would be to do this:

for (var rec = 1; rec <= data.recordCount; rec++)
{
 function ExField(str) { return str ? TaggedTextFromRaw(data.GetFieldValue(rec, str)) : ""; }
 var content = ["first","last","address 1","city","state","zip","","month","day","year"].map(ExField);
 var row = table.AddRow();
 row.SetContents.apply(row, content);
 row.Cells[6].Content = FormatPhoneNumber(ExField("PHONE"), '-');
}

Edited by Dan Korn
Link to comment
Share on other sites

Thank you. I've got my template working the way I need it to ... sort of.

 

Each student is supposed to get a kit containing addressed envelopes, blank thank you cards and a listing of 53 patrons. They are to handwrite a personal thank you for donating to their colleges' different fund programs.

 

When I do a 1-up output everything works fine. As soon as I place an imposition on it everything goes wonky. Tried everything I could think of to make it impose ... I even told FusionPro to pre-process the datafile thinking that maybe the multi-line threw it off with the quantity of output. NOPE. I ended up having to do this as a 2-pass process: first imposing the data file 1-up and then imposing that 1-up output file to 2 up. :confused:

 

I've included the zipped template files and I've also placed into the zip the 1-up and 2-up output files for you to look at. The only difference in it is that I've replaced the "list names" with sample names and addresses for security. The dates and dollar amounts are accurate and the initial "student name" is also accurate.

018907_DonorList.zip

Link to comment
Share on other sites

Each student is supposed to get a kit containing addressed envelopes, blank thank you cards and a listing of 53 patrons. They are to handwrite a personal thank you for donating to their colleges' different fund programs.

Okay, you say that each kit should have a list of 53 patrons, but each multi-line record in the data seems to have at lot more than 53 lines. For instance, the Student Number and Student Name fields are the same for the first 110 lines, not changing until line 112.

When I do a 1-up output everything works fine. As soon as I place an imposition on it everything goes wonky.

I'm not sure I understand exactly what you want the output to look like. Can you post a mockup?

Link to comment
Share on other sites

Dan, you are correct I misspoke in my explanation of this job. Originally there were 53 students each getting a kit that contains thank you cards and envelopes for a list of 110 patrons. The client then removed 1 student from the list so I ended up with just 52.

 

I've attached an example of the 2-up pdf file that I eventually ended up with after my 2-step process as describe previously. This one just shows the output from the sample file that I included in the previous attachment.

 

Sorry for the confusion ...

DonorList_2up.pdf

Link to comment
Share on other sites

Thanks David.

 

I looked into this, and it's a known issue, case FP-221. Imposition and multi-line records don't work well together. Imposition relies on saved lookup positions in the data file, which gets messed up with multi-line records. Hopefully we'll have a fix for this in an upcoming release.

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...