• J Keener
  • NEWBIE
  • 10 Points
  • Member since 2007

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 5
    Questions
  • 9
    Replies
When I render a vf page normally with Chinese characters on it, everything works fine.  If I attempt to render it as a PDF however, the Chinese characters are skipped.
 
The challenge here is that we are rolled out globally, with hundreds of users in China.  A number of accounts and contacts are entered in Chinese. 
 
page rendered as HTML:
 
 
 
page rendered as PDF, missing the Account Name:
 
 
 
 
Is there any way to support multi-character sets when rendering to a PDF?
 
Jon Keener
I've developed a Visualforce page that is working fine in Firefox 3 (Where I did all of my testing), but when I run it in IE6, an actionSupport is not working at all.  I've created the following set of code to reproduce the issue that I'm seeing.

Visualforce Page:
Code:
<apex:page controller="TestController1" tabStyle="Account">
  <apex:form >
    <apex:pageBlock title="Test Page Block" id="Test_PageBlock">
        <apex:pageBlockSection columns="1" collapsible="false">
            <apex:facet name="header">
                <apex:outputPanel>
                    <CENTER>
                    <apex:outputText value="Number of Accounts"/>
                    <apex:selectList value="{!Num_Accounts}" size="1" multiselect="false">
                        <apex:selectOptions value="{!Num_Accounts_items}"/>
                    </apex:selectList>
                    <apex:actionSupport event="onchange" rerender="Test_PageBlock" status="status_Test_PageBlock_filtering"/>
                    <apex:actionStatus id="status_Test_PageBlock_filtering" startText=" Requesting..."/>
                    </CENTER>
                </apex:outputPanel>
            </apex:facet>
            <apex:dataTable value="{!Accounts}" var="lines" styleClass="list" id="accountsSection" width="100%">
                <apex:column style="width: 150px" >
                    <apex:facet name="header"><b>Account Name(s)</b></apex:facet>
                    <apex:outputText value="{!lines.Name}"  />
                </apex:column>
            </apex:dataTable>
        </apex:pageBlockSection>
    </apex:pageBlock>
  </apex:form>
</apex:page>

 
Controller:
Code:
public class TestController1 {

    public String Num_Accounts { get; set; }

    public TestController1() {Num_Accounts = '1';}

    public List<SelectOption> getNum_Accounts_items() {
        List<SelectOption> options = new List<SelectOption>();
        options.add(new SelectOption('1','Top 1 Record'));
        options.add(new SelectOption('2','Top 2 Records'));
        options.add(new SelectOption('3','Top 3 Records'));
        return options;
    }

    public List<Account> getAccounts() {
        List<Account> results;
        if (Num_Accounts == '1') {results = [SELECT Name FROM Account LIMIT 1];}
        if (Num_Accounts == '2') {results = [SELECT Name FROM Account LIMIT 2];}
        if (Num_Accounts == '3') {results = [SELECT Name FROM Account LIMIT 3];}
        return results;
    }
}


Basically, when the picklist value is changed, the PageBlock is supposed to be rerendered and the Account dataTable will reflect the new results.  The actionSupport is doing this correctly in firefox, but in IE6, nothing happens when the picklist is changed.

Does anyone have any idea as to the best approach to get this to work correctly in IE6?  Most of our end users are still using IE6.

Jon Keener
jhkeener@ashland.com
 


I'm in the process of converting an s-control to a Visualforce page, and the only stumbling block I've ran into is sending the page to the printer.

As a background, in the s-control, I had added the following code to the top and bottom of the s-control to provide "Print Screen" buttons that allowed for printing.

Code:
     <form name="PrintInformationTop">
        <input type="button" name="PrintInformationTop" value=" Print Screen " onClick = "window.print()">
     </form>

 The above code worked nicely by bringing up the standard print dialog and the output generated nicely.  In addition, it only printed the s-control frame and did not print the top tabs nor the sidebar.

When I placed the above code into Visualforce page, it continues to work, but it does not exclude the top tabs and the sidebar.  I'm assuming visualforce pages are not rendering in the same sort of a frame as s-controls did.

In addition, as you can see in the screenshots below, I've got a bit of basic formatting to do on the visualforce pages so that they print nicely with grids, etc. 

