项目中表之间关联关系特别多,比如三个表中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,转发方式第一次进入走构造函数,以后均不在走构造函数,而重定向需要每次都走构造函数。如果使用重定向,则前一页修改的数据重定向以后在回此页面,修改的数据便会回滚到以前的状态。有错误的地方欢迎指正,有问题欢迎留言。