Convert Radio Button Groups to Checkbox Groups in PDF Forms

If you’ve worked with PDF forms, you are probably familiar with radio buttons:

Radiobutton

There is one problem with radio buttons: When you have a selection that also includes “non of the above”, you have to create a separate option for that: A radio button group – once selected – cannot be unselected.

Sometimes it would be useful to allow the user to unselect a radio button. This can be accomplished with a checkbox group:

Checkboxgroup

A checkbox group behaves just like a radio button group (e.g. only one option can be selected), but does allow you to have all options deselected by clicking on the currently selected item.

There is no automatic way to create these checkbox groups as for radio buttons, we have to manually apply the same name to all checkboxes that we want to be part of the group (on the “General” tab of the field properties), and then provide different export values for the different checkboxes in one group. This can be done on the “Options” tab of the field properties:

Options

The same tab also allows us to modify the style of the checkbox. To make it look more like a radio button, I usually select “Circle” as the check box style. As you can see from the screenshots above, the checkbox still has a square “box”, whereas a real radio button uses a round container, but the checkmark is now a black “dot” or circle, just like for a radio button.

If you’ve created a complex form with radio buttons, and your requirements for the form change late in the implementation phase, and all of a sudden you need to make sure that a radio button selection can be deselected, you will have to convert all radio button groups to checkbox groups.

This is may be a very cumbersome change for a complex form if done manually, but with the help of some JavaScript, we can make this change automatically with a few lines of JavaScript code.

If you run the following code in e.g. an Acrobat Action, all radio button groups will get converted to equivalent checkbox groups:

function processRB(f) {
	// try to get all the widgets
	var nWidgets = 0;
	var fields = [];
	while (true) {
		var w = this.getField(f.name + "." + nWidgets);
		if (w == null) break;
		// work with this widget:
		var w_info = {
			name: f.name,
			name2: w.name,
			rect: w.rect,
			style: w.style,
			display: w.display,
			page: w.page
		};
		fields.push(w_info);
		nWidgets++;
	}
	console.println("Found " + nWidgets + " widgets");
	var theExportValues = f.exportValues;
	var theName = f.name;
	var theStyle = f.style;
	var theDisplay = f.display;
	this.removeField(f.name);

	for (var rb in fields) {
		var fn = this.addField({
			cName: theName + "_CB",
			cFieldType: "checkbox",
			nPageNum: fields.page,
			oCoords: fields.rect
		});
	}
	var cb = this.getField(theName + "_CB");
	cb.exportValues = theExportValues;
	cb.style = theStyle;
	cb.display = theDisplay;
}


// iterate over all form fields and look for radio button groups
for (var i = 0; i < this.numFields; i++) {
	var f = this.getField(this.getNthFieldName(i));

	if (f.type == "radiobutton") {
		processRB(f);
	}
}

To “fine tune” this process, it would also be possible to run the conversion script only for radio buttons that have a certain name. You can do this by e.g. changing the loop in the last few lines to something like this:

// iterate over all form fields and look for radio button groups
for (var i = 0; i < this.numFields; i++) {
	var f = this.getField(this.getNthFieldName(i));

	if (f.type == "radiobutton") {
		var p = /RadioButtonGroup$/g;
		if (p.test(f.name)) {
			processRB(f);
		}
	}
}

This will only convert a group that is named “RadioButtonGroup”. You can come up with a more complex test for the name by using any method that JavaScript allows.

The same approach can also be used to change the type of other field typesΒ (e.g. change a number of text fields to drop down controls).

This entry was posted in Acrobat, JavaScript, PDF, Tutorial and tagged , , , , , . Bookmark the permalink.

