You need to sign in to do that
Don't have an account?

Field value not being set in VisualForce component
Hi,
I have a VisualForce component that presents a SelectList of TimeZones using a jQuery dialog. I have used an "onChange" event on the SelectList with action support that attempts to return the selected value using action support.
All seems to work ok, but the selected time zone does not appear to be set; at least it comes through as a null on the setter.
I have tried all kinds of things but cannot get this to work properly - - I have used this technique successfully elsewhere, though not in a component.
Here are the relevant code excerpts:
The component
The component controller:
NB: The component was working perfectly until I turned into a jQuery modal dialog!
I have a VisualForce component that presents a SelectList of TimeZones using a jQuery dialog. I have used an "onChange" event on the SelectList with action support that attempts to return the selected value using action support.
All seems to work ok, but the selected time zone does not appear to be set; at least it comes through as a null on the setter.
I have tried all kinds of things but cannot get this to work properly - - I have used this technique successfully elsewhere, though not in a component.
Here are the relevant code excerpts:
The component
<apex:component controller="TimeZonePickerController"> <apex:includeScript value="{!URLFOR($Resource.jQuery, 'jquery-ui-1.12.1.custom/external/jquery/jquery.js')}"/> <apex:includeScript value="{!URLFOR($Resource.jQuery, 'jquery-ui-1.12.1.custom/jquery-ui.js')}"/> <apex:stylesheet value="{!URLFOR($Resource.jQuery, 'jquery-ui-1.12.1.custom/jquery-ui.css')}"/> <script> // Create a new alias for jQuery (j$) var j$ = jQuery.noConflict(); // When document loaded show the dialog j$(document).ready(function(){ j$("#dialog").dialog( { title:"Select a Time Zone", autoOpen: false, width:510, height:70, modal:true, closeable:false, resizable:false, draggable:true }); j$("#dialog").dialog('open'); }); function closeTheDialog() { j$('#dialog').dialog('close'); } function tzChanged(chosenTz) { // Perform the action - call to Apex doAction(); // Close the dialog closeTheDialog(); } </script> <apex:attribute name="attrTimePickerData" assignTo="{!theData}" description="" type="TimePickerData"/> <div id="dialog"> <apex:outputPanel > <apex:selectList id="TimeZone" value="{!selectedTimeZoneStr}" size="1" onchange="tzChanged(this);"> <apex:selectOptions value="{!TimeZones}"/> </apex:selectList> <apex:actionFunction name="doAction" action="{!selectTz}"/> </apex:outputPanel> </div> </apex:component>
The component controller:
public with sharing class TimeZonePickerController { public TimePickerData theData; public List<SelectOption> TimeZones {get; set;} public String selectedTimeZoneStr; private boolean timeZonesFetched = false; public TimeZonePickerController() { } public TimePickerData getTheData() { return theData; } public void setTheData(TimePickerData argTheData) { theData = argTheData; // Establish time picker settings for the given type // (Using setter because it is the first time the class TimePickerData is populated) buildTimeZoneList(); // Default timezone to user's if not already set if (string.isNotBlank(theData.selectedTimeZoneStr)) { selectedTimeZoneStr = theData.selectedTimeZoneStr; } else { selectedTimeZoneStr = UserInfo.getTimeZone().getID(); } } public String getSelectedTimeZoneStr() { return selectedTimeZoneStr; } public void setSelectedTimeZoneStr(String argSelectedTimeZoneStr) { system.debug('---------- TZ PICKER COMPONENT - setSelectedTimeZoneStr: Start - Value: ' + argSelectedTimeZoneStr); selectedTimeZoneStr = argSelectedTimeZoneStr; system.debug('---------- TZ PICKER COMPONENT - setSelectedTimeZoneStr - Value: ' + argSelectedTimeZoneStr); // Set the TimeZone as string and Timezone for return to calling page theData.selectedTimeZoneStr = selectedTimeZoneStr; // theData.selectedTimeZone = TimeZone.getTimeZone(theData.selectedTimeZoneStr); system.debug('---------- TZ PICKER COMPONENT - setSelectedTimeZoneStr: End'); } public PageReference selectTz() { // Close the dialog - does this work? theData.displayTzPicker = false; system.debug('---------- TZ PICKER COMPONENT - selectTz - Str value: ' + selectedTimeZoneStr); system.debug('---------- TZ PICKER COMPONENT - selectTz - The Data value: ' + theData.selectedTimeZoneStr); return null; } public void buildTimeZoneList() { // Already fetched? if (timeZonesFetched) { return; } // Build timezones TimeZones = new List<SelectOption>(); Schema.DescribeFieldResult fieldResult = User.TimeZoneSidKey.getDescribe(); // Descibes the field in an object (User in this case) List<Schema.PicklistEntry> PkListEntry = fieldResult.getPicklistValues(); // Returns the picklist options for( Schema.PicklistEntry pkEnt : PkListEntry) { TimeZones.add(new SelectOption(pkEnt.getValue(), pkEnt.getLabel())); } timeZonesFetched = true; } }
NB: The component was working perfectly until I turned into a jQuery modal dialog!
Hello Rusty,
To set the value in the controller, try adding a apex:param to apex:actionfunction and then you can pass the selected value as a parameter of your doAction function.
To read more about:
https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_compref_actionFunction.htm
Hope to have helped!https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_compref_param.htm
Furthermore, an action function must be a child of an apex:form. So with a few changes your VF should look like this:
Regards.
Don't forget to mark your thread as 'SOLVED' with the answer that best helps you.
I added the param and the call within the js, but still not setting. I have similar code working in a page that is not within a component; feels like this may be an issue with using a component.
ps: The component itself is within a form so cannot add another form. However, the action function is firing, I can even see the selected value in a js alert, but it is not getting set in the controller.
Here are the relevant code excerpts for completeness (ps renamed "doAction" to "chooseTz" to make the code more specific:
Thanks