• jdogsailing
  • NEWBIE
  • 50 Points
  • Member since 2009

  • Chatter
    Feed
  • 2
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 10
    Questions
  • 14
    Replies

I have a simple component, SingletonResponseWidget, shown below that populates some input text widgets using a SurveyFragment bean passed in as an attribute. Without the assignTo= tag, this component works just fine except that the input text values are not stored in the SurveyFragment when they are entered. Following the Visualforce example, I tried creating a controller for this widget, the ResponseWidgetController also shown below.

 

When I attempt to assign the SurveyFragment attribute value to this controller's controllerValue; however, it throws an internal server error. I followed the instructions and posted the error to Salesforce support but they were not helpful. Evidently Support folks do not actually read any code, even if it caused their platform to barf.

 

Seems to me that code which compiles and is, essentially, copied from the manual should work. Any ideas?

Jeff

 

PS: Note that the component does not currently use any of the fields provided by the controller. It only tries to set the componentValue. If I could set the controller, I would then try to use the fields to see if their new values would get returned.

 

<apex:component controller="ResponseWidgetController">
    <apex:attribute name="fragment" description="This is the fragment for the component"
        type="SurveyFragment" required="required" assignTo="{!controllerValue}"/> 
    <apex:outputText >{!fragment.firstResponse.question}</apex:outputText><br />
    <em>{!fragment.sInstructions}</em><br />
    <apex:inputText value="{!fragment.firstResponse.score}" title="Score"/><br /> 
    <em>{!fragment.cInstructions}</em><br />
    <apex:inputTextarea value="{!fragment.firstResponse.comment}" cols="80" title="Comment"/><br /> 
</apex:component>

 

public class ResponseWidgetController {
   
    public SurveyFragment controllerValue {get; set;}
   
    public String getQuestion() {
        return controllerValue.firstResponse.question;
    }
   
    public Integer getScore() {
        return controllerValue.firstResponse.score;
    }
   
    public void setScore(Integer score) {
        controllerValue.firstResponse.score = score;
    }
   
    public String getComment() {
        return controllerValue.firstResponse.comment;
    }
   
    public void setComment(String comment) {
        controllerValue.firstResponse.comment = comment;
    }
}

This is related to http://community.salesforce.com/sforce/board/message?board.id=Visualforce&thread.id=10946. The SurveyBean contains a list of SurveyFragments and they each contain a ResponseBean object. When my VF page elaborates the SurveyBean it invokes a custom component which renders the survey as a list of input widgets:

 

public class SurveyBean { ...

    public List<SurveyFragment> fragments {get; set;}
    public Boolean noContact {get; set; }
}

 

public class SurveyFragment { ...

    public ResponseBean response {get; set;}

}

     <apex:form >
        ...
        <apex:variable var="bean" value="{!ResponseDetail}">
            <apex:datalist var="fragment" value="{!bean.fragments}" type="1">
                <c:ResponseWidget fragment="{!fragment}" />
            </apex:datalist>
           <apex:inputCheckbox value="{!bean.noContact}" />

           <apex:commandButton value="Update" action="{!updateSurvey}" />
        </apex:variable>
    </apex:form>

<apex:component >
    <apex:attribute name="fragment" description="This is the fragment for the component"
        type="SurveyFragment" required="true"/> 
    <apex:outputText >{!fragment.response.question}</apex:outputText><br />
    <em>{!fragment.sInstructions}</em><br />
    <apex:inputText value="{!fragment.response.score}" title="Score"/><br /> 
    <em>{!fragment.cInstructions}</em><br />
    <apex:inputTextarea value="{!fragment.response.comment}" cols="80" title="Comment"/><br /> 
</apex:component>

 

public class SurveyBean { ...

    public List<SurveyFragment> fragments {get; set;}
    public Boolean noContact {get; set; }
}

 

public class SurveyFragment { ...

    public ResponseBean response {get; set;}

}

 

This works great for displaying the survey, but not when I press Update. Now, when the modified SurveyBean gets back to my controller, none of the values which were set into its ResponseBeans are available. They all have their original values. I know the SurveyBean is getting updated correctly, because it has a noContact checkbox widget and its state is being transmitted to the controller. My expectation is that the values set in the component should be copied back to the controller but this is evidently not the case. Where are the other values going? What do I need to do to make this do the right thing?

 

Jeff

I have an Apex page that displays fields from a structured bean returned from my controller using custom components:

 

    <apex:form >
        <apex:variable var="bean" value="{!ResponseDetail}">
            <apex:datalist var="fragment" value="{!bean.fragments}" type="1">
                <c:ResponseWidget fragment="{!fragment}" />
                <br />
            </apex:datalist>
           <apex:commandButton value="Update" action="{!updateSurvey}" />
        </apex:variable>
    </apex:form>
 

 

The controller has an instance variable with getter and setter:

 

    public SurveyBean ResponseDetail {
        get {

             ...
             return new SurveyBean(...);
        }
        set;}
   
    public PageReference updateSurvey() {
        if (ResponseDetail.fragments != null)
           return null;
        return null;
    }
 

The page displays fine, but when I press the update button I get a null pointer exception. The setter is not being called before the update method as the documentation suggests. What am I doing wrong?

 

Jeff

I have established a many-many relationship between Survey and Question objects using a SurveyQuestion junction object and two master-detail relationships as suggested. I'm now tearing my hair trying to query accross the relationship. I'm still an Apex SOQL noob so I must have missed something obvious but how would I:

 

- select all Questions for a Survey in a single query?

- select all Surveys for a Question in a single query?

 

Extra credit:

 

SurveyQuestion has an order_in_survey field. In the first query, I'd like the Questions ordered by it.

 

Jeff

I have two custom objects (Survey and Question) that are m-n linked via junction objects (SurveyQuestion has a lookup relationship to each). I can use these junction objects just fine in my Apex code but I'd like to define some report types that can operate across the relationship. Is this possible?

 