My initial question is what is the best way to print a Visualforce page to exclude the top bar and the side bar?

Secondly, for the formatting, based on what I found on the discussion boards, I was considering using "media" stylesheets to try to cleanup the look and feel for printing.  Visually on the page, the Visualforce page looks great, but when printed without gridlines, it doesn't read as well as the old s-control page.  Below is a snippet of what I found elsewhere in the discussion forum that I was going to try and use?  Does this seem to be the best approach to doing this?

Code:
style type="text/css" media="print">
...
</style>

 
I did review the solutions regarding displaying a Visualforce page as a PDF, and although I like that functionality, I don't know if it would help in this instance.  When I display this page, It contains a lot of historical actiivities.  By default the descriptions for these activities are hidden, but "Show"/"Hide" functionality exists so that a user can unhide the descriptions they want to print prior to printing.  What I can tell about the PDF functionality, it redraws the Visualforce page from scratch, so if I used some of the current methods discussed, if I had the button generate a PDF version, it would be a brand new page of the Visualforce page, not one where the user has made a number of changes upon.  If I'm incorrect on this one, let me know, because this would be a nice way of handling it.  (I know when calling the PDF version of the page, I could try to pass parameters, but this would get pretty complex with hundreds of activities...)

Thanks for any ideas!

Jon Keener
jhkeener@ashland.com






I've been tasked with putting a number of tabs into Salesforce.com that access internal intranet sites via web links.  These sites will obviously not work correctly if someone is connecting outside of our intranet.  What I would like to do, is proactively present the users a message if they go to this tab that tells them something like: "To use this functionality, you need to have access to the Intranet.  To do so, please run your xyz vpn software and then return to this tab."

What I'm brainstorming is how to tell if a user is on our intranet, so I can perform the above.

Option 1, would be to somehow either ping, or connect to the page and if it errors, capture the error somehow and present my message.

Option 2, would be to look at the users originating IP Address.  In our case, we are coming from behind a proxy, so everyone's IP address appears to Salesforce as the same IP if they are connected to our intranet. 

Looking at those two options, Option 2 seems the most feasible.  Unfortunately, I don't see a way in APEX to obtain the users originating IP address.  I'm wondering if I am missing something, or if maybe the right answer to obtaining the IP address might be to include some additional Javascript in the VF page to try to obtain it. 

If anyone has done something similar, please let me know!

Thanks!

Jon Keener
jhkeener@ashland.com

I've built a simple trigger that will stop an update to a record based on a user's profile.  In building a test method for this trigger, I don't see any way to simulate both sides of the processing, since the logic in the trigger is dependant on the results of the getUserInfo calls. 
 
The issue, is how to get to 100% code coverage in a test method in this sort of situation?
 
What I'd like to be able to do in my test method is the following:
 
using my current admin login,
update 200 records  (These would succeed, as the admin profile is allowed to make the updates)
 
switch login to a non-admin user login
update 200 records (These would not succeed, and the addError would be applied to the appropriate fields)
 
Jon Keener
 

I temporarily deactivated an Approval Process because I need to remove some of the Approval Steps. I still don't see any options for removing them. I see remove links for Initial Submission Actions, Final Approval Actions , Final Rejection Actions but not in the Approval Steps section. What gives?

Warning, this thread has a lot of data to take in but if you like a good challenge continue on.....

200,000 script statements!?! What the heck are you doing?

Business Problem:
Our sales team sends out e-mails to massive company wide e-mail distributions lists asking, "Does anyone know of a company in Industry X using one of our products for application Y. Due to sharing rules running reports doesn't return all of our results and our sales team has reporting phobia even if this was an option. :smileywink:.

Solution:
What we are trying to do is create a custom VF page that is like a sales wins portal / advanced search interface. There are a few pick lists, Industry, Application, etc. A user selects values then hits submit and Apex runs a dynamic SOQL search on opportunities to find all of these results.

Technical Problem:
When displaying the data the results should not show individual opps but group these by accounts. It should also display the list so that the largest accounts are at the top of the list. If SOQL had SUM and GROUP BY options everything would be great but alas this is not an option. So what I have done when querying the opps is order them by AccountId. As the loop cycles through these opps it sums up the opp amounts and when it detects an AccountID change creates Account container that can be displayed on the page.

The next step is to add the "Account" to a List but this list must be in order from largest to smallest. So what I have done is create an algorithm that grabs two objects and compares the values to each. If it is less that the first but greater than the second it takes the index of the second.

With all this manual grouping and sorting I sometimes hit the script statement limits.

The Challenge:
Obviously my algorithms are not very efficient. I am not a classically trained programmer (learned must of it on my own) so I don't really know all the slick algorithm tricks a seasoned developer may know. So finally, is there a better/more efficient way of doing this to reduce my script statements or am I just out of luck?

The Code:

Code:
List<cAccount> resultsAcct = new List<cAccount>();
Opportunity holder;
Decimal totalAmount = 0;
Integer count = 0;
   
for(Opportunity opp : Database.query(queryString)){
 
 boolean added = false;
 
 //------There was a change in accounts-------
 //holder.Account.Id  is the account Id of the previous opp in this loop so if they don't match account grouping has changed
 if(holder != null && opp.Account.Id != holder.Account.Id){
  cAccount newAcct = new cAccount();
  newAcct.accountName = holder.Account.Name;
  newAcct.accountID = holder.AccountId;
  newAcct.info.amount = totalAmount;
  newAcct.info.OwnerID = holder.Account.OwnerId;
  newAcct.info.Theater__c = holder.Account.Theater__c;
  
  //If there is only one entry in our set we only have one comparison to make
  if(resultsAcct.Size() == 1){
   if(newAcct.info.amount > resultsAcct[0].info.amount){
    added = true;
    resultsAcct.add(0,newAcct);
   }
  //Here is the meat and potatoes 
  //Basically compares the new value to indexes 0-1, then 1-2 then 2-3, and then insert accordingly
  }else if(resultsAcct.Size() > 1){
   for(Integer i = 0; i < resultsAcct.Size()-1; i++){
    cAccount acctCompareHigh = resultsAcct[i];
    cAccount acctCompareLow = resultsAcct[i+1];
      
    if(newAcct.info.amount >= acctCompareHigh.info.amount){
     added = true;
     resultsAcct.add(0,newAcct);
     break;
    }else if(newAcct.info.amount < acctCompareHigh.info.amount && newAcct.info.amount >= acctCompareLow.info.amount){
     added = true;
     resultsAcct.add(i+1,newAcct);
     break;
    }
   }
   if(added == false){
    resultsAcct.add(newAcct);
   }
  //This is entered if the size = 0 
  }else{
   resultsAcct.add(newAcct);
  }
  totalAmount = 0;
 }
 //-------------------------------------------------           
 if(opp.Amount == null){
  opp.Amount = 0;
 }
 totalAmount += opp.Amount;
 holder = opp;
}

//cAccount class / container
public class cAccount{
 public Opportunity info {get; set;}
 public String accountName {get; set;}
 public ID accountId {get; set;}
 
 public cAccount(){
  info = new Opportunity();
 }
}

Thanks a ton!
-Jason


Admins/Mods: I debated on what board to post this on (Apex/VF) as it is Apex but I am working with it for the sole purpose of formatting the data to be displayed on a VF page. Feel free to move it you deem necessary.



Message Edited by TehNrd on 09-19-2008 04:32 PM
  • September 19, 2008
  • Like
  • 0
I've developed a Visualforce page that is working fine in Firefox 3 (Where I did all of my testing), but when I run it in IE6, an actionSupport is not working at all.  I've created the following set of code to reproduce the issue that I'm seeing.

Visualforce Page:
Code:
<apex:page controller="TestController1" tabStyle="Account">
  <apex:form >
    <apex:pageBlock title="Test Page Block" id="Test_PageBlock">
        <apex:pageBlockSection columns="1" collapsible="false">
            <apex:facet name="header">
                <apex:outputPanel>
                    <CENTER>
                    <apex:outputText value="Number of Accounts"/>
                    <apex:selectList value="{!Num_Accounts}" size="1" multiselect="false">
                        <apex:selectOptions value="{!Num_Accounts_items}"/>
                    </apex:selectList>
                    <apex:actionSupport event="onchange" rerender="Test_PageBlock" status="status_Test_PageBlock_filtering"/>
                    <apex:actionStatus id="status_Test_PageBlock_filtering" startText=" Requesting..."/>
                    </CENTER>
                </apex:outputPanel>
            </apex:facet>
            <apex:dataTable value="{!Accounts}" var="lines" styleClass="list" id="accountsSection" width="100%">
                <apex:column style="width: 150px" >
                    <apex:facet name="header"><b>Account Name(s)</b></apex:facet>
                    <apex:outputText value="{!lines.Name}"  />
                </apex:column>
            </apex:dataTable>
        </apex:pageBlockSection>
    </apex:pageBlock>
  </apex:form>
</apex:page>

 
Controller:
Code:
public class TestController1 {

    public String Num_Accounts { get; set; }

    public TestController1() {Num_Accounts = '1';}

    public List<SelectOption> getNum_Accounts_items() {
        List<SelectOption> options = new List<SelectOption>();
        options.add(new SelectOption('1','Top 1 Record'));
        options.add(new SelectOption('2','Top 2 Records'));
        options.add(new SelectOption('3','Top 3 Records'));
        return options;
    }

    public List<Account> getAccounts() {
        List<Account> results;
        if (Num_Accounts == '1') {results = [SELECT Name FROM Account LIMIT 1];}
        if (Num_Accounts == '2') {results = [SELECT Name FROM Account LIMIT 2];}
        if (Num_Accounts == '3') {results = [SELECT Name FROM Account LIMIT 3];}
        return results;
    }
}


Basically, when the picklist value is changed, the PageBlock is supposed to be rerendered and the Account dataTable will reflect the new results.  The actionSupport is doing this correctly in firefox, but in IE6, nothing happens when the picklist is changed.

Does anyone have any idea as to the best approach to get this to work correctly in IE6?  Most of our end users are still using IE6.

Jon Keener
jhkeener@ashland.com
 


I've been tasked with putting a number of tabs into Salesforce.com that access internal intranet sites via web links.  These sites will obviously not work correctly if someone is connecting outside of our intranet.  What I would like to do, is proactively present the users a message if they go to this tab that tells them something like: "To use this functionality, you need to have access to the Intranet.  To do so, please run your xyz vpn software and then return to this tab."

What I'm brainstorming is how to tell if a user is on our intranet, so I can perform the above.

Option 1, would be to somehow either ping, or connect to the page and if it errors, capture the error somehow and present my message.

Option 2, would be to look at the users originating IP Address.  In our case, we are coming from behind a proxy, so everyone's IP address appears to Salesforce as the same IP if they are connected to our intranet. 

Looking at those two options, Option 2 seems the most feasible.  Unfortunately, I don't see a way in APEX to obtain the users originating IP address.  I'm wondering if I am missing something, or if maybe the right answer to obtaining the IP address might be to include some additional Javascript in the VF page to try to obtain it. 

If anyone has done something similar, please let me know!

Thanks!

Jon Keener
jhkeener@ashland.com

I've built a simple trigger that will stop an update to a record based on a user's profile.  In building a test method for this trigger, I don't see any way to simulate both sides of the processing, since the logic in the trigger is dependant on the results of the getUserInfo calls. 
 
The issue, is how to get to 100% code coverage in a test method in this sort of situation?
 
What I'd like to be able to do in my test method is the following:
 
using my current admin login,
update 200 records  (These would succeed, as the admin profile is allowed to make the updates)
 
switch login to a non-admin user login
update 200 records (These would not succeed, and the addError would be applied to the appropriate fields)
 
Jon Keener
 
Since visualForce doesn't have good  error handling for custom controllers, I am  writing some custom code show error messages.

My custom controller is editing a table.

In the code below, I am a trying to insert a line feed after every error using '\n'. 

However,  when error messages are output, there are no separate lines - it is one big error message. i have tried '\r' as well - doesn't work.

Any thoughts.

Code:
       } catch (DmlException e) {
for (Integer i = 0; i < e.getNumDml(); i++) { string[] fields = e.getDmlFields(i); //strip __c string field = fields[0].subString(0,fields[0].length()-3); integer row = e.getDmlIndex(i); String rowError = 'Row:' + (row+1) + ' Field:' + field + ':' + e.getDMLMessage(i); if (ErrorString[0] <> null) { ErrorString = ErrorString + '\n' + rowError; } else { ErrorString = 'ERROR:' + rowError + '\n'; } }