After looking at a LOT of posts, I've concluded that I'm confused on exactly how input checkboxes behave. I've created a custom wrapper class around a select option that looks like list<string boxId, boolean selected, string Option, string Descr>MS
.
As it turns out, it appears that inputcheckboxes won't allow me to use anything other than an actual textstring for an Id. As in it won't allow me to assing a variable to it. Is that correct behavior? I'd like to first confirm that is what's expected and it doesn't have anything to do with something else I've done.
That issue aside, it seems that I'm having difficulty retrieve the value of the checkbox when it's been checked. I've attempted several different methods, so am getting rather perplexed. I want to assign the value to the "selected" variable in the wrapper class which I've also been using in the code on my page which has been assigned an initial value of "false". Here's the most recent iteration of the relevant code and related portions of the controller. I look forward to being enlightened.
Page:
<apex:pageBlockSection Title="Call Types" id="chckbxs" collapsible="false" >
<apex:pageBlockTable width="100%" id="data" value="{!MS}" var="m" align="center" >
<apex:column id="col1" >
<apex:outputLabel value="{!m.Option}" >
<apex:inputCheckbox value="{!m.selected}" styleClass="$('.'+{!m.boxId}+'_box')" label="{!m.Option}" onselect="assignSelectedJS(m.boxId,m.selected,m.Option,m.Descr)" onclick="$('.'+{!m.boxId}+'_descr').toggle();"/>
</apex:outputLabel>
<apex:outputLabel value="{!m.Descr}" styleClass="$('.'+{!m.boxId}+'_descr')" >
<apex:inputTextarea label="{!m.Descr}" value="{!m.Descr}" styleClass="$('.'+{!m.boxId}+'_descr')" />
</apex:outputLabel>
</apex:column>
</apex:pageBlockTable>
<apex:actionFunction action="{!assignSelected}"
name="assignSelectedJS" rerender="chckbxs">
<apex:param name="boxId" assignTo="{!m.boxId}" value="" />
<apex:param name="selected" assignTo="{!m.selected}" value="" />
<apex:param name="Option" assignTo="{!m.Option}" value="" />
<apex:param name="Description" assignTo="{!m.Descr}" value="" />
</apex:actionFunction>
</apex:pageBlockSection>
<apex:commandButton value="Save Selected" action="{!ProcessSelected}" rerender="thePage" immediate="true">
</apex:commandButton>
In case you're wondering, I'd like the description box to show/hide when the checkbox is clicked, thus the reason for the some of the code that you're seeing, but that's secondary to what I'm trying to learn because right now, I'm not seeing the values for the checkboxes appear in the controller when checked. Also, this code is far different than what I started with. I'm just putting up something you can look at, so I can learn how this needs to be done. I'm tired of wandering in circles in the forest!
Controller:
Controller {
public void assignSelected(){
// cycle through list of SelectOptions and check to see if true
for(ssOption m : MS) {
if(m.selected == true) {
selectedOptions.add(m.boxId);
posOption.put(m.boxId,m.Option);
posDesc.put(m.boxId,m.Descr);
}
}
}
public pageReference processSelected() {
Do something with selected...
list<Task>ntsks = new list<Task>();
For(string b:selectedOptions){
task t = new task( Description = posDesc.get(b).....;
ntsks.add(t);
}
if(ntsks.isEmpty() == false) Database.SaveResult[] lsr = Database.insert(ntsks,false);
}
}
Best Answer
I'll update this with an additional version that uses an
actionFunction
in the way that it appears you're trying to use it... but wanted to start with this base.Update: ActionFunction version added down below. It demonstrates the concept, but isn't 100% functional from a requirements perspective in the same way that the actionSupport version is primarily because of the lifecycle of the operations in this page.
Nothing fancy initially, just
actionSupport
to provide the rerenderonchange
event to the checkbox. Removed thestyleClass
attributes written in a jQuery-like selector syntax as they don't directly contribute to the solution.This page maintains the collection of all items (selected and non) in the page viewstate along with all of the other bits of data contained in the wrapper class instances.
Non-actionFunction version
VF markup:
The controller:
ActionFunction version
The actionfunction has 4 named parameters on it, these show up in the parameters collection in the controller just as URL params and all of the other form data. The parameter values from calling the actionfunction will be available there and don't necessarily need to be assigned to a controller member using the
assignTo
syntax.Data is passed to the actionfunction the same way you would with any JS function params. In this case 3 of them are strings populated with data from merge fields and the 4th is the
checked
attribute of the checkbox DOM element.onchange="assignSelectedJS('{!ssOpt.boxId}', this.checked, '{!ssOpt.Option}', '{!ssOpt.Descr}');"
The page:
The controller: