3

I need a table showing sObjects within independent rows.

I need to perform actions on single rows without even taking care about all the other rows. Reason: Some rows might be invalid (having required fields not filled). To prevent validation exceptions immediate="true" is not an option, since this will not send any object data to the backend. (prooved with debuging) But I need the possibly changed object of this row in my backend! (You can add apex:params to your buttons or links, that will be passed to the backend but params are limited to primitive data types.)

So in my example I have a clone link in my row. After changing some fields on that row, I want to clone it. Therefor I need the current object state in my controller, to have a consistent clone of my possibly modiefied object.

My Table

But I have no chance to send the object to my controller, without sending all the other objects too. apex:actionRegion seems to be the solution, but with visualforce-tables I have no chance to encapsulate rows. (see: Only rerender row)

So I wrote my own html table using apex:repeat, to be able to wrap my html row tags (tr) within an apex:actionRegion.

<table>
    <!-- HEADER -->
    <tr class="headerRow">
        <th class="headerRow">Actions</th>

        <apex:repeat value="{!fields}" var="field">
            <th class="headerRow">
                <apex:outputText value="{!field.Label}" />
            </th>
        </apex:repeat>
    </tr>

    <!-- ROWS -->
    <apex:repeat value="{!rows}" var="row">
        <apex:actionRegion id="rowRegion">
            <tr>
                <!-- ACTIONS -->
                <td>
                    <apex:commandLink value="clone" action="{!doClone}" rerender="rowRegion">
                        <apex:param name="selectedRow" value="{!row.index}" assignTo="{!selectedRow}" />
                    </apex:commandLink>
                </td>

                <!-- DATA -->
                <apex:repeat value="{!fields}" var="field">
                    <td>
                        <apex:outputField value="{!row.record[field]}" />
                    </td>
                </apex:repeat>
            </tr>
        </apex:actionRegion>
    </apex:repeat>
</table>

But it seems like visualforce can not handle looped objects independently. It does not even see the variable as an sObject. So I get this error message:

Could not resolve the entity from value binding '{!row.record[field]}'. can only be used with SObjects, or objects that are Visualforce field component resolvable.

May someone confirm my thoughts, or does anyone have another Idea how to solve this problem?

  • I would suggest you to move logic that you are trying to do in command link to row itself, can call it like {!row.doSomeAction}. Then, you would be able to use it without any params as that action would be executed per concrete record – kurunve Mar 2 '16 at 14:19
  • Good idea, but this would not make it independent from the other objects in my table. And with making the action immediate, it would not send the current state of the object back to my controller. – Basti Mar 2 '16 at 14:37
  • 2
    an alternative solution is to use the red bar "required" styling on your page but not the `required="true" on the apex VF component - do your validation for 'required' in the controller but only for the row(s) affected by the action method – cropredy Mar 2 '16 at 17:34
  • Would setting required=false on an apex:inputField work even if the field is required by the database (not layout or fieldset)? – Robert Sösemann Mar 3 '16 at 12:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.