Showing posts with label Visualforce. Show all posts
Showing posts with label Visualforce. Show all posts

Monday, May 18, 2015

Forecasting Quota and Risk of Salesforce Upgrade


Problem

This is a bit of old problem, but we had this custom Visualforce interface in our internal org that allows you to mass insert and edit Forecast Quota.  This has been working fine for years, but when we tried to enter forecast for this year, we suddenly got this error:

Missing Required Field: [Quota Quantity]
However, when we tried to modify the code to allow manual entering of quota, we were getting error indicating that this field is not writable.


Solution

What turned out happen was that you need to have ForecastingType set if you are using ForecastingQuota inside of code after API v28.  Once we enabled a revenue forecast on opportunity (Setup > Customize > Forecasts > Setting), the interface worked again.

Takeaway

This was another lesson on using custom code with Salesforce (especially something that interacts with Standard feature, such as Standard object) and Salesforce upgrade.  Writing custom code can certainly improve the usability of Salesforce, and I do believe it to be one of major feature of Salesforce, but one has to be mindful that it can suddenly get broken without warning.  This is one of the reason why Salesforce recommends using as much of standard functionality as possible (70 to 80% standard functionality is the Salesforce benchmark).

Sunday, March 22, 2015

Mobile Design Template and Angular.JS

Problem

We had implemented a multi-step wizard for our client.  Two of the requirements for this wizard was that it needed to be mobile-friendly, and it needs to have bilingual support.  To meet this requirement I had tried to implement a mobile version of the wizard using Mobile Design Templates.   I had previously built a simple mobile-friendly Visualforce page using Mobile Design Templates and Underscore.JS following the Getting Started with Mobile Design Templates blog post from Salesforce.

Given the complexity of this application, I had used Angular.JS as the back-end.  However, I ran into trouble when I tried to incorporate the Mobile Design Templates' toggle input into this application.

We had this picklist field with two values that we want to render as a toggle input.  To do so I had the Angular.JS controller called the service that would grab the labels for those two values from Salesforce, in order to meet the bilingual requirement, and set those label as data-on-label and data-off-label.

(function() {

var app = angular.module('app', []);



 app.controller('InputCtrl', function InputCtrl(InputLabelService) {

        var inputScope = this;



        // Get the label of the input form from Salesforce
        InputLabelService.getFormValues().then(
            function(picklists) {
                inputScope. inputLabels = picklists. inputLabels;


               // This renders the toggle input
               $(document).trigger('onTemplateReady');
        });
    });
})();



<section class="border-bottom">
    <div class="content">
    <h3>Input</h3>
        <div class="form-control-group">
            <div class="form-control form-control-toggle" data-on-label="{{inputLabels[0]}}" data-off-label="{{inputLabels[1]}}">
                <input type="checkbox" name="toggle">
             </div>
         </div>
     </div>
 </section>
The problem was that Mobile Design Templates render data-on-label and data-off-label on the toggle input upon the call to 'onTemplateReady' Javascript trigger.  However, because how the two-way binding of Angular.JS is done, the rendering of the toggle input is done before Angular.JS can set the data-on-label and data-off-label with appropriate values, which ended up rendering the toggle input without any label.

Solution

The way I had gotten around this issue was by putting a $watch listener on the inputLabels and to trigger 'onTemplateReady' when it has a new value.

(function() {

var app = angular.module('app', []);



 app.controller('InputCtrl', function InputCtrl(InputLabelService) {

        // Get the label of the input form from Salesforce
        InputLabelService.getFormValues().then(
            function(picklists) {
                $scope.inputLabels = picklists.inputLabels;



                $scope.$watch('inputLabels', function(newVal, oldVal) {



                    if (newVal) {

                       // This renders the toggle input
                       $(document).trigger('onTemplateReady');
                   }
               });
        });
    });
})();




Takeaway

In the end, I actually ended up not using Mobile Design Templates as the tabbed navigation, which I had used in one of the page, didn't work in iPhone.  Instead, I ended up using Bootstrap along with Angular.JS.  I still think Mobile Design Templates is a good tool to have in your tool belt if you are building a very simple mobile application on Salesforce1; however, for any application with a moderate complexity, I would definitely look at alternative, such as Bootstrap I have used for this project or Ionic Framework.