From the developer resources (http://wiki.apexdevnet.com/index.php/An_Introduction_to_Force_Database) it says I should be using master-detail relationships but gives no further instructions. In another online document (many to many relationships.doc) it says to use lookup relationships as I have done. That document also suggests that the tabs for the related objects can be customized to traverse the junction object automatically but that document is for an earlier UI version and it no longer applies.

 

Are there any current documents that describe how to make these relationships really work in the UI?

Jeff

I have a component that has two possible display formats, so I created a new sub-component for each. Now I can't figure out how to switch between them. The {!IF()} expression does not seem to get the job done. Here's the fragment:

 

<apex:component >
    <apex:attribute name="fragment" description="This is the fragment for the component"
                    type="SurveyFragment" required="true"/>
    {!IF(fragment.singleton,
        <c:SingletonResponseWidget fragment="{!fragment}" />,
        <c:TableResponseWidget fragment="{!fragment}" />)}
</apex:component>

 

 Can somebody suggest how to do this?

Jeff

According to the Help documents, it should be possible to follow relationship chains to fill out mail merge fields (e.g. "Opportunity.Account.CreatedBy.Phone"). For my custom objects; however, I can only get them to work across a single relationship.

 

So, "{!NullValue(Answer__c.Response__c.Account__c.OwnerFirstName, "Account Manager")}," seems like it ought to work but it doesn't. (In my object model, Answer__c has a lookup relationship named "Response" to a Response__c, which has a lookup relationship "Account" to an Account).

 

The string "Answer__c.Response__c" works, but the string "Answer__c.Response__c.Account__c" does not either.

 

I see there is some 40 character limit on merge field names? 40 characters, REALLY???

 

I've tried removing the "__c" names, also using "__r" but no help. Does this feature actually work? Can someone help get me back on the right track?

Jeff

I've got a page, a snippet of which follows, that works great when I replace the {!obj.detailQuestion} with raw text. In this situation; however, I get an unhelpful Visualforce Error notifier which only says: "getDetailQuestion()". The wrapper class returned by {!Detail} has the instance variable declared as "public String detailQuestion {get;set;}.

 

What does this mean?

 

    <apex:form>
        <apex:variable var="obj" value="{!Detail}">
            <ol>
                <li>{!obj.detailQuestion} <br />
 

 

I'm trying to build a page with a datatable that can display multiple values derived from, but not stored in an SObject. All the examples show the controller extension method returning SObject lists (e.g. Account[], which works just fine), but I want to display some computed values that are not stored in the SObject (e.g. the number of Contacts in the Account).

 

Normally, I would just declare a bean with the SObject fields plus the computed fields and have the controller return that, but I do not see a way to do this in force.com. All SObjects are persistent and I do not wish to create table fields to store these computed values.

 

The only way I can think of to proceed is by having the controller extension method return a List<Map<String, String>> instead of SObject[]. I have coded the controller method and it is happy, but when I try to invoke the get() method on the map my page will no longer compile (save error: unknown function obj.get. Check spelling). Here's a fragment...

 

    public List<Map<String, String>> getSummary(){...}

 

             <apex:datatable value="{!summary}" var="obj" styleClass="list">
                <apex:column>
                    <apex:facet name="header">Account Name</apex:facet>
                    <apex:outputText>
                        <a href="Detail?id={!obj.get('id')}">{!obj.get('name')}</a>
                    </apex:outputText>
                </apex:column>
                <apex:column>
                    <apex:facet name="header">#Contacts</apex:facet>
                    <apex:outputText>{!obj.get('contacts')}</apex:outputText>
                </apex:column>

 

Can someone give me a hint about how to proceed?

I'm trying to build an extension controller that can return a list of arbitrary computed values to a web page. What I really would like to return from the controller method is a list of transient objects that contains the field values to be displayed in the apex:datatable. I don't see a direct way to do this, and while I can imagine faking it with a List<Map<String, String>> I wonder if this is the recommended practice?

I have a simple component, SingletonResponseWidget, shown below that populates some input text widgets using a SurveyFragment bean passed in as an attribute. Without the assignTo= tag, this component works just fine except that the input text values are not stored in the SurveyFragment when they are entered. Following the Visualforce example, I tried creating a controller for this widget, the ResponseWidgetController also shown below.

 

When I attempt to assign the SurveyFragment attribute value to this controller's controllerValue; however, it throws an internal server error. I followed the instructions and posted the error to Salesforce support but they were not helpful. Evidently Support folks do not actually read any code, even if it caused their platform to barf.

 

Seems to me that code which compiles and is, essentially, copied from the manual should work. Any ideas?

Jeff

 

PS: Note that the component does not currently use any of the fields provided by the controller. It only tries to set the componentValue. If I could set the controller, I would then try to use the fields to see if their new values would get returned.

 

<apex:component controller="ResponseWidgetController">
    <apex:attribute name="fragment" description="This is the fragment for the component"
        type="SurveyFragment" required="required" assignTo="{!controllerValue}"/> 
    <apex:outputText >{!fragment.firstResponse.question}</apex:outputText><br />
    <em>{!fragment.sInstructions}</em><br />
    <apex:inputText value="{!fragment.firstResponse.score}" title="Score"/><br /> 
    <em>{!fragment.cInstructions}</em><br />
    <apex:inputTextarea value="{!fragment.firstResponse.comment}" cols="80" title="Comment"/><br /> 
</apex:component>

 

public class ResponseWidgetController {
   
    public SurveyFragment controllerValue {get; set;}
   
    public String getQuestion() {
        return controllerValue.firstResponse.question;
    }
   
    public Integer getScore() {
        return controllerValue.firstResponse.score;
    }
   
    public void setScore(Integer score) {
        controllerValue.firstResponse.score = score;
    }
   
    public String getComment() {
        return controllerValue.firstResponse.comment;
    }
   
    public void setComment(String comment) {
        controllerValue.firstResponse.comment = comment;
    }
}

I have an Apex page that displays fields from a structured bean returned from my controller using custom components:

 

    <apex:form >
        <apex:variable var="bean" value="{!ResponseDetail}">
            <apex:datalist var="fragment" value="{!bean.fragments}" type="1">
                <c:ResponseWidget fragment="{!fragment}" />
                <br />
            </apex:datalist>
           <apex:commandButton value="Update" action="{!updateSurvey}" />
        </apex:variable>
    </apex:form>
 

 

The controller has an instance variable with getter and setter:

 

    public SurveyBean ResponseDetail {
        get {

             ...
             return new SurveyBean(...);
        }
        set;}
   
    public PageReference updateSurvey() {
        if (ResponseDetail.fragments != null)
           return null;
        return null;
    }
 

The page displays fine, but when I press the update button I get a null pointer exception. The setter is not being called before the update method as the documentation suggests. What am I doing wrong?

 

Jeff

I have two custom objects (Survey and Question) that are m-n linked via junction objects (SurveyQuestion has a lookup relationship to each). I can use these junction objects just fine in my Apex code but I'd like to define some report types that can operate across the relationship. Is this possible?

 

From the developer resources (http://wiki.apexdevnet.com/index.php/An_Introduction_to_Force_Database) it says I should be using master-detail relationships but gives no further instructions. In another online document (many to many relationships.doc) it says to use lookup relationships as I have done. That document also suggests that the tabs for the related objects can be customized to traverse the junction object automatically but that document is for an earlier UI version and it no longer applies.

 

Are there any current documents that describe how to make these relationships really work in the UI?

Jeff

According to the Help documents, it should be possible to follow relationship chains to fill out mail merge fields (e.g. "Opportunity.Account.CreatedBy.Phone"). For my custom objects; however, I can only get them to work across a single relationship.

 

So, "{!NullValue(Answer__c.Response__c.Account__c.OwnerFirstName, "Account Manager")}," seems like it ought to work but it doesn't. (In my object model, Answer__c has a lookup relationship named "Response" to a Response__c, which has a lookup relationship "Account" to an Account).

 

The string "Answer__c.Response__c" works, but the string "Answer__c.Response__c.Account__c" does not either.

 

I see there is some 40 character limit on merge field names? 40 characters, REALLY???

 

I've tried removing the "__c" names, also using "__r" but no help. Does this feature actually work? Can someone help get me back on the right track?

Jeff

I've got a page, a snippet of which follows, that works great when I replace the {!obj.detailQuestion} with raw text. In this situation; however, I get an unhelpful Visualforce Error notifier which only says: "getDetailQuestion()". The wrapper class returned by {!Detail} has the instance variable declared as "public String detailQuestion {get;set;}.

 

What does this mean?

 

    <apex:form>
        <apex:variable var="obj" value="{!Detail}">
            <ol>
                <li>{!obj.detailQuestion} <br />
 

 

I'm trying to build a page with a datatable that can display multiple values derived from, but not stored in an SObject. All the examples show the controller extension method returning SObject lists (e.g. Account[], which works just fine), but I want to display some computed values that are not stored in the SObject (e.g. the number of Contacts in the Account).

 

Normally, I would just declare a bean with the SObject fields plus the computed fields and have the controller return that, but I do not see a way to do this in force.com. All SObjects are persistent and I do not wish to create table fields to store these computed values.

 

The only way I can think of to proceed is by having the controller extension method return a List<Map<String, String>> instead of SObject[]. I have coded the controller method and it is happy, but when I try to invoke the get() method on the map my page will no longer compile (save error: unknown function obj.get. Check spelling). Here's a fragment...

 

    public List<Map<String, String>> getSummary(){...}

 

             <apex:datatable value="{!summary}" var="obj" styleClass="list">
                <apex:column>
                    <apex:facet name="header">Account Name</apex:facet>
                    <apex:outputText>
                        <a href="Detail?id={!obj.get('id')}">{!obj.get('name')}</a>
                    </apex:outputText>
                </apex:column>
                <apex:column>
                    <apex:facet name="header">#Contacts</apex:facet>
                    <apex:outputText>{!obj.get('contacts')}</apex:outputText>
                </apex:column>

 

Can someone give me a hint about how to proceed?

I'm trying to build an extension controller that can return a list of arbitrary computed values to a web page. What I really would like to return from the controller method is a list of transient objects that contains the field values to be displayed in the apex:datatable. I don't see a direct way to do this, and while I can imagine faking it with a List<Map<String, String>> I wonder if this is the recommended practice?