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
TwEEkTwEEk 

Passing inputField value to a component

I am having trouble finding a simple way to take the value of an inputfield and use it to pass parameters to a custom component. For example

 

<apex:inputField id="textInput" />

<apex:commandButton value="Go" id="buttonGo" rerender="output" />

<apex:outputPanel id="output">

            <c:myCustomComponent />

</apex:outputPanel>

 

So what i'd like to be able to do, is on clicking the command button "buttonGo",  is take the value of inputfield "textinput" and pass it to the  customcomponent and then rerender it. I would also like not refresh the page - so putting it into the query string is not a solution in this case.

 

Any help would be appreciated.

Best Answer chosen by Admin (Salesforce Developers) 
sfdcfoxsfdcfox

Actually, I'm not Bob. I just jumped in on this conversation. But I saw your point, and updated the example to show you how it would work:

 

<apex:component >
<apex:attribute type="date" name="param1" description="The default parameter."/>
Value is: {!param1}
</apex:component>

 

public class testController {
public Task test { get; set; }
public testController() {
test = new Task();
}
}

 

 

 

<apex:page controller="testController">
<apex:form >
<apex:inputField value="{!test.activitydate}"/>
<apex:commandButton reRender="test" value="Update"/>
</apex:form>
<c:test id="test" param1="{!test.activitydate}"/>
</apex:page>

The logic still works, but the kicker is you must make sure that the object is not NULL. This means that you have to initialize it to a record in the constructor (either a query or create a new in-memory record). That might be your missing link.


Edit: Copied the wrong component.

Message Edited by sfdcfox on 12-03-2009 09:02 PM

All Answers

bob_buzzardbob_buzzard

You don't pass parameters quite the way that you are thinking.  The entire page is built server side and sent to the client, rather than being processed piecemeal on the client side.  

 

If you do something like the code below, this will use someObject.someField as the backing variable for the input field and as a parameter to the component.  If you change the input field and click the button, this will submit the page back to the controller, update the value of someObject.someField and then redraw just the component using the new value. 

 

 

 

<apex:inputField id="textInput" value="{!someObject.someField}" /> <apex:commandButton value="Go" id="buttonGo" rerender="output" /> <apex:outputPanel id="output"> <c:myCustomComponent param1="{!someObject.someField}"/> </apex:outputPanel>

 

 

 

TwEEkTwEEk
Looks like what I need, however could you show me how to access it from the components controller?
TwEEkTwEEk

Bob,

 

This DOES NOT work.

 

 

<apex:pageBlock> <apex:pageBlockSection columns="1"> <apex:inputField id="myField" value="{!myObject.someField}" rerender="output"/> </apex:pageBlockSection></apex:pageBlockSection><apex:pageBlock > <apex:outputPanel id="output"> <c:myComponent param1="{!myObject.someField}" /> </apex:outputPanel></apex:pageBlock>

 

Any thoughts? I have also tried using parameters which fails.

 

 

 

 

sfdcfoxsfdcfox

That should work, assuming your Component has the following code:

 

<apex:component controller="myComponentController">
<apex:attribute name="param1" assignTo="{!param1}" type="string"/>
<!-- OTHER CODE HERE -->
</apex:component>

 

 At this point, your controller needs to have the following:

 

public class myComponentController {
public string param1 { get; set; }
// Other code here.
}

At that point, the controller has access to the string variable "param1".

 

I believe you have to need to provide the component with an ID and use a reRender attribute on an action tag (i.e. commandButton) in order to pass a "new" parameter to the component. I have not actually tried this yet, so I'm not sure what the results would be.

 

 Edit: Corrected controller example.

Message Edited by sfdcfox on 12-03-2009 08:24 PM
sfdcfoxsfdcfox

Update: Confirmed. You can indeed do this. Here is an example:

 

 

<!-- page "test" --> <apex:page controller="testController"> <apex:form > <apex:inputText value="{!test}"/> <apex:commandButton reRender="test" value="Update"/> </apex:form> <c:test id="test" param1="{!test}"/> </apex:page>

 

public class testController { public string test { get; set; } }

 

<apex:component > <apex:attribute type="string" name="param1" description="The default parameter."/> {!param1} </apex:component>

 

 

 

 This simple example will show whatever you place into the inputText box when you click the Update button.

 

I hope this example assists you with your problem.

 

TwEEkTwEEk

Bob,

 

Sorry - but you have modified it to make it work for you. 

 

You are using a inputText tag which is a HTML input element of type text.

 

I require in this place an inputField tag. Which is an input element that corresponds to a field on a custom object.

 

I require a datepicker. There is no such SalesForce tag/object as a inputDate or similar. Instead I intend to use an inputField which is bound to an Date field on an object.

 

So please retry your code with inputField. It does not work.

 

 

sfdcfoxsfdcfox

Actually, I'm not Bob. I just jumped in on this conversation. But I saw your point, and updated the example to show you how it would work:

 

<apex:component >
<apex:attribute type="date" name="param1" description="The default parameter."/>
Value is: {!param1}
</apex:component>

 

public class testController {
public Task test { get; set; }
public testController() {
test = new Task();
}
}

 

 

 

