salesforce零基础学习(八十)使用autoComplete 输入内容自动联想结果以及去重实现

项目中,我们有时候会需要实现自动联想功能,比如我们想输入用户或者联系人名称,去联想出系统中有的相关的用户和联系人,当点击以后获取相关的邮箱或者其他信息等等。这种情况下可以使用jquery ui中的autoComplete实现。

此篇需求为在输入框中输入检索词对数据库中User表和Contact表的Name字段进行检索,符合条件的放在联想列表中,当用户选择相应的名称后,输入框中显示此名称对应的邮箱地址。

实现此功能可以整体分成三步:

1.通过输入内容检索相关表中符合条件的数据;

2.对检索的数据进行去重以及封装;

3.前台绑定autoComplete实现自动联想功能。

一.通过输入内容检索相关表中符合条件的数据

因为要对两个表进行操作,使用SOQL需要对两个表进行查询,并对搜索结果进行拼接,这种方式使用SOQL只能对每个字符进行like操作。比如输入中行大连,使用SOQL需要拆分成 where name like '%中%行%大%连%'。此种检索搜索出来的结果可能会搜索出用户不想搜索出来的结果,比如 ‘行连大中’。而且对多个表操作推荐使用SOSL,所以此处使用SOSL进行检索操作。

SOSL的操作以及检索封装可以参看:salesforce零基础学习(七十五)浅谈SOSL(Salesforce Object Search Language),此篇使用封装的方法作为Util。

二.对检索的数据进行去重以及封装

对于搜索结果,我们需要三部分内容:

  • 搜索的数据中对象的名称:objName;
  • 搜索的数据类型,属于User还是Contact: objType;
  • 搜索的数据中对象的邮箱:objEmail

所以我们封装一下这个结果集的类,包含三个字段。因为我们最终需要的是用户/联系人邮箱,如果用户/联系人名称和用户/联系人邮箱完全相同,则我们假定他们是相同的数据。所以我们重写一下equals()和hashCode()方法,定义一下两条数据相同的规则。定义后,可以先使用Set接受结果集进行去重,然后转换成List进行结果返回。代码如下:

 1 public without sharing class AutoRetrieveController {
 2 
 3     public String content{get;set;}
 4 
 5     @RemoteAction
 6     public static List<ObjWrapper> retrieveUsersOrContacts(String name) {
 7         //返回的结果集
 8         List<ObjWrapper> results;
 9         //用于去重的set,去除名称和email相同的数据
10         Set<ObjWrapper> resultSet = new Set<ObjWrapper>();
11         //封装数据查询曾
12         SOSLController.RetrieveWrapper wrapper = new SOSLController.RetrieveWrapper();
13         wrapper.retrieveKeyword = name;
14         wrapper.searchGroup = 'NAME FIELDS';
15         wrapper.objName2FieldsMap = new Map<String,List<String>>();
16         List<String> userFields = new List<String>{'Name','Email'};
17         List<String> contactFields = new List<String>{'Name','Email'};
18         wrapper.objName2FieldsMap.put('user',userFields);
19         wrapper.objName2FieldsMap.put('contact',contactFields);
20         //获取结果显示列表
21         List<SOSLController.SearchResultWrapper> searchResultList = SOSLController.search(wrapper);
22         //迭代,数据转换以及去重处理
23         if(searchResultList!= null && searchResultList.size() > 0) {
24             for(SOSLController.SearchResultWrapper temp : searchResultList) {
25                 ObjWrapper tempWrapper = new ObjWrapper();
26                 tempWrapper.objType = temp.objName;
27                 Map<String,Object> fieldsMap = temp.objFieldName2Value;
28                 if(fieldsMap.get('Name') != null) {
29                     tempWrapper.objName = (String)fieldsMap.get('Name');
30                 }
31                 if(fieldsMap.get('Email') != null) {
32                     tempWrapper.objEmail = (String)fieldsMap.get('Email');
33                 }
34                 resultSet.add(tempWrapper);
35             }
36         }
37         if(resultSet.size() > 0) {
38             results = new List<ObjWrapper>(resultSet);
39         } else {
40             results = new List<ObjWrapper>();
41         }
42         return results;
43     }
44 
45     public class ObjWrapper {
46         public String objName{get;set;}
47         public String objEmail{get;set;}
48         public String objType{get;set;}
49 
50         public Boolean equals(Object o){
51             Boolean result = false;
52             if(o instanceof ObjWrapper) {
53                 ObjWrapper obj = (ObjWrapper)o;
54                 if(objEmail != null && objName != null) {
55                     if(objEmail.equalsIgnoreCase(obj.objEmail) && objName.equalsIgnoreCase(obj.objName)) {
56                         result = true;
57                     }
58                 }
59                 
60             }
61             return result;
62         }
63 
64         public Integer hashCode() {
65             return 1;
66         }
67     }
68 }

三.前台绑定autoComplete实现自动联想功能

使用jquery ui的autoComplete功能,需要下载jquery ui 的js以及css文件,页面使用了jquery,所以也需要使用jquery的js文件。下载后压缩成zip包,上传到static resource便可以引用了。

