Jump to content

step

Registered Users - Approved
  • Posts

    962
  • Joined

Everything posted by step

  1. Okay, yeah it's probably a cleaner solution to assign the colors to the bullets in the legend rule rather than trying to ensure that the results of the legend rule line up correctly with the colored bullets on the chart. You could do that by modifying the code to look like this: [color="red"]var colors = [ 'Red', 'Green', 'Blue', 'Cyan', // etc ];[/color] var slices = { Salary: "", Commission: "Commissions and or Bonus", Incentives: "September Incentive", STI: "Short Term Incentive STI", "401(k) Match": "", "401(k) Profit Share": "Profit Share", "Company Paid Healthcare": "", "Life And Disability" : "", } var sum = 0; [color="red"]var color = 0;[/color] for (var i in slices) sum += Field((slices[i] || i)); var result = []; for (var title in slices) { var val = slices[title] || title; [color="Red"]var bullet = '<span font="Webdings" color="' + colors[(color++ % colors.length)] + '">g</span>';[/color] result.push([color="red"]bullet + ' ' + [/color]title + ' ' + Round((Field(val)/sum) * 100, 1) + '%'); } return result.join('\n<br>'); Or you could use the same rule for both if you set the rule to "Re-evaluate for every text flow" and name your legend frame "chartLegend": var sum = 0; var legendFrame = 'chartLegend'; var isLegend = FusionPro.inValidation ? true : FusionPro.Composition.CurrentFlow.name == legendFrame; function Slice(title, color, field) { this.color = color || 'Black'; var bullet = '<span font="Webdings" color="' + this.color + '">g</span>'; this.title = bullet + ' ' + title; this.field = Field((field || title)); sum += this.field; } var glue = isLegend ? '<br>' : '<row>'; var slices = [ // Key Color Field name (defaults to key) new Slice('Salary', 'Red'), new Slice('Commission', 'Green', 'Commissions and or Bonus'), new Slice('Incentives', 'Blue', 'September Incentive'), new Slice('SIT', 'Cyan', 'Short Term Incentive STI'), new Slice('401(k) Match', 'Magenta'), new Slice('401(k) Profit Share', 'Yellow', 'Profit Share'), new Slice('Company Paid Healthcare', 'Black'), new Slice('Life And Disability', 'Purple') ] return '<row>' + slices.map(function(slice) { var val = Round((slice.field/sum)*100, 1); return isLegend ? slice.title + ' ' + val + '%' : '<cell>' + val; }).join(glue);
  2. Is your first line and body text all part of the same text field? If so, you might try something like this: var paragraph = 'This is the first line. This is the second line'; // Or Field("YOUR PARAGRAPH FIELD"); var boldFont = '75 Helvetica Bold'; return paragraph.replace(/^([^\.\?!]+.)/, '<span font="' + boldFont + '">$1</span><br>'); The code uses a Regular Expression to capture (from the beginning of a string) one or more characters that aren't an exclamation mark (!), period (.), or question mark (?) and then captures the next character – which should be the punctuation. Then it replaces that captured string with the string that was captured wrapped in a span tag to assign the bold font followed by a break tag.
  3. Rounding functions aside, it seems to me that FP takes it upon itself to round every number to two places – regardless of input value. I'm assuming what's happening behind the scenes is that FP is totaling the values of each cell and calculating percentages on its own so that you always have an even 100%. Makes sense – but doesn't give you any control (from what I can tell) over the extent to which the numbers are rounded. I think what you'd end up having to do is fake it by creating the legend yourself using the logic outlined above. Then you'd set the color of the legend's text in the chart to white (or the background color) and lay another frame over the top of it that returns your custom legend rule. If you set the text size of the legend frame to match the text defined in the chart properties, the colors should match up with each row. var slices = { Salary: "", Commission: "Commissions and or Bonus", Incentives: "September Incentive", STI: "Short Term Incentive STI", "401(k) Match": "", "401(k) Profit Share": "Profit Share", "Company Paid Healthcare": "", "Life And Disability" : "", } [color="Red"]var sum = 0; for (var i in slices) sum += Field((slices[i] || i)); [/color] var result = [color="red"][][/color]; for (var title in slices) { var val = slices[title] || title; [color="red"]result.push(title + ' ' + Round((Field(val)/sum) * 100, 1) + '%');[/color] } return result.join('\n[color="red"]<br>[/color]');
  4. Sure it will. You may have just had a typo in your syntax. Try this: return '<p br=false superoffset=30 superratio=70>' + '<superscript>$</superscript>' + Field("Adult Cut Dollar") + [color="Red"]'<p br=false superoffset=10 superratio=90>' + [/color] '<superscript>' + Field("Adult Cut Cents") + '</superscript>';
  5. You don't need to set the superscript offset and ratio twice for the same paragraph. You can just write it like this: return '<p br=false superoffset=30 superratio=70>' + '<superscript>$</superscript>' + Field("Adult Cut Dollar") + '<superscript>' + Field("Adult Cut Cents") + '</superscript>';
  6. Does it work if you remove the part you don't want to copyfit from the CopyfitLine function? if (Field("Title2")) return '<span font="Lato Bold" pointsize="11.5">' + Field("Pipe3") + '</span>' + CopyfitLine("", Field("Title2"), "Lato Regular", 9, 152, 4, true); return "";
  7. What do you mean by "still not working?" Initially, you said the code worked in one of your templates. What is the output you're seeing? Are you getting errors when composing? Can you collect and upload your template/data so that it would be to diagnose the issue?
  8. You still haven't provided any more information about what the rules are doing. How were you changing the color in the first, working template? Check out page 48 of the FusionPro TagsRefGuide.pdf (FusionPro > Documentation > Tags Reference) for information on how to use color tags or search the forum to yield results like this thread or this one.
  9. It's kind of impossible to say based on the information you've provided. What is the code for "Cell Dot Rule" and "Phone Dot Rule"? Have you checked the text frame in which you placed the new rule to see if "suppress if containing empty variables" is checked in your new template? In any event, this code should work for you: return [ 'p ' + Rule("Phone Dot Rule"), 'c ' + Rule("Cell Dot Rule") ].filter(function(s){ return RawTextFromTagged(s).length > 2 }).join(' ');
  10. As noted in this thread: So, you want to use Math.ceil: var x = parseInt(Rule("g1")) var mult = (x*1.25) var z = Math.[color="Red"]ceil[/color](mult / 5) *5 var y = parseInt(z) return y; That said, there is a little bit of redundancy in your code. In rule G1, why parseFloat (keeping decimals), then round to the nearest integer (drop decimals), and then parseInt (convert an integer to an integer)? It might be cleaner/easier to read if you just did something like this: return Math.ceil(Field("AMT") * 1.25 / 5) * 5;
  11. I think the DateFromString function is anticipating the input being in month-day-year format. You can give this a try: var [d,m,y] = Field("Date").split("-").map(Int); var myDate = new Date(y, m + Int(Field("Months") - 1), d); return FormatDate(myDate, "dd lm yyyy"); FusionPro has many built in functions and callbacks that are specific to the FusionPro application, so outside of this forum, it might be difficult to find how to code a FP-specific solution. That being said, anyone who uses FP could certainly benefit from understanding the JavaScript basics and syntax. Taking a course online or doing tutorials is a great way to familiarize yourself with JavaScript and will help you better understand code posted to this forum.
  12. What version of FusionPro are you using? I believe FusionPro 10 has functionality that does exactly what you're describing. That being said, if you're using an older version (version 9 for example – because it's what I'm using), you'll need to link to your primary data file as an external data file. Then you'll want to query the data file for all records that have the same "MAILING ADDRESS" value. You'll probably want to make sure you don't compose those records again once its "STORE ADDRESS" has been associated with a mailing address so you don't end up with duplicates. You can do this by using a global variable to track which mailing addresses have been used. JavaScript Globals processed = []; OnRecordStart FusionPro.Composition.composeThisRecord = processed.indexOf(Field("MAILING ADDRESS")) == -1; Text Rule processed.push(Field("MAILING ADDRESS")); var data = new ExternalDataFileEx(PrimaryInputFile(), ','); return data .FindRecords('MAILING ADDRESS', Field('MAILING ADDRESS')) .map(function(rec){ return data.GetFieldValue(rec, 'STORE ADDRESS'); }) .filter(String) .join('<br>'); FusionPro > Manage Pages > Page Usage Select the page to which you want to over flow, click edit, and change its type to "Overflow" and click "OK" Select the text box you want to overflow Select "Overflow" from the "text frame" properties window Select "Overflow text to new pages" Select the overflow page you just created in the "Page Usage" section Selecting "as few added pages as possible" in the option list under "Add pages" will give you your desired results.
  13. It's not working because you're using the join method. Try this: var fax = Rule("Change fax phone format Rule"); var cell = Rule("Change Cell phone format Rule"); var result = ""; if (fax) result += '• Fax: ' + fax + ' '; if (cell) result += '• Cell: ' + cell; return Trim(result); Or: var fax = Rule("Change fax phone format Rule"); var cell = Rule("Change Cell phone format Rule"); return ["Fax: " + fax,"Cell: " + cell].map(function(s){ return /^.*\s\w+$/.test(s) ? '• ' + s : ''; }).filter(String).join(' ');
  14. Java is different than JavaScript. You won't be able to write Java for FusionPro. I feel like this thread does a pretty excellent job of "teaching you to fish" for the exact fish you're trying to catch (inserting multi-page PDFs). It has an example with well-commented code. But if you ever come across code that's been posted here on the forum that doesn't quite make sense, reply on that thread and ask for further clarification. You don't need to create 'if' statements for each of those scenarios if your resources are named according to the value of the "REP" field. Instead you could just write this: return Resource(Field("REP") + "1.pdf"); There is. If you reference the "Building Blocks" window, you will find a list of properties for FusionProResources (Objects > Resources > FusionProResource) and you will notice that "pagenumber" is one such property. So you can add you PDF resource and then set the page number to return like this: // Assigns AAA.pdf to the "pdf" variable var pdf = Resource(Field("REP") + ".pdf"); pdf.pagenumber = 2; // sets the page number to 2 return pdf; // returns the second page of AAA.pdf
  15. That's because you're creating 664 pages for every record. To get the layout you're describing, you'd need 664 records each producing 1 page. Assuming your template is just the 664 page PDF, you'll need to repeat the record 664 times and enable the page that corresponds with the repeat number. OnRecordStart var pages = 664; FusionPro.Composition.repeatRecordCount = pages; for (var i=1; i <= pages; i++) FusionPro.Composition.SetBodyPageUsage(i, i == FusionPro.Composition.repeatRecordNumber);
  16. Why not just sort the data before it gets to FusionPro? That would save you from reworking your template code. But if you really want FusionPro to do it, it's possible. You'll have to link to your primary data file as an external data file, push all of the records into an array and then sort the records based on the "Last Name" field. From there, you'll have to reference the array to determine the correct record number to use and read it from the external data file. JavaScript Globals ex = null; data = []; function ExField(name) { return ex.GetFieldValue(data[FusionPro.Composition.inputRecordNumber - 1], name); } OnJobStart ex = new ExternalDataFileEx(PrimaryInputFile(), ','); for (var i=1; i <= ex.recordCount; i++) data.push({ name: ex.GetFieldValue(i, 'Last Name'), rec: i }); data = data.sort(function(a,b){ return a.name < b.name ? -1 : a.name > b.name ? 1 : 0; }).map(function(s){ return s.rec }); Note, that you'll have to replace any use of the "Field" function in your rules with "ExField."
  17. First of all, you're doing exactly the same thing when the value of "PLANOPTION" is "500," "750," or "1000" so you could simplify your code by writing it like this: switch (Field("PLANOPTION")) { case "200": FusionPro.Composition.SetBodyPageUsage("200 P1", true) FusionPro.Composition.SetBodyPageUsage("200 P2", true) FusionPro.Composition.SetBodyPageUsage("200NonInsured P1", true) FusionPro.Composition.SetBodyPageUsage("200NonInsured P2", true) break; case "250": FusionPro.Composition.SetBodyPageUsage("250 P1", true) FusionPro.Composition.SetBodyPageUsage("250 P2", true) FusionPro.Composition.SetBodyPageUsage("250_500_750_1000NonInsured P1", true) FusionPro.Composition.SetBodyPageUsage("250_500_750_1000NonInsured P2", true) break; case "500": [color="Red"] case "750": case "1000":[/color] FusionPro.Composition.SetBodyPageUsage("500_750_1000 P1", true) FusionPro.Composition.SetBodyPageUsage("500_750_1000 P2", true) FusionPro.Composition.SetBodyPageUsage("250_500_750_1000NonInsured P1", true) FusionPro.Composition.SetBodyPageUsage("250_500_750_1000NonInsured P2", true) break; } In other words, you only want to enable the "250_500_750_1000NonInsured" pages if the "Amount" field contains a value? You can do that: switch (Field("PLANOPTION")) { case "200": FusionPro.Composition.SetBodyPageUsage("200 P1", true) FusionPro.Composition.SetBodyPageUsage("200 P2", true) FusionPro.Composition.SetBodyPageUsage("200NonInsured P1", true) FusionPro.Composition.SetBodyPageUsage("200NonInsured P2", true) break; case "250": FusionPro.Composition.SetBodyPageUsage("250 P1", true) FusionPro.Composition.SetBodyPageUsage("250 P2", true) FusionPro.Composition.SetBodyPageUsage("250_500_750_1000NonInsured P1", [color="red"]Field("Amount")[/color]) FusionPro.Composition.SetBodyPageUsage("250_500_750_1000NonInsured P2", [color="red"]Field("Amount")[/color]) break; case "500": case "750": case "1000": FusionPro.Composition.SetBodyPageUsage("500_750_1000 P1", true) FusionPro.Composition.SetBodyPageUsage("500_750_1000 P2", true) FusionPro.Composition.SetBodyPageUsage("250_500_750_1000NonInsured P1", [color="red"]Field("Amount")[/color]) FusionPro.Composition.SetBodyPageUsage("250_500_750_1000NonInsured P2", [color="red"]Field("Amount")[/color]) break; } Or you could not use a switch statement at all: var front = Field("PLANOPTION") > 250 ? '500_750_1000' : ''; var back = Field("PLANOPTION") > 200 ? '250_500_750_1000' : ''; for (var i=1; i<=2; i++) { FusionPro.Composition.SetBodyPageUsage((front || Field("PLANOPTION")) + ' P' + i, true); if (!back || Field("Amount")) FusionPro.Composition.SetBodyPageUsage((back || Field("PLANOPTION")) + 'NonInsured P' + i, true); }
  18. There are a number of ways to create a numbered list in FusionPro and none of them require HTML. I'm going to assume you're trying to accomplish something more complicated than the example you gave so I'll ignore the "why don't you just type the numbers in the text editor window" elephant in the room. Perhaps you have several fields that represent list items but you only want them to appear in the list if they have a value: var list = [ Field("ListItem1"), Field("ListItem2"), Field("ListItem3") ]; return list.filter(String).map(function(s,p){ return p + 1 + '. ' + s; }).join('<br>'); Or maybe you just want each item's indent to line up in the event that the text wraps. If that the case, you don't need a rule at all. Check out this thread: http://forums.pti.com/showthread.php?t=4075
  19. You can determine how many pages are in a PDF by using the 'countPages' method of a FusionProResource. For example: var pdf = CreateResource(Field("Uploaded PDF Location")); return pdf.countPages; Aside from that, though, I'm not sure how to answer the rest of your question. How are you going to "build additional pages as needed?" Are you just trying to output the first page of the uploaded PDF X times? In other words: if they upload a 2 page PDF and input "8" pages, you'd duplicate the first page 6 more times so that you'd end up with an 8 page PDF? If that's the case, it doesn't really matter how many pages are in the PDF they upload, you could just set the record to repeat as many times as the client input – each time returning the first page of their uploaded PDF: OnRecordStart FusionPro.Composition.repeatRecordNumber = Field("Number of pages"); FindGraphicFrame("Your graphic frame").content(CreateResource(Field("Uploaded PDF Location"), 'graphic'));
  20. You can replace the German words with the French words in the "NAME" field by using the replace method: return Field("NAME").replace('Herrn', 'Cher').replace('Frau','Chère'); You could do the same for your generic salutation, as well: return Field("SALUT").replace("Sehr geehrte Damen und Herren", "Chère Madame cher Monsieur"); If you're goal is to return the generic salutation when the "NAME" field is empty and otherwise return the value of the "NAME" field translated to French you could remove all of your 'if/else' statements and simplify your code: return Field("NAME") ? Field("NAME").replace('Herrn', 'Cher').replace('Frau','Chère') : "Chère Madame cher Monsieur";
  21. The thing to keep in mind is that FusionPro, by default, will compose your template (the letter) for each record in your data file. In your case it sounds like your data is set up in such a way that each record (row of data) is a person's name. So one letter would be created for Tom Jones, another separate letter would be created for Lisa Jones, and so on. Ideally, what you'd want is for each record to compose a letter for the Office Number. So if reworking your data is an option, you could make it look like this: "Office Number" "Workers" "001" "Tom Jones,Lisa Jones,Billy Jones" "002" "Joe Smith,Howard Evans" On a side note, I can't help but feel like there is some serious nepotism at office 001. Anyway, then for each record you could create your list by splitting the comma separated "workers" field and joining it with a line break: return Field("Workers").split(",").join("<br>"); In terms of using an external data file, something like this might work for your particular case and wouldn't require you to rework your data: OnJobStart FusionPro.Composition.compseAllRecords = false; FusionPro.Composition.endRecordNumber = 360; YourTextRule var ex = ExternalDataFileEx(FusionPro.Composition.inputFileName, ','); var list = []; for (var i = 1; i <= ex.recordCount; i++) { function ExField(name) { return ex.GetFieldValue(i, name); } var officeNumber = ExField("Office Number"); if (officeNumber == FormatNumber('000', FusionPro.Composition.inputRecordNumber)) list.push(ExField("First Name") + ' ' + ExField("Last Name")); } return list.join("<br>"); You might find that you need to add the path to your data file rather than FusionPro.Composition.inputFileName when trying to preview the template.
  22. You mean you tried importing the color library from another FusionPro template? The implication being that you have FusionPro template with the color library available? If you don't see a FusionPro palette within InDesign, how exactly did you try to export the Pantone library? I understand that you felt like you were being clear but extra clarification is always helpful when describing your problem to someone who hasn't been dealing with it for two hours. And, speaking only for myself – if I were the one who took time out of my day to try to help you with your problem only to have you turn around and take your frustrations out on me, I imagine I'd start to find it hard to care about whether or not you figured out how to import colors. Do you need the entire Pantone book to be imported or do you just need the blue? If it's the latter, I'd suggest just creating the color in FusionPro. FusionPro > Advanced > Colors Select "New" Name it PANTONE 662 C Enter a build and select "Spot Color" Once you do that, you'll be able to select "PANTONE 662 C" from the color drop-down list in the text editor. I will say that I've noticed in the past that the colors don't always seem to visually match the colors that are embedded in the FP template but with spot colors it shouldn't matter because you just want the "PANTONE 662 C" variable data to print on the "PANTONE 662 C" separation of the FP template.
  23. That isn't the composition log; that is the collection log. The composition log would likely be in the same place as your composed output file. Are you composing the output on a different machine than the one you're using to preview the template? I still think that the issue is that your template can't find your external data file at the time of composition. You can try adding an absolute path to your external data file: data = new ExternalDataFileEx("C:\Users\Desktop\FusionPro\data_feed.csv", ","); Or you could add the path to your external data file to the "Search Path" under the "Advanced" tab of the composition settings.
  24. Are you getting any errors in your message log? Like: "Cannot successfully read/find the external data file."? You could try just defining your data file within the rule itself rather than assigning it to a global variable in OnJobStart: [color="Red"]//Link to the external data file. data = new ExternalDataFileEx("data_feed.csv", ","); if (!data.valid) { ReportError("Cannot successfully read/find the external data file."); } [/color] //Create empty var table = []; var tbl = []; //Get a count of the total number of records in the external data file NumberOfRecords = data.recordCount; var type = [ [' '] //Header ]; //Create Table var myTable = new FPTable; myTable.AddColumns(13000, 2000, 20000, 8500, 6500); tbl.push(["", "", "Provider Name", "Phone Number", "Miles Away"]); //Header Rows //Now, loop through all records in the external data file and find the records for (var n=1; n<=NumberOfRecords; n++) { function ExField(field) {return data.GetFieldValue(n, field);} if (Field("MCE_Case_Number") == ExField("Case_Number")) { type.forEach(function(s) { var [provider, phone, miles] = s; provider = ExField("Prov_Name"); phone = ExField("Prov_Phone").replace(/^[\D]*(\d{3})[\D]*(\d{3})[\D]*(\d{4})$/, "($1) $2-$3"); miles = FormatNumber("0.0", ExField("Prov_Mileage")/100); tbl.push(['Check to choose this provider', '', provider, phone, miles]); }); } } // Formatting for (var i=0; i<tbl.length; i++) { var row = myTable.AddRow(); var cell = row.Cells[0]; row.minHeight = 2000; cell.Margins = new FPTableMargins; cell.Margins.Bottom = 0; row.CopyCells (0,1,2,3,4); if (i >= 1) myTable.Rows[i].Cells[1].SetBorders ("Thin", "Black", "Top", "Bottom", "Right", "Left"); if (i == 0) cell.HStraddle = 2; myTable.Rows[0].Cells[1].Bold = "On"; cell.VAlign = "Middle"; row.CopyCells (1,2,3,4); myTable.Rows[i].Cells[2].HAlign = "Left"; myTable.Rows[i].Cells[3].HAlign = "Center"; myTable.Rows[i].Cells[4].HAlign = "Right"; var [col0, col1, col2, col3, col4] = tbl[i]; row.SetContents (col0, col1, col2, col3, col4); } myTable.AddRow(1); //Blank row for seperation //Push variable into Array table.push(myTable.MakeTags()); return table;
  25. Well, it doesn't sound like you're trying to achieve the same thing you were in your initial post so I'm not totally surprised that the code doesn't work the way you're expecting it to. Initially, you said you wanted a minimum value of $25 for each price and to drop the ".00" from even dollar amounts. Now it just sounds like you're asking how to remove the ".00" which doesn't really fall under the topic of "comparing numbers" but is more in line with formatting numbers. Basically, now you just want to format the price to two decimal places: return FormatNumber("0.00", "2.1"); // 2.10 And then move the ".00" if present: return "FormatNumber("0.00", Field("LASTGIFT")).replace(".00", "");
×
×
  • Create New...