function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
tankgirlrstankgirlrs 

Issue with Attachments

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
Best Answer chosen by Admin (Salesforce Developers) 
tankgirlrstankgirlrs

Ok i found the solution, It was a one line fix of the following in my select statement:

 

public Attachment[] getAttachmentResults(){
Attachment[] attachmentInfo = [Select CreatedBy.Name,ParentId, Name, Id, CreatedDate, CreatedById From Attachment where ParentId = :pageid ORDER BY CreatedDate DESC];
if(attachmentInfo.size() > 0){
renderattachmentlist = true;
}
return attachmentInfo;
}

 

 so to take a closer look at what changed:

//This:

[Select ParentId, Name, Id, CreatedDate, CreatedById From Attachment where ParentId = :pageid ORDER BY CreatedDate DESC];

//To this:

[Select CreatedBy.Name,ParentId, Name, Id, CreatedDate, CreatedById From Attachment where ParentId = :pageid ORDER BY CreatedDate DESC];

Apperantly that was all it was that was perventing my data from showing on the VFpage.... 

 

The other piece i was having trouble with was the actual act of uploading a file to the case and it wasnt working but what was happening was that the apex:inputfile couldnt be on the same 'page' as a rerender, so it would in effect brake any rerender and not work if it had renender on it as well...(if it cant have it than why does it have rerender as an attribute???) So the fix was to put the file upload in its own apex:component and also i needed to add 'allowDML="true"' to the apex:component tag to allow it to actually upload a file.

so for thouse who want to know how to do it easly here is the code:

 

String newCurTicketAttachmentName;
Blob newCurTicketAttachmentBody;

public String getNewCurTicketAttachmentName(){
return newCurTicketAttachmentName;
}
public void setNewCurTicketAttachmentName(string s){
this.newCurTicketAttachmentName = s;
}
public Blob getNewCurTicketAttachmentBody(){
return newCurTicketAttachmentBody;
}
public void setNewCurTicketAttachmentBody(Blob b){
this.newCurTicketAttachmentBody = b;
}
public PageReference saveCurAttachment(){
Attachment a = new Attachment();
a.Body = newCurTicketAttachmentBody;
a.Name = newCurTicketAttachmentName;
a.IsPrivate = false;
a.ParentId = pageid;
try{
insert a;
update a;
return null;
}catch(exception e){
return null;
}
}

 and the visualforce component:

 

<apex:component id="pFileUploadComponent" controller="MainProtalController" allowDML="true">

<apex:inputFile value="{!newCurTicketAttachmentBody}" filename="{!newCurTicketAttachmentName}" size="75" styleclass="inputfilebox"/>

<apex:commandButton value="Save" action="{!saveCurAttachment}" status="loadingcasestatus"/>

</apex:component>

 

 

:-) 

 

 

Message Edited by tankgirlrs on 12-02-2009 10:14 AM

All Answers

BulentBulent

the portal user profile must have read access to the parent object and must be able to read the parent record (sharing settings)

 

tankgirlrstankgirlrs

Ok i found the solution, It was a one line fix of the following in my select statement:

 

public Attachment[] getAttachmentResults(){
Attachment[] attachmentInfo = [Select CreatedBy.Name,ParentId, Name, Id, CreatedDate, CreatedById From Attachment where ParentId = :pageid ORDER BY CreatedDate DESC];
if(attachmentInfo.size() > 0){
renderattachmentlist = true;
}
return attachmentInfo;
}

 

 so to take a closer look at what changed:

//This:

[Select ParentId, Name, Id, CreatedDate, CreatedById From Attachment where ParentId = :pageid ORDER BY CreatedDate DESC];

//To this:

[Select CreatedBy.Name,ParentId, Name, Id, CreatedDate, CreatedById From Attachment where ParentId = :pageid ORDER BY CreatedDate DESC];

Apperantly that was all it was that was perventing my data from showing on the VFpage.... 

 

The other piece i was having trouble with was the actual act of uploading a file to the case and it wasnt working but what was happening was that the apex:inputfile couldnt be on the same 'page' as a rerender, so it would in effect brake any rerender and not work if it had renender on it as well...(if it cant have it than why does it have rerender as an attribute???) So the fix was to put the file upload in its own apex:component and also i needed to add 'allowDML="true"' to the apex:component tag to allow it to actually upload a file.

so for thouse who want to know how to do it easly here is the code:

 

String newCurTicketAttachmentName;
Blob newCurTicketAttachmentBody;

public String getNewCurTicketAttachmentName(){
return newCurTicketAttachmentName;
}
public void setNewCurTicketAttachmentName(string s){
this.newCurTicketAttachmentName = s;
}
public Blob getNewCurTicketAttachmentBody(){
return newCurTicketAttachmentBody;
}
public void setNewCurTicketAttachmentBody(Blob b){
this.newCurTicketAttachmentBody = b;
}
public PageReference saveCurAttachment(){
Attachment a = new Attachment();
a.Body = newCurTicketAttachmentBody;
a.Name = newCurTicketAttachmentName;
a.IsPrivate = false;
a.ParentId = pageid;
try{
insert a;
update a;
return null;
}catch(exception e){
return null;
}
}

 and the visualforce component:

 

<apex:component id="pFileUploadComponent" controller="MainProtalController" allowDML="true">

<apex:inputFile value="{!newCurTicketAttachmentBody}" filename="{!newCurTicketAttachmentName}" size="75" styleclass="inputfilebox"/>

<apex:commandButton value="Save" action="{!saveCurAttachment}" status="loadingcasestatus"/>

</apex:component>

 

 

:-) 

 

 

Message Edited by tankgirlrs on 12-02-2009 10:14 AM
This was selected as the best answer
saharisahari

hie.

Using your code I can successfully upload new attachments as a portal authenticated user.

But I am also displaying list of existing attachments. I have no prob till here.

But to download these attachemnst is where I am facing the prob. Here I am enabling attachment names as links to donwload.

But when i click the, I get insufficient priviliges.

Were you able to download the existing attachments?

 

Thanks for any help.

Bob_zBob_z

Is there a way to use attachements on a new case submission? 

I am trying to build a force.com case page with the ability to attach files before the user submit the case.

 

Is this possible? or is there a way for a redirect page to popup and give the customer the option to attach a file?

SalesForceGirlSalesForceGirl

Yes, this is possible. 

 

On the back end, after you have inserted the case, you need to used that id to link the attachment to the case. Of cores you wouldn't need the case variables if you were doing an extension class from case. But you would need the Attachment variables. 

 

Public string sCaseSubject{get;set;}
public string sCaseEmail{get;set;}
public string sAttName{get;set;}
public blob sAttBody{get;set;}
public string sAttType{get;set;}

Public PageReference CreateCase(){

//create the case
Case cse = new Case();
cse.suppliedEmial = sCaseEmail;
cse.Subject = sCaseSubject;

insert cse;


//create the attachment using the case id
Attachment att = new Attachment();
att.Name = sAttName;
att.IsPrivate = false;
att.ParentId = cse.id;
att.Body = sAttBody;
att.ContentType = sAttType;

insert att;

return null;
}

 

The trick with attachments is that they can't be in a rerender panel, or in a section that has something rerendereing in it. I have tried a number of ways to make the process more streamline, but you find working with the visual force side of it can be VERY annoying. Let me know if you need any further help :-) and these should also help:

apex:inputFile

Attachments API Ref

 

Bob_zBob_z

So where would i put this code? Am I creating a new class? Sorry i'm new at this. 

SalesForceGirlSalesForceGirl

Yes you would need to write a class. Do you have anything started? What is this for? Is it for a Sites page for the public? Is it going to be internal? Do you want to use the standard Case Controller and write and extension class? Or just write a class? Both have pros and cons, the extension can be more tricky for beginners, but at the same time its easy. 

 

If you have something started, I can help you from there if you share it here.

 

 

Bob_zBob_z

I haven't started anything yet, I was trying to get away wih just setting up a case page with attachments using visualforce and force.com sites.

 

The issue is we started using web 2 case and now customer service needs the ability to attach files to the submitted cases.

 

 

 

 

SalesForceGirlSalesForceGirl

I think it might be best to do a case page, that redirects to an attachment page or popup. This could be easily accomplished by doing a standard controller and one extension class. 

 

The page:

 

<apex:page standardController="Case" extensions="YourClassNameHere">
<script type="text/javascript" language="javascript" src="{!URLFOR($Resource.jQuery, '/js/jquery-1.5.1.min.js')}" ></script>
<script language="javascript" type="text/javascript">

//hides the main Case form and shows the attachment form on complete of the ticket save
function hideAfterClick(){
$('#mainCaseWrap').attr('style','display:none;');
$('#fileUploadWrap').removeAttr('style');
}

</script>
<div id="mainCaseWrap">
<apex:outputpanel id="mainCasePanel">
<apex:pageblock>

<!-- Put all case fields here that are required -->
<apex:pageBlocksection>
<apex:inputfield value="{!Case.SuppliedEmail}" />
<apex:inputfield value="{!Case.SuppliedName}" />
</apex:pageblocksection>

<apex:pageBlocksection>
<apex:inputfield value="{!Case.Subject}" />
<apex:inputfield value="{!Case.Description}" />
</apex:pageblocksection>
</apex:pageBlock>

<apex:commandButton id="submitCaseBottom" action="{!CreateCase}" value="Create" onComplete="hideAfterClick();"></apex:commandButton>

</apex:outputpanel>
</div>

<div id="fileUploadWrap" style="display:none;">
<apex:outputpanel id="FileUpload">

