function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student 

Survey Object and slider for rating field

Hey,

 

Basically my plan is to create a simple object with maybe even 5 fields. One of these fields will either be a number field or a picklist field (numbered 1-10). A visualforce page is created for the object with the number/picklist depicted as a slider. The goal is to have this survey sent to clients and then once they fill it out, it will insert itself into their account? 

How would I go about doing this?

I have tried very hard to get the slider bar working, there are many many people that have posted how to do it but I can not seem to get it working? I do not know if I am uploading J querry wrong or if I am not altering it well enough?

 

Please help

 

Mikie

Best Answer chosen by Admin (Salesforce Developers) 
GlynAGlynA

Once you have the original code working with the static resource, try this version.  You will have to give it the ID of an Account record, any account will do, because I am using the numeric field 'NumberOfEmployees' on Account to demonstrate how to put the slider value into an inputField component.  Load the page with something like this:

 

<your org URL>/apex/<your page name>?id=<id of an Account>

 

<apex:page standardController="Account">

<apex:includeScript value="{!URLFOR($Resource.JQuery, '/js/jquery-1.9.1.js')}"/>
<apex:includeScript value="{!URLFOR($Resource.JQuery, '/js/jquery-ui-1.10.3.custom.min.js')}"/>
<apex:stylesheet value="{!URLFOR($Resource.JQuery, '/css/ui-lightness/jquery-ui-1.10.3.custom.css')}"/>

<apex:form id="theForm">
<apex:pageBlock id="theBlock">
<apex:pageBlockSection id="theSection">
    <apex:inputField value="{!Account.NumberOfEmployees}" id="value"/>
    <div id="slider"/>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>


<script>
    function getCleanName(theName)
    {
        return '#' + theName.replace(/:/gi,"\\:");
    }
    var valueField = getCleanName( '{!$Component.theForm.theBlock.theSection.value}' );

    $j = jQuery.noConflict();
    $j( "#slider" ).slider( {enable: true, min: 1, max: 10, orientation: "vertical", value: 10} );
    $j( "#slider" ).on( "slidechange",
        function( event, ui )
        {
            var value = $j( "#slider" ).slider( "option", "value" );
            $j( valueField ).val( value );
        }
    );
</script>

</apex:page>

 

If this helps, please mark it as a solution, and give kudos (click on the star) if you think I deserve them. Thanks!

 

-Glyn Anderson
Certified Salesforce Developer | Certified Salesforce Administrator

All Answers

GlynAGlynA

Mikie,

 

Here is a simple example of a jQuery slider.  The slider is initialized with a range from 1 to 10 (min = 1, max = 10) and an initial value of 10.  A simple event listener is registered that updates the "value" div whenever the slider value changes.

 

<apex:page >

<apex:includeScript value="{!URLFOR($Resource.JQuery, '/js/jquery-1.9.1.js')}"/>
<apex:includeScript value="{!URLFOR($Resource.JQuery, '/js/jquery-ui-1.10.3.custom.min.js')}"/>
<apex:stylesheet value="{!URLFOR($Resource.JQuery, '/css/ui-lightness/jquery-ui-1.10.3.custom.css')}"/>

<div id="slider"/>
<div id="value">10</div>

<script>
    $j = jQuery.noConflict();
    $j( "#slider" ).slider( {enable: true, min: 1, max: 10, orientation: "horizontal", value: 10} );
    $j( "#slider" ).on( "slidechange",
        function( event, ui )
        {
            var value = $j( "#slider" ).slider( "option", "value" );
            $j( "#value" ).text( value );
        }
    );
</script>

</apex:page>

Let me know if you need any additional information.

 

If this helps, please mark it as a solution, and give kudos (click on the star) if you think I deserve them. Thanks!

 

-Glyn Anderson
Certified Salesforce Developer | Certified Salesforce Administrator

Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student

Hey Glyna,

 

Basically one of the questions is a rating out of 10, so I need the slider to update a field, whether it be a picklist 1-10 or just a number field. I think your slider is exactly what I need, except I tried it out and the slider does not show. All that appears on the visualforce page is a 10.

 

What do you think could be the problem, thank you so much for your help.

 

Mikie

GlynAGlynA

You will have to download the jQuery files and create a static resource called "jQuery".  You can get the files from:

 

jQuery UI Download

 

