项目中表之间关联关系特别多,比如三个表中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的列表方法
1 public without sharing class GoodsHelper {
2
3 public static final String BASE_GOODS_QUERY = 'SELECT CreatedById, CreatedDate, IsDeleted,' +
4 ' Goods_Code_Unique__c, Name, GoodsPicture__c, GoodsBrand__c, GoodsCostPrice__c,' +
5 ' GoodsDescribe__c, GoodsName__c, GoodsPrice__c, GoodsProfit__c, Is_Draft__c,' +
6 ' LastModifiedById, LastModifiedDate, No__c, OwnerId, Id, RecordTypeId,' +
7 ' Status__c, SystemModstamp' +
8 ' FROM Goods__c where IsDeleted = false';
9 public static final String BASE_GOODS_COUNT_QUERY = 'SELECT count() from Goods__c where IsDeleted = false';
10 public static MyPaginationEnhancement getGoodsList(String goodsName,String goodsBrand,MyPaginationEnhancement pagination) {
11 String queryCondition= '';
12 String orderBy ='';
13 if(goodsName != null) {
14 queryCondition += ' and GoodsName__c like %\'' + goodsName + '%\'';
15 }
16 if(goodsBrand != null) {
17 queryCondition += ' and GoodsBrand__c = :goodsBrand';
18 }
19 orderBy = ' order by createddate';
20
21 pagination.getQueryResult(BASE_GOODS_COUNT_QUERY,BASE_GOODS_QUERY,queryCondition,null,orderBy);
22 return pagination;
23 }
24 }
2.GoodsListController:Goods列表Controller
1 public with sharing class GoodsListController {
2 public Map<String,String> parameters;
3
4 public GoodsListController() {
5 parameters=ApexPages.currentPage().getParameters();
6 init();
7 }
8
9 public MyPaginationEnhancement pagination = new MyPaginationEnhancement();
10
11 public String goodsName{get;set;}
12
13 public String goodsBrand{get;set;}
14
15
16 public void init() {
17 queryByCondition();
18 }
19
20 public void queryByCondition() {
21 GoodsHelper.getGoodsList(goodsName,goodsBrand,pagination);
22 }
23
24 public MyPaginationEnhancement resultPagination{
25 get{
26 if(pagination ==null){
27 pagination =new MyPaginationEnhancement();
28 }
29 return pagination;
30 }
31 set;
32 }
33
34 public List<Goods__c> resultList{
35 get{
36 if(pagination==null || pagination.resultList==null){
37 return new List<Goods__c>();
38 }
39 return pagination.resultList;
40 }
41 set;
42 }
43
44 public PageReference newGoods() {
45 return Page.detailGoods;
46 }
47
48 public void firstPage() {
49 pagination.first();
50 queryByCondition();
51 }
52
53 public void lastPage() {
54 pagination.last();
55 queryByCondition();
56 }
57
58 public void previousPage() {
59 pagination.previous();
60 queryByCondition();
61 }
62
63 public void nextPage() {
64 pagination.next();
65 queryByCondition();
66 }
67 }
3.GoodsListPage
1 <apex:page controller="GoodsListController">
2 <style>
3 /*-- 分页 --*/
4 .paginator {font:12px Arial, Helvetica, sans-serif; padding:10px 0; margin:0px;}
5 .paginator a {padding:1px 6px;border:solid 1px #ddd;background:#fff;color:#000;text-decoration:none;margin-right:2px;}
6 .paginator a:visited {padding:1px 6px;border:solid 1px #ddd;background:#fff;text-decoration:none;}
7 .paginator .current {padding:1px 6px; font-weight:bold; color:#f0ab00; font-size:12px; border:none;}
8 .paginator a:hover {color:#fff; background:#ffa501; border-color:#ffa501; text-decoration:none;}
9
10 </style>
11
12 <apex:form >
13 <apex:commandButton value="新建商品" action="{!newGoods}"/>
14 <apex:outputPanel layout="block">
15 <apex:outputPanel layout="block">
16 <apex:outputPanel layout="block">
17 <apex:outputPanel layout="block" id="goodsList">
18 <apex:dataTable align="center" value="{!resultList}" var="goods">
19 <apex:column style="width:180px;">
20 <apex:facet name="header">{!$ObjectType.Goods__c.fields.GoodsName__c.label}</apex:facet>
21 <apex:outputText value="{!goods.GoodsName__c}" />
22 </apex:column>
23 <apex:column style="width:225px;">
24 <apex:facet name="header">{!$ObjectType.Goods__c.fields.GoodsPrice__c.label}</apex:facet>
25 <apex:outputText value="{!goods.GoodsPrice__c}" />
26 </apex:column>
27 <apex:column style="width:225px;">
28 <apex:facet name="header">{!$ObjectType.Goods__c.fields.GoodsCostPrice__c.label}</apex:facet>
29 <apex:outputText value="{!goods.GoodsCostPrice__c}" />
30 </apex:column>
31 <apex:column style="width:500px;">
32 <apex:facet name="header">操作</apex:facet>
33 <apex:outputLink value="/apex/detailGoods">编辑
34 <apex:param name="goodsId" value="{!goods.Id}"/>
35 </apex:outputLink>
36 </apex:column>
37 </apex:dataTable>
38
39 <apex:outputPanel layout="block" styleClass="paginator"
40 style="padding:0px;">
41 <apex:panelGrid columns="2" style="width:100%;"
42 styleClass="az_text_table" rowClasses="paginator,paginator">
43 <apex:outputText rendered="{!!resultPagination.hasRecord}"
44 value="第 0 页,共 0 页,每页 {!resultPagination.pageSize} 条" />
45 <apex:outputText rendered="{!resultPagination.hasRecord}"
46 value="第 {!resultPagination.pageNumber} 页,共 {!resultPagination.totalPage} 页,每页 {!resultPagination.pageSize} 条" />
47 <apex:panelGroup >
48 <apex:outputPanel >
49 <apex:outputText value="首页"
50 rendered="{!(!resultPagination.hasRecord)||(!resultPagination.hasPrevious)}"
51 style="border: solid 1px #ddd;padding:1px 6px;background: #e8e8e9;margin-right:5px;"></apex:outputText>
52 <apex:commandLink action="{!firstPage}"
53 rendered="{!resultPagination.hasRecord && resultPagination.hasPrevious}"
54 immediate="true" reRender="companyList" value="首页"
55 style="margin-right:5px;" />
56 </apex:outputPanel>
57 <apex:outputPanel >
58 <apex:outputText value="上一页"
59 rendered="{!!resultPagination.hasRecord || (!resultPagination.hasPrevious)}"
60 style="border: solid 1px #ddd;padding:1px 6px;background: #e8e8e9;margin-right:5px;"></apex:outputText>
61 <apex:commandLink action="{!previousPage}"
62 rendered="{!resultPagination.hasRecord && resultPagination.hasPrevious}"
63 immediate="true" reRender="companyList" value="上一页"
64 style="margin-right:5px;" />
65 </apex:outputPanel>
66 <apex:outputPanel >
67 <apex:outputText value="{!resultPagination.pageNumber}"
68 styleClass="current" />
69 </apex:outputPanel>
70 <apex:outputPanel >
71 <apex:outputText value="下一页"
72 rendered="{!!resultPagination.hasRecord || !resultPagination.hasNext}"
73 style="border: solid 1px #ddd;padding:1px 6px;background: #e8e8e9;margin-right:5px;margin-left:5px;"></apex:outputText>
74 <apex:commandLink action="{!nextPage}"
75 rendered="{!resultPagination.hasRecord && resultPagination.hasNext}"
76 immediate="true" reRender="companyList" value="下一页"
77 style="margin-right:5px;margin-left:5px;" />
78 </apex:outputPanel>
79 <apex:outputPanel >
80 <apex:outputText value="尾页"
81 rendered="{!!resultPagination.hasRecord || !resultPagination.hasNext}"
82 style="border: solid 1px #ddd;padding:1px 6px;background: #e8e8e9;margin-right:5px;"></apex:outputText>
83 <apex:commandLink action="{!lastPage}"
84 rendered="{!resultPagination.hasRecord && resultPagination.hasNext}"
85 immediate="true" reRender="companyList" value="尾页"
86 style="margin-right:5px;" />
87 </apex:outputPanel>
88 </apex:panelGroup>
89 </apex:panelGrid>
90 </apex:outputPanel>
91 </apex:outputPanel>
92 </apex:outputPanel>
93 </apex:outputPanel>
94 </apex:outputPanel>
95 </apex:form>
96 </apex:page>
4.GoodsDetailController:此类中封装了Wizard的相关方式,Wizard的相关跳转均为转发方式。
1 public with sharing class GoodsDetailController {
2
3 /*入口是新建还是更新:新建为false,更新为true*/
4 public Boolean isEditView{
5 get {
6 if(isEditView == null) {
7 isEditView = false;
8 }
9 return isEditView;
10 }
11 set;
12 }
13
14 public GoodsDetailController() {
15 init();
16 }
17
18 public GoodsDetailController(ApexPages.StandardController controller) {
19 init();
20 }
21
22 public void init() {
23 String goodsId = ApexPages.currentPage().getParameters().get('goodsId');
24 if(goodsId != null) {
25 isEditView = true;
26 String queryGoods = 'SELECT Goods_Code_Unique__c, Name, GoodsBrand__c,' +
27 ' GoodsCostPrice__c, GoodsDescribe__c, GoodsName__c, GoodsPrice__c,' +
28 ' GoodsProfit__c, No__c,Id, Status__c' +
29 ' FROM Goods__c where Id = :goodsId';
30 String queryGoodsVendor = 'SELECT Goods__c, Id, Vendor_Name__c' +
31 ' FROM Goods_Vendor__c where Goods__c = :goodsId';
32 List<Goods__c> goodsList = Database.query(queryGoods);
33 if(goodsList != null && goodsList.size() > 0) {
34 goods = goodsList.get(0);
35 }
36 List<Goods_Vendor__c> goodsVendorList = Database.query(queryGoodsVendor);
37 if(goodsVendorList != null && goodsVendorList.size() > 0) {
38 goodsVendor = goodsVendorList.get(0);
39 }
40 }
41 }
42
43 public Goods__c goods{
44 get{
45 if(goods == null) {
46 goods = new Goods__c();
47 }
48 return goods;
49 }
50 set;
51 }
52
53 public Goods_Vendor__c goodsVendor{
54 get{
55 if(goodsVendor == null) {
56 goodsVendor = new Goods_Vendor__c();
57 }
58 return goodsVendor;
59 }
60 set;
61 }
62
63 public PageReference saveFinally() {
64 Savepoint sp = Database.setSavepoint();
65 try {
66 upsert goods;
67 goodsVendor.Goods__c = goods.Id;
68 upsert goodsVendor;
69 } catch(DMLException e) {
70 Database.rollback(sp);
71 ApexPages.addMessage(new ApexPages.Message(ApexPages.SEVERITY.ERROR,e.getMessage()));
72 return null;
73 }
74 return redirectToGoodsList();
75 }
76
77
78
79 public PageReference redirectToGoods() {
80 return Page.detailGoods;
81 }
82
83 public PageReference redirectToVendor() {
84 return Page.detailVendor;
85 }
86
87 public PageReference redirectToTotal() {
88 return Page.detailGoodsTotal;
89 }
90
91 public PageReference cancelCreateGoods() {
92 if(!isEditView) {
93 if(goodsVendor != null && goodsVendor.Id != null) {
94 delete goodsVendor;
95 }
96 if(goods != null && goods.Id != null) {
97 delete goods;
98 }
99 }
100 return redirectToGoodsList();
101 }
102
103 public PageReference redirectToGoodsList() {
104 PageReference ref = new PageReference('/apex/GoodsListPage');
105 ref.setRedirect(true);
106 return ref;
107 }
108
109 }
5.detailGoods.page:商品信息详情页面
1 <apex:page controller="GoodsDetailController" tabStyle="Goods__c">
2 <script>
3 function confirmCancel() {
4 var isCancel = confirm("确定取消新建商品信息?");
5 if (isCancel) {
6 return true;
7 }
8 return false;
9 }
10 </script>
11 <apex:sectionHeader title="New Goods " subtitle="Step 1 of 3"/>
12 <apex:form >
13 <apex:pageBlock title="Goods Information" mode="edit">
14 <apex:pageBlockButtons >
15 <apex:commandButton action="{!redirectToVendor}" value="Next"></apex:commandButton>
16 <apex:commandButton action="{!cancelCreateGoods}" value="Cancel" onclick="return confirmCancel()" immediate="true"/>
17 </apex:pageBlockButtons>
18 <apex:pageBlockSection title="Goods Basic Information">
19 <apex:inputField id="GoodsUniqueCode" value="{!goods.Goods_Code_Unique__c}"/>
20 <apex:inputField id="GoodsName" value="{!goods.GoodsName__c}"/>
21 <apex:inputField id="GoodsPrice" value="{!goods.GoodsPrice__c}"/>
22 <apex:inputField id="GoodsCostPrice" value="{!goods.GoodsCostPrice__c}"/>
23 </apex:pageBlockSection>
24 </apex:pageBlock>
25 </apex:form>
26 </apex:page>
6.detailVendor.page:vendor详情页
1 <apex:page controller="GoodsDetailController" tabStyle="Goods_Vendor__c">
2 <script>
3 function confirmCancel() {
4 var isCancel = confirm("确定取消新建商品信息?");
5 if (isCancel)
6 return true;
7 return false;
8 }
9 </script>
10 <apex:sectionHeader title="New Vendor" subtitle="Step 2 of 3"/>
11 <apex:form >
12 <apex:pageBlock title="Vendor Information" mode="edit">
13 <apex:pageBlockButtons >
14 <apex:commandButton action="{!redirectToGoods}" value="Previous">
15 </apex:commandButton>
16 <apex:commandButton action="{!redirectToTotal}" value="Next">
17 </apex:commandButton>
18 <apex:commandButton action="{!cancelCreateGoods}" value="Cancel" onclick="return confirmCancel()" immediate="true"/>
19 </apex:pageBlockButtons>
20 <apex:pageBlockSection title="Vendor Basic Information">
21 <apex:inputField id="VendorName" value="{!goodsVendor.Vendor_Name__c}"/>
22 </apex:pageBlockSection>
23 </apex:pageBlock>
24 </apex:form>
25 </apex:page>
7.detailTotal.page:用于显示goods以及vendor的详细信息以及提交按钮
1 <apex:page controller="GoodsDetailController" tabStyle="Goods__c">
2 <script>
3 function confirmCancel() {
4 var isCancel = confirm("确定取消新建商品信息?");
5 if (isCancel)
6 return true;
7 return false;
8 }
9 </script>
10 <apex:sectionHeader title="Goods Total Infomation" subtitle="Step 3 of 3"/>
11 <apex:form >
12 <apex:pageMessages />
13 <apex:pageBlock title="Total Information">
14 <apex:pageBlockButtons >
15 <apex:commandButton action="{!redirectToVendor}" value="Previous"/>
16 <apex:commandButton action="{!saveFinally}" value="Save"/>
17 <apex:commandButton action="{!cancelCreateGoods}" value="Cancel" onclick="return confirmCancel()" immediate="true"/>
18 </apex:pageBlockButtons>
19 <apex:pageBlockSection title="Goods Information">
20 <apex:outputField value="{!goods.Goods_Code_Unique__c}"/>
21 <apex:outputField value="{!goods.GoodsName__c}"/>
22 <apex:outputField value="{!goods.GoodsPrice__c}"/>
23 <apex:outputField value="{!goods.GoodsCostPrice__c}"/>
24 </apex:pageBlockSection>
25 <apex:pageBlockSection title="Vendor Information">
26 <apex:outputField value="{!goodsVendor.Vendor_Name__c}"/>
27 </apex:pageBlockSection>
28 </apex:pageBlock>
29 </apex:form>
30 </apex:page>
效果展示:
1.商品列表
2.点击编辑,如果点击新建其他内容均为空,此处只显示编辑
3.点击next进入vendor页面
4.total页面
5.点击save以后,成功则跳转到list页面,失败则显示失败ERROR
失败情况:
成功情况:
总结:Wizard适用于新建数据时创建一套级联数据情况,篇中step1-3之间的跳转均使用转发方式,而不是重定向(ref.setRedirect(true)),原因为:三个页面绑定了同一个controller,转发方式第一次进入走构造函数,以后均不在走构造函数,而重定向需要每次都走构造函数。如果使用重定向,则前一页修改的数据重定向以后在回此页面,修改的数据便会回滚到以前的状态。有错误的地方欢迎指正,有问题欢迎留言。