前言

  最近有这么一个需求,就是用到中国的各种行政区,然后还是三级联动,就琢磨写这么一个字段。然后,觉得挺有意义的,写字段的过程也有点心得,就想到拿到博客里分享给大家,一起看看。

  1、 创建字段的解决方案,包括:字段类、字段控件类、字段控件的前台文件、字段的描述文件、城市和区域的数据列表、字段的Feature和其中所需要的JavaScript库和文件。

  2、 在字段的前台控件上,添加我们需要的控件,当在显示视图(DispForm)的时候,只有一个Label控件用来显示值,除此之外的视图(NewForm和EditForm)的时候,有一个Label控件用来输入下拉框等的html,一个TextBox控件用来保存和修改值,一个隐藏字段用来存一个Guid,防止一个列表加多个字段时,控件的Id有重复。

  3、 初始化控件的核心代码,主要包括输入城市和区域下拉框控件的Html代码,并且绑定相关的事件。

  1. protected override void CreateChildControls()
  2. {
  3. base.CreateChildControls();
  4. if (this.Field != null)
  5. {
  6. this.lbValue = (Label)TemplateContainer.FindControl("lbValue");
  7. this.tbValue = (TextBox)TemplateContainer.FindControl("tbValue");
  8. this.hfValue = (HiddenField)TemplateContainer.FindControl("hfValue");
  9. this.lbValueResult = (Label)TemplateContainer.FindControl("lbValueResult");
  10. }
  11. if (this.ControlMode == SPControlMode.Display)
  12. {
  13. if (lbValueResult != null)
  14. {
  15. lbValueResult.Text = this.ItemFieldValue.ToString();
  16. }
  17. }
  18. else
  19. {
  20. string myGuid = Guid.NewGuid().ToString().Replace("-", "");
  21.  
  22. string scriptLink = "<script type='text/javascript' src='/_layouts/15/LinyuCityField/Script.js'></script><script type='text/javascript' src='/_layouts/15/LinyuCityField/jquery-1.7.1.js'></script>";
  23. string scriptInit = @"<script type='text/javascript'>$(document).ready(function(){
  24. setInterval(syncValue,1000);
  25. initSelect('" + myGuid + @"province','0');
  26. $('#" + myGuid + @"province').change(function(){
  27. var vv = $(this).val();
  28. //if(vv=='11'||vv=='12'||vv=='31'||vv=='50'){$('#" + myGuid + @"district').hide();}else{$('#" + myGuid + @"district').show();}
  29. $('#" + myGuid + @"city').empty();
  30. initSelect('" + myGuid + @"city',vv);
  31. $('#" + myGuid + @"district').empty();
  32. });
  33. $('#" + myGuid + @"city').change(function(){
  34. var vv = $(this).val();
  35. var lsvv=vv.substring(0,2);
  36. //if(lsvv=='11'||lsvv=='31'||lsvv=='12'||lsvv=='50'){$('#" + myGuid + @"district').hide();}else{$('#" + myGuid + @"district').show();}
  37. $('#" + myGuid + @"district').empty();
  38. initSelect('" + myGuid + @"district',vv);
  39. });
  40. });</script>";
  41.  
  42. string scriptInit2 = @"<script type='text/javascript'>$(document).ready(function(){
  43. setInterval(syncValue,1000);
  44. $('#" + myGuid + @"province').change(function(){
  45. var vv = $(this).val();
  46. //if(vv=='11'||vv=='12'||vv=='31'||vv=='50'){$('#" + myGuid + @"district').hide();}else{$('#" + myGuid + @"district').show();}
  47. $('#" + myGuid + @"city').empty();
  48. initSelect('" + myGuid + @"city',vv);
  49. $('#" + myGuid + @"district').empty();
  50. });
  51. $('#" + myGuid + @"city').change(function(){
  52. var vv = $(this).val();
  53. var lsvv=vv.substring(0,2);
  54. //if(lsvv=='11'||lsvv=='31'||lsvv=='12'||lsvv=='50'){$('#" + myGuid + @"district').hide();}else{$('#" + myGuid + @"district').show();}
  55. $('#" + myGuid + @"district').empty();
  56. initSelect('" + myGuid + @"district',vv);
  57. });
  58. });</script>";
  59.  
  60. Page.ClientScript.RegisterStartupScript(this.GetType(), "scriptLink", scriptLink);
  61. string selectHtml = string.Empty;
  62. if (this.ControlMode == SPControlMode.New)
  63. {
  64. Page.ClientScript.RegisterStartupScript(this.GetType(), "scriptInit", scriptInit);
  65. selectHtml = "<select id='" + myGuid + "province'></select><select id='" + myGuid + "city'></select><select id='" + myGuid + "district'></select>";
  66. }
  67. else
  68. {
  69. string fieldValue = this.ItemFieldValue.ToString();
  70. string[] filedValues = fieldValue.Split('-');
  71. selectHtml = initEditHtml(myGuid, fieldValue);
  72. Page.ClientScript.RegisterStartupScript(this.GetType(), "scriptInit2", scriptInit2);
  73. }
  74.  
  75. if (hfValue != null)
  76. hfValue.Value = myGuid;
  77.  
  78. if (lbValue != null)
  79. lbValue.Text = selectHtml;
  80. }
  81. }

  4、 编辑页面时初始化控件的代码,包括省、城市、区域。

  1. public string initEditHtml(string myGuid, string fieldValue)
  2. {
  3. string html = string.Empty;
  4. string[] fvs = fieldValue.Split('-');
  5. string province = string.Empty;
  6. string city = string.Empty;
  7. string district = string.Empty;
  8. using (SPSite site = new SPSite(SPContext.Current.Site.ID))
  9. {
  10. using (SPWeb web = site.OpenWeb(SPContext.Current.Web.ID))
  11. {
  12. SPList list = web.Lists.TryGetList("CityDataSourse");
  13. SPQuery query1 = new SPQuery();
  14. SPQuery query2 = new SPQuery();
  15. SPQuery query3 = new SPQuery();
  16. SPListItem item1;
  17. SPListItem item2;
  18. SPListItem item3;
  19. switch (fvs.Length)
  20. {
  21. case :
  22. query1.Query = "<Where><Eq><FieldRef Name='Title' /><Value Type='Text'>" + fvs[] + "</Value></Eq></Where>";
  23. item1 = list.GetItems(query1)[];
  24. province = getOptions(item1["ParentId"].ToString(), item1["Title"].ToString());
  25. break;
  26.  
  27. case :
  28. query1.Query = "<Where><Eq><FieldRef Name='Title' /><Value Type='Text'>" + fvs[] + "</Value></Eq></Where>";
  29. item1 = list.GetItems(query1)[];
  30. province = getOptions(item1["ParentId"].ToString(), item1["Title"].ToString());
  31. query2.Query = "<Where><Eq><FieldRef Name='Title' /><Value Type='Text'>" + fvs[] + "</Value></Eq></Where>";
  32. item2 = list.GetItems(query2)[];
  33. city = getOptions(item2["ParentId"].ToString(), item2["Title"].ToString());
  34. break;
  35.  
  36. case :
  37. query1.Query = "<Where><Eq><FieldRef Name='Title' /><Value Type='Text'>" + fvs[] + "</Value></Eq></Where>";
  38. item1 = list.GetItems(query1)[];
  39. province = getOptions(item1["ParentId"].ToString(), item1["Title"].ToString());
  40. query2.Query = "<Where><Eq><FieldRef Name='Title' /><Value Type='Text'>" + fvs[] + "</Value></Eq></Where>";
  41. item2 = list.GetItems(query2)[];
  42. city = getOptions(item2["ParentId"].ToString(), item2["Title"].ToString());
  43. query3.Query = "<Where><Eq><FieldRef Name='Title' /><Value Type='Text'>" + fvs[] + "</Value></Eq></Where>";
  44. item3 = list.GetItems(query3)[];
  45. district = getOptions(item3["ParentId"].ToString(), item3["Title"].ToString());
  46. break;
  47. }
  48. }
  49. }
  50. html = "<select id='" + myGuid + "province'>" + province + "</select><select id='" + myGuid + "city'>" + city + "</select><select id='" + myGuid + "district'>" + district + "</select>";
  51. return html;
  52. }

  5、 前台JavaScript的原理,根据当前选项的ID获取下一级控件并初始化,Id是下一级控件的Id后缀部分,vv也就是关联的ParentId。

  http://www.stats.gov.cn/tjsj/tjbz/xzqhdm/201608/t20160809_1386477.html

  1. function initSelect(Id, vv) {
  2. try {
  3. var hfId = $("#DefaultCustomFieldControlZone input[type='hidden']").val();
  4. if (vv == "11" || vv == "12" || vv == "31" || vv == "50") {
  5. $("#" + hfId + "district").hide();
  6. }
  7. else {
  8. $("#" + hfId + "district").show();
  9. }
  10. var mycontext = new SP.ClientContext.get_current();
  11. var mysite = mycontext.get_web();
  12. var query = new SP.CamlQuery();
  13. query.set_viewXml("<View><Query><Where><Eq><FieldRef Name='ParentId' /><Value Type='Text'>" + vv + "</Value></Eq></Where></Query></View>");
  14. var mylist = mysite.get_lists().getByTitle('CityDataSourse');
  15. myitem = mylist.getItems(query);
  16. mycontext.load(myitem, 'Include(Title,Id,CityId,Code)');
  17. mycontext.executeQueryAsync(Function.createDelegate(this, function () {
  18. try {
  19. $("#" + Id + " option").remove();
  20. var listsE = myitem.getEnumerator();
  21. while (listsE.moveNext()) {
  22. $("#" + Id).append("<option value='" + listsE.get_current().get_item("CityId") + "'>" + listsE.get_current().get_item("Title") + "</option>");
  23. }
  24. }
  25. catch (ex) { console.log(ex) }
  26. }), Function.createDelegate(this, function () { alert("failed") }));
  27. }
  28. catch (ex) { }
  29. }

  6、 初始化行政区,根据国家统计局的最新县及县以上行政区划代码,用jquery获取DOM元素,并且格式化成我需要的格式,放到列表实例里面使用,这样激活解决方案以后,就有数据源了。

  7、 初始化行政区的JavaScript脚本,水平有限,写的比较烂,大家参考即可。

  1. function GetResult()
  2. {
  3. var h1 = "<Row><Field Name='Title'>";
  4. var h2 = "</Field><Field Name='CityId'>";
  5. var h3 = "</Field><Field Name='ParentId1'>";
  6. var h4 = "</Field><Field Name='Code'>";
  7. var h5 = "</Field></Row>";
  8. var result = "";
  9. var num = 0;
  10.  
  11. $(".TRS_PreAppend p").each(function(){
  12. var spans = $(this).find("span");
  13. if($(spans[1]).text()!="县"&&$(spans[1]).text()!="市辖区")
  14. {
  15. if($(spans[0]).text().substring(0,2)=="11"||$(spans[0]).text().substring(0,2)=="12"||$(spans[0]).text().substring(0,2)=="31"||$(spans[0]).text().substring(0,2)=="50")
  16. {
  17. if($(spans[0]).text().substring(2,6)=="0000")
  18. {
  19. result += h1 + $(spans[1]).text() + h2 + $(spans[0]).text().substring(0,2) + h3 + "0" + h4 + $(spans[0]).text() + h5;
  20. num++;
  21. }
  22. else
  23. {
  24. result += h1 + $(spans[1]).text() + h2 + $(spans[0]).text().substring(0,4) + h3 + $(spans[0]).text().substring(0,2) + h4 + $(spans[0]).text() + h5;
  25. num++;
  26. }
  27. }
  28. else
  29. {
  30. if($(spans[0]).text().substring(2,6)=="0000")
  31. {
  32. result += h1 + $(spans[1]).text() + h2 + $(spans[0]).text().substring(0,2) + h3 + "0" + h4 + $(spans[0]).text() + h5;
  33. num++;
  34. }
  35. else
  36. {
  37. if($(spans[0]).text().substring(4,6)=="00")
  38. {
  39. result += h1 + $(spans[1]).text() + h2 + $(spans[0]).text().substring(0,4) + h3 + $(spans[0]).text().substring(0,2) + h4 + $(spans[0]).text() + h5;
  40. num++;
  41. }
  42. else
  43. {
  44. result += h1 + $(spans[1]).text() + h2 + $(spans[0]).text().substring(0,6) + h3 + $(spans[0]).text().substring(0,4) + h4 + $(spans[0]).text() + h5;
  45. num++;
  46. }
  47. }
  48. }
  49. }
  50. })
  51. $("#Result").text(result);
  52. }

  8、 添加的城市字段,类型为城市和区域,如下图。

  9、 城市字段的效果图,选中省会初始化市,然后初始化区。如果直辖市是初始化区,如下图:

