Friday 27 June 2014

Date conversion within JsRender using Moment.js

Moment.js rocks!

I dare say I've said it before and I know I'll say it again but it really, really rocks! You know what else rocks? JsRender also rocks!

Why do they rock? They rock because they allow me to write Converters which are a line long and allow me to convert US formated dates to UK formated dates with this:

$.views.converters({
    ukDate: function (value) {
        return moment(value).format("DD/MM/YYYY");
    }
});

This means that I use this line in my JsRender template:

<dt>Date Recieved</dt>
<dd>{{ukDate:Date_Received__c}}</dd>

And the US formated date gets converted without me having to worry!

That's why Moment.js and JsRender rock!

Wednesday 25 June 2014

Update SalesForce rich text area in VisualForce page

I've just come across this post by Matt Lacey, a day too late as I discovered this yesterday!

Basically the issue is that Salesforce has rich text fields which are not in the least bit easy to re-render. A colleague had a requirement to change the text within the rich text area depending upon the user changing a select value, the base starting points for the rich text area were contained within hidden fields on the form but he needed to update the rich text area upon the select being changed without Salesforce complaining too much.

I inspected the elephant and clocked that the ids he had given to various apex components were coming through properly but that they were mixed up in some sort of colon-and-alphabet soup. That's where I got to thinking about jQuerys selectors and had a wee brain wave... the missing piece then was looking at the CKEDITOR object and its setData method and we were in business.

Given this structure on the visualforce page:

<apex:pageBlockSection rendered="{!NOT(draftMode)}">
  <apex:selectList 
    label="Request Description source:"
    value="{!descriptionSelected}" 
    multiselect="false" 
    size="1"
    id="descOption">
    <apex:selectOptions 
      value="{!descriptionList}" />
  </apex:selectList>
</apex:pageBlockSection>

 ... 

<apex:pageBlockSection>
  <apex:inputField 
    label="Request" 
    value="{!pagePubRec.Published_Request__c}"
    id="requestText" />
</apex:pageBlockSection>

 ... 

<apex:inputHidden 
  id="customerDescription" 
  value="{!customerDescription}"
  />
<apex:inputHidden 
  id="caseDescription" 
  value="{!caseDescription}" />

We can use this javascript:

<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
  $(function(){
    // Select the select that ends with the id of 'descOption'
    // and listen to it changing...
    $("[id$='descOption']").on("change", function(){
      // Probably not needed but better safe than sorry.
      var $this = $(this);
      // Get the full id if the textarea which contains 'requestText',
      // including all the salesforcie stuff, as that'll be the reference
      // we'll use to grab the correct CKEDITOR instance.
      var cke_editor_instance = $("textarea[id*='requestText']").attr("id");
      if ($this.val() === "Customer Request description"){
        // If the value of the select is "Customer Request description"
        // update the textarea which underlays the rich text editor with 
        // the data from our hidden field...
        $("textarea[id*='requestText']")
          .val($("[id$='customerDescription']").val());
        // ...and set the data for the CKEDITOR instance with the same value.
        CKEDITOR.instances[cke_editor_instance]
          .setData($("[id$='customerDescription']").val());
      }else{
        // We've only got 2 so no need to use a switch or 
        // something else more fun.
        $("textarea[id*='requestText']")
          .val($("[id$='caseDescription']").val());
        CKEDITOR.instances[cke_editor_instance]
          .setData($("[id$='caseDescription']").val());
      }
    });
  });
</script>

Yon Matt Lacey is right though, this is a hack... it's not a terrible hack... but it is a hack! There's no guarantee taht this approach will continue to work, but I'll keep my fingers crossed!

Tuesday 17 June 2014

Words for today... and the day before...

I'm doing masses of things to do with dates and created some lovely objects using PHPs strtotime for yesterday, and the day before yesterday and I wanted to name them. Apparently in lots of languages there is a specific word for the day before yesterday but we're a bit stuck in modern English... so a wee Google search found this lovely answer. As such I've going to be using these words as much as possible!

ereyesterday
The day before yesterday; On the day before yesterday
overmorrow
The day after tomorrow; On the day after tomorrow

Sunday 8 June 2014

A picture is worth a thousand lines of code... or is it?

I got really quite excited when I read about Codeivate last week and spent ages installing it on everything that'd work with it... and then - after it collecting some statistics - really quite sad that thus far my longest streak of coding is 20mins.

There's me claiming to work bloody hard and only managing a stint of 20 mins!

Then I got to thinking about my work flow and I clocked that a lot of what I do is code like a crazy thing and then test that what I've done is working... often dipping into the console and writing code in there that then gets cut and pasted into the IDE when it's working as I want it to... so actually recording the code that gets put into the IDE isn't a correct representation of the amount of work I do - just a representation of the amount of work I'm willing to commit to a file rather than some nebulous space within the browsers memory.

Phew!

(At least that's what I'm telling myself! ;-))