Select version 1.10.3, leave all the default selections, scroll to the bottom and hit download.  Then, create a jQuery.ZIP file from the folders "css" and "js", and load that file as a static resource called "jQuery".  Hopefully then, the slider will appear.  Let me know if you continue to have problems.

GlynAGlynA

Once you have the original code working with the static resource, try this version.  You will have to give it the ID of an Account record, any account will do, because I am using the numeric field 'NumberOfEmployees' on Account to demonstrate how to put the slider value into an inputField component.  Load the page with something like this:

 

<your org URL>/apex/<your page name>?id=<id of an Account>

 

<apex:page standardController="Account">

<apex:includeScript value="{!URLFOR($Resource.JQuery, '/js/jquery-1.9.1.js')}"/>
<apex:includeScript value="{!URLFOR($Resource.JQuery, '/js/jquery-ui-1.10.3.custom.min.js')}"/>
<apex:stylesheet value="{!URLFOR($Resource.JQuery, '/css/ui-lightness/jquery-ui-1.10.3.custom.css')}"/>

<apex:form id="theForm">
<apex:pageBlock id="theBlock">
<apex:pageBlockSection id="theSection">
    <apex:inputField value="{!Account.NumberOfEmployees}" id="value"/>
    <div id="slider"/>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>


<script>
    function getCleanName(theName)
    {
        return '#' + theName.replace(/:/gi,"\\:");
    }
    var valueField = getCleanName( '{!$Component.theForm.theBlock.theSection.value}' );

    $j = jQuery.noConflict();
    $j( "#slider" ).slider( {enable: true, min: 1, max: 10, orientation: "vertical", value: 10} );
    $j( "#slider" ).on( "slidechange",
        function( event, ui )
        {
            var value = $j( "#slider" ).slider( "option", "value" );
            $j( valueField ).val( value );
        }
    );
</script>

</apex:page>

 

If this helps, please mark it as a solution, and give kudos (click on the star) if you think I deserve them. Thanks!

 

-Glyn Anderson
Certified Salesforce Developer | Certified Salesforce Administrator

This was selected as the best answer
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student

Hey Glyna, the slider still does not show up. I downloaded the file and then I deleted the other files (not css and js) and then I zipped them inside a jQuery fodler. It goes 

 

jQuery.zip---->jQuery----->js & css

 

is that right? Do i need any other fields or anything to make it work. Should I do it in production rather than sandbox?

 

Thank you for your help again. I feel like I am so close now

Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student

Ok, awesome. I got it working. Now onto the second part.

Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student

Hey GlynA,

 

I have created the page and I feel I am well on the right track, I just have a few questions.

1. Would it be possible to post this on site.com. Then when a client finishes a product or service, an email is sent out with a link. The link is based on a email template which will change the ID so that it will insert the clients account ID. Upon completion and submission of the form, the survey is inserted into the clients account on salesforce.

2. How would I go about making the slider smaller and then maybe adding the numbers 1-10 below the slider so it changes as the slider point is adjusted?

 

Thank you for your help again.

 

<apex:page standardController="Destiny_Survey__c">

<apex:includeScript value="{!URLFOR($Resource.jQuery, '/js/jquery-1.9.1.js')}"/>
<apex:includeScript value="{!URLFOR($Resource.jQuery, '/js/jquery-ui-1.10.3.custom.min.js')}"/>
<apex:stylesheet value="{!URLFOR($Resource.jQuery, '/css/ui-lightness/jquery-ui-1.10.3.custom.css')}"/>

<apex:form id="theForm">
<apex:pageBlock id="theBlock">
Thank you for completing our Destiny Survey {!Destiny_Survey__c.Account__c}.
<apex:pageBlockSection id="theSection"  >
    <div id="slider" />
    <apex:inputField value="{!Destiny_Survey__c.How_likely_are_you_to_refer_Destiny__c}" label="How likely is it that you would recommend us to a friend or colleague?" id="value"/>
     <apex:inputField value="{!Destiny_Survey__c.Explain_why_you_gave_your_rating__c}" label="Explain why you gave your rating." id="value2"/>  
     <apex:inputField value="{!Destiny_Survey__c.Which_Product_or_Service__c}" label="Which Destiny Product or Service have you just completed?" id="value3"/>
     
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>


