项目中表之间关联关系特别多,比如三个表中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. 在 ML2 中配置 OVS flat network - 每天5分钟玩转 OpenStack(133)

    前面讨论了 OVS local network,今天开始学习 flat network. flat network 是不带 tag 的网络,宿主机的物理网卡通过网桥与 flat network 连接, ...

  2. 对抗假人 —— 前后端结合的 WAF

    前言 之前介绍了一些前后端结合的中间人攻击方案.由于 Web 程序的特殊性,前端脚本的参与能大幅弥补后端的不足,从而达到传统难以实现的效果. 攻防本为一体,既然能用于攻击,类似的思路同样也可用于防御. ...

  3. Laravel Composer and ServiceProvider

    Composer and: 创建自定义类库时,按命名空间把文件夹结构组织好 composer.json>autoload>classmap>psr-4 composer dump-a ...

  4. 猖獗的假新闻:2017年1月1日起iOS的APP必须使用HTTPS

    一.假新闻如此猖獗 刚才一位老同事 打电话问:我们公司还是用的HTTP,马上就到2017年了,提交AppStore会被拒绝,怎么办? 公司里已经有很多人问过这个问题,回答一下: HTTP还是可以正常提 ...

  5. MJRefresh 源码解读 + 使用

    MJRefresh这个刷新控件是一款非常好用的框架,我们在使用一个框架的同时,最好能了解下它的实现原理,不管是根据业务要求在原有的基础上修改代码,还是其他的目的,弄明白作者的思路和代码风格,会受益匪浅 ...

  6. %iowait和CPU使用率的正确认知

    resources 理解 %IOWAIT (%WIO) LINUX系统的CPU使用率和LOAD Linux Performance Observability Tools How Linux CPU ...

  7. 浅谈java异常[Exception]

    学习Java的同学注意了!!! 学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群,群号码:589809992 我们一起学Java! 一. 异常的定义 在<java编程思想 ...

  8. windows下mongodb配置

    打开cmd(windows键+r输入cmd)命令行,进入D:\mongodb\bin目录(如图先输入d:进入d盘然后输入cd d:\mongodb\bin), 输入如下的命令启动mongodb服务: ...

  9. 编写简单的Makefile文件

    makefile中的编写内容如下: www:hello.c x.h gcc hello.c -o hello clean: rm hello www:hello.c  x.h 表示生成www这个文件需 ...

  10. D3.js学习(七)

    上一节中我们学会了如何旋转x轴标签以及自定义标签内容,在这一节中,我们将接触动画(transition) 首先,我们要在页面上添加一个按钮,当我们点击这个按钮时,调用我们的动画.所以,我们还需要在原来 ...