├── .gitignore
├── LICENSE
├── README.md
├── images
└── demo_picklist_select_component.png
└── src
├── aura
└── PicklistSelect
│ ├── PicklistSelect.cmp
│ ├── PicklistSelect.cmp-meta.xml
│ ├── PicklistSelect.design
│ ├── PicklistSelectController.js
│ └── PicklistSelectHelper.js
├── classes
├── PicklistSelectController.cls
├── PicklistSelectController.cls-meta.xml
├── PicklistSelectControllerTest.cls
└── PicklistSelectControllerTest.cls-meta.xml
├── flexipages
└── Demo_PicklistSelect_Component.flexipage
├── package.xml
└── tabs
└── Demo_PicklistSelect_Component.tab
/.gitignore:
--------------------------------------------------------------------------------
1 | config/
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2017, Doug Ayers
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | * Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | * Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Lightning Picklist Field Select Component
2 |
3 | Lightning Component that renders `lightning:select` with options from an sobject picklist field. Ideally, this component shouldn't be needed but as of Winter '16 release the `force:inputField` component has a [bug that when used with picklist fields it renders disabled](https://success.salesforce.com/issues_view?id=a1p3A0000001BaTQAU). Disabled form fields are not conducive to users entering data.
4 |
5 |
6 |
8 |
9 |
10 | 
11 |
12 | # Usage
13 |
14 | The simplest way is to use the component and specify `objectName` and `fieldName` required attributes:
15 |
16 | ```
17 |
18 | ```
19 |
20 | Since the standard [lightning:select](https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/aura_compref_lightning_select.htm) component is used by this component, most of the standard attributes are available to you as well:
21 |
22 | | Attribute | Description | Required? |
23 | |-----------|-------------|-----------|
24 | | objectName | API name of object | yes |
25 | | fieldName | API name of picklist field | yes |
26 | | label | Text that describes the desired select input. Default is the field's label. | no |
27 | | value | The value of the select, also used as the default value to select the right option during init. If no value is provided, the first option will be selected. | no |
28 | | class | A CSS class that will be applied to the outer element. This style is in addition to base classes associated with the component. | no
29 | | onblur | The action triggered when the element releases focus. | no |
30 | | onfocus | The action triggered when the element receives focus. | no |
31 | | onchange | The action triggered when a value attribute changes. | no |
32 |
--------------------------------------------------------------------------------
/images/demo_picklist_select_component.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/douglascayers/sfdc-lightning-picklist-field-component/703a09a7d00080408ecff2b64634bf6471299007/images/demo_picklist_select_component.png
--------------------------------------------------------------------------------
/src/aura/PicklistSelect/PicklistSelect.cmp:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/src/aura/PicklistSelect/PicklistSelect.cmp-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 38.0
4 | A Lightning Component Bundle
5 |
6 |
--------------------------------------------------------------------------------
/src/aura/PicklistSelect/PicklistSelect.design:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/aura/PicklistSelect/PicklistSelectController.js:
--------------------------------------------------------------------------------
1 | ({
2 | doInit : function(component, event, helper) {
3 |
4 | helper.callAction( component, 'c.getFieldLabel', {
5 | 'objectName' : component.get('v.objectName'),
6 | 'fieldName' : component.get('v.fieldName')
7 | }, function( data ) {
8 | component.set('v.label', data);
9 | });
10 |
11 | helper.callAction( component, 'c.getPicklistOptions', {
12 | 'objectName' : component.get('v.objectName'),
13 | 'fieldName' : component.get('v.fieldName')
14 | }, function( data ) {
15 | component.set('v.options', data);
16 | });
17 |
18 | }
19 |
20 | })
--------------------------------------------------------------------------------
/src/aura/PicklistSelect/PicklistSelectHelper.js:
--------------------------------------------------------------------------------
1 | ({
2 | /**
3 | * actionName = the apex controller method to call (e.g. 'c.myMethod' )
4 | * params = JSON object specifying action parameters (e.g. { 'x' : 42 } )
5 | * successCallback = function to call when action completes (e.g. function( response ) { ... } )
6 | * failureCallback = function to call when action fails (e.g. function( response ) { ... } )
7 | */
8 | callAction : function( component, actionName, params, successCallback, failureCallback ) {
9 |
10 | var action = component.get( actionName );
11 |
12 | if ( params ) {
13 | action.setParams( params );
14 | }
15 |
16 | action.setCallback( this, function( response ) {
17 | if ( component.isValid() && response.getState() === 'SUCCESS' ) {
18 |
19 | if ( successCallback ) {
20 | successCallback( response.getReturnValue() );
21 | }
22 |
23 | } else {
24 |
25 | console.error( 'Error calling action "' + actionName + '" with state: ' + response.getState() );
26 |
27 | if ( failureCallback ) {
28 | failureCallback( response.getError(), response.getState() );
29 | } else {
30 | this.logActionErrors( component, response.getError() );
31 | }
32 |
33 | }
34 | });
35 |
36 | $A.enqueueAction( action );
37 |
38 | },
39 |
40 | logActionErrors : function( component, errors ) {
41 | if ( errors ) {
42 | for ( var index in errors ) {
43 | console.error( 'Error: ' + errors[index].message );
44 | }
45 | } else {
46 | console.error( 'Unknown error' );
47 | }
48 | }
49 |
50 | })
51 |
--------------------------------------------------------------------------------
/src/classes/PicklistSelectController.cls:
--------------------------------------------------------------------------------
1 | public with sharing class PicklistSelectController {
2 |
3 | /**
4 | * Given an API object and field name, returns the configured field label to display to users.
5 | */
6 | @AuraEnabled
7 | public static String getFieldLabel( String objectName, String fieldName ) {
8 |
9 | System.debug( 'Getting field label: objectName=' + objectName + ', fieldName=' + fieldName );
10 |
11 | String label = Schema.getGlobalDescribe().get( objectName ).getDescribe().fields.getMap().get( fieldName ).getDescribe().getLabel();
12 |
13 | System.debug( 'label= ' + label );
14 |
15 | return label;
16 | }
17 |
18 | /**
19 | * Given an API object and field name, returns list of the picklist values for use in select input.
20 | */
21 | @AuraEnabled
22 | public static List getPicklistOptions( String objectName, String fieldName ) {
23 |
24 | System.debug( 'Getting picklist options: objectName=' + objectName + ', fieldName=' + fieldName );
25 |
26 | List options = new List();
27 |
28 | for ( PicklistEntry entry : Schema.getGlobalDescribe().get( objectName ).getDescribe().fields.getMap().get( fieldName ).getDescribe().getPicklistValues() ) {
29 | options.add( new PicklistOption( entry.getLabel(), entry.getValue() ) );
30 | }
31 |
32 | System.debug( 'options=' + options );
33 |
34 | return options;
35 | }
36 |
37 | /**
38 | * The system class PicklistEntry is not aura enabled so cannot be returned from @AuraEnabled method.
39 | * Workaround is to define our own class with aura enabled properties.
40 | */
41 | public class PicklistOption {
42 |
43 | @AuraEnabled
44 | public String label { get; set; }
45 |
46 | @AuraEnabled
47 | public String value { get; set; }
48 |
49 | public PicklistOption( String label, String value ) {
50 | this.label = label;
51 | this.value = value;
52 | }
53 |
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/src/classes/PicklistSelectController.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 38.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/PicklistSelectControllerTest.cls:
--------------------------------------------------------------------------------
1 | @isTest
2 | private class PicklistSelectControllerTest {
3 |
4 | @isTest
5 | static void test_get_field_label() {
6 |
7 | Test.startTest();
8 |
9 | String fieldLabel = PicklistSelectController.getFieldLabel( 'Account', 'Type' );
10 |
11 | Test.stopTest();
12 |
13 | System.assertEquals( Account.Type.getDescribe().getLabel(), fieldLabel );
14 |
15 | }
16 |
17 | @isTest
18 | static void test_get_picklist_values() {
19 |
20 | Test.startTest();
21 |
22 | List options = PicklistSelectController.getPicklistOptions( 'Account', 'Type' );
23 |
24 | Test.stopTest();
25 |
26 | List values = Account.Type.getDescribe().getPicklistValues();
27 |
28 | for ( Integer i = 0; i < options.size(); i++ ) {
29 | System.assertEquals( values[i].getLabel(), options[i].label );
30 | System.assertEquals( values[i].getValue(), options[i].value );
31 | }
32 |
33 | }
34 |
35 | }
--------------------------------------------------------------------------------
/src/classes/PicklistSelectControllerTest.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 38.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/flexipages/Demo_PicklistSelect_Component.flexipage:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | fieldName
7 | Type
8 |
9 |
10 | objectName
11 | Account
12 |
13 | PicklistSelect
14 |
15 |
16 |
17 | fieldName
18 | Status
19 |
20 |
21 | objectName
22 | Lead
23 |
24 | PicklistSelect
25 |
26 |
27 |
28 | fieldName
29 | StageName
30 |
31 |
32 | objectName
33 | Opportunity
34 |
35 | PicklistSelect
36 |
37 | main
38 | Region
39 |
40 | Demo PicklistSelect Component
41 | flexipage:defaultAppHomeTemplate
42 | AppPage
43 |
44 |
--------------------------------------------------------------------------------
/src/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | PicklistSelectController
5 | PicklistSelectControllerTest
6 | ApexClass
7 |
8 |
9 | PicklistSelect
10 | AuraDefinitionBundle
11 |
12 |
13 | Demo_PicklistSelect_Component
14 | CustomTab
15 |
16 |
17 | Demo_PicklistSelect_Component
18 | FlexiPage
19 |
20 | 38.0
21 |
22 |
--------------------------------------------------------------------------------
/src/tabs/Demo_PicklistSelect_Component.tab:
--------------------------------------------------------------------------------
1 |
2 |
3 | Created by Lightning App Builder
4 | Demo_PicklistSelect_Component
5 |
6 | true
7 | Custom60: Umbrella
8 |
9 |
--------------------------------------------------------------------------------