项目中表之间关联关系特别多,比如三个表中A,B,C  C作为主表,A,B作为从表,有时候C表需要创建数据时,同时需要创建A,B两个表的数据,这种情况下,使用Wizard样式会更加友好。

以Goods__c表和Goods_Vendor__c表为例,Goods__c为主表,Goods_Vendor__c为从表。新建Goods__c记录以后同时要创建其相关的数据。

表结构关系如下:

代码:

1.GoodsHelper:封装获取goods的列表方法

 public without sharing class GoodsHelper {

     public static final String BASE_GOODS_QUERY = 'SELECT CreatedById, CreatedDate, IsDeleted,' +
' Goods_Code_Unique__c, Name, GoodsPicture__c, GoodsBrand__c, GoodsCostPrice__c,' +
' GoodsDescribe__c, GoodsName__c, GoodsPrice__c, GoodsProfit__c, Is_Draft__c,' +
' LastModifiedById, LastModifiedDate, No__c, OwnerId, Id, RecordTypeId,' +
' Status__c, SystemModstamp' +
' FROM Goods__c where IsDeleted = false';
public static final String BASE_GOODS_COUNT_QUERY = 'SELECT count() from Goods__c where IsDeleted = false';
public static MyPaginationEnhancement getGoodsList(String goodsName,String goodsBrand,MyPaginationEnhancement pagination) {
String queryCondition= '';
String orderBy ='';
if(goodsName != null) {
queryCondition += ' and GoodsName__c like %\'' + goodsName + '%\'';
}
if(goodsBrand != null) {
queryCondition += ' and GoodsBrand__c = :goodsBrand';
}
orderBy = ' order by createddate'; pagination.getQueryResult(BASE_GOODS_COUNT_QUERY,BASE_GOODS_QUERY,queryCondition,null,orderBy);
return pagination;
}
}

2.GoodsListController:Goods列表Controller

 public with sharing class GoodsListController {
public Map<String,String> parameters; public GoodsListController() {
parameters=ApexPages.currentPage().getParameters();
init();
} public MyPaginationEnhancement pagination = new MyPaginationEnhancement(); public String goodsName{get;set;} public String goodsBrand{get;set;} public void init() {
queryByCondition();
} public void queryByCondition() {
GoodsHelper.getGoodsList(goodsName,goodsBrand,pagination);
} public MyPaginationEnhancement resultPagination{
get{
if(pagination ==null){
pagination =new MyPaginationEnhancement();
}
return pagination;
}
set;
} public List<Goods__c> resultList{
get{
if(pagination==null || pagination.resultList==null){
return new List<Goods__c>();
}
return pagination.resultList;
}
set;
} public PageReference newGoods() {
return Page.detailGoods;
} public void firstPage() {
pagination.first();
queryByCondition();
} public void lastPage() {
pagination.last();
queryByCondition();
} public void previousPage() {
pagination.previous();
queryByCondition();
} public void nextPage() {
pagination.next();
queryByCondition();
}
}

3.GoodsListPage

 <apex:page controller="GoodsListController">