40 Responses to Convert Radio Button Groups to Checkbox Groups in PDF Forms

  1. jay says:

    Karl,
    I’m not a programmer, so I’m not sure how to edit your JavaScript to convert other types of form fields. It would really help if you could give an example of how the script could be changed for other types of form fields, as in your example of changing text fields to drop down controls.

  2. Karl Heinz Kremer says:

    Jay, you can use something like this:


    function convertTextToDropdown(doc, f) {
    var theName = f.name;
    var rect = f.rect;
    var page = f.page;

    doc.removeField(f.name);
    doc.addField({
    cName : theName,
    oCoords : rect,
    nPageNum : page,
    cFieldType : "combobox"
    });
    }

    // iterate over all form fields and look for text fields
    for (var i = 0; i < this.numFields; i++) { var aFields = []; var f = this.getField(this.getNthFieldName(i)); if (f.type == "text") { aFields.push(f.name); } for (var j in aFields) { convertTextToDropdown(this, this.getField(aFields[j])); } }

  3. Sarah says:

    I need to change text fields into radio buttons. Can you please tell me how to manipulate the java script to achieve this? Thank you!

  4. srinivasan .R says:

    Can u explain how to unlock all field using javascript or else tell me how to check unlock fields in a entire document

  5. Karl Heinz Kremer says:

    Even though this has nothing to do with the blog post, here is some information about the “Locked” property: This checkbox only locks the properties of the field when using the properties dialog. The user can easily uncheck that box and get write-access to the properties again. There is no JavaScript equivalent to this checkbox, we cannot uncheck it or check it via JavaScript. However, you can modify the field, even though it may be locked, via JavaScript.

  6. Tucker Peterson says:

    I am hoping to change checkboxes INTO radio buttons.. what is the best way to do that?

  7. Karl Heinz Kremer says:

    Tucker, it looks like I missed your question when you posted it. Sorry about that. You can certainly change checkbox groups into radio buttons. When you look at the script, you should see how I am detecting radio buttons, and then getting all “widgets” for that control. You can do the same thing for widgets in a checkbox group. Just follow my example and look for widgets in a checkbox group, and then create a radio button group out of that information.

  8. Peter says:

    I tried to modify your script to change several Buttons in one document, all Buttons perform a mailto:xyz@abc.com, i want to change this to 123@abc.com, but i stuck. Is it possible to do this with JavaScript?

  9. Karl Heinz Kremer says:

    Peter, what you want to do is something completely different than to convert a group of boxes. You can add an action to a button via JavaScript (see the Field.setAction() method), but this will replace anything that was there before. This means you cannot just replace a string in an existing button action, you will have to know what was there before and recreate everything else that you may have to do when the button is pressed.

  10. Peter says:

    Thank you for your hint. I found a way to delete the old buttons and create new ones via js, but unfortunately the ios Reader does not support submitForm via js.

  11. Tim Farnan says:

    How do you run these scripts (in Acrobat DC)?

  12. Karl Heinz Kremer says:

    Tim, the same way as in Acrobat XI: Create an Action using the Action Wizard, then add a “Run JavaScript” action step to your Action and paste this script into the editor.

  13. Jafet says:

    Is there a way to allow for multi-checkboxes to be clicked?

  14. Karl Heinz Kremer says:

    Jafet, a group of checkboxes can have multiple selections, whereas a radio button group only allows one selected button.

  15. Mitch says:

    Wow!! Thank you so much for this. Just saved me at least an hour of tedious work.

  16. Anon says:

    Dude, You are a WIZARD! Thanks so much!

  17. Dan says:

    Hi There, I know this is an old article but, I tried using it and I’m getting an Syntax error; SyntaxError: syntax error
    1:Console:Exec
    undefined
    Not sure what to do to fix it, any help would be appreciated.

  18. Jill Stevens says:

    I have a form to create in Adobe Pro. 4 boxes to select from but the last button is an Opt out choice so the other 3 cannot be checked. How do I do that, using radio boxes?

  19. Karl Heinz Kremer says:

    Dan, without more information, it’s impossible to suggest a fix. How are you running the code? Which version of Acrobat do you have? Did you modify the code I posted, and if so, how?

  20. Karl Heinz Kremer says:

    Jill, I am sorry, but I don’t quite understand how your form is working. when you have radio buttons, you can only select one button at a time. So if you selected your opt-out button, you cannot select any other button without also deselecting the opt-out selection again.

  21. Dan says:

    Karl, I have Acrobat Pro DC (2015), I have not modified the code at all (it is exactly what I want to do), and have tried running the code from the debugger as well as attached to a temporary button placement. Thanks for the response.

  22. Sarah says:

    Hello, I am very unfamiliar with javaScript and would like to use this to change some radio buttons. Is there something I need to change in the posted javascript to relate specifically to my document?

  23. Karl Heinz Kremer says:

    Sarah, without knowing any JavaScript, you will not be able to recover if something goes wrong. In theory, you should not have to change anything, but usually, you don’t want to convert all radio button groups (and you do say “some” in your comment), so ideally, you would write a filter in JavaScript so that only those groups you want to have converted will get processed.

  24. Russell Mitchell says:

    Dan / others; If you encounter the same issue of the “syntax error”, make sure you highlight the code within the console before executing.

    Verified steps from the latest Acrobat Pro DC:
    1) Open the Javascript Toolbar via Tools -> Javascripts.
    2) Click “Debugger” on the toolbar.
    3) In the “View” section, select “Console” in the dropdown, then paste the code from Karl in the box.
    4) Highlight the code in the box, and press Ctrl + Enter on your keyboard.

  25. Joel E says:

    Thank you for this information. I was able to successfully convert the radio button group “sources” to checkboxes using your code; however, even though the properties indicate they are checkboxes, they still act like radio buttons (i.e. when I check one and then another, the check in the first goes away). What am I missing? Thanks.

    Version: Acrobat Pro XI

  26. Karl Heinz Kremer says:

    Joel, a checkbox group behaves exactly like a radio button group: Only one item can be selected at any given time. The only difference is that you can deselect all options, by clicking on the currently selected item. This is not possible with a radio button group. If you want a different behavior, you need to use different names for the individual checkboxes. Using the same name will create such a checkbox group. The script will always use a checkbox group (meaning that all buttons share the same name), but you can of course modify the script to adjust the output.

  27. Chris Frank says:

    Hi, Karl-

    I just ran onto your blog as I was searching for a way to convert checkboxes to radio buttons, fabulous resource.

    I tried running the script as written, just to see what happens, and it deleted existing radio buttons. (Trying this before trying to edit the script to do the opposite) I wonder what I’m doing wrong? Acrobat 11.

    I would be glad to pay you for the script to do the conversion from checkbox to radiobutton. In addition, I’m interested in getting you to create some plugins- for example, could you create a plugin (or a script) to convert all H1 tags to H2? What about table scoping, say, scoping top row to column and left column to row, globally, for all tables in a document?

    Thanks for your patience with a newbie!

  28. Karl Heinz Kremer says:

    Chris, I will reply by email to you directly.

  29. Amelia says:

    Apparently, my company does not give me permissions to edit or create Java Script πŸ™
    I tried doing the check boxes instead of radio buttons manually and I am not able to give them the same name/different export values as I had with my radio buttons.

  30. Karl Heinz Kremer says:

    Amelia, unfortunately, I don’t understand what you are asking for. Radio buttons and checkboxes should be able to be named the same way (and have the same export values). You just need to make sure that you remove your radio buttons before you add your checkboxes. You cannot have two fields with different types share the same field name.

  31. Gary says:

    Thank you for posting this. I have Acrobat forms form the IRS that other programs could not process because there was something unusual about the checkboxes, but modifying your script to simply replace the checkboxes with new checkboxes solved the problem. Thanks again.

  32. Gary Borek says:

    I followed Russell’s instructions for running the script in Acrobat DC, but still get the errors:

    Found 2 widgets
    Exception in line 32 of function processRB, script Console:Exec
    Exception in line 47 of function top_level, script Console:Exec

    RangeError: Invalid argument value.
    Doc.addField:32:Console undefined:Exec

    undefined

  33. Gary Borek says:

    When I run it from the console or as an action, it deletes the first two “buttons” (a yes and no choice) then stops with this error:

    “Found 2 widgets
    Exception in line 32 of function processRB, script Console:Exec
    Exception in line 47 of function top_level, script Console:Exec
    RangeError: Invalid argument value.
    Doc.addField:32:Console undefined:Exec
    undefined”

    line 32 is this: oCoords: fields.rect
    line 47 is this: processRB(f);

    Any idea what the problem might be?

  34. Yvan says:

    Hi Karl I have this script for a stamp that I modified for my use and it has 3 radio button selection in it and i would need the script to allow me to deselect the one so none of them are selected I’ve tried to run your script but it just end up deleting all 3 radio button not sure why. Im not sure if I can post the script in this post or if I could email your the script if you could help me out that would be great.

    Thanks

    Acrobat Pro X

  35. Karl Heinz Kremer says:

    Yvan – please email the script to me. My email address is on the About page. Make sure that you reference this comment in your email, so that I know what I am looking at πŸ™‚

  36. D says:

    Your script worked for me when I changed the following lines:

    nPageNum: fields[rb].page,
    oCoords: fields[rb].rect

    However, the checkboxes did not retain the tab order from the replaced radio buttons. Is that possible?

  37. Karl Heinz Kremer says:

    @D: Yes, that’s possible. The tab order is different from the order in which the script processes the fields, so the newly created fields would be inserted into the tab order in the order in which they were created. This means that you save some time by not having to manually create these fields, but you need to spend (a lot less) time to update the tab order.

  38. Nick Licouris says:

    Thanks for your script Karl, it’s been extremely useful to help gain some insight into Acrobat scripting syntax and for making conversions across multi-page documents. Unfortunately, I have several hundred PDF Forms where text fields are getting placed by the form detection instead of check boxes. I’ve been trying to modify your script to change a “text” field into a “checkbox” field, by basically doing the same process of creating a new field type with the same name and then deleting the original.

    I was wondering if you could point out what’s wrong in this particular script:

    function processCB(f) {
    console.println(“Doing ” + f.name);

    var theName = f.name;
    var theStyle = f.style;
    var theDisplay = f.display;
    var thePage = f.page;
    var theRect = f.rect;

    this.removeField(f.name);

    var newName = theName.substring(theName.indexOf(“_”)+1);

    var fn = this.addField({
    cName: newName,
    cFieldType: “checkbox”,
    nPageNum: thePage,
    oCoords: theRect
    });

    fn.exportValues = [ theName ];
    fn.style = theStyle;
    fn.display = theDisplay
    }

    // iterate over all form fields and look for text fields
    for (var i = 0; i < this.numFields; i++) {
    var f = this.getField(this.getNthFieldName(i));

    if (f.type == "text") {
    processCB(f);
    –i;
    }
    }

    Any guidance you can offer would be greatly appreciated, the project to convert all of these PDF's to make them usable has been a nightmare.

    Thanks again!

  39. Nick Licouris says:

    Also, just noticed Sarah asked essentially the same thing previously, so my apologies if I missed the explanation somewhere. Thanks again for all your expertise and assistance.

  40. Warren says:

    Hi Karl, THANK YOU!!! And I hope the below can help others πŸ™‚

    I had issues with this script. First, it didn’t work until I did what D said:
    nPageNum: fields[rb].page,
    oCoords: fields[rb].rect

    Then I had some display issues so I put the “cb” block in the loop.

    Then, I’ve overriden the export value to be “on” just like my other fields.

    And finally, I added another bit at the end to change every checkbox (including the new ones) to have the check mark style.

    Like I said, I hope this helps others the way you have helped me πŸ™‚

    function processRB(f) {
    // try to get all the widgets
    var nWidgets = 0;
    var fields = [];
    while (true) {
    var w = this.getField(f.name + “.” + nWidgets);
    if (w == null) break;
    // work with this widget:
    var w_info = {
    name: f.name,
    name2: w.name,
    rect: w.rect,
    style: w.style,
    display: w.display,
    page: w.page
    };
    fields.push(w_info);
    nWidgets++;
    }
    console.println(“Found ” + nWidgets + ” widgets”);

    var theExportValues = f.exportValues;
    var theName = f.name;
    var theStyle = f.style;
    var theDisplay = f.display;
    this.removeField(f.name);

    for (var rb in fields) {
    console.println(” Doing widget #” + rb);
    var fn = this.addField({
    cName: theName + “_CB” + rb,
    cFieldType: “checkbox”,
    nPageNum: fields[rb].page,
    oCoords: fields[rb].rect
    });

    var cb = this.getField(theName + “_CB” + rb);
    //cb.exportValues = theExportValues;
    cb.exportValues = [“On”];
    cb.style = theStyle;
    cb.display = theDisplay;
    }
    }

    // iterate over all form fields and look for radio button groups
    for (var i = 0; i < this.numFields; i++) {
    var f = this.getField(this.getNthFieldName(i));

    if (f.type == "radiobutton") {
    processRB(f);
    }
    }

    // iterate over all form fields and convert checkboxes to the check style
    for (var j = 0; j < this.numFields; j++) {
    var f = this.getField(this.getNthFieldName(j));

    if (f.type == "checkbox") {
    f.style = style.ch
    }
    }

Leave a Reply

Your email address will not be published. Required fields are marked *