• Eric Kokmanian
  • NEWBIE
  • 0 Points
  • Member since 2018

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 2
    Likes Given
  • 1
    Questions
  • 2
    Replies
As many of you surely already know, it is possible to get the content from a text template, part of a flow, into a ContentNote object. However, when the note is created, its format does not correspond correctly to the one in the text template. More specifically, in the notes, line breaks are simply considered as single spaces. Anyone with an idea on how to include these line breaks in the ContentNote is more than welcome to share!

I have already tried to use <br/> or BR(), but flow displays following error message : "This error occurred when the flow tried to create records: INVALID_INPUT: Note can't be saved because it contains HTML tags or unescaped characters that are not allowed in a Note.. "

I have also tried, after reading on this matter, to import the content of the text template as a .txt file using the Data Loader... line breaks did appear, but the expressions of the variabes were displayed as simple text. Which makes sense, I guess.

So, I contacted a Salesforce Support Agent and he believed the line breaks were lost due to the fact that the ContentNote is referencing a visual force page. This page is basically the last screen the flow displays, after it runned successfully. It displays the content of the new note created, with all the line breaks, but when you navigate to the record page to see its notes and expand the note, you realize the line breaks disappeared and format is not respected.

The following image illustrates the issue where lines breaks are omitted (Image to left is the text template / Image to the right is result once note created).
User-added image
I have developed code to over come limitation of print option for list view.
VF Page
<apex:page sidebar="false" standardStylesheets="false" cache="false" standardController="Account" recordSetVar="accounts" lightningStylesheets="true">
    <button id="upload-button" onclick="window.print();" style="margin-left: 50%;" Class="slds-button">Print</button>
    <apex:includeLightning />
    <div id="lightning" ></div> 
    <script>
        $Lightning.use("c:ListView", function() {
          $Lightning.createComponent("c:ListViewComponent",
          { label : "" },
          "lightning",
          function(cmp) {
             
          });
        });
    </script>
</apex:page>


Controller class
public with sharing class ListViewController {
    
    // Method to get all list view option available for the Account object 
    @AuraEnabled
    public static List<SelectOption> getListViews(){
        SelectOption  lstView=new SelectOption ('--None--','--None--');
        List<SelectOption> listviews = new List<SelectOption>();
        listviews.add(lstView);
        for(ListView lstObj : [SELECT Id, Name FROM ListView WHERE SobjectType = 'Account' order by name ASC]){
            listviews.add(new SelectOption (lstObj.id,lstObj.name));
        }
        return listviews; 
    }
    // Method to get the Account records based on the selected list view
    @AuraEnabled  
    public static DynamicTableMapping getFilteredAccounts(String filterId){
        list<string> headervalue =new list<string>();
        HttpRequest req = new HttpRequest();
        String baseUrl = URL.getSalesforceBaseUrl().toExternalForm();
        String endPoinURL = baseUrl+'/services/data/v32.0/sobjects/Account/listviews/'+filterId+'/describe';
        req.setEndpoint(endPoinURL);
        req.setMethod('GET');
        req.setHeader('Authorization',  'Bearer ' + UserInfo.getSessionId());
        Http http = new Http();
        HTTPResponse response = http.send(req);
        Map<String, Object> tokenResponse = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
        String query = (String) tokenResponse.get('query');
        system.debug('query--->'+query);
       for(string s:query.split(',')){
            s=s.trim();    
            if(s.startsWith('SELECT')){
                headervalue.add((s.removeStart('SELECT')).trim());        
            }else if(!s.startsWith('SYSTEMMODSTAMP') && !s.equalsIgnoreCase('SYSTEMMODSTAMP FROM ACCOUNT ORDER BY NAME ASC NULLS FIRST') && !s.contains('ASC')){
                headervalue.add(s.trim());
            }
        }
        
        List<ObjectValueMap> AccountList = new List<ObjectValueMap>();
        
        for(Account accountObj : database.query(query)){
            
            Map<String, Schema.SObjectField> objectFields = Account.getSObjectType().getDescribe().fields.getMap();
            list<FieldValues> fieldValue=new list<FieldValues>();
            for(string s:headervalue){
                Schema.DescribeFieldResult dr;
                if (objectFields.containsKey(s)) 
                      dr = objectFields.get(s).getDescribe();
                if(null!=dr)
                    fieldValue.add(new FieldValues(string.valueof(null==accountObj.get(dr.getName())?'':accountObj.get(dr.getName()))));            
                else
                    fieldValue.add(new FieldValues(string.valueof('')));
            }
            AccountList.add(new ObjectValueMap(accountObj,fieldValue));
        }
        
        return new DynamicTableMapping(headervalue,AccountList);        
    }
      
}



Lightning component
<aura:component controller="ListViewController" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" >
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    <aura:attribute name="AccountListViewList" type="SelectOption[]"/>
    <aura:attribute name="AccountList" type="DynamicTableMapping"/>
    <aura:attribute name="fieldList" type="string[]"/>
    <ui:inputSelect class="slds-select slds-size_small" aura:id="selectedViewId" label="Account View" change="{!c.getFilteredAccount}">
        <aura:iteration items="{!v.AccountListViewList}" var="listview">
            <ui:inputSelectOption text="{!listview.value}" label="{!listview.label}"/>
        </aura:iteration>
    </ui:inputSelect>
   
    <br/><br/>
    
    <table class="slds-table slds-table_bordered slds-table_cell-buffer">
        <thead>
            <tr class="slds-text-title_caps">
                <aura:iteration items="{!v.fieldList}" var="item">
                    <th scope="col">
                        <div class="slds-truncate" title="{!item}">{!item}</div>
                    </th>
                </aura:iteration>
            </tr>
        </thead>
        <tbody>
        <aura:iteration items="{!v.AccountList}" var="item" indexVar="index">
        <tr>
       
            <aura:iteration items="{!item.values}" var="item1">
                <td>
                     {!item1.value}   
                </td></aura:iteration>
        </tr>
        </aura:iteration>
        </tbody>
    </table>
