4

I've set up the following test page:

Visualforce Page:

<apex:page controller="Emojis" action="{!Emojis}" >

<apex:form >
    <apex:actionPoller interval="5" reRender="emoji"/>

    <apex:outputText id="emoji" value="{!emojiCase.Subject}"/>

</apex:form>

</apex:page>

Apex Controller:

public class Emojis {

    public Case emojiCase {get;set;}

    public void Emojis() {
        // This is a case which has Emojis in the Subject
        emojiCase = [SELECT Id, Subject FROM CASE WHERE CaseNumber = '00034143'];
    }

}

When the page first loads, the page action fires and retrieves the case with emojis, and it looks like this:

Emojis displaying fine.

However when the actionPoller rerenders the output text, it changes to this:

enter image description here

I can't figure out why it does this, does the encoding change upon refresh?

  • 1
    I am not sure, but it's probably because of the rerendring option. Put your output text within an OutputPanel and assign "emoji" id to this panel. – Salesforcesmarty Dec 13 '16 at 10:20
  • @Salesforcesmarty It doesn't seem to work after any component is rerendered. I'm wondering what else this affects apart from emojis, are their only certain supported unicode characters useable in a rerender? – user24634 Dec 13 '16 at 10:27
  • 1
    What are the unicodes for these emojis? I tested it and working for different set of emojis. – Saroj Bera Dec 15 '16 at 11:54
  • @SarojBera The outside ones are Japanese Ogre symbols with the code 1F479 and the inside symbol is a Japanese Goblin with the code 1F47A – user24634 Dec 15 '16 at 12:41
3
+50

I solved this problem by using urlencoding. Below is a working example. What I do here is, first I encoded the Case Subject in Condroller using EncodingUtil.URLENCODE then again decode the value in VF page using decodeURI. I have used two <apex:outputText here, one is hidden and used to hold the encoded value and other used to display the characters in the page. Once the <apex:actionPoller completes the action call I am calling another JS function stop to decode the value and update the <apex:outputText with the help of <apex:actionStatus. Also on the page load, I am calling the JavaScript stop(); method to decode and render the character properly.

VF Page

<apex:page controller="exampleConEx">
    <apex:form id="myform" >
        <apex:actionStatus id="status" onstart="start()" onstop="stop()"/> 
        <apex:outputText value="Watch this counter: {!count}" id="counter"/><br/>
        <apex:outputText  value="{!emojiCase.Subject}" id="emoji"/><br/>
        <apex:outputText  value="{!emojiCase.Subject}" id="emojihidden" style="display:none;" />
        <apex:actionPoller action="{!incrementCounter}" reRender="counter,emojihidden" interval="15" status="status" />
    </apex:form>
    <script type="text/javascript">
      stop();   
      function start(){
          //alert("Starting");
      }
      function stop(){
          var casesub = document.getElementById('{!$Component.myform.emojihidden}').innerHTML;
          document.getElementById('{!$Component.myform.emoji}').innerHTML = decodeURI(casesub);
      }    
    </script>    
</apex:page>

Controller

public class exampleConEx {
    Integer count = 0;
    Case emojiCase = null;

    public PageReference incrementCounter() {
        count++;
        return null;
    }

    public Integer getCount() {
        return count;
    }
    public Case getEmojiCase(){
        emojiCase = [SELECT Id, Subject FROM CASE WHERE CaseNumber = '00001036'];
        String str = emojiCase.Subject;
        emojiCase.Subject = EncodingUtil.URLENCODE(str,'UTF-8');
        return emojiCase; 
    }    
}

On Page load

enter image description here

Issue after rerender happens as described by Sam C

enter image description here

Working example with URL Encoding (The case has been updated in the backend to add more characters)

enter image description here

  • Thanks Saroj. I have reported this to Salesforce. Their response from R&D was: "If a character is more that two bytes long (like an emoji), then the array in which the same is saved internally fails to write it correctly. This behavior has been identified as a Bug and R&D will be working on the fix. " – user24634 Jan 4 '17 at 9:32
  • 1
    Thanks for the update. If you got to know that it is fixed, let me know I will update the answer. – Saroj Bera Jan 4 '17 at 9:36
0

I've seen a few articles (from a quick Google search) where it talks about the need to escape output on a re-render.

For example, https://developer.salesforce.com/forums/?id=906F0000000DBRDIA4 talks about the re-render encoding the ampersand into &amp which then breaks the thing you actually wanted to encode.

Could it be that the re-render is encoding the already-encoded output for your emoji?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy