• SalesForceGirl
  • NEWBIE
  • 0 Points
  • Member since 2011

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 3
    Questions
  • 16
    Replies

I have been having some serious issues getting maps to work like they should in VF pages, but it seems that the functions we have to check if it has null or blank values don't really work for maps. Here is a simple example of what I am trying to do:

<apex:page showHeader="true" sidebar="true" controller="sfg_ContactPhotos">
  <apex:repeat value="{!lstOfContacts}" var="c">

    <apex:image rendered="{!ISBLANK(mapOfPhotos[c.Id])}" url="{!URLFOR($Action.Attachment.Download, mapOfPhotos[c.Id])}" width="50" height="50" />

  </apex:repeat>
</apex:page>

 Even it it wasn't an Attachment, it could be anything, the point is that the ISBLANK should see if the map has a value and if not, don't show it, instead it causes an error on the page:


Map key 003J000000T3woPIAR not found in map

Error is in expression '{!ISBLANK(mapOfPhotos[c.Id])}' in component <apex:image> in page sfg_contactphoto
 
I added a debug and the Map key is there, even though the error complains about it not being there.
 
USER_DEBUG|[42]|DEBUG|{003G0000010ItFZIA0=null, 003G0000010JMiwIAG=null, 003J000000Q0n7FIAR=null, 003J000000Q0nBGIAZ=null, 003J000000Q1E9XIAV=null, 003J000000Q1EAyIAN=null, 003J000000SfAzLIAV=00PJ0000000fM1YMAU, 003J000000Shhd2IAB=null, 003J000000T3wmxIAB=00PJ0000000fsDfMAI, 003J000000T3woPIAR=null, ...}
 
At the very least the error should say something like:
 
Map value not found in Map 
 
Regardless, is there a VF function to check maps? I am trying to give sfdc the benefit of the doubt that I am just using the wrong function, but when looking at the documentation there seems to be nothing. I even tried NULLVALUE even though its not exactly what I need since it has an alternate value instead of boolean likst ISBLANK and so can't really be used in the rendered attribute. I even tried changing it so that it wasnt an Object or Id, and to a String, but then the Attachment complains that its not the correct type of value:
 
Invalid parameter for function URLFOR
Error is in expression '{!URLFOR($Action.Attachment.Download, mapOfPhotos[c.Id])}' in component <apex:page> in page sfg_contactphoto

I also tried conveting the Id to a string for just the check since it seemed to work above:
 
<apex:image rendered="{!NOT(ISBLANK(TEXT(mapOfPhotos[c.Id])))}" url="{!URLFOR($Action.Attachment.Download, mapOfPhotos[c.Id])}" width="50" height="50" />

 but it just give the same error as the first time:

 

Map key 003J000000T3woPIAR not found in map

Error is in expression '{!ISBLANK(mapOfPhotos[c.Id])}' in component <apex:image> in page sfg_contactphoto

I can get what I need do using an alternative way, but it should work with maps. 
 
here is the controller if anyone is interested:
public class sfg_ContactPhotos {

  public List<Contact> lstOfContacts {get; set;}
  public Map<Id, Id> mapOfPhotos {get; set;}

  public sfg_ContactPhotos() {
    lstOfContacts = findContacts();
    mapOfPhotos = buildPhotoMap(lstOfContacts);
  }

  private List<Contact> findContacts() {
    return [select Name, 
                   Email,
                   (select ContentType
                    from Attachments
                    where isPrivate = false
                    order by LastModifiedDate desc)
            from Contact
            order by LastModifiedDate desc
            limit 10];
  }

  private Map<Id, Id> buildPhotoMap(List<Contact> pContacts) {
    if (pContacts.isEmpty()) {
      return new Map<Id, Id>();
    }

    Map<Id, Id> returnMap = new Map<Id, Id>();
    for (Contact c : pContacts) {
      for (Attachment a : c.Attachments) {
        if (returnMap.containsKey(c.Id)) {
          break;
        }
        if (a.ContentType.contains('image/')) {
          returnMap.put(c.Id, a.Id);
          break;
        }
      }
      if (!returnMap.containsKey(c.Id)) {
        returnMap.put(c.Id, null);
      }
    }
    return returnMap;
  }

}

 


Right now it seems that anything with the <apex:selectCheckboxes> wont work (regardless of version since I did try bumping it back on both the page and controller). See blog entry for full debugging steps:http://salesforcegirl.blogspot.hu/2013/05/bug-with.html

when trying to use a repeat to populate the Lists via maps it fails as well for both<apex:selectCheckboxes> and <apex:selectList>. But if you do it the long way(like shown bellow), you can get<apex:selectList> to work at the very least, however not the <apex:selectCheckboxes> (which is what i need).

Here is the code:

public class sfg_testBugWithActionButton {

  public String fGrade {get; set;}
  public List<SelectOption> soGrade {get; set;}
  public String resultString {get; set;}

  public sfg_testBugWithActionButton() {
    createfilterMap();
    resultString = 'on Load of page';
  }

  public PageReference preformAction() {
    system.debug('Grade: ' + fGrade);//this wont be hit unless you use selectList
    resultString = 'button action preformed';
    return null;
  }

  private void createfilterMap() {
    soGrade = new List<SelectOption>();
    soGrade.add(new SelectOption('A', 'A'));
    soGrade.add(new SelectOption('B', 'B'));
    soGrade.add(new SelectOption('C', 'C'));
  }

}

Page:

<apex:page showHeader="true" sidebar="true" controller="sfg_testBugWithActionButton">
  <apex:form>
  <apex:outputpanel id="mainWrap">

    <h2>Grade</h2>
    <apex:selectCheckboxes value="{!fGrade}" layout="pageDirection">
      <apex:selectOptions value="{!soGrade}" />
    </apex:selectCheckboxes>

    <apex:commandButton action="{!preformAction}" rerender="renderWrap" value="Submit Action" />
    <br />

    <apex:outputpanel id="renderWrap">
      {!resultString}
    </apex:outputpanel>

  </apex:outputpanel>
  </apex:form>
</apex:page>

In the Contact edit there is a name prefix that allows you to select Mr. Mrs, Dr etc, but I find no reference to this field, and on the edit it appears to be apart of the FirstName field, however when you do and apex:inputfield with firstname it only shows an input box for the actual first name, not to mention that there is no way to save to this 'field' so if I wanted to make a custom contact create, it wont allow me to show/populate it on the record... Which leads me to think that I would need to make a custom field, but that isn't the answer. This field should be accessible via the API. 

I have been having some serious issues getting maps to work like they should in VF pages, but it seems that the functions we have to check if it has null or blank values don't really work for maps. Here is a simple example of what I am trying to do:

<apex:page showHeader="true" sidebar="true" controller="sfg_ContactPhotos">
  <apex:repeat value="{!lstOfContacts}" var="c">

    <apex:image rendered="{!ISBLANK(mapOfPhotos[c.Id])}" url="{!URLFOR($Action.Attachment.Download, mapOfPhotos[c.Id])}" width="50" height="50" />

  </apex:repeat>
</apex:page>

 Even it it wasn't an Attachment, it could be anything, the point is that the ISBLANK should see if the map has a value and if not, don't show it, instead it causes an error on the page:


Map key 003J000000T3woPIAR not found in map

Error is in expression '{!ISBLANK(mapOfPhotos[c.Id])}' in component <apex:image> in page sfg_contactphoto
 
I added a debug and the Map key is there, even though the error complains about it not being there.
 
USER_DEBUG|[42]|DEBUG|{003G0000010ItFZIA0=null, 003G0000010JMiwIAG=null, 003J000000Q0n7FIAR=null, 003J000000Q0nBGIAZ=null, 003J000000Q1E9XIAV=null, 003J000000Q1EAyIAN=null, 003J000000SfAzLIAV=00PJ0000000fM1YMAU, 003J000000Shhd2IAB=null, 003J000000T3wmxIAB=00PJ0000000fsDfMAI, 003J000000T3woPIAR=null, ...}
 
At the very least the error should say something like:
 
Map value not found in Map 
 
Regardless, is there a VF function to check maps? I am trying to give sfdc the benefit of the doubt that I am just using the wrong function, but when looking at the documentation there seems to be nothing. I even tried NULLVALUE even though its not exactly what I need since it has an alternate value instead of boolean likst ISBLANK and so can't really be used in the rendered attribute. I even tried changing it so that it wasnt an Object or Id, and to a String, but then the Attachment complains that its not the correct type of value:
 
Invalid parameter for function URLFOR
Error is in expression '{!URLFOR($Action.Attachment.Download, mapOfPhotos[c.Id])}' in component <apex:page> in page sfg_contactphoto

I also tried conveting the Id to a string for just the check since it seemed to work above:
 
<apex:image rendered="{!NOT(ISBLANK(TEXT(mapOfPhotos[c.Id])))}" url="{!URLFOR($Action.Attachment.Download, mapOfPhotos[c.Id])}" width="50" height="50" />

 but it just give the same error as the first time:

 

Map key 003J000000T3woPIAR not found in map

Error is in expression '{!ISBLANK(mapOfPhotos[c.Id])}' in component <apex:image> in page sfg_contactphoto

I can get what I need do using an alternative way, but it should work with maps. 
 
here is the controller if anyone is interested:
public class sfg_ContactPhotos {

  public List<Contact> lstOfContacts {get; set;}
  public Map<Id, Id> mapOfPhotos {get; set;}

  public sfg_ContactPhotos() {
    lstOfContacts = findContacts();
    mapOfPhotos = buildPhotoMap(lstOfContacts);
  }