<script>
    function getCleanName(theName)
    {
        return '#' + theName.replace(/:/gi,"\\:");
    }
    var valueField = getCleanName( '{!$Component.theForm.theBlock.theSection.value}' );

    $j = jQuery.noConflict();
    $j( "#slider" ).slider( {enable: true, min: 1, max: 10, orientation: "horizontal", value: 10} );
    $j( "#slider" ).on( "slidechange",
        function( event, ui )
        {
            var value = $j( "#slider" ).slider( "option", "value" );
            $j( valueField ).val( value );
        }
    );
</script>

</apex:page>

 

GlynAGlynA

1.  If your email includes a link with a parameter, such as:  ?acct=001000000123AbC

your controller can access the parameter using

 

Id accountId;
String acctParam = ApexPages.currentPage().getParameters().get( 'acct' );
if ( !String.isBlank( acctParam ) )
{
    try
    {
        accountId = Id.valueOf( acctParam );
    }
    catch ( Exception e )
    {
        accountId = null;
    }
}

and you can use the resulting Id (if it exists) to access the user's Account record.

 

2.  You might try using the "vertical" orientation and see if you like that better.  You can also style the slider's div so that it has a fixed size, or a min and max size, if you prefer.  Currently, without any styling, the div will take up all available space.  For example:

 

<div id="slider" style="width:100"/>

 

 

To add numbers along the slider can be done, I'm sure, but that's a question for someone with more CSS experience than I have.  I imagine you'd have to define a table with 1 row and 10 cells, styled to be the same size as the slider, and put the numbers in the cells.  That's just my idea.  A CSS expert might know of a better way.

 

-Glyn

Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student

You have been so helpful to me...a few quick question quickly and I will set the answer as the solution.

1. Would you be able to help me out in writing the controller, I still struggle quite alot with controllers and extensions.

 

2. When it is done, will i be able to create an email template with a link that looks something like this: https://c.cs6.<Site.com Name>/apex/Slider_Survey/acct={!Account.id}

Then when they click it, it will open to the VF page published through site.com. Upon clicking submit or save, which will then insert the survey into the account. Sort of like a webtolead.

 

Thank you so much for your help.

GlynAGlynA

1.  My time is limited, but if you write the controller, I will be happy to answer questions and make suggestions.  It's easier for me to refactor code than to write it from scratch, and there's no better way for you to learn than by doing.

 

2.  Your link will look like: https://c.cs6.<Site.com Name>/apex/Slider_Survey?acct={!Account.id}  (Note the '?', not '/'.)  The page controller can get the parameter (with something like the code above) and associate the survey with the account.  No problem.  ;-)

 

Glad to be of help!

 

-Glyn

Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student

Hey Glyn,

 

This is probably way off, but this is my attempt at the controller. It would not let me save as there was an error as it wasnt expecting the if statement.

 

 

 

public class SliderSurveyController {
 
    Destiny_Survey__c d;        
 
    public SliderSurveyController(ApexPages.StandardController controller){        
        d = (Destiny_Survey__c)controller.getRecord();             
    }        
 
    public void save(){        
        update d;        
    }
Id accountId;
String acctParam = ApexPages.currentPage().getParameters().get( 'acct' );
if ( !String.isBlank( acctParam ) )
{
    try
    {
        accountId = Id.valueOf( acctParam );
    }
    catch ( Exception e )
    {
        accountId = null;
    }
}

}

 

Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student

Maybe this will be closer. I am not sure if it will still work. An extension of the object rather than controller.

 

public class extDestinySurvey {
 
    public Destiny_Survey__c Dess {get;set;}

    
    public extDestinySurvey(ApexPages.StandardController controller) {
        this.Dess = (Destiny_Survey__c)controller.getRecord();
 

    }
    
    public PageReference saveDestinySurvey(){


        //Set record id to null

        Dess.Id = null; 

    }
    
        insert Dess;
        // Send the user to the detail page for the new account.
       PageReference pageRef= new PageReference('/apex/DestinyAccount?id='+fac.account__c+'&Sfdc.override=1');
        return pageRef;
  

    
    }
Id accountId;
String acctParam = ApexPages.currentPage().getParameters().get( 'acct' );
if ( !String.isBlank( acctParam ) )
{
    try
    {
        accountId = Id.valueOf( acctParam );
    }
    catch ( Exception e )
    {
        accountId = null;
    }
}
}

 

GlynAGlynA

Try this:

 

public class extDestinySurvey
{
    public Destiny_Survey__c Dess {get;set;}

