Skip to main content
Saher Naji
Inspiring
November 29, 2022
Answered

Show and hide layers based on radio buttons options

  • November 29, 2022
  • 2 replies
  • 4936 views

Hello there,

I have thousands of layers here, I want to edit this JavaScript code to make it working well with radio buttons case,

Now when I check on an option, the layer appears (the red circle), and when I click on the same option again, it disappears, (this is perfect when I hava a button to show and hide some insturctions, or hints)

 

But what I'm looking for in this case, make the layer disappears once I click on the second option or third.. etc, and of course the layer of the second option appears, and so on..

this is the code:

var layers = this.getOCGs();
for(var i=0;i<this.layers.length;i++)
{
if(layers[i].name == "a_1_0")
layers[i].state = !(layers[i].state);
}

also I tried to use this code, and give the same result:

var layerName = "a_1_0";
var layers = this.getOCGs();
if (layers!=null && layers.length!=0) {
for (var i in layers) {
if (layers[i].name==layerName) {
layers[i].state = !layers[i].state;
break;
}
}
}

 

 

 

 

Thank you very much

 

This topic has been closed for replies.
Correct answer Thom Parker

So first off, you're creating code that performs a complex action. You need to do a little debug to understand the different parts of this process and how it's working. Have you done anything to firgure out why it's taking two clicks? 

 

Next. Are you saying the layers are only for adding circles to the radio buttons?  Why not just set the border properties of the radio button?

You can turn the circle border of a radio button on and off with the lineWidth Property. Here's an update to the code that does this. 

function SetLayerStateFromRadioButton(){
	event.target.exportValues.forEach(function(cVal,i){
		oWidget = this.getField(event.targetName + "." + i);
		oWidget.lineWidth = (cVal == event.value)?2:0;
		oWidget.borderColor = (cVal == event.value)?color.black:["T"];
	});
}

 

2 replies

Thom Parker
Community Expert
Community Expert
November 29, 2022

 

 

The code you've shown toggles the state of a specific OCG layer. It does not change the layer state based on the checkbox state.  Is this code in the MouseUp?  

The code works because there is a one to one relationship between the checkbox and a layer. With radio buttons you now have a one to many relationship.  The name of the previously modified layer needs to be saved, so that it can be hidden before the newly selected layer is shown. 

 

The best approach is to have some way to directly associate the specific radio button with a specific layer.  To do this, set the "Choice/Export" Value of the radio button to the name of the OCG layer.  Now you can use a generic script to hide and show layers.  

The best way to do this is with a validation script on the radio buttons. Unfortunately the validation event script is no exposed for a radio button. Fortunately it is there and can be set through a script.

 

Do this

1)  Add the following function definition to a Document Script

 

// Validation script for radio buttons
function SetLayerStateFromRadioButton(){
   // In validation, the actual field value has not changed
    var strOldLayer = event.target.value;
    // In validation, the new value is in the event, not the field
    var strNewLayer = event.value;

    // Set counter used to detect when the OCG search is finished
       // Advance counter if no old layer was selected
    var nCnt = (strOldLayer == "Off")?1:0;

    var layers = this.getOCGs();
    if (layers!=null && layers.length!=0) {
        for (var i in layers) {
           if (layers[i].name==strOldLayer ){
                 nCnt++;
                 layers[i].state = false;
           }
           else if (layers[i].name==strNewLayer ){
                 nCnt++;
                 layers[i].state = true;
           }
           if(nCnt == 2)
                 break;
       }
    }
}

 

 

 

 

2) Run this code in the console window to set all of the radio button validation scripts

 

 

var oFld;
for(var i=0;i<this.numFields;i++){
    oFld = this.getField(this.getNthFieldName(i));
    if(oFld.type == "radiobutton")
       oFld.setAction("Validate", "SetLayerStateFromRadioButton()");
}

 

 

 

Thom Parker - Software Developer at PDFScriptingUse the Acrobat JavaScript Reference early and often
Saher Naji
Inspiring
November 29, 2022

Thank you @Thom Parker,

It's working, but I have to click twice on each number, watch this short video please

and the important thing is:  Export Values of the radio buttons are important to use in calculations, I can't use the name of layer instead of 0, 1, 2, 3!

https://clipchamp.com/watch/eDohdUlvooI

 

I was forced to choose this hard way because I want to circle the numbers, and the available styles for radio buttons do not have an empty circle or an empty square with a border
Is it possible to write code to change the those styles?

This will save the time, and it will be the ideal way

and to be honest, @Nesa Nurani offered a solution, in a previous discussion, but the solution would take too long, (Also my solution!)
The problem is that the form I'm working on is long and contains hundreds of questions

Thank you

Saher Naji
Inspiring
November 30, 2022

So first off, you're creating code that performs a complex action. You need to do a little debug to understand the different parts of this process and how it's working. Have you done anything to firgure out why it's taking two clicks? 

 

Next. Are you saying the layers are only for adding circles to the radio buttons?  Why not just set the border properties of the radio button?

You can turn the circle border of a radio button on and off with the lineWidth Property. Here's an update to the code that does this. 

function SetLayerStateFromRadioButton(){
	event.target.exportValues.forEach(function(cVal,i){
		oWidget = this.getField(event.targetName + "." + i);
		oWidget.lineWidth = (cVal == event.value)?2:0;
		oWidget.borderColor = (cVal == event.value)?color.black:["T"];
	});
}

 


@Thom Parker

 

This is what I'm looking for from the beginning,
Now, I can say there is no need to the crazy layers idea

 

THANK YOU VERY MUCH♥

 

 

try67
Community Expert
Community Expert
November 29, 2022

It's not enough to specify which layer to show, you also need to tell it which one(s) to hide.

I would use an array with layer names in the group and apply those same names as the export values of the radio-buttons. Then use a (hidden) text field's Calculate event to trigger showing/hiding those layers, based on the value of the radio-button group.

Saher Naji
Inspiring
November 29, 2022

Thanks @try67

Actually I don't want to change the export values, because I will need them for the calculations

I'm going to work on hundreds of questions, and therefore thousands of radio-buttons.

Do you think there is another way to change styles of the buttons?