总结

  整个代码的思路就是首先创建一个字段,然后字段的前台控件主要是展示,TextBox里面是值的修改和保存,用JavaScript和前台控件进行交互。为了防止一个列表加多个字段,控件的Id会重复,特意加了Guid作区分。同时,总结行政区的时候也很费劲,突发奇想用JavaScript去整理,然后花了不到两个小时,就整理好了,如果有其他格式的,改改就能用。善哉善哉。

  好吧,如果大家想说没有什么技术含量,确实是体力活居多,有需要的人可以参考参考。好了,就到这里,已经过了12点,睡吧。。

SharePoint 2016 自定义城市和区域字段的更多相关文章

  1. SharePoint 2016 入门视频教程

    之前一直有朋友让自己录一些SharePoint的入门视频,之前没有太多时间,一个巧合的机会收到CSDN学院的邮件,可以在CSDN上发布视频教程,自己就录了一些.说起录视频也是蛮辛苦的,每天下班吃完饭要 ...

  2. 每日学习心得:SharePoint 2013 自定义列表项添加Callout菜单项、文档关注、SharePoint服务端对象模型查询

    前言: 前一段时间一直都比较忙,没有什么时间进行总结,刚好节前项目上线,同时趁着放假可以好好的对之前遇到的一些问题进行总结.主要内容有使用SharePoint服务端对象模型进行查询.为SharePoi ...

  3. SharePoint 2016 配置工作流环境

    前言 SharePoint 2016 默认创建工作流的时候,工作流平台只包含2010版本,如果想要使用状态机工作流,需要单独安装workflow manager 1.0才可以,下面,我们为大家介绍一下 ...

  4. 在Visual Studio 2015 中添加SharePoint 2016 开发模板

    前言 SharePoint 2016已经发布很久了,然而,默认安装VS2015以后,却没有SharePoint 2016的开发模板.其实问题很简单,和VS2012开发SharePoint 2013一样 ...

  5. SharePoint 2016 配置向导报错 - The 'ListInternal' attribute is not allowed

    前言 配置SharePoint 2016的配置向导中,第三步创建配置数据库报错,然后百度.谷歌了一下,都没有解决,自己看日志搞定,也许会有人遇到类似问题,分享一下. 1.配置向导的错误截图,如下图: ...

  6. SharePoint 2013 自定义扩展菜单

    在对SharePoint进行开发或者功能扩展的时候,经常需要对一些默认的菜单进行扩展,以使我们开发的东西更适合SharePoint本身的样式.SharePoint的各种功能菜单,像网站设置.Ribbo ...

  7. SharePoint 2013 自定义扩展菜单(二)

    接博文<SharePoint 2013 自定义扩展菜单>,多加了几个例子,方便大家理解. 例七 列表设置菜单扩展(listedit.aspx) 扩展效果 XML描述 <CustomA ...

  8. SharePoint 2016 图文安装教程

    前言 SharePoint 2016如约而至,之前也装过预览版,但是这次是正式版,还是分享一个完整的安装过程给大家,希望能给有需要的人有所帮助. 1.首先安装操作系统,我这里是Windows Serv ...

  9. sharePoint 2016 弃用和删除的功能

    前言 sharepoint 2016版本正式发布,但是相比较2013版本,还是删除或者准备删除一些功能,我们需要了解一下哪些功能已经被删除掉或者在下一个版本中移除,因为这些可能影响我们现有系统是否能够 ...