<apex:page controller="testController">
<apex:form >
<apex:inputField value="{!test.activitydate}"/>
<apex:commandButton reRender="test" value="Update"/>
</apex:form>
<c:test id="test" param1="{!test.activitydate}"/>
</apex:page>

The logic still works, but the kicker is you must make sure that the object is not NULL. This means that you have to initialize it to a record in the constructor (either a query or create a new in-memory record). That might be your missing link.


Edit: Copied the wrong component.

Message Edited by sfdcfox on 12-03-2009 09:02 PM
This was selected as the best answer
TwEEkTwEEk

Sorry about the bob thing, scrolled to the top and saw his name.

as for the solution: Bingo! Worked a treat :)

Thanks Fox 

 


Big EarsBig Ears

Hey guys,

 

I feel like this discussion is close to providing a solution to an issue I have around VF & VF email templates.

 

I have a simple VF page with an input text field. The contents of the VF field are held in the APEX class that is the custom controller for the page.

 

The page has a button that triggers a VF email template to get sent with a few merge fields from the record. However, I'd also like to include the contents of the input text field. My current code looks like this.

 

VF PAGE

<apex:page tabstyle="Lead" Title="Confirm Ownership Request" controller="RequestOwnershipOfRecord"> <apex:form > <apex:pageblock title="Confirm Ownership Request"> <apex:pageblockbuttons > <apex:commandbutton action="{!Cancel}" value="Cancel"/> <apex:commandbutton action="{!Confirm}" value="Confirm"/> </apex:pageblockbuttons> <p>You have requested ownership of this record. An email will be sent to the current owner.</p> <p>Current owner - {!lead.owner.Firstname} {!lead.owner.lastname}</p> <p>Do you want to continue?</p> <apex:pageblocksection columns="1" title="Notes for record owner"> <apex:inputtextarea value="{!NotesForRequest}" rows="3" cols="100"/> </apex:pageblocksection> </apex:pageblock> </apex:form> </apex:page>

 

CONTROLLER

 

public with sharing class RequestOwnershipOfRecord { public Lead lead; private string NotesForRequest = ''; public string getNotesForRequest(){ return NotesForRequest; } public void setNotesForRequest(string NotesForRequest){ this.NotesForRequest = NotesForRequest; } public String getParam(String name) { return ApexPages.currentPage().getParameters().get(name); } public Lead getlead(){ String Leadid = getparam('id'); if(lead == null){ lead = [select firstname, ownerid, owner.email, owner.firstname, owner.lastname from Lead where id = :Leadid]; } return lead; } public PageReference cancel(){ string id = getparam('id'); PageReference BackToLead = new PageReference('/'+id); return BackToLead; } public PageReference Confirm(){ string id = getparam('id'); PageReference BackToLead = new PageReference('/'+id); EmailToRequestOwnershipOfRecord.SendEmail(id, Lead.Owner.Email, Lead.OwnerId);

THIS IS THE CLASS/METHOD THAT SENDS THE EMAIL

return BackToLead; } }

 

VF TEMPLATE

<messaging:emailTemplate subject="Please transfer the following record to me" recipientType="User" relatedToType="Lead"> <messaging:htmlEmailBody >

SOME TEXT

 

Notes: <c:NotesField id="Notes"/> </messaging:htmlEmailBody> </messaging:emailTemplate>

 

COMPONENT

 

<apex:component controller="RequestOwnershipOfRecord" access="global"> <apex:attribute type="string" name="Notes" Description="The input text from the VF page" assignTo="{!NotesForRequest}"/> {!Notes} </apex:component>

 

CLASS THAT SENDS THE EMAIL

public with sharing class EmailToRequestOwnershipOfRecord { public static void SendEmail(string recordid, string email, string ownerid){ Messaging.Singleemailmessage mail = new Messaging.Singleemailmessage(); string UserId = UserInfo.getUserId(); User user = [select email, IsActive from User where id = :UserId]; User Owner = [select email, isActive from User where id = :ownerid]; mail.setReplyTo(user.email); mail.setwhatId(recordid); mail.setSaveAsActivity(false); mail.setUseSignature(true); mail.setBccSender(true); if(recordid.startsWith('00Q')){ EmailTemplate LeadTemplate = [select id from EmailTemplate where Name = 'Request for Ownership - Visualforce - Lead']; mail.setTemplateId(LeadTemplate.id); } else { EmailTemplate AccountTemplate = [select id from EmailTemplate where Name = 'Request for Ownership - Visualforce - Account']; mail.setTemplateId(AccountTemplate.id); } if(owner.IsActive){ mail.setTargetObjectId(ownerid); } else { User[] AdminUsers = [select id, email, username from User where Profileid = '00e20000000hYfe']; string AdminId = null; for(User u : AdminUsers){ if(u.username == 'andrew@carbonneutral.com'){ AdminId = u.id; } } if(AdminId == null){ AdminId = AdminUsers[0].id; } mail.setTargetObjectId(AdminId); } Messaging.sendEmail(new Messaging.Singleemailmessage[]{mail}); } }

 

 

Currently, if I hardcode any text into the Component, this shows up in the received email. However, the {!Notes} parameter is blank, indicating that values aren't being passed into the the component.

 

Is it simply not possible to pass values into the email template in this way? Should I include the getter/setter methods for the notes in the class that sends the email?

 

Any thoughts would be appreciated.