Embed a Flex Slider in a Visualforce Page

October 29th, 2009

I did a simple Flex callback with JavaScript about a year ago and I always wanted to follow up with this topic. Somehow I never quite found the time. This is an example of how you can create a Flex component (a horizontal slider in this case), wrap it up as a Visualforce component and then make it reusable in your Visualforce pages. This technique provides you with some great ways to add “eye candy” to your Visualforce pages without breaking the UI model.

You can run this example on my Developer Site.

FlexSlider

The Flex component is simply a wrapper around the standard HSlider control. It expects some setup values to be passed into it and then when the users moves the slider, it makes a callback to a JavaScript function in the Visualforce page to update the value in the record. It’s loosely coupled so that you can pass in the values, the name of the JavaScript function to call and the ID of the DOM property to update.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
 
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
	layout="absolute" alpha="1.0" backgroundGradientAlphas="[0,0,0,0]"
	creationComplete="init()">
 
<mx:Script>
	<![CDATA[
		import flash.external.ExternalInterface;
		import mx.events.SliderEvent;
 
		// bind the variables so that can be notified of value updates
        [Bindable] private var slideInterval:int;
        [Bindable] private var minSliderValue:int;
        [Bindable] private var maxSliderValue:int;
        [Bindable] private var sliderLabels:Array = new Array();
        [Bindable] private var sliderTickValues:Array = new Array();
        [Bindable] private var callbackFunction:String;
        private var startSliderValue:int;
        private var boundDomId:String;
 
		// method to be called immediately after component is created
		private function init():void {
 
			// set some values passed in from the Visualforce page
			startSliderValue = this.parameters.startSliderValue;
			minSliderValue = this.parameters.minSliderValue;
			maxSliderValue = this.parameters.maxSliderValue;
			slideInterval = this.parameters.slideInterval;
			// add the min & max as the slider labels
			sliderLabels.push(minSliderValue,maxSliderValue);
			// add the min & max as the slider values
			sliderTickValues.push(minSliderValue,maxSliderValue);
 
			// set name of the callback javascript function
			callbackFunction = this.parameters.callbackFunction;
			// set the id of the DOM element attached to the slider so we can reference it
			boundDomId = this.parameters.boundDomId;
 
			// set the values initially for the component
			mySlider.tickValues = sliderTickValues;
			mySlider.labels = sliderLabels;
			mySlider.value = startSliderValue;
 
			// set the background color of the flex component so it matches the page
			Application.application.setStyle("backgroundColor",this.parameters.bgColor ? this.parameters.bgColor : "#F3F3EC");
 
		}
 
		// notify the external interface that the slider was changed
		public function handleSliderChange(evt:SliderEvent):void {
			ExternalInterface.call(this.callbackFunction,evt.currentTarget.value,this.boundDomId);
		}
	]]>
</mx:Script>
 
<mx:HSlider
	id="mySlider"
	minimum="{minSliderValue}"
	maximum="{maxSliderValue}"
	snapInterval="{slideInterval}"
	tickValues="{sliderTickValues}"
	labels="{sliderLabels}"
	allowTrackClick="false"
	liveDragging="false"
	change="handleSliderChange(event)"/>
 
</mx:Application>

So that I can reuse slider, I created a Visualforce component with it that can be embedded into other Visualforce pages. I’ve included a default JavaScript function but you can override it with your own in the embedded Visualforce page if needed. There are a number of attributes included which make for handy syntax coding in the browser and Eclipse.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 
<apex:component >
 
    <script language="JavaScript" type="text/javascript">
        function updateHiddenValue(value, eId){
            var e = document.getElementById(eId);
            e.value = value;
        }
    </script>
 
    <apex:attribute name="minSliderValue" description="Minimum slider value" type="Integer" required="true"/>
    <apex:attribute name="maxSliderValue" description="Maximum slider value" type="Integer" required="true"/>
    <apex:attribute name="startSliderValue" description="Starting value of the slider" type="Integer" required="false" />
    <apex:attribute name="slideInterval" description="The tick interval that the slider can be moved" type="Integer" default="1" required="false" />
    <apex:attribute name="callbackFunction" description="The name of the JavaScript function that is called by the Flex components and passes the bound value of the slider. By default the component uses updateHiddenField but you can override it with your own." type="String" default="updateHiddenValue" required="false" />
    <apex:attribute name="boundDomId" description="The $Component id of the DOM element bound to the slider value's. The slider's change event passes the value of boundDomId back to the JavaScript function." type="String" required="false"/>
    <apex:attribute name="height" description="The height of the slider" type="Integer" default="50" required="false" />
    <apex:attribute name="width" description="The width of the slider" type="Integer" default="200" required="false" />
    <apex:attribute name="bgColor" description="The background color of the flex component so it matches the page. Defaults to Salesforce gray." type="String" default="#F3F3EC" required="false" />
 
    <apex:flash src="{!$Resource.FlexSlider}"
        height="{!height}"
        width="{!width}"
        flashVars="minSliderValue={!minSliderValue}&maxSliderValue={!maxSliderValue}
                &startSliderValue={!startSliderValue}&slideInterval={!slideInterval}
                &callbackFunction={!callbackFunction}&boundDomId={!boundDomId}&bgColor={!bgColor}" />
 
