+ Start a Discussion
AussieBattlerAussieBattler 

Toggle display based on Picklist selection

Hi. Perhaps I am over complicating this. I hope it is something simple I have missed.

Basically, I have a picklist on a page I have created and when the user changes the selection on the picklist I want to either show or hide parts of the screen (using ajax). My code below almost works (i.e.: the javascript function works but for some reason the variable I am storing the current state in appears to lose its value).

I have tried this a variety of ways but it always ends up with the same problem - I can see the value being assigned to the variable testval but when I want to render the section of the screen and make a call to get the testval value, the value has changed to being true all the time.

Can anybody assist?

Code:
<apex:page id="step4" controller="testpage" tabstyle="Enquiry__c">
<apex:form>
<script>
function currentval(id) {
var newval = document.getElementById(id).value;
switch (newval) {
case "1" :
var chgVal = '{!ToggleFalse}';
break;
default :
var chgVal = '{!ToggleTrue}';
break;
}
}
</script>

<apex:pageBlock title="test">
<apex:pageBlockSection title="test">
<apex:panelGrid columns="2" columnClasses="labelCol,dataCol">
<apex:outputLabel value="Picklist 1" for="picklist1"></apex:outputLabel>
<apex:inputField id="picklist1" value="{! testing.xyz__c}"></apex:inputField>
<apex:actionSupport event="onchange" onsubmit="currentval('{!$Component.picklist1}')" rerender="details"></apex:actionSupport>
</apex:panelGrid>
</apex:pageBlockSection>

<apex:outputPanel id="details">
<apex:pageBlockSection title="Details" rendered="{! hideshow}">
<apex:panelGrid columns="2" columnClasses="labelCol,dataCol">
<apex:outputLabel value="Name" for="personname"></apex:outputLabel>
<apex:inputField id="personname" value="{! testing.abcd__c}"></apex:inputField>
</apex:panelGrid>
</apex:pageBlockSection>
</apex:outputPanel>
</apex:pageBlock>
</apex:form>
</apex:page>



Code:
public class testpage {

testing123__c testing;

boolean testval = false;

public String getToggleTrue() {
testval = true;
return null;
}

public String getToggleFalse() {
testval = false;
return null;
}

public testing123__c gettesting() {
if (testing == null) testing = new testing123__c();
return testing;
}

public Boolean gethideshow() {
return testval;
}

}


 


Ron HessRon Hess
invoking controller actions from javascript is not currently supported, it may be supported in a future release.