  private List<Contact> findContacts() {
    return [select Name, 
                   Email,
                   (select ContentType
                    from Attachments
                    where isPrivate = false
                    order by LastModifiedDate desc)
            from Contact
            order by LastModifiedDate desc
            limit 10];
  }

  private Map<Id, Id> buildPhotoMap(List<Contact> pContacts) {
    if (pContacts.isEmpty()) {
      return new Map<Id, Id>();
    }

    Map<Id, Id> returnMap = new Map<Id, Id>();
    for (Contact c : pContacts) {
      for (Attachment a : c.Attachments) {
        if (returnMap.containsKey(c.Id)) {
          break;
        }
        if (a.ContentType.contains('image/')) {
          returnMap.put(c.Id, a.Id);
          break;
        }
      }
      if (!returnMap.containsKey(c.Id)) {
        returnMap.put(c.Id, null);
      }
    }
    return returnMap;
  }

}

 


Right now it seems that anything with the <apex:selectCheckboxes> wont work (regardless of version since I did try bumping it back on both the page and controller). See blog entry for full debugging steps:http://salesforcegirl.blogspot.hu/2013/05/bug-with.html

when trying to use a repeat to populate the Lists via maps it fails as well for both<apex:selectCheckboxes> and <apex:selectList>. But if you do it the long way(like shown bellow), you can get<apex:selectList> to work at the very least, however not the <apex:selectCheckboxes> (which is what i need).

Here is the code:

public class sfg_testBugWithActionButton {

  public String fGrade {get; set;}
  public List<SelectOption> soGrade {get; set;}
  public String resultString {get; set;}

  public sfg_testBugWithActionButton() {
    createfilterMap();
    resultString = 'on Load of page';
  }

  public PageReference preformAction() {
    system.debug('Grade: ' + fGrade);//this wont be hit unless you use selectList
    resultString = 'button action preformed';
    return null;
  }

  private void createfilterMap() {
    soGrade = new List<SelectOption>();
    soGrade.add(new SelectOption('A', 'A'));
    soGrade.add(new SelectOption('B', 'B'));
    soGrade.add(new SelectOption('C', 'C'));
  }

}

Page:

<apex:page showHeader="true" sidebar="true" controller="sfg_testBugWithActionButton">
  <apex:form>
  <apex:outputpanel id="mainWrap">

    <h2>Grade</h2>
    <apex:selectCheckboxes value="{!fGrade}" layout="pageDirection">
      <apex:selectOptions value="{!soGrade}" />
    </apex:selectCheckboxes>

    <apex:commandButton action="{!preformAction}" rerender="renderWrap" value="Submit Action" />
    <br />

    <apex:outputpanel id="renderWrap">
      {!resultString}
    </apex:outputpanel>

  </apex:outputpanel>
  </apex:form>
</apex:page>

In the Contact edit there is a name prefix that allows you to select Mr. Mrs, Dr etc, but I find no reference to this field, and on the edit it appears to be apart of the FirstName field, however when you do and apex:inputfield with firstname it only shows an input box for the actual first name, not to mention that there is no way to save to this 'field' so if I wanted to make a custom contact create, it wont allow me to show/populate it on the record... Which leads me to think that I would need to make a custom field, but that isn't the answer. This field should be accessible via the API. 

I have created a customer portal for our VIP accounts with force.com sites, so they can log in and see any tickets(cases) under there account, and be able to submit new ones or add comments or attachments to current ones.

 

I have managed to create all of it with no trouble, except for the attachments piece. I can't even display existing attachments that may be on the ticket(case), it errors out the page. I am wondering if there is any sort of permissions issue with seeing attachments and sites/portal users? 

 

I have the table set up to only render if there is results from the query, and the table shows, but the data wont(since I have to make the get method return null.... Or the page wont load...)

 

here is the code I am using to get the existing attachments:

 

//get the id of the case so we can look for attachments in it
String pageid = ApexPages.currentPage().getParameters().get('id');
public string getPageid(){
return pageid;
}
//set the table to false so it wont show unless there is data
Boolean renderattachmentlist = false;
//run the query and render the list if there is data
public Boolean getRenderattachmentlist(){
getAttachmentResults();
return renderattachmentlist;
}
//select the attachment data to be shown from the case
public Attachment[] getAttachmentResults(){
Attachment[] attachmentInfo = [Select ParentId, Name, Id, CreatedDate, CreatedById From Attachment where ParentId = :pageid ORDER BY CreatedDate DESC];
//if there is data show the list
if(attachmentInfo.size() > 0){
renderattachmentlist = true;
}
return attachmentInfo;
}

 at the end of the getAttachmentResults() method I have it set to return null since the page wont load if I leave it as shown above.

 

Since I can't even get the existing attachments to show I figure it must be some sort of permissions issue. Can this be changed or fixed? 

 

The other piece that isn't working is adding new attachments, but I figure its for the same reason as above....

 

HELP!


 

Message Edited by tankgirlrs on 12-01-2009 09:56 AM