    public extDestinySurvey(ApexPages.StandardController controller)
    {
        Dess = (Destiny_Survey__c)controller.getRecord();

        //  you're not really doing anything with this and the whole thing could be deleted.
        Id accountId = null;
String acctParam = ApexPages.currentPage().getParameters().get( 'acct' ); try { if ( !String.isBlank( acctParam ) ) accountId = Id.valueOf( acctParam ); } catch ( Exception e ) {} } public PageReference saveDestinySurvey() { upsert Dess; Destiny_Survey__c theSurvey = null; for ( Destiny_Survey__c aSurvey : [SELECT Id, Account__c FROM Destiny_Survey__c WHERE Id = :Dess.Id] ) { theSurvey = aSurvey; break; } // Send the user to the detail page for the new account. return theSurvey != null ? new PageReference('/apex/DestinyAccount?id=' + theSurvey.account__c + '&Sfdc.override=1') : null; } }

-Glyn

Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student

It said that the variable acctParam does not exist on line 13 colu,mn 73. How might I rectify this?

Thank you for your speedy replies. You are a lifesaver.

 

I also noticed your tag, about not really doing anything with that section of code, dont we need that to set the account id from the url and use it to insert the survey into the account?

GlynAGlynA

Yes - I accidentally deleted that line.  I have restored it in the post.  But, you're not using the whole AccountID parameter thing, and you could delete lines 8-16 without any issue.

 

-Glyn

GlynAGlynA

Hey, I just saw the question on your last post.  Yes, the AccountId will be useful for associating the survey with the account, but I guess the controller isn't that far along yet.  So, don't delete it just yet.  We'll be using it later.

 

-Glyn

Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student

Ok, I added the save button to the page and the extension. Upon clicking save (after I had set the url to: https://c.cs6.visual.force.com/apex/Slider_Survey?acct=001N000000819na

 

Which is the account id for one of my test accounts, it failed as the required field account was missing. Maybe I misunderstood you wrong, I could delete the lines 8-16? But are they not the important partts which tell the page which account to deposit the survey into?

GlynAGlynA

OK.  I was confused by the code you posted because the AccountId stuff was in there, but it didn't seem to be used for anything.  Now that I see what you're trying to do (the URL was very helpful - thanks!) I've modified the code.  As long as your VF page references the Account__c field of the Destiny_Survey__c object, then the record that the standard controller provides you will contain that field.  (Or if you are creating a record, you should be able to write all fields.)

 

public class extDestinySurvey
{
    public Destiny_Survey__c Dess {get;set;}

    private Id AccountId
    {
        get
        {
            if ( AccountId == null )
            {
                String acctParam = ApexPages.currentPage().getParameters().get( 'acct' );
                try
                {
                    if ( !String.isBlank( acctParam ) ) AccountId = Id.valueOf( acctParam );
                }
                catch ( Exception e ) {}
            }
            return AccountId;
        }
        private set;
    }

    public extDestinySurvey(ApexPages.StandardController controller)
    {
        Dess = (Destiny_Survey__c)controller.getRecord();
    }

    public PageReference saveDestinySurvey()
    {
        Dess.Account__c = AccountId;
        upsert Dess;

        // Send the user to the detail page for the new account.
        return new PageReference('/apex/DestinyAccount?id=' + AccountId + '&Sfdc.override=1');
    }
}

Hopefully, this will do it.

 

-Glyn

Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student

Hey Glyn,

 

At first it said that it does not recognise the variable thesurvey, so i added the reference to thesurvey from your previous code and it saved. I think did the url thing and it all worked perfectly. You are a genius, thank you so much!!

I will mark as solved, I was just wondering, that should I implement this on site.com and I send them the site with the acct id in the url (which i suppose I will be able to do), will the extension still be able to read the account ID and post it accordingly?

Thank you so much. You have helped me get passed a major obstacle.

 

Mikie

GlynAGlynA

Mikie,

 

I'm glad we got it worked out.  I'm pretty sure it will work on site.com as well.  I don't see why it shouldn't, as long as the user has permission to access the VF pages.

 

For completeness, I've modified my last code posting to fix the unknown 'theSurvey' problem.  While you got it to work by defining 'theSurvey', it's not necessary anymore, and I just forgot to remove all the references to it.

 

Good luck with the rest of the project!

 

-Glyn

Salesforce BlitzSalesforce Blitz
HI GlynA,

I  am struck with small issue...Need to save the Survey reults back to salesforce Object.

The link is provided below:
https://developer.salesforce.com/forums/?id=906F0000000D95tIAC


Thanks in advance,
Laxman