此处为将三个文件放在了jquery的文件夹下,上传了zip包名称为JqueryUI。页面代码如下:

 1 <apex:page controller="AutoRetrieveController">
 2 
 3     <apex:includeScript value="{!URLFOR($Resource.JqueryUI, 'jquery/jquery.js')}" />
 4     <apex:includeScript value="{!URLFOR($Resource.JqueryUI, 'jquery/jquery-ui.min.js')}" />
 5     <apex:stylesheet value="{!URLFOR($Resource.JqueryUI, 'jquery/jquery-ui.min.css')}" />
 6     <apex:form>
 7         <apex:inputText id="content" value="{!content}" onmousedown="autoCompleteList()" styleClass="contentWidth"/>
 8     </apex:form>
 9 
10 
11     <script>
12 
13         j$ = jQuery.noConflict();
14 
15         function autoCompleteList(){
16             var contentDom = j$("input[id$=content]");
17             if (contentDom.size() == 0) {
18                 return ;
19             }
20             contentDom.autocomplete({
21                 minLength: 2,
22                 autoFocus: true,
23                 source: function(request, response) {
24                     queryTerm =  request.term;
25                     console.log(queryTerm);
26                     if(queryTerm != '') {
27                         AutoRetrievController.retrieveUsersOrContacts(
28                             queryTerm,
29                             function(result, event) {
30                                 if (event.type == 'exception') {
31                                 } else {
32                                     sObjects = result;
33                                     if (0 == sObjects.length) {
34                                         response(null);
35                                     } else {
36                                         response(sObjects);
37                                     }
38                                 }
39                         });
40                     }
41                 },
42                 focus: function(event, ui) {
43                     return false;
44                 },
45 
46                 select: function(event, ui) {
47                     this.value = ui.item.objEmail;
48                     return false;
49                 },
50             }).data("uiAutocomplete")._renderItem = function(ul, item) {
51                     var entry = item.objName +'\t\t' + item.objType;
52                     entry = entry.replace(queryTerm, "<b>" + queryTerm + "</b>");
53                     return j$( "<li></li>" )
54                             .data( "item.autocomplete", item )
55                             .append( "<a>" + entry + "</a>" )
56                             .appendTo( ul );
57             };
58         }
59 
60     </script>
61 </apex:page>

效果展示:

总结:联想功能在开发中还是比较常用的,autoComplete功能有好多相关的方法,可以去官网或者其他渠道了解相关方法进行UI的美化。篇中只是对基础功能进行抛砖引玉。

还有好多功能点需要优化,比如对数据检索没有进行相关limit的限制,去重方法写的过于简单,没有分别考虑null的处理等等。有兴趣的小伙伴可以继续完善。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏walterlv - 吕毅的博客

利用 ReSharper 自定义代码中的错误模式,在代码审查之前就发现并修改错误

发布于 2018-03-20 11:54 更新于 2018-03...

550
来自专栏QQ音乐技术团队的专栏

打通Android Gradle编译过程的任督二脉

本文主要是基于自己在工作当中的一些Android Gradle实践经验,对gradle相关知识做的一个简单总结和分享,希望对大家有帮助。 首先会讲Gradle大...

8598
来自专栏专注研发

PageHelper分页插件及通用分页js

物理分页依赖的是某一物理实体,这个物理实体就是数据库,比如MySQL数据库提供了limit关键字,程序员只需要编写带有limit关键字的SQL语句,数据库返回的...

1151
来自专栏Elasticsearch实验室

Elasitcsearch 底层系列 Lucene 内核解析之 Stored Fields

Lucene 的 stored fields 主要用于行存文档需要保存的字段内容,每个文档的所有 stored fields 保存在一起,在查询请求需要返回字段...

2075
来自专栏圣杰的专栏

ABP入门系列(17)——使用ABP集成的邮件系统发送邮件

ABP中对邮件的封装主要集成在Abp.Net.Mail和Abp.Net.Mail.Smtp命名空间下,相应源码在此。 #一、Abp集成的邮件模块是如何实现的 ?...

21010
来自专栏cnblogs

简单实现 C# 与 Javascript的兼容

本文章介绍下自己这刚实现的一个c#与js交互的插件。需求来源于一次与朋友的讨论。主要对话如下: 朋友:最近我想模拟一些数据,来测试我现在写的接口,但手工编写这些...

21510
来自专栏更流畅、简洁的软件开发方式

数据访问函数库的使用方法(一)——添加修改数据

由于这个类库是需要实例化的,如果每一次都要实例化,然后用完了在销毁,无形中就多了不少的代码,而且很容易忘记销毁实例。 同时在用户的一次访问的过程中不断地实例...

1938
来自专栏CDA数据分析师

Python 探针实现原理

本文将简单讲述一下 Python 探针的实现原理。 同时为了验证这个原理,我们也会一起来实现一个简单的统计指定函数执行时间的探针程序。 探针的实现主要涉及以下几...

2348
来自专栏lulianqi

一个基于.NET平台的自动化/压力测试系统设计简述

AutoTest是一个基于.NET平台实现的自动化/压力测试的系统,可独立运行于windows平台下,支持分布式部署,不需要其他配置或编译器的支持。(本质是一个...

981
来自专栏HansBug's Lab

【技巧】Java工程中的Debug信息分级输出接口及部署模式

UPDATE: 2018.4.4 笔者将考虑将这一模块封装成一个完整的java第三方包并可能进行开源放送,完成后将会再次发布最新消息,敬请期待。 -------...

3846

扫码关注云+社区