0

Derived from Jeff S's methodology found here, I can add a "Checkbox" to a PDF page like so:

PdfPTable tblFirstRow = new PdfPTable(5);
tblFirstRow.SpacingBefore = 4f;
tblFirstRow.HorizontalAlignment = Element.ALIGN_LEFT;

. . . // code where textboxes are added has been elided for brevity

PdfPCell cell204Submitted = new PdfPCell()
{
    CellEvent = new DynamicCheckbox("checkbox204Submitted", "204 Submitted or on file")
};
tblFirstRow.AddCell(cell204Submitted);

doc.Add(tblFirstRow);

The DynamicCheckbox class, based on Jeff S's CustomCellLayout class, is:

public class DynamicCheckbox : IPdfPCellEvent
{
    private string fieldname;
    private string cap;

    public DynamicCheckbox(string name, String caption)
    {
        fieldname = name;
        cap = caption;
    }

    public void CellLayout(PdfPCell cell, Rectangle rectangle, PdfContentByte[] canvases)
    {
        PdfWriter writer = canvases[0].PdfWriter;
        RadioCheckField ckbx = new RadioCheckField(writer, rectangle, fieldname, "Yes");
        ckbx.CheckType = RadioCheckField.TYPE_CHECK;
        ckbx.Text = cap;
        PdfFormField field = ckbx.CheckField;
        writer.AddAnnotation(field);
    }
}

My problem is that the checkbox's text (the string assigned to ckbx.Text) is not displaying. The checkbox (outsized) occupies the last cell in the table row, but there is no (visible) accompanying text.

What's missing from my code?

Note: I tried to reduce the size of the checkbox by doing this:

Rectangle tangle = new Rectangle(20, 20);
//RadioCheckField ckbx = new RadioCheckField(writer, rectangle, fieldname, "Yes");
RadioCheckField ckbx = new RadioCheckField(writer, tangle, fieldname, "Yes");

...but that attempt failed - with that code, I can't even "find" the checkbox in the generated PDF file - clicking willy-nilly in column 5 conjures up no checkbox...

Community
  • 1
  • 1
B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862

3 Answers3

2

Others have answered the label part. The Rectangle that you have called "tangle" needs to be calculated off of the rectangle that comes into the event handler, similar to

Rectangle tangle = new Rectangle(
            rectangle.Left,
            rectangle.Top - PDFStyle.boxsize - 4.5f,
            rectangle.Left + PDFStyle.boxsize,
            rectangle.Top - 4.5f
        );

Where PDFStyle.boxsize is the width/height of the checkbox and 4.5f is the padding the edge of the cell. Basically the rectangle isn't relative to the cell, but absolute to the page.

Jeff S
  • 554
  • 5
  • 13
  • It turns out that in my case, keeping the default rectangle works fine. Trying to "mess with" the values by replacing the rectangle with a new one just skewed things up. Maybe this is because the rectangle is the first thing on a row? I don't know... – B. Clay Shannon-B. Crow Raven Apr 15 '15 at 22:10
1

As described in ISO-32000-1, a check box is a field of type Button. If you define text for a button, you want to define the text that is displayed on the button. However: in the case of a check box, there is no such text! Instead, you have two appearances, one for the Off value and one for the Yes value.

An educated guess made by an attentive reader would be that you don't want to add text (to the button), but that you want to add a label (for a checkbox). Again you should consult ISO-32000-1 and you'll discover that the spec doesn't say anything about labels for check boxes. The concept just doesn't exist at the level of an AcroForm.

This doesn't mean the concept doesn't exist in general. Many PDF tools allow you to define check boxes that are preceded by a label. When you look inside the PDF, you'll discover that this label is just part of the content, whereas the check box is represented by a widget orientation.

Let's take a look at the official documentation instead of frustrating ourselves searching on every place of the web except on the official web site. More specifically: let's take a look at the Buttons example from Chapter 7 of my book. You'll see that one can set text for a real button:

PushbuttonField button = new PushbuttonField(writer, rect, "Buttons");
button.setText("Push me");

This isn't possible with check boxes (for the obvious reason that the appearance of a check box is completely different). If we want to add a label, we can add it for instance like this:

checkbox = new RadioCheckField(writer, rect, LANGUAGES[i], "Yes");
field = checkbox.getCheckField();
field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, "Off", onOff[0]);
field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, "Yes", onOff[1]);
writer.addAnnotation(field);
ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT,
    new Phrase(LANGUAGES[i], font), 210, 790 - i * 40, 0);

You can find the C# version of these examples here: http://tinyurl.com/itextsharpIIA2C07

Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165
  • Which example relates to a checkbox? – Phil C Apr 08 '17 at 13:23
  • The time you needed to ask the question, is equal to the time you would have needed to find the answer yourself (with a little bit of effort): https://sourceforge.net/p/itextsharp/code/HEAD/tree/book/iTextExamplesWeb/iTextExamplesWeb/iTextInAction2Ed/Chapter08/Buttons.cs – Bruno Lowagie Apr 08 '17 at 13:45
  • Touche but that doesn't work for what I want to achieve. It has dependencies on Ionic for one. I'll post the question separately. – Phil C Apr 08 '17 at 13:50
  • I've added the question here. It's driving me nuts: http://stackoverflow.com/q/43294968/388267 – Phil C Apr 08 '17 at 14:02
  • The dependency on Ionic is irrelevant. You don't really need it if you don't create a ZIP file with the resulting PDFs. I looked at your question. I know you've deleted it, but my reputation is high enough to see deleted questions. There is no reference to a check box whatsoever in your code. My assumption is that you don't want to create a form, only display a check box. – Bruno Lowagie Apr 08 '17 at 20:22
  • Sure; I resolved the issue of displaying the checkbox. That's the reason I deleted the question (no need for answer to that specific question). Now I'm having issues with showing the checkbox as checked in the generated pdf. – Phil C Apr 09 '17 at 03:41
1

Creating a checkbox, and then accompanying text to its right, can be done like this:

PdfPCell cell204Submitted = new PdfPCell()
{
    CellEvent = new DynamicCheckbox("checkbox204Submitted")
};
tblFirstRow.AddCell(cell204Submitted);

// . . . Chunks and an anchor created; that code has been elided for brevity
Paragraph parCkbxText = new Paragraph();
parCkbxText.Add(Chunk204SubmittedPreamble);
parCkbxText.Add(ChunkBoldNote);
parCkbxText.Add(Chunk204Midsection);
parCkbxText.Add(anchorPayeeSetup204);
PdfPCell cellCkbxText = new PdfPCell(parCkbxText);
cellCkbxText.BorderWidth = PdfPCell.NO_BORDER;
tblFirstRow.AddCell(cellCkbxText);

public class DynamicCheckbox : IPdfPCellEvent
{
    private string fieldname;

    public DynamicCheckbox(string name)
    {
        fieldname = name;
    }

    public void CellLayout(PdfPCell cell, Rectangle rectangle, PdfContentByte[] canvases)
    {
        PdfWriter writer = canvases[0].PdfWriter;
        RadioCheckField ckbx = new RadioCheckField(writer, rectangle, fieldname, "Yes");
        ckbx.CheckType = RadioCheckField.TYPE_CHECK;
        ckbx.BackgroundColor = BaseColor.ORANGE;
        ckbx.FontSize = 6;
        ckbx.TextColor = BaseColor.WHITE;
        PdfFormField field = ckbx.CheckField;
        writer.AddAnnotation(field);
    }
}
B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862