项目中表之间关联关系特别多,比如三个表中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. AngularJS过滤器filter-保留小数,小数点-$filter

    AngularJS      保留小数 默认是保留3位 固定的套路是 {{deom | number:4}} 意思就是保留小数点 的后四位 在渲染页面的时候 加入这儿个代码 用来精确浮点数,指定小数点 ...

  2. App你真的需要么

    随着智能手机.移动路联网的普及,APP火的一塌糊涂,APP应用可谓五花八门,街上经常看到各种推广:扫码安装送东西,送优惠券.仿佛一夜之间一个企业没有自己的APP就跟不上时代了. 有时我在想:APP,你 ...

  3. wordpress优化之结合prism.js为编辑器自定义按钮转化代码

    原文链接 http://ymblog.net/2016/07/24/wordpress-prism/ 继昨天花了一天一夜的时间匆匆写了主题Jiameil3.0之后,心中一直在想着优化加速,体验更好,插 ...

  4. ASP.NET MVC学习之母版页和自定义控件的使用

    一.母板页_Layout.cshtml类似于传统WebForm中的.master文件,起到页面整体框架重用的目地1.母板页代码预览 <!DOCTYPE html> <html> ...

  5. 太多选择——企业如何选择合适的BI工具?

    在没认清现状前,企业当然不能一言不合就上BI. BI不同于一般的企业管理软件,不能简单归类为类似用于提高管理的ERP和WMS,或用于提高企业效率的OA.BPM.BI的本质应该是通过展现数据,用于加强企 ...

  6. arcpy+PyQt+py2exe快速开发桌面端ArcGIS应用程序

    前段时间有一个项目,大体是要做一个GIS数据处理工具. 一般的方法是基于ArcObjects来进行开发,因为我对ArcObjects不太熟悉,所以就思考有没有其他简单快速的方法来做. 在查看ArcGI ...

  7. Android Studio分类整理res/Layout中的布局文件(创建子目录)

    res/layout中的布局文件太杂,没有层次感,受不了的我治好想办法解决这个问题. 前几天看博客说可以使用插件分组,可惜我没找到.知道看到另一篇博客时,才知道这个方法不能用了. 不能用插件,那就手动 ...

  8. centos tomcat安装

    官网http://tomcat.apache.org/download-70.cgi下载zip的文件unzip apache-tomcat-7.0.54.zipmv apache-tomcat-7.0 ...

  9. Linux上运行NET

    今天尝试了下Ubuntu上运行NET程序,按照 https://github.com/aspnet/Home 的指引,一步一步来: 1.安装DNVM(原名KVM) Linux控制台下输入 curl - ...

  10. 进程监控工具supervisor 启动Mongodb

    进程监控工具supervisor 启动Mongodb 一什么是supervisor Superviosr是一个UNIX-like系统上的进程监控工具. Supervisor是一个Python开发的cl ...