</apex:component>

So now that you have your Flex slider built and uploaded as a Static Resource you can build your Visualforce page using your new component. If you want to pass more parameters into the component from your Visualforce page, you add them to the FlexSliderComponent attributes based up what is available from the component itself.

So now when you move the slider in the Flex component, it makes a callback to your Visualforce page to a JavaScript function which updates the value of the “geek factor” field in the record. When you save the record, that value is update.

When using the demo link above, after submitting the form you will see a white page. This is because I am lazy. You’ll have to go back and reload the form to see the value change.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 
<apex:page standardController="Person__c">
 
  <apex:sectionHeader title="{!Person__c.First_Name__c} {!Person__c.Last_Name__c}" subtitle="Flex Slider Example"/>
 
  <apex:form id="myForm">
        <apex:pageBlock title="Geek Rating" id="myBlock" mode="edit">
            <apex:pageBlockButtons >
                <apex:commandButton value="Save" action="{!save}"/>
                <apex:commandButton value="Cancel" action="{!cancel}" />
            </apex:pageBlockButtons>
            <apex:pageMessages />
 
            <apex:pageBlockSection id="ratings" showHeader="true" title="Contact Info" columns="2">
 
                <apex:inputField value="{!Person__c.First_Name__c}"/>
                <apex:pageBlockSectionItem >
                    <apex:outputLabel value="Geek Factor Slider"/>
                    <c:FlexSliderComponent minSliderValue="0" maxSliderValue="10"
                                      startSliderValue="{!Person__c.Geek_Factor__c}"
                                      boundDomId="{!$Component.ratings.geekfactor}" />
                </apex:pageBlockSectionItem>
 
                <apex:inputField value="{!Person__c.Last_Name__c}"/>
                <apex:inputField id="geekfactor" value="{!Person__c.Geek_Factor__c}" />
 
            </apex:pageBlockSection>
        </apex:pageBlock>
  </apex:form>
 
</apex:page>
VN:F [1.9.22_1171]
Rating: 7.0/10 (3 votes cast)
VN:F [1.9.22_1171]
Rating: +2 (from 2 votes)
Embed a Flex Slider in a Visualforce Page, 7.0 out of 10 based on 3 ratings

Categories: Code Sample, Flex, Salesforce, Visualforce

Leave a comment

Comments Feed6 Comments

  1. Wes

    ooooh! Now that’s pretty frikkin cool:)

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.22_1171]
    Rating: +1 (from 1 vote)
  2. Ron Hess

    well done !

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.22_1171]
    Rating: 0 (from 0 votes)
  3. Forcedotcom

    Great job as always Jeff

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.22_1171]
    Rating: 0 (from 0 votes)
  4. Flash Components

    Thanks for this detailed examples.
    yeah, due to Visualforce component the slider can be reused.
    Nice work!

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.22_1171]
    Rating: 0 (from 0 votes)
  5. Eluladaby

    Many of people write about this matter but you wrote down really true words.

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.22_1171]
    Rating: 0 (from 0 votes)
  6. FlexMonster

    Nice work!
    But … what the size of swf file? 200-300K? I think javascript is better.

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
    VA:F [1.9.22_1171]
    Rating: 0 (from 0 votes)

Leave a comment

Feed

http://blog.jeffdouglas.com / Embed a Flex Slider in a Visualforce Page