Come stalk me at Dreamforce 2012

*Updated 9/14*
DreamForce 2012 is only a few weeks away. You can still register or sign up for a free pass that gets you access to only the keynote addresses and campground. Free is nice, but you don't get access to all the sessions and trainings and more importantly … the Red Hot Chili Peppers concert.
As this will be my sixth (or seventh?) DreamForce, I've already started preparing by getting some new Dr. Scholls and loading up on Vitamin C, since I'll be on my feet talking away most of the time I'm there. If you want to come see me in action, sign up for one of the following;

The code consultations have got to be the most valuable and under-utilized session. (NOTE: You'll have to have a valid Dreamforce registration and login to use the session links above.) Essentially, you sign up for a half-hour one-on-one with a Salesforce expert; usually a senior level developer or Technical Architect (like myself) from Strategic Services (ie Salesforce's consulting division). Given what our hourly rate is, that half hour alone could cover your registration. I can't tell you how many people sign up and then cancel last minute. The people who have come with very specific, detailed, thought-out questions have sometimes walked away with fully coded solution. (Safe Harbor!) So, if you've hit the wall on some code or can't figure out some integration issue, sign up for a consultation today. Even you you can't pre-register, try swinging by the Developer Zone information desk and asking about cancellations. Odds are you can find a free chair. Maybe you'll even find me.

See you soon.

 

Addendum Sept 5 2012 6PM EST- Apparently the Red Hot Chili Peppers are not the only attraction as Dreamforce will host a free music festival the entire week! Check out the details here. Check out this cool video from The Limousines who will be playing Tues 18 at 6:15. Be there or … don't. I will, though.

Advertisements

Upload and Parse CSV via VisualForce

Update August 22nd, 2015 – Please note that this is an experiment in reading a CSV and pulling the data into Visualforce. In no way should this be part of a Production-ready solution as it DOES NOT SCALE. You will hit limits as the number of rows in the CSV increases. As a solution, this would NOT be considered a best practice.

I recently had to develop a Visualforce page that allowed a Salesforce user to upload a CSV file and then generate some records from the parsed values. Yes, I know that is what the Data Loader is for, but the intended user here was not technically adept. And I thought it was an interesting experiment.

Csv upload

The Salesforce Developer Wiki already had a sample class for parsing the file – http://wiki.developerforce.com/index.php/Code_Samples#Parse_a_CSV_with_APEX . So, I had to just create the VF page and my controller. Though, I did modify the parsing method from the Wiki to use the carriage return in the string split. CSV’s produced on my Mac didn’t parse correctly using the newline ‘\n’. I found a good post here explaining how Windows and Mac/Unix handle carriage returns differently. Here’s the results.

Visualforce page: uploadCSV

<apex:page controller=”uploadCSVcontroller” >
  <apex:form >
  <apex:inputFile value=”{!contentFile}” filename=”{!nameFile}” /><br/>
  <apex:commandButton value=”Upload” id=”theButton”/>
  </apex:form>
  <apex:outputPanel id=”results”>
  <p>nameFile: {!nameFile}</p>
  <p>rowCount: {!rowCount}</p>
  <p>colCount: {!colCount}</p>
    <table title=”CSV Output” border=”1″ width=”100%”>
       <apex:repeat value=”{!results}” var=”row”>
           <tr>
               <apex:repeat value=”{!row}” var=”cell”>
                   <td> {!cell} </td>
               </apex:repeat>
           </tr>
       </apex:repeat>
     </table>
  </apex:outputPanel>
</apex:page>

Apex Class:

public class uploadCSVcontroller {

    public Blob contentFile { get; set; }
    public String nameFile { get; set; }
    public Integer rowCount { get; set; }
    public Integer colCount { get; set; }

