项目中表之间关联关系特别多,比如三个表中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. angular实现统一的消息服务

    后台API返回的消息怎么显示更优雅,怎么处理才更简洁?看看这个效果怎么样? 自定义指令和服务实现 自定义指令和服务实现消息自动显示在页面的顶部,3秒之后消失 1. 显示消息 这种显示消息的方式是不是有 ...

  2. 我为NET狂官方面试题-数据库篇答案

    题目:http://www.cnblogs.com/dunitian/p/6028838.html 汇总:http://www.cnblogs.com/dunitian/p/5977425.html ...

  3. C# 发送邮件 附件名称为空

     示例代码: // 1.创建邮件 MailMessage mailMsg = new MailMessage(); mailMsg.To.Add(new MailAddress("test@ ...

  4. ASP.NET Core中如影随形的”依赖注入”[下]: 历数依赖注入的N种玩法

    在对ASP.NET Core管道中关于依赖注入的两个核心对象(ServiceCollection和ServiceProvider)有了足够的认识之后,我们将关注的目光转移到编程层面.在ASP.NET ...

  5. 自定义搭建PHP开发环境

    学习了一段时间php了,因为之前是刚接触php,所以用的是集成安装包(wamp).现在想进一步了解apache.mysql.php之间的关系以及提升自己所以进行自定义搭建PHP开发环境.废话不多说,请 ...

  6. WebGIS中等值面展示的相关方案简析

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 等值面是气象.环保等相关项目上常用到的效果展示.在传统的CS项 ...

  7. Java定时任务的常用实现

    Java的定时任务有以下几种常用的实现方式: 1)Timer 2)ScheduledThreadPoolExecutor 3)Spring中集成Cron Quartz 接下来依次介绍这几类具体实现的方 ...

  8. Activity之概览屏幕(Overview Screen)

    概览屏幕 概览屏幕(也称为最新动态屏幕.最近任务列表或最近使用的应用)是一个系统级别 UI,其中列出了最近访问过的 Activity 和任务. 用户可以浏览该列表并选择要恢复的任务,也可以通过滑动清除 ...

  9. MSSQL 事务,视图,索引,存储过程,触发器

    事务 事务是一种机制.是一种操作序列,它包含了一组数据库操作命令,这组命令要么全部执行,要么全部不执行. 在数据库系统上执行并发操作时事务是作为最小的控制单元来使用的.这特别适用于多用户同时操作的数据 ...

  10. ubuntu15.04 nginx1.6.5 配置虚拟主机

    1 在/etc/hosts   添加host 2 在/etc/nginx/nginx.conf中查看http里的include ****** /*.conf的路径,在此路径下添加一个新的******. ...