<apex:inputFile size="75" id="fileattachmentinput" value="{!bAttBody}" filename="{!sAttName}" contentType="{!sAttType}"/>

<apex:commandButton value="{!$Label.Save}" action="{!saveAttachment}"/>

</apex:outputpanel>
</div>
</apex:page>

 the controller:

public with sharing class YourClassNameHere{

private Final Case cse;
public string sCaseId{get;set;}
public string sAttName{get;set;}
public blob sAttBody{get;set;}
public string sAttType{get;set;}

public NewTicketCreationCon(ApexPages.StandardController stdController){
	this.cse = (Case)stdController.getRecord();
}

public pageReference CreateTicket(){

/*define the DMLOptions for the Case*/
database.DMLOptions dmo = new database.DMLOptions();
dmo.assignmentRuleHeader.useDefaultRule = useAssignmentRule;

Case c = new Case();
c.SuppliedEmail = cse.SuppliedEmail;
c.SuppliedName = cse.SuppliedName;
c.Subject = cse.Subject;
c.Description = cse.Description;

insert c;
//set the case id so we can use it later
sCaseId = c.id;

c.setOptions(dmo);
update c;

return null;
}

public PageReference saveAttachment(){
if(sCaseId != null && sCaseId.lenght() > 0)
{
Attachment att = new Attachment();
att.Name = sAttName;
att.IsPrivate = false;
att.ParentId = sCaseId;
att.Body = sAttBody;
att.ContentType = sAttType;

insert att;
}
return null;
}

}

 

None of this was tested, but it should work lol

 

Bob_zBob_z

I received an error when creating the apex class for this section

 

public NewTicketCreationCon(ApexPages.StandardController stdController){
    this.cse = (Case)stdController.getRecord();
}

 

Invalid constructor name NewTicketCreationCon

SalesForceGirlSalesForceGirl

sorry, 

 

public NewTicketCreationCon(ApexPages.StandardController stdController){
    this.cse = (Case)stdController.getRecord();

 

the "NewTicketCreationCon" needs to be the name of the class you created.

Bob_zBob_z

another error while creating the visualforce page.

 

I keep getting a Static REsource named jQuery does not exist. Check Spelling

 

<script type="text/javascript" language="javascript" src="{!URLFOR($Resource.jQuery, '/js/jquery-1.5.1.min.js')}" ></script>

 

Also I was gettting a apex:form tag error, so I added them right after <apex:page> and </apex:page>

SalesForceGirlSalesForceGirl

Yes, the apex:form tag is needed b/c of the command buttons, so just add them around the content but inside the page tags. As for the resource, you will need to add your own Setup > develop > Static Resources > new

<script type="text/javascript" language="javascript" src="{!URLFOR($Resource.Name_of_resource, '/File_path_to_desired_file')}" ></script>

 OR

you can just replace that line with 

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript"></script>

 

Bob_zBob_z

Sorry a couple of issue.

 

Should this line of code have the actual name of the assignment rule

dmo.assignmentRuleHeader.useDefaultRule = useDefaultRule;

 

I keep getting a variable does not exist error in eclipse.

 

and on the VF page I am getting a ErrorError: Unknown method 'CaseStandardController.CreateCase()'

 

Thanks

SalesForceGirlSalesForceGirl

if you dont have any dmo options set up then you can nix those lines, in my org we have assignment rules set up so i have to include that each time. 

 

and change the method on the controller that says CreateTicket() to CreateCase()

SalesForceGirlSalesForceGirl

So that method should now look more like:

 

public pageReference CreateCase(){

Case c = new Case();
c.SuppliedEmail = cse.SuppliedEmail;
c.SuppliedName = cse.SuppliedName;
c.Subject = cse.Subject;
c.Description = cse.Description;

insert c;
//set the case id so we can use it later
sCaseId = c.id;

return null;
}

 

And more fields can be added just as i have them above, just need to add them to the page as well.

 

Bob_zBob_z

I made the changes and unfortunately I am getting another error

 

Save error: Method does not exist or incorrect signature: [String].lenght()

 

if(sCaseId != null && sCaseId.lenght() > 0)

Bob_zBob_z

length was miss spelled

Bob_zBob_z

Sorry to bother you, but I was able to get the new force.com site to work, but it gives me an Authorization Required error when I clicked create, and does'nt go to the attachment page. also you had a {!Label.Save} in the command button subject. It kept giving me an error that there was you field with that name, so i changed it to text. I'm not sure what that did. 

Bob_zBob_z

Sorry to bother you, but I was able to get the new force.com site to work, but it gives me an Authorization Required error when I clicked create, and doesn't go to the attachment page. Also you had a {!Label.Save} in the command button subject. It kept giving me an error that there was no field with that name, so I changed it to text. 

 

I could really use an explanation as to why the attachment did not popup and gave me the authorization error.