So, you must put your getter/setter inside a component (
Therefore your actionSupport component should have an Action= and that controller action will be called to toggle the visibility flag. Then when the detail is re-rendered it can call the getter to determine the hideshow value.
AussieBattlerAussieBattler
Ah. I thought that might be the case but I couldn't get the getter/setter approach working as I couldn't work out how I could get the DETAIL section to re-render based on the selected value in the picklist (which is why I went down the javascript route).

Do you have any suggestions on this?

Many thanks for the response Ron.
Ron HessRon Hess
here is my understanding of your problem, perhaps i've oversimplified it.

i changed your code to work with the Account object since i didn't have your custom object in my developer org.


Code:
<apex:page id="step4" controller="testpage" tabstyle="Account">
<apex:form>

<apex:pageBlock title="test">
<apex:pageBlockSection title="test">
<apex:panelGrid columns="2" columnClasses="labelCol,dataCol">
<apex:outputLabel value="Picklist 1" for="picklist1"></apex:outputLabel>
<apex:inputField id="picklist1" value="{!testing.rating}"></apex:inputField>
<apex:actionSupport event="onchange" action="{!ToggleTrue}" rerender="details"></apex:actionSupport>
</apex:panelGrid>
</apex:pageBlockSection>

<apex:outputPanel id="details">
<apex:pageBlockSection title="Details" rendered="{!hideshow}">
<apex:panelGrid columns="2" columnClasses="labelCol,dataCol">
<apex:outputLabel value="Name" for="personname"></apex:outputLabel>
<apex:inputField id="personname" value="{!testing.Ownerid}"></apex:inputField>
</apex:panelGrid>
</apex:pageBlockSection>
</apex:outputPanel>
</apex:pageBlock>
</apex:form>
</apex:page>




---------------------- controller --------

public class testpage {

Account testing;

boolean testval = false;

public String ToggleTrue() {
testval = true;
return null;
}

public Account gettesting() {
if (testing == null) testing = new Account();
return testing;
}

public Boolean gethideshow() {
return testval;
}

}

 

AussieBattlerAussieBattler
Hi Ron. Many thanks for your assistance. The only thing missing is that I ony want the pageBlockSection to appear if the user selects a particular option from the picklist. For example, lets say the picklist has three options (Yes, No, Maybe) then only if the user selects YES do I want the pageBlockSection to be rendered, for all other options is stays hidden.

I hope that makes sense. Thanks again.
Ron HessRon Hess
I understand, here is a modified example that only shows the lower area if you select Warm in the picklist

Code:
<apex:page id="step4" controller="testpage" tabstyle="Account">
<apex:form>

<apex:pageBlock title="test">
<apex:pageBlockSection title="test">
<apex:panelGrid columns="2" columnClasses="labelCol,dataCol">
<apex:outputLabel value="Picklist 1" for="picklist1"></apex:outputLabel>
<apex:inputField id="picklist1" value="{!testing.rating}" ></apex:inputField>
<apex:actionSupport event="onchange" action="{!ToggleTrue}" rerender="details"></apex:actionSupport>
</apex:panelGrid>
</apex:pageBlockSection>

<apex:outputPanel id="details">
<apex:pageBlockSection title="Details" rendered="{!hideshow}">
<apex:panelGrid columns="2" columnClasses="labelCol,dataCol">
<apex:outputLabel value="Name" for="personname"></apex:outputLabel>
<apex:inputField id="personname" value="{!testing.Ownerid}" required="false" ></apex:inputField>
</apex:panelGrid>
</apex:pageBlockSection>
</apex:outputPanel>
</apex:pageBlock>
</apex:form>
</apex:page>


---------- controller
public class testpage {

Account testing;

boolean testval = false;

public String ToggleTrue() {
if ( testing.rating =='Warm') {
testval = true;
} else { testval = false; }
return null;
}

public Account gettesting() {
if (testing == null) testing = new Account();
return testing;
}

public Boolean gethideshow() {
return testval;
}

}

 

AussieBattlerAussieBattler
Thanks Ron. That did the trick. In otherwords I was being far more complicated than I needed to be.
AussieBattlerAussieBattler
Hi Ron. Sorry to be a pain but I do have one more question on the code and I am not sure if this is this a bug or if there is a workaround, but if I add an additional picklist below the first one (the second picklist behaves normally/no actions associated with it) is the ActionSupport component meant to fire everytime both picklists change?

Here is the slightly amended code and the controller code remains the same as in your example.

Code:
<apex:page id="step4" controller="testpage" tabstyle="Account">
<apex:form>

<apex:pageBlock title="test">
<apex:pageBlockSection title="test">
<apex:panelGrid columns="2" columnClasses="labelCol,dataCol">
<apex:outputLabel value="Picklist 1" for="picklist1"></apex:outputLabel>
<apex:inputField id="picklist1" value="{!testing.rating}" ></apex:inputField>
<apex:actionSupport event="onchange" action="{!ToggleTrue}" rerender="details"></apex:actionSupport>
<apex:outputLabel value="Picklist 2" for="picklist2"></apex:outputLabel>
<apex:inputField id="picklist2" value="{!testing.greeting}" ></apex:inputField>
</apex:panelGrid>
</apex:pageBlockSection>

<apex:outputPanel id="details">
<apex:pageBlockSection title="Details" rendered="{!hideshow}">
<apex:panelGrid columns="2" columnClasses="labelCol,dataCol">
<apex:outputLabel value="Name" for="personname"></apex:outputLabel>
<apex:inputField id="personname" value="{!testing.Ownerid}" required="false" ></apex:inputField>
</apex:panelGrid>
</apex:pageBlockSection>
</apex:outputPanel>
</apex:pageBlock>
</apex:form>
</apex:page>

 

Ron HessRon Hess
Here is a modified version that should only call the action method for the first picklist onchange

Code:
<apex:pageBlock title="test">
<apex:pageBlockSection title="test">

<apex:panelGrid columns="2" columnClasses="labelCol,dataCol">

<apex:outputLabel value="Picklist 1" for="picklist1" />
<apex:outputPanel>
<apex:actionSupport event="onchange" action="{!ToggleTrue}" rerender="details" />
<apex:inputField id="picklist1" value="{!testing.rating}" />
</apex:outputPanel>

<apex:outputLabel value="Picklist 2" for="picklist2" />
<apex:inputField id="picklist2" value="{!testing.industry}" />
</apex:panelGrid>
</apex:pageBlockSection>

<apex:outputPanel id="details">
<apex:pageBlockSection title="Details" rendered="{!hideshow}">
<apex:panelGrid columns="2" columnClasses="labelCol,dataCol">
<apex:outputLabel value="Name" for="personname" />
<apex:inputField id="personname" value="{!testing.Ownerid}" required="false" />
</apex:panelGrid>
</apex:pageBlockSection>
</apex:outputPanel>
</apex:pageBlock>
</apex:form>
</apex:page>

 

AussieBattlerAussieBattler
Yep. That did the trick. Thanks Ron.
dchasmandchasman
Spring '08 has a new support component called <apex:actionFunction> similar to <apex:actionSupport> that makes it a snap to invoke actions from javascript. Basically, you'll be able to use it like this:

<apex:form>
  <apex:actionFunction name="myActionFunction" action="{!theActionIWantToInvoke}"/>
</apex:form>

<script>
myActionFunction();
</script>




Message Edited by dchasman on 12-10-2007 08:23 AM
AussieBattlerAussieBattler
Hi Doug. Is this new function documented anywhere? Are there any other new functions also available?

In regards to your example, is that correct or should it be as amended below (based on the <apex:actionSupport> component (where the action attribute calls the function and event determines which event executes the function).

<apex:form>
  <apex:actionFunction name="myActionFunction" action="{!theActionIWantToInvoke}"/>
</apex:form>

<script>
theActionIWantToInvoke();
</script>
dchasmandchasman
Sorry the previous post should have read Spring '08 not Winter '08 for the release (already corrected that).

apex:actionFunction does not perform any event wiring - it basically generates a javascript stub that makes it easy to invoke the action method from any block of javascript (event handlers or whatever - totally up to you).
Jon KeenerJon Keener
I've been trying to reproduce this sample for some coding I'm doing.  Currenty, using the code here, it works fine in Firefox, but not in Internet Explorer 6.  In Internet Explorer 6, the "details" section does not become visible when "Warm" is selected from the picklist.  In firefox, it works fine.  From what I can tell, the "onchange" is not firing the code in the controller in IE6 correctly.