Search code examples
c#.netabcpdf

abcPDF eForm Radio Fields - Value Options Contain Special Characters


I am trying to use abcPDF to fill form fields, and I am running into problems when selecting certain radio buttons. The form I am working on has several radio button fields, most of which I am able to set the following way:

Doc theDoc = new Doc();
theDoc.Read(Server.MapPath("fileName.pdf"));
Field areYouHappy = theDoc.Form["Q28_happy"];
areYouHappy.Value = areYouHappy.Options[0]; // set Field areYouHappy to Option 0 (yes)
theDoc.Save(Server.MapPath("newFileName.pdf"));

This works swimmingly for most of the buttons, but some are not being set properly (or rather, at all). The only difference between the functioning and faulty buttons is the Field's options helper text or name.

For example the broken fields, when viewed in debugger, have the following options:

Options[0] "If your answer is �Yes,� select this option."
Options[1] "If your answer is �No,� select this option."

In contrast to the functional fields:

Options[0] "If you're happy and you know it, select this option."
Options[1] "Clap your hands, select this option."

It appears either a non-unicode character is being used in the Field object's Option object, or perhaps a non-escaped ", that results in , but it seems strange that this would be interfering with checking the right radio button, since I pass it an index anyway.

I've tried "renaming" the Option values in code by doing the following:

Field areYouHappy = theDoc.Form["Q28_happy"];
areYouHappy.Options[0] = areYouHappy.Options[0].RemoveSymbols();
areYouHappy.Options[1] = areYouHappy.Options[1].RemoveSymbols();
areYouHappy.Value = areYouHappy.Options[0];

but this does not work, although the debugger shows RemoveSymbols is doing its job:

Options[0] "IfyouranswerisYesselectthisoption."
Options[1] "IfyouranswerisNoselectthisoption."

Does abcPDF have a way of setting radio buttons that have values with 'special characters' in them, or is there a way to change those option values themselves?


Solution

  • I reached out to the WebSupergoo team, and they were extremely helpful. They explained there wasn't a way to select the radio buttons by some sort of index, and that the strings each option refers to has to match the string in the form option.

    To that end, there is no way to select the radio button without interacting with the Option object's string, and since the string is malformed, the normal option select code is not working.

    As a work-around, in case anyone else finds themselves in my shoes, the WebSupergoo team provided this function:

    /// <summary>
    /// Checks each field to ensure it has properly formatted options
    /// </summary>
    /// <param name="field"></param>
    /// <returns>An array of options that have been safely formatted</returns>
    private static string[] VetField(Field field)
    {
        List<string> options = new List<string>();
        foreach (Field kid in field.Kids)
        {
            bool different = false;
            DictAtom ap1 = kid.Resolve(Atom.GetItem(kid.Atom, "AP")) as DictAtom;
            if (ap1 == null) continue;
            DictAtom ap2 = new DictAtom();
            foreach (var pair1 in ap1)
            {
                DictAtom apType1 = kid.Resolve(pair1.Value) as DictAtom;
                Debug.Assert(apType1 != null); // should never happen
                DictAtom apType2 = new DictAtom();
                ap2[pair1.Key] = apType2;
                foreach (var pair2 in apType1)
                {
                    string name1 = pair2.Key;
                    StringBuilder sb = new StringBuilder();
                    foreach (char c in name1)
                    {
                        if (c < 128)
                            sb.Append(c);
                    }
                    string name2 = sb.ToString();
                    if (name1 != name2)
                        different = true;
                    apType2[name2] = pair2.Value;
                    if (pair1.Key == "N")
                        options.Add(name2);
                }
            }
            if (different)
                    ((DictAtom)kid.Atom)["AP"] = ap2;
        }
        return options.ToArray();
    }
    

    which checks the Option field's strings for formatting issues, and returns a sanitized list of options. So, using the code in the question as an example, I would be able to properly select option radio buttons by doing the following:

    Doc theDoc = new Doc();
    theDoc.Read(Server.MapPath("fileName.pdf"));
    
    Field areYouHappy = theDoc.Form["Q28_happy"];
    string[] options = VetField(areYouHappy); //uses above function to check for formatting errors
    
    areYouHappy.Value = options[0];
    theDoc.Save(Server.MapPath("newFileName.pdf"));
    

    This method works great, and I hope it can help someone else in the future!