<style>
/*-- 分页 --*/
.paginator {font:12px Arial, Helvetica, sans-serif; padding:10px 0; margin:0px;}
.paginator a {padding:1px 6px;border:solid 1px #ddd;background:#fff;color:#000;text-decoration:none;margin-right:2px;}
.paginator a:visited {padding:1px 6px;border:solid 1px #ddd;background:#fff;text-decoration:none;}
.paginator .current {padding:1px 6px; font-weight:bold; color:#f0ab00; font-size:12px; border:none;}
.paginator a:hover {color:#fff; background:#ffa501; border-color:#ffa501; text-decoration:none;} </style> <apex:form >
<apex:commandButton value="新建商品" action="{!newGoods}"/>
<apex:outputPanel layout="block">
<apex:outputPanel layout="block">
<apex:outputPanel layout="block">
<apex:outputPanel layout="block" id="goodsList">
<apex:dataTable align="center" value="{!resultList}" var="goods">
<apex:column style="width:180px;">
<apex:facet name="header">{!$ObjectType.Goods__c.fields.GoodsName__c.label}</apex:facet>
<apex:outputText value="{!goods.GoodsName__c}" />
</apex:column>
<apex:column style="width:225px;">
<apex:facet name="header">{!$ObjectType.Goods__c.fields.GoodsPrice__c.label}</apex:facet>
<apex:outputText value="{!goods.GoodsPrice__c}" />
</apex:column>
<apex:column style="width:225px;">
<apex:facet name="header">{!$ObjectType.Goods__c.fields.GoodsCostPrice__c.label}</apex:facet>
<apex:outputText value="{!goods.GoodsCostPrice__c}" />
</apex:column>
<apex:column style="width:500px;">
<apex:facet name="header">操作</apex:facet>
<apex:outputLink value="/apex/detailGoods">编辑
<apex:param name="goodsId" value="{!goods.Id}"/>
</apex:outputLink>
</apex:column>
</apex:dataTable> <apex:outputPanel layout="block" styleClass="paginator"
style="padding:0px;">
<apex:panelGrid columns="2" style="width:100%;"
styleClass="az_text_table" rowClasses="paginator,paginator">
<apex:outputText rendered="{!!resultPagination.hasRecord}"
value="第 0 页,共 0 页,每页 {!resultPagination.pageSize} 条" />
<apex:outputText rendered="{!resultPagination.hasRecord}"
value="第 {!resultPagination.pageNumber} 页,共 {!resultPagination.totalPage} 页,每页 {!resultPagination.pageSize} 条" />
<apex:panelGroup >
<apex:outputPanel >
<apex:outputText value="首页"
rendered="{!(!resultPagination.hasRecord)||(!resultPagination.hasPrevious)}"
style="border: solid 1px #ddd;padding:1px 6px;background: #e8e8e9;margin-right:5px;"></apex:outputText>
<apex:commandLink action="{!firstPage}"
rendered="{!resultPagination.hasRecord && resultPagination.hasPrevious}"
immediate="true" reRender="companyList" value="首页"
style="margin-right:5px;" />
</apex:outputPanel>
<apex:outputPanel >
<apex:outputText value="上一页"
rendered="{!!resultPagination.hasRecord || (!resultPagination.hasPrevious)}"
style="border: solid 1px #ddd;padding:1px 6px;background: #e8e8e9;margin-right:5px;"></apex:outputText>
<apex:commandLink action="{!previousPage}"
rendered="{!resultPagination.hasRecord && resultPagination.hasPrevious}"
immediate="true" reRender="companyList" value="上一页"
style="margin-right:5px;" />
</apex:outputPanel>
<apex:outputPanel >
<apex:outputText value="{!resultPagination.pageNumber}"
styleClass="current" />
</apex:outputPanel>
<apex:outputPanel >
<apex:outputText value="下一页"
rendered="{!!resultPagination.hasRecord || !resultPagination.hasNext}"
style="border: solid 1px #ddd;padding:1px 6px;background: #e8e8e9;margin-right:5px;margin-left:5px;"></apex:outputText>
<apex:commandLink action="{!nextPage}"
rendered="{!resultPagination.hasRecord && resultPagination.hasNext}"
immediate="true" reRender="companyList" value="下一页"
style="margin-right:5px;margin-left:5px;" />
</apex:outputPanel>
<apex:outputPanel >
<apex:outputText value="尾页"
rendered="{!!resultPagination.hasRecord || !resultPagination.hasNext}"
style="border: solid 1px #ddd;padding:1px 6px;background: #e8e8e9;margin-right:5px;"></apex:outputText>
<apex:commandLink action="{!lastPage}"
rendered="{!resultPagination.hasRecord && resultPagination.hasNext}"
immediate="true" reRender="companyList" value="尾页"
style="margin-right:5px;" />
</apex:outputPanel>
</apex:panelGroup>
</apex:panelGrid>
</apex:outputPanel>
</apex:outputPanel>
</apex:outputPanel>
</apex:outputPanel>
</apex:outputPanel>
</apex:form>
</apex:page>

4.GoodsDetailController:此类中封装了Wizard的相关方式,Wizard的相关跳转均为转发方式。

 public with sharing class GoodsDetailController {

     /*入口是新建还是更新:新建为false,更新为true*/
public Boolean isEditView{
get {
if(isEditView == null) {
isEditView = false;
}
return isEditView;
}
set;
} public GoodsDetailController() {
init();
} public GoodsDetailController(ApexPages.StandardController controller) {
init();
} public void init() {
String goodsId = ApexPages.currentPage().getParameters().get('goodsId');
if(goodsId != null) {
isEditView = true;
String queryGoods = 'SELECT Goods_Code_Unique__c, Name, GoodsBrand__c,' +
' GoodsCostPrice__c, GoodsDescribe__c, GoodsName__c, GoodsPrice__c,' +
' GoodsProfit__c, No__c,Id, Status__c' +
' FROM Goods__c where Id = :goodsId';
String queryGoodsVendor = 'SELECT Goods__c, Id, Vendor_Name__c' +
' FROM Goods_Vendor__c where Goods__c = :goodsId';
List<Goods__c> goodsList = Database.query(queryGoods);
if(goodsList != null && goodsList.size() > 0) {
goods = goodsList.get(0);
}
List<Goods_Vendor__c> goodsVendorList = Database.query(queryGoodsVendor);
if(goodsVendorList != null && goodsVendorList.size() > 0) {
goodsVendor = goodsVendorList.get(0);
}
}
} public Goods__c goods{
get{
if(goods == null) {
goods = new Goods__c();
}
return goods;
}
set;
} public Goods_Vendor__c goodsVendor{
get{
if(goodsVendor == null) {
goodsVendor = new Goods_Vendor__c();
}
return goodsVendor;
}
set;
} public PageReference saveFinally() {
Savepoint sp = Database.setSavepoint();
try {
upsert goods;
goodsVendor.Goods__c = goods.Id;
upsert goodsVendor;
} catch(DMLException e) {
Database.rollback(sp);
ApexPages.addMessage(new ApexPages.Message(ApexPages.SEVERITY.ERROR,e.getMessage()));
return null;
}
return redirectToGoodsList();
} public PageReference redirectToGoods() {
return Page.detailGoods;
} public PageReference redirectToVendor() {
return Page.detailVendor;
} public PageReference redirectToTotal() {
return Page.detailGoodsTotal;
} public PageReference cancelCreateGoods() {
if(!isEditView) {
if(goodsVendor != null && goodsVendor.Id != null) {
delete goodsVendor;
}
if(goods != null && goods.Id != null) {
delete goods;
}
}
return redirectToGoodsList();
} public PageReference redirectToGoodsList() {
PageReference ref = new PageReference('/apex/GoodsListPage');
ref.setRedirect(true);
return ref;
} }

5.detailGoods.page:商品信息详情页面

 <apex:page controller="GoodsDetailController" tabStyle="Goods__c">
<script>
function confirmCancel() {
var isCancel = confirm("确定取消新建商品信息?");
if (isCancel) {
return true;
}
return false;
}
</script>
<apex:sectionHeader title="New Goods " subtitle="Step 1 of 3"/>
<apex:form >
<apex:pageBlock title="Goods Information" mode="edit">
<apex:pageBlockButtons >
<apex:commandButton action="{!redirectToVendor}" value="Next"></apex:commandButton>
<apex:commandButton action="{!cancelCreateGoods}" value="Cancel" onclick="return confirmCancel()" immediate="true"/>
</apex:pageBlockButtons>
<apex:pageBlockSection title="Goods Basic Information">
<apex:inputField id="GoodsUniqueCode" value="{!goods.Goods_Code_Unique__c}"/>
<apex:inputField id="GoodsName" value="{!goods.GoodsName__c}"/>
<apex:inputField id="GoodsPrice" value="{!goods.GoodsPrice__c}"/>
<apex:inputField id="GoodsCostPrice" value="{!goods.GoodsCostPrice__c}"/>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
</apex:page>

6.detailVendor.page:vendor详情页

 <apex:page controller="GoodsDetailController" tabStyle="Goods_Vendor__c">
<script>
function confirmCancel() {
var isCancel = confirm("确定取消新建商品信息?");
if (isCancel)
return true;
return false;
}
</script>
<apex:sectionHeader title="New Vendor" subtitle="Step 2 of 3"/>
<apex:form >
<apex:pageBlock title="Vendor Information" mode="edit">
<apex:pageBlockButtons >
<apex:commandButton action="{!redirectToGoods}" value="Previous">
</apex:commandButton>
<apex:commandButton action="{!redirectToTotal}" value="Next">
</apex:commandButton>
<apex:commandButton action="{!cancelCreateGoods}" value="Cancel" onclick="return confirmCancel()" immediate="true"/>
</apex:pageBlockButtons>
<apex:pageBlockSection title="Vendor Basic Information">
<apex:inputField id="VendorName" value="{!goodsVendor.Vendor_Name__c}"/>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
</apex:page>

7.detailTotal.page:用于显示goods以及vendor的详细信息以及提交按钮

 <apex:page controller="GoodsDetailController" tabStyle="Goods__c">
<script>
function confirmCancel() {
var isCancel = confirm("确定取消新建商品信息?");
if (isCancel)
return true;
return false;
}
</script>
<apex:sectionHeader title="Goods Total Infomation" subtitle="Step 3 of 3"/>
<apex:form >
<apex:pageMessages />
<apex:pageBlock title="Total Information">
<apex:pageBlockButtons >
<apex:commandButton action="{!redirectToVendor}" value="Previous"/>
<apex:commandButton action="{!saveFinally}" value="Save"/>
<apex:commandButton action="{!cancelCreateGoods}" value="Cancel" onclick="return confirmCancel()" immediate="true"/>
</apex:pageBlockButtons>
<apex:pageBlockSection title="Goods Information">
<apex:outputField value="{!goods.Goods_Code_Unique__c}"/>
<apex:outputField value="{!goods.GoodsName__c}"/>
<apex:outputField value="{!goods.GoodsPrice__c}"/>
<apex:outputField value="{!goods.GoodsCostPrice__c}"/>
</apex:pageBlockSection>
<apex:pageBlockSection title="Vendor Information">
<apex:outputField value="{!goodsVendor.Vendor_Name__c}"/>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
</apex:page>

效果展示:

1.商品列表

2.点击编辑,如果点击新建其他内容均为空,此处只显示编辑

3.点击next进入vendor页面

4.total页面

5.点击save以后,成功则跳转到list页面,失败则显示失败ERROR

失败情况:

成功情况:

总结:Wizard适用于新建数据时创建一套级联数据情况,篇中step1-3之间的跳转均使用转发方式,而不是重定向(ref.setRedirect(true)),原因为:三个页面绑定了同一个controller,转发方式第一次进入走构造函数,以后均不在走构造函数,而重定向需要每次都走构造函数。如果使用重定向,则前一页修改的数据重定向以后在回此页面,修改的数据便会回滚到以前的状态。有错误的地方欢迎指正,有问题欢迎留言。

salesforce 零基础学习(六十)Wizard样式创建数据的更多相关文章

  1. salesforce 零基础学习(十六)Validation Rules & Date/time

    上一篇介绍的内容为Formula,其中的Date/time部分未指出,此篇主要介绍Date/time部分以及Validation rules. 本篇参考PDF: Date/time:https://r ...

  2. salesforce 零基础学习(十九)Permission sets 讲解及设置

    Permission sets以及Profile是常见的设置访问权限的方式. Profile规则为'who see what'.通过Profile可以将一类的用户设置相同的访问权限.对于有着相同Pro ...

  3. salesforce 零基础学习(十八)WorkFlow介绍及用法

    说起workflow大家肯定都不陌生,这里简单介绍一下salesforce中什么情况下使用workflow. 当你分配许多任务,定期发送电子邮件,记录修改时,可以通过自动配置workflow来完成以上 ...

  4. salesforce 零基础学习(六十八)http callout test class写法

    此篇可以参考: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_restfu ...

  5. salesforce零基础学习(八十)使用autoComplete 输入内容自动联想结果以及去重实现

    项目中,我们有时候会需要实现自动联想功能,比如我们想输入用户或者联系人名称,去联想出系统中有的相关的用户和联系人,当点击以后获取相关的邮箱或者其他信息等等.这种情况下可以使用jquery ui中的au ...

  6. salesforce零基础学习(八十二)审批邮件获取最终审批人和审批意见

    项目中,审批操作无处不在.配置审批流时,我们有时候会用到queue,related user设置当前步骤的审批人,审批人可以一个或者多个.当审批人有多个时,邮件中获取当前记录的审批人和审批意见就不能随 ...

  7. salesforce零基础学习(八十九)使用 input type=file 以及RemoteAction方式上传附件

    在classic环境中,salesforce提供了<apex:inputFile>标签用来实现附件的上传以及内容获取.salesforce 零基础学习(二十四)解析csv格式内容中有类似的 ...

  8. salesforce零基础学习(九十六)Platform Event浅谈

    本篇参考:https://developer.salesforce.com/blogs/2018/07/which-streaming-event-do-i-use.html https://trai ...

  9. salesforce 零基础学习(五十二)Trigger使用篇(二)

    第十七篇的Trigger用法为通过Handler方式实现Trigger的封装,此种好处是一个Handler对应一个sObject,使本该在Trigger中写的代码分到Handler中,代码更加清晰. ...

  10. salesforce零基础学习(一百一十)list button实现的一些有趣事情

    本篇参考: salesforce零基础学习(九十五)lightning out https://developer.salesforce.com/docs/component-library/docu ...

随机推荐

  1. LDR详解

    ARM指令集中,LDR通常都是作加载指令的,但是它也可以作伪指令. LDR伪指令的形式是"LDR Rn,=expr".下面举一个例子来说明它的用法. COUNT EQU       ...

  2. 在.NET Core 里使用 BouncyCastle 的DES加密算法

    .NET Core上面的DES等加密算法要等到1.2 才支持,我们可是急需这个算法的支持,文章<使用 JavaScriptService 在.NET Core 里实现DES加密算法>需要用 ...

  3. 用CIL写程序:你好,沃尔德

    前言: 项目紧赶慢赶总算在年前有了一些成绩,所以沉寂了几周之后,小匹夫也终于有时间写点东西了.以前匹夫写过一篇文章,对CIL做了一个简单地介绍,不过不知道各位看官看的是否过瘾,至少小匹夫觉得很不过瘾. ...

  4. “不给力啊,老湿!”:RSA加密与破解

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 加密和解密是自古就有技术了.经常看到侦探电影的桥段,勇敢又机智的主角,拿着一长串毫 ...

  5. 关于Android避免按钮重复点击事件

    最近测试人员测试我们的APP的时候,喜欢快速点击某个按钮,出现一个页面出现多次,测试人员能不能禁止这样.我自己点击了几下,确实存在这个问题,也感觉用户体验不太好.于是乎后来我搜了下加一个方法放在我们U ...

  6. 来吧,HTML5之一些注意事项

    1.说什么是HTML HTML是一种超文本标记语言(Hyper Text Markup Language), 标记语言是一套标记标签(markup tag),用来描述网页的非编程语言. 2.标签特性: ...

  7. Oracle 数据库知识汇总篇

    Oracle 数据库知识汇总篇(更新中..) 1.安装部署篇 2.管理维护篇 3.数据迁移篇 4.故障处理篇 5.性能调优篇 6.SQL PL/SQL篇 7.考试认证篇 8.原理体系篇 9.架构设计篇 ...

  8. UVA-146 ID Codes

    It is 2084 and the year of Big Brother has finally arrived, albeit a century late. In order to exerc ...

  9. 【iOS10 SpeechRecognition】语音识别 现说现译的最佳实践

    首先想强调一下“语音识别”四个字字面意义上的需求:用户说话然后马上把用户说的话转成文字显示!,这才是开发者真正需要的功能. 做需求之前其实是先谷歌百度一下看有没有造好的轮子直接用,结果真的很呵呵,都是 ...

  10. git提交项目到已存在的远程分支

    今天想提交项目到github的远程分支上,那个远程分支是之前就创建好的,而我的本地关联分支还没创建.   之前从未用github提交到远程分支过,弄了半个钟,看了几篇博文,终于折腾出来.现在把步骤整理 ...