</aura:component>


Component controller JS
({
    doInit : function(component, event, helper){
        var action = component.get("c.getListViews");
        action.setCallback(this, function(response){
            var state = response.getState();
            if (state === "SUCCESS") {
                component.set("v.AccountListViewList",response.getReturnValue());
            }
        });
       
        $A.enqueueAction(action);
    },
    getFilteredAccount : function (component, event, helper) {
        var selected = component.find("selectedViewId").get("v.value");
        var action = component.get("c.getFilteredAccounts");
        action.setParams({filterId : selected});
        action.setCallback(this, function(response){
            var state = response.getState();
            if (state === "SUCCESS") {
                component.set("v.AccountList",response.getReturnValue().value);
                component.set("v.fieldList",response.getReturnValue().headervalues);
            }
        });
        
        $A.enqueueAction(action); 
    },
    
})


Helper classes
public class DynamicTableMapping {
    
    @AuraEnabled
    public list<string> headervalues{get;set;}
    @AuraEnabled 
    public list<ObjectValueMap> value{get;set;}
    
    public DynamicTableMapping(list<string> headervalues,list<ObjectValueMap> value){
        this.headervalues=headervalues;
        this.value=value;
    }
}

--- Value map class--

public class ObjectValueMap {
	
    @AuraEnabled
    public account account{get;set;}
    @AuraEnabled
    public list<fieldValues> values{get;set;}
    
    public ObjectValueMap(account acc,list<fieldValues> values){
    	this.account=acc;
        this.values=values;
    }
}

-- Field values class--
public class FieldValues {
	@auraenabled
    public object value{get;set;}
    
    public FieldValues(object value){
        this.value=value;
    }
}

You can modify this code any other object you wish to implement.
Create listview button with the VF page.
I'm working on a Visualforce page to simplify logging of Activities. As a portion of this process, users are asked to enter supporting text, which is to be attached to the resulting Activity in a note record (I'm using the new ContentNote). What I keep encountering is two issues:
  • In the resulting note, all line breaks are removed: all of the lines are run together with no intervening space.
  • There is an exception thrown repeatedly as follows:
"Note can't be saved because it contains HTML tags or unescaped characters that are not allowed in a Note.
Error is in expression '{!save}' in component <apex:commandButton> in page log_activity: Class.LogActivityController.save: line 123, column 1"

Note that I do use String.escapeHTML4() to prepare the text. Based on my testing the exception appears to be thrown when Unicode characters are present. Am I failing to prepare Unicode text appropriately in some fashion I'm not aware of?

Does anyone have any ideas? 

 
ContentNote n = new ContentNote();
        	
        	if (task.Subject != null && task.Subject != '') {
	        	n.Title = task.Subject;
        	} else {
        		n.Title = 'Activity Notes';
        	}
        	
        	n.Content = Blob.valueOf(longDescription.escapeHtml4());
        	
        	insert n;
        	
        	ContentDocumentLink cdl = new ContentDocumentLink();
        	
        	cdl.ContentDocumentId = n.Id;
        	cdl.LinkedEntityId = task.Id;
        	cdl.Visibility = 'AllUsers';
        	cdl.ShareType = 'I';
        	
        	insert cdl;

 
I'm working on a Visualforce page to simplify logging of Activities. As a portion of this process, users are asked to enter supporting text, which is to be attached to the resulting Activity in a note record (I'm using the new ContentNote). What I keep encountering is two issues:
  • In the resulting note, all line breaks are removed: all of the lines are run together with no intervening space.
  • There is an exception thrown repeatedly as follows:
"Note can't be saved because it contains HTML tags or unescaped characters that are not allowed in a Note.
Error is in expression '{!save}' in component <apex:commandButton> in page log_activity: Class.LogActivityController.save: line 123, column 1"

Note that I do use String.escapeHTML4() to prepare the text. Based on my testing the exception appears to be thrown when Unicode characters are present. Am I failing to prepare Unicode text appropriately in some fashion I'm not aware of?

Does anyone have any ideas? 

 
ContentNote n = new ContentNote();
        	
        	if (task.Subject != null && task.Subject != '') {
	        	n.Title = task.Subject;
        	} else {
        		n.Title = 'Activity Notes';
        	}
        	
        	n.Content = Blob.valueOf(longDescription.escapeHtml4());
        	
        	insert n;
        	
        	ContentDocumentLink cdl = new ContentDocumentLink();
        	
        	cdl.ContentDocumentId = n.Id;
        	cdl.LinkedEntityId = task.Id;
        	cdl.Visibility = 'AllUsers';
        	cdl.ShareType = 'I';
        	
        	insert cdl;

 

Hi,

 

When our app makes a callout to an external webservice over SSL, we get the following Exception:

 

System.CalloutException: IO Exception: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

 

 This doesn't happen with regular http callout. our certificate is NOT expired on the target server and everything seems to be normal. no alert or anything from the browser.

 any idea?

 

Thanks,

 

P.S We need to resolve this for security review.

 

 

 

 

 

 

Message Edited by Bms270 on 05-14-2009 07:17 PM
Message Edited by Bms270 on 05-14-2009 07:19 PM