2013-04-15 30 views
1

我目前在联系人记录中嵌入了一个Visualforce页面,该页面显示所有与chexckbox有效的活动,指示联系人是否为活动的成员(如果选中,则联系人为成员)。我也有一个命令按钮来保存更改。使用顶点生成visualforce码:重复喜欢像这样:Salesforce/Apex - 保存动态复选框数量

<apex:repeat value="{!campaignWrappers}" var="cm"> 
    <div class="MailingRow"> 
    <apex:outputText styleClass="CampaignLabel" value="{!cm.c.Name}" ></apex:outputText> 
    <apex:inputCheckbox styleClass="CampaignCheck" value="{!cm.selected}" /> 
    </div> 
</apex:repeat>

我的问题是,什么是去传递复选框值到控制器的最佳方式?理想情况下,我希望仅传递已更改的复选框,将已从选中状态变为未选中状态的复选框传递给第二个列表,其中包含从未选中状态变为已选中状态的复选框。然后我可以插入和删除这些列表。

这是一个应该在复选框上使用actionSupport标签的情况吗?

<apex:actionSupport event="onChange" action="{!updateChangeList}" />

回答

1

整个收集将被发送回服务器(因此所有复选框的状态)。 Salesforce和其他与网络相关的语言并没有太大差别(例如Get $_POST from multiple checkboxes),主要区别在于,通常您会使用名称以[]结尾的变量,并且SF将使用名称中某处增加数字的唯一名称。

如果你真的想建立2个列表 - 也许一些JavaScript魔法添加/删除2个隐藏文本字段的内容......但有点混乱。

当表单被提交并且您的updateChangeList()被调用时,您可以迭代CampaignWrappers的集合并与之前的值进行比较。无论是在1以上变量存储在包装以前的值&将其暴露给用户,或者你还是会基于什么是在竞选知道:

Set<Id> campaignsToBeAddedTo = new Set<Id>(); 
Set<Id> campaignsToBeRemovedFrom = new Set<Id>(); 

for(CampaignMember cm : campaignWrappers){ 
    if(cm.selected && cm.c.CampaignMembers.isEmpty(){ 
     // is ticket but wasn't a member before 
     campaignsToBeAddedTo.add(cm.c.Id); 
    } else if (!cm.selected && !cm.c.CampaignMembers.isEmpty()){ 
     // not ticked but used to be a member 
     campaignsToBeRemovedFrom.add(cm.c.Id); 
    } 
} 

你甚至可以优化它有点(就像放isEmpty()检查辅助变量)。或者阅读可能产生“副作用”的setter方法。无论如何,当表单数据将被反序列化时,所有类似的循环都会为您运行。 http://blogs.developerforce.com/developer-relations/2008/06/property-access.html是一个很好的起点(这是古老的,我知道。基本上在这篇博客文章之前,我们必须为我们想在VF中使用的每个变量编写Boolean getSelected()void setSelected(Boolan b))。

最后但并非最不重要 - 链接到page execution order

+0

感谢您的信息eyescream。我有点困惑。因此,在每个复选框上使用actionSupport并不是前进的方向,相反,我会对我的commandbutton执行一个操作,该操作根据上面的示例执行逻辑操作。我需要为每个复选框设置一个ID,以便我可以在控制器中识别它们吗?我无法像这样在Visualforce中设置ID:id = {!cm.c.id},因为它必须是文字? – Ronnie

+0

ActionSupport不是魔术棒;)这是一个AJAX快捷方式,可以提交整个表单并执行操作。把它当作用户选择一个复选框的瞬间点击一下隐藏的按钮。关键是它会成为网络流量。如果你想一个接一个地发送它们 - 当然可以。你可以但不必设置ID。他们会自动设置“id”和“name”。只要不用担心,假设当方法体输入时,所有的变量都会被解析等等,随时可以使用 – eyescream

+0

感谢您的详细解释eyescream! – Ronnie

2

您可以使用联系人对象的包装类来存储联系人的当前和新状态,以检查联系人是否为广告系列的成员。

public class ContactWrapper 
{     
public Boolean checked{ get; set; }    
public Contact con { get; set;}      

public AccountSKUWrapper() 
{     
    con = new Contact();     
    checked = false;    
}      

public ContactWrapper(Contact c) 
{     
    con= c;     
    checked = c.selected;    
}        

}

使用选择领域,我们可以识别联系人是否是活动的一员,检查在包装变量有助于识别VF页给出什么样的输入。创建ContactWrapper列表并使用重载构造函数“ContactWrapper(Contact c)”初始化每个ContactWrapper对象。

<apex:repeat value="<ContactWrapper Object>" var="cm"> 
    <div class="MailingRow"> 
    <apex:outputText styleClass="CampaignLabel" value="{!cm.con.Name}" ></apex:outputText> 
    <apex:inputCheckbox styleClass="CampaignCheck" value="{!cm.checked}" /> 
    </div> 
</apex:repeat> 

保存按钮点击过程中,按照以下步骤:检查与选定字段不同的选中变量的值。

Create 2 list **CHANGEDCONTACTLIST** and **UNCHANGEDCONTACTLIST** and then Loop through the list of ContactWrapper 

begin loop 
1.If checked differs then load **CHANGEDCONTACTLIST** with Contact Wrapper object as this need to be updated in Contact object; in order to update selected field of contact. 

2.Else load **UNCHANGEDCONTACTLIST**. 
end loop 

最终使用这两个列表CHANGEDCONTACTLISTUNCHANGEDCONTACTLIST。你可以插入或删除dml。

我相信这里没有使用ActionSupport标签,因为所有需要的值都将使用(读/写)使用ContactWrapper列表的getter和setter。

public List<ContactWrapper> wrapper {get;set;}