    public List<List<String>> getResults() {
        List<List<String>> parsedCSV = new List<List<String>>();
        rowCount = 0;
        colCount = 0;
        if (contentFile != null){
            String fileString = contentFile.toString();
            parsedCSV = parseCSV(fileString, false);
            rowCount = parsedCSV.size();
            for (List<String> row : parsedCSV){
                if (row.size() > colCount){
                    colCount = row.size();
                }
            }
        }
        return parsedCSV;
    }
    /*
    Credit to
    http://wiki.developerforce.com/index.php/Code_Samples#Parse_a_CSV_with_APEX
    */
    public static List<List<String>> parseCSV(String contents,Boolean skipHeaders) {
        List<List<String>> allFields = new List<List<String>>();

        // replace instances where a double quote begins a field containing a comma
        // in this case you get a double quote followed by a doubled double quote
        // do this for beginning and end of a field
        contents = contents.replaceAll(‘,”””‘,’,”DBLQT’).replaceall(‘”””,’,’DBLQT”,’);
        // now replace all remaining double quotes – we do this so that we can reconstruct
        // fields with commas inside assuming they begin and end with a double quote
        contents = contents.replaceAll(‘””‘,’DBLQT’);
        // we are not attempting to handle fields with a newline inside of them
        // so, split on newline to get the spreadsheet rows
        List<String> lines = new List<String>();
        try {
            //lines = contents.split(‘\n’); //correction: this only accomodates windows files
            lines = contents.split(‘\r’); // using carriage return accomodates windows, unix, and mac files
            //http://www.maxi-pedia.com/Line+termination+line+feed+versus+carriage+return+0d0a
        } catch (System.ListException e) {
            System.debug(‘Limits exceeded?’ + e.getMessage());
        }
        Integer num = 0;
        for(String line: lines) {
            // check for blank CSV lines (only commas)
            if (line.replaceAll(‘,’,”).trim().length() == 0) break;

            List<String> fields = line.split(‘,’); 
            List<String> cleanFields = new List<String>();
            String compositeField;
            Boolean makeCompositeField = false;
            for(String field: fields) {
                if (field.startsWith(‘”‘) && field.endsWith(‘”‘)) {
                    cleanFields.add(field.replaceAll(‘DBLQT’,'”‘));
                } else if (field.startsWith(‘”‘)) {
                    makeCompositeField = true;
                    compositeField = field;
                } else if (field.endsWith(‘”‘)) {
                    compositeField += ‘,’ + field;
                    cleanFields.add(compositeField.replaceAll(‘DBLQT’,'”‘));
                    makeCompositeField = false;
                } else if (makeCompositeField) {
                    compositeField +=  ‘,’ + field;
                } else {
                    cleanFields.add(field.replaceAll(‘DBLQT’,'”‘));
                }
            }

            allFields.add(cleanFields);
        }
        if (skipHeaders) allFields.remove(0);
        return allFields;      
    }

}

 

 

HTML WYSIWYG editor for fields in Salesforce using Visualforce

This is something I wanted to play around with ever since I first saw something similar demoed back in Dreamforce '07. To the best of my knowledge, there still isn't a native VisualForce component for this. My earlier effort was an Scontrol, but I really wanted to take advantage of VF's speed. So, here's my stab at it.
 

<!--- Proof of concept WYSIWYG Editor
references
http://dojotoolkit.org/book/dojo-book-0-9/part-2-dijit/
advanced-editing-and-display/editor-rich-text

-->

<apex:page StandardController="Account">
<apex:stylesheet
value="http://ajax.googleapis.com/ajax/libs/dojo/1.2.0/
dijit/themes/tundra/tundra.css
"/>
<apex:stylesheet
value="http://ajax.googleapis.com/ajax/libs/dojo/1.2.0/
dojo/resources/dojo.css
"/>
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/dojo/1.2.0/
dojo/dojo.xd.js
"
djConfig="parseOnLoad: true"/>
<script type="text/javascript">
dojo.require("dojo.parser");
dojo.require("dijit.Editor");
</script>
<apex:sectionHeader title="Sample WYSIWYG editor
using Visualforce and Dojo"></apex:sectionHeader>
<apex:form id="editorForm">
<apex:pageBlock ><apex:pageBlockButtons >
<apex:commandButton action="{!save}" value="Save"
id="theButton"/>
</apex:pageBlockButtons>
<div class="tundra"
style="background-color: #f5f5f5;width:400px;">
<textarea id="editor1" name="editor1"
   dojoType="dijit.Editor" inheritWidth="false"
    name="tmpTextString"
   onBlur="document.getElementById('{!$Component.descript}')
    .value = dijit.byId('editor1').getValue(false)">
{!Account.description}
</textarea>
<apex:inputHidden id="descript"
value="{!Account.description}"></apex:inputHidden>

</div>
</apex:pageBlock></apex:form>
</apex:page>

 

The above code provides a working example (Note:check for line breaks when you copy and paste) of a inline editor that provides rich text formatting for the Account description field. I used the Dojo Toolkit. You'll see that it references javascript files stored on Google's Ajax API site. I would suggest uploading the library as a static resource instead.

To eliminate the need for a custom controller, I used javascipt to write the text from the editor field to the Account.Description field once the editor looses focus (onBlur). That way the standard controller save function takes care of the rest.