MeeshKB Posted October 20, 2014 Share Posted October 20, 2014 This is bit a of a "creative" use of FP (at least it is for me). So please bear with me. I am wondering if there is a way to return a count of the number of instances of a variable within a job. For reference and context, a composed copy of my form is attached. This is essentially what it looks like (except that there are a total of 12 available items - I cropped the image to make it easier to view). It is a form to allow our client to order double sided posters. http://i141.photobucket.com/albums/r42/Turtlegirl203/Public/Professional/MS-TOPPERDS-Output-1_zpsf9207355.jpg Basically, the user will choose artwork for each side, for each "topper" poster. They will also indicate a quantity. This form will not return the print ready artwork - rather, it will create a form suitable for them to review and confirm, and for our customer service reps to create the job. I would like to include, on the second page of the output, a summary of each art file required (resources, in my form) as well as how many total prints of each are require to fulfill the job (ie, how many occurrences of the resource within the job). I know I will need to work in some additional math for the quantities, but I wasn't sure if there is a function to count the occurrences. If anyone is still with me, could you kindly point me in the right direction or divest me of my grand illusions?MS-TOPPERDS-Output.pdf Quote Link to comment Share on other sites More sharing options...
Dan Korn Posted October 21, 2014 Share Posted October 21, 2014 I'm not sure I understand what it is that we're trying to count. The PDF just has a bunch of entries with "Qty. 1." Is that "Qty" number going to vary? Also, is this imposed output, or are these all separate frames on a single Body page? Furthermore, it's not clear to me what this "form" is that you mention: Is it a web form, and if so, in what web application? I assume that the web form is generating an input data file for FusionPro, with some kind of quantity field. If so, why can't you just grab that field value? Maybe posting the collected job would clarify things a bit. Quote Link to comment Share on other sites More sharing options...
MeeshKB Posted October 21, 2014 Author Share Posted October 21, 2014 Sorry - I didn't explain myself particularly well. I forget how many different applications FP has. This is a web form which I am loading to Avanti eAccess. Our client will use the form to choose art and indicate quantities for each double-sided poster. The composed file will look similar to the image in my previous post (except with varying pieces of art and quantities in each category). These items are set up as a bunch of frames on a single body page. The composed file is not final art but rather a "key" which will allow our CSRs to see which art needs to be retrieved and printed, as well as for production to understand which items need to be partnered for laminating back to back. I would like to include a second page in the output which lists all the art files required, and a tally of how many of each we need to print. Based on the collected job I'm attaching, it might look something like this: Antacids and Laxitives - 1 First Aid - 1 Men's Health - 1 Women's Health - 1 Skin Care - 2 Pain & Discomfort - 2 I hope this, along with the collected job, makes some sense. Thanks for whatever insight you can provide.MS-TOPPERDS.zip Quote Link to comment Share on other sites More sharing options...
Dan Korn Posted October 23, 2014 Share Posted October 23, 2014 (edited) Okay, so looking at this job, it seems to be in the category I like to call "mowing your lawn with tweezers." That is, you're quite painstakingly creating a whole series of frames and rules numbered from 1 to n, laying them out just so, and linking everything up. That's a lot more work than you need to do. There are several ways in which the complexity of this job, and the work needed to do to set it up and maintain it, can be greatly simplified. Many of these optimizations will also result in faster composition times, and smaller file sizes. And they will also make it much easier to program in the concept of repeating an element. One approach that comes to mind right away is to use a table or a repeatable component, or perhaps imposition, to lay out multiple instances of that same basic set of frames in an automated way. A table might be tricky with the graphic frames, although I think you could actually do everything here with text and inline graphics, without a table. A repeatable component would also work: Basically, you would recreate that same basic set of three frames on a page of type Template, and then use the FPRepeatableComponent object in a rule to create instances of the repeatable component in a text frame (probably a two-column frame). As an imposed job, the entire PDF template would be a single body page with those three frames, which would be imposed multi-up onto a finished 8.5x11" sheet. With any of these strategies, you also don't need to have 12 sets of rules. Actually, even with the layout the way it is with all of those multiple frames, you still don't need all those rules. They can be reduced in several ways: variable injection, frame assignment, or per-flow rules. In all of these cases, you can use a loop based on something like "for (var i = 1; i <= 12; i++)" and then assign the values in the loop, in one bit of code, not 12 separate copied-and-pasted bits of code. Without naming all of the frames, you can use variable injection. Believe it or not, you can delete all those rules you have now, and instead, simply have one rule, OnRecordStart, like so: for (var i = 1; i <= 12; i++) { var baseName = "Topper " + i; var text = (Field(baseName + " Side 1") == "None" ? "" : baseName + " - Qty. " + TaggedDataField(baseName + " Qty")); FusionPro.Composition.AddVariable(baseName + " Text", text, true); // true to treat as tagged for (var side = 1; side <= 2; side++) { var sideName = baseName + " Side " + side; var r = NullResource(); try { r = Resource(Field(sideName)); } catch (e) {} FusionPro.Composition.AddGraphicVariable(sideName + " Fill", r); } } You can do something very similar in a loop if you name all of the frames the same as their variable names. (You don't even need to assign variables to the frames with this approach; it's all about the frame names). Then the OnRecordStart logic becomes this: for (var i = 1; i <= 12; i++) { var baseName = "Topper " + i; var text = (Field(baseName + " Side 1") == "None" ? "" : baseName + " - Qty. " + TaggedDataField(baseName + " Qty")); FindTextFrame(baseName + " Text").content = text; for (var side = 1; side <= 2; side++) { var sideName = baseName + " Side " + side; var r = NullResource(); try { r = Resource(Field(sideName)); } catch (e) {} FindGraphicFrame(sideName + " Fill").SetGraphic(r); } } Or, with the named frames, you could have three separate rules, one for each of the three frames in the set, and check the "Re-evaluate this rule for every text flow/graphic frame" box, grab the name of the flow with FusionPro.Composition.CurrentFlow.name, parse that out to get the index number (1 to 12), and then return the associated indexed text or resources. But these strategies all still require you to lay out 12 separate sets of frames. Remember how I said that you could actually do everything here with text and inline graphics? You can actually do this with just a single text frame on the page, with two columns, and get rid of all those other frames. Again, you just need a single rule (this time a regular Text rule, not OnRecordStart). If you name that single text frame and check the "Re-evaluate this rule for every text flow" box for the rule, the single rule can look like this: var result = []; for (var i = 1; i <= 12; i++) { var baseName = "Topper " + i; var text = (Field(baseName + " Side 1") == "None" ? "" : baseName + " - Qty. " + TaggedDataField(baseName + " Qty")); result.push(text); for (var side = 1; side <= 2; side++) { var sideName = baseName + " Side " + side; var r = null; try { r = Resource(Field(sideName)); } catch (e) {} if (r) { var width = 24000; if (!FusionPro.inValidation) width = FindTextFrame(FusionPro.Composition.CurrentFlow.name).GetSettableTextWidth(); var tag = '<graphic resource="' + Field(sideName) + '" width="' + width + '">'; result.push(tag); } else result.push("<br><br>"); } } return result.join("<p>\n\n"); You may need to play around a bit with the size and position of the text frame, and the gutter width, and possibly inter-paragraph spacing, to get the layout just so, but that should be a lot easier than laying out all those multiple frames. (A repeatable component could give you a bit more fine-grained control over the layout, although the JavaScript code for that is just a bit more complicated; I'll leave that as an exercise for later, or for someone else to tackle.) Now, we still haven't done anything here to handle the repeat quantities. It's also still not exactly clear to me what you want to do with those. But, assuming that you want to actually repeat the set of frames that number of times, now we have an easy way to do that: var result = []; for (var i = 1; i <= 12; i++) { var baseName = "Topper " + i; var repeatCount = Int(Field(baseName + " Qty")) || 1; for (var repeat = 1; repeat <= repeatCount; repeat++) { var text = (Field(baseName + " Side 1") == "None" ? "" : baseName + " - " + repeat + " of " + repeatCount); result.push(text); for (var side = 1; side <= 2; side++) { var sideName = baseName + " Side " + side; var r = null; try { r = Resource(Field(sideName)); } catch (e) {} if (r) { var width = 24000; if (!FusionPro.inValidation) width = FindTextFrame(FusionPro.Composition.CurrentFlow.name).GetSettableTextWidth(); var tag = '<graphic resource="' + Field(sideName) + '" width="' + width + '">'; result.push(tag); } else result.push("<br><br>"); } } } return result.join("<p>\n\n"); But now that we're repeating those, what happens when we fill more than those 12 frames (or 12 spaces on the page where there used to be separate frames)? Easy! Just add an Overflow page, with the same-sized frame on it, and overflow to that. I've attached a modified version of your PDF template to demonstrate both of these approaches (multi-frame with variable injection and single-frame with inline graphics).MS-TOPPERDS-dan.pdf Edited October 23, 2014 by Dan Korn Added a note about using a repeatable component. Quote Link to comment Share on other sites More sharing options...
MeeshKB Posted October 23, 2014 Author Share Posted October 23, 2014 Thank you so much for this, Dan. I can definitely see that my approach was...what is the polar opposite of succinct? That. I was definitely "mowing my lawn with tweezers". In my defense, I hadn't yet learned how to use the lawnmower and was afraid of cutting my feet off. Anyway, I sincerely appreciate the guidance. I would like to explore this further even though - and I apologize for this - I learned this morning that my multi-up solution isn't suitable for this application. Because pricing is attached to these jobs on a "per layout" basis, I need a simple form which only includes one layout. That's up and running now. Regardless of that, I do want to understand this approach. Unfortunately, I am unable to work with your PDF. A version compatibility issue, perhaps? Although, I am on 9.1.0. I can open and view the PDF, but my FP menus are greyed out. I can access the Text Editor by double-clicking, but all else is inaccessible. Quote Link to comment Share on other sites More sharing options...
Dan Korn Posted October 23, 2014 Share Posted October 23, 2014 I can definitely see that my approach was...what is the polar opposite of succinct? That. I was definitely "mowing my lawn with tweezers". In my defense, I hadn't yet learned how to use the lawnmower and was afraid of cutting my feet off. Understood. This stuff isn't necessarily obvious; that's why I wanted to lay it all out. Anyway, I sincerely appreciate the guidance. I would like to explore this further even though - and I apologize for this - I learned this morning that my multi-up solution isn't suitable for this application. Because pricing is attached to these jobs on a "per layout" basis, I need a simple form which only includes one layout. That's up and running now. Okay. I'm no stranger to having to completely restart a project due to poorly communicated customer requirements. Regardless of that, I do want to understand this approach. Unfortunately, I am unable to work with your PDF. A version compatibility issue, perhaps? Although, I am on 9.1.0. I can open and view the PDF, but my FP menus are greyed out. I can access the Text Editor by double-clicking, but all else is inaccessible. Sorry about that; I'm using FusionPro 9.3, and templates created with 9.2 or later aren't readable by older versions (9.1 and earlier) due to everything being double-byte Unicode. But we're adding a new feature to 9.3 to collect the job in 9.1 compatibility mode. I've utilized that and re-attached the PDF here. This should work for you.MS-TOPPERDS-dan.pdf Quote Link to comment Share on other sites More sharing options...
MeeshKB Posted October 23, 2014 Author Share Posted October 23, 2014 Thanks, Dan. I'll review this tomorrow and no doubt be back with questions. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.