随机推荐

  1. 关于PHP的工作流引擎

    关于PHP的工作流引擎,除了三大主流开源:PorcessMaker(排名第一,因其有拖放式图形定义界面),RadiCore(基于PETRI NET)和CuteFlow以外,另外还有一个不为人知的,但却 ...

  2. C#-利用ZPL语言完毕条形码的生成和打印

     近期由于公司项目的须要,研究了一项对我来说算是新的技术-条形码的生成和打印.由于之前没有接触过这方面的知识,所以刚開始还有点小迷茫和小兴奋,只是一步一步来,问题总会解决的.如今来总结一下做条形码 ...

  3. POJ 1201 &amp;&amp; HDU 1384 Intervals(差动制动系统)

    职务地址:POJ 1201   HDU 1384 依据题目意思.能够列出不等式例如以下: Sj-Si>=c; Si-S(i-1)>=0; S(i-1)-Si>=-1; 然后用最短路s ...

  4. 设计与实现的简单和经常使用的权限系统(五岁以下儿童):不维护节点的深度level,手工计算level,树形结构

     以这种方式.和第三的类似介绍.所不同的是.深度未在数据库中存储节点level,添加和更改时间,护.而是,在程序中,实时去计算的. 至于后面的,依照level升序排序,再迭代全部的节点构造树,与第三篇 ...

  5. HDU1024 Max Sum Plus Plus(DP)

    状态:d(i,j)它代表前j划分数i部并且包括第一j最佳结果时的数.g(i,j)表示前j划分数i最好的结果时,段,g(m,n)结果,需要. 本题数据较大.需採用滚动数组.注意:这题int类型就够用了, ...

  6. Extjs grid分页多选记忆功能

    很多同事在用extjs grid做分页的时候,往往会想用grid的多选功能来实现导出Excel之类的功能(也就是所谓的多选记忆功能),但在选选择下一页的时候 上一页选中的已经清除 这是因为做分页的时候 ...

  7. cocos2d的-X- luaproject的LUA脚本加密

    2014/1/26 更新 近期又发现了一个非常easy的方法,事实上coco2dx已经给我们提供设置loader的方法. 注意:有个局限性,在非android平台下调用pEngine->exec ...

  8. Run QTP script wiht host in HPQC

  9. Hdu 1016 Prime Ring Problem (素数环经典dfs)

    Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  10. MVC ValidationAttribute 服务器端自定义验证

    MVC ValidationAttribute 服务器端自定义验证 客户端验证 上文只说了客户端的自定义验证,这样对于用户的输入还是不够可靠,用户完全可以绕过我们定义的客户端验证.所以仅有客户端的验证 ...