MVC地区多级联动扩展实现(非递归形式)
MVC前台界面调用方式如下:
@Html.AreaDropDownList("areaCode", areaCode, , string.Empty)
参数说明:
第一个参数控件的名称;
第二个参数选中的地区编码;
第三个参数地区层级;
第四个参数根级地区;
地区数据库表设计如下:

下拉列表的扩展:
#region 下拉列表
/// <summary>
/// 联动下拉列表
/// </summary>
/// <param name="htmlHelper">被扩展的HtmlHelper实例</param>
/// <param name="expression">获取数据集合</param>
/// <param name="level">显示多少级</param>
/// <param name="defaultValue">TProperty类型的默认值(如string默认值为"")</param>
/// <param name="rootItems">获取根级列表数据</param>
/// <param name="getParentID">获取列表项的ParentID方法</param>
/// <param name="getChildItems">获取子级列表数据集合方法</param>
/// <param name="getChildSelectDataUrl">获取子级列表数据的远程地址</param>
/// <returns>html代码</returns>
public static MvcHtmlString LinkageDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, TProperty defaultValue, int level, Dictionary<TProperty, string> rootItems,Func<TProperty, TProperty> getParentID, Func<TProperty, Dictionary<TProperty, string>> getChildItems,string getChildSelectDataUrl,string optionLabel = "请选择")
{
ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
return LinkageDropDownList(htmlHelper, ExpressionHelper.GetExpressionText(expression), (TProperty)metadata.Model, defaultValue, level, rootItems, getParentID,getChildItems,getChildSelectDataUrl,optionLabel);
}
/// <summary>
/// 联动下拉列表
/// </summary>
/// <param name="htmlHelper">被扩展的HtmlHelper实例</param>
/// <param name="level">显示多少级</param>
/// <param name="defaultValue">TProperty类型的默认值(如string默认值为"")</param>
/// <param name="name">下拉列表表单项名</param>
/// <param name="selectedValue">当前选中值</param>
/// <param name="rootItems">获取根级列表数据</param>
/// <param name="getParentId">获取列表项的ParentID方法</param>
/// <param name="getChildItems">获取子级列表数据集合方法</param>
/// <param name="getChildSelectDataUrl">获取子级列表数据的远程地址</param>
/// <returns>html代码</returns>
public static MvcHtmlString LinkageDropDownList<TProperty>(this HtmlHelper htmlHelper, string name, TProperty selectedValue,TProperty defaultValue, int level, Dictionary<TProperty, string> rootItems, Func<TProperty, TProperty> getParentId, Func<TProperty, Dictionary<TProperty, string>> getChildItems, string getChildSelectDataUrl, string optionLabel = "请选择")
{
string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
//select data init
Stack<Dictionary<TProperty, string>> stack = new Stack<Dictionary<TProperty, string>>();
//如果有选中的值,则查找其所在列表前面的所有列表
IList<TProperty> selectedValues = new List<TProperty>();
if (selectedValue != null && !selectedValue.Equals(defaultValue))
{
TProperty itemId = selectedValue;
TProperty parentItemId = getParentId(itemId);
while (!itemId.Equals(defaultValue) && !parentItemId.Equals(defaultValue))
{
stack.Push(getChildItems(parentItemId));
selectedValues.Add(itemId);
itemId = parentItemId;
parentItemId = getParentId(itemId);
}
if (rootItems.Count() > )
{
TProperty rootId = getParentId(rootItems.First().Key);
if (!itemId.Equals(rootId))
{
stack.Push(rootItems);
selectedValues.Add(itemId);
}
}
}
else
{
TProperty rootItemID = rootItems.Select(n => n.Key).FirstOrDefault();
stack.Push(rootItems);
}
//生成标签
TagBuilder containerBuilder = new TagBuilder("span");
containerBuilder.MergeAttribute("plugin", "linkageDropDownList");
var data = new Dictionary<string, object>();
data.TryAdd("GetChildSelectDataUrl", getChildSelectDataUrl);
data.TryAdd("ControlName", name);
data.TryAdd("Level", level);
data.TryAdd("OptionLabel", optionLabel);
data.TryAdd("DefaultValue", defaultValue.ToString());
containerBuilder.MergeAttribute("data", Json.Encode(data));
int currentIndex = ;
while (stack.Count > )
{
Dictionary<TProperty, string> dictionary = stack.Pop();
IEnumerable<SelectListItem> selectList = dictionary.Select(n => new SelectListItem() { Selected = selectedValues.Contains(n.Key), Text = n.Value, Value = n.Key.ToString() });
containerBuilder.InnerHtml += "\r\n" + htmlHelper.DropDownList(string.Format("{0}_{1}", name, currentIndex), selectList,
optionLabel, new { @class = "tn-dropdownlist" });
currentIndex++;
}
containerBuilder.InnerHtml += "\r\n" + htmlHelper.Hidden(name);
return MvcHtmlString.Create(containerBuilder.ToString());
}
#endregion
对外的调用的实现:
/// <summary>
/// 地区下拉列表
/// </summary>
/// <param name="htmlHelper">被扩展的htmlHelper实例</param>
/// <param name="expression">选择实体中类别属性的lamda表达式</param>
/// <param name="areaLevel">地区层级(默认取站点地区配置)</param>
/// <param name="rootAreaCode">根级地区(默认取站点地区配置)</param>
public static MvcHtmlString AreaDropDownListFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, string>> expression, int? areaLevel = null, string rootAreaCode = null)
{
string getChildAreasUrl = "/Channel/GetChildAreas";//获取子地区的远程地址,(AreaCode,name)的JSON数据
if (areaLevel == null)
{
areaLevel = ;//区域设置级别,可以作为配置文件获取
}
return htmlHelper.LinkageDropDownListFor<TModel, string>(expression, string.Empty, areaLevel.Value, 获取根级区域的(AreaCode,name)键值对,获取当前选中区域的父区域, 获取当前的子区域, getChildAreasUrl);
} /// <summary>
/// 地区下拉列表
/// </summary>
/// <param name="htmlHelper">被扩展的htmlHelper实例</param>
/// <param name="name">控件name属性</param>
/// <param name="name">选中的地区编码</param>
/// <param name="areaLevel">地区层级(默认取站点配置)</param>
/// <param name="rootAreaCode">根级地区(默认取站点地区配置)</param>
public static MvcHtmlString AreaDropDownList(this HtmlHelper htmlHelper, string name, string value, int? areaLevel = null, string rootAreaCode = null)
{
string getChildAreasUrl = "/Channel/GetChildAreas";//获取子地区的远程地址,(AreaCode,name)的JSON数据
if (areaLevel == null)
{
areaLevel = ;//区域设置级别,可以作为配置文件获取
}
return htmlHelper.LinkageDropDownList<string>(name, value, string.Empty, areaLevel.Value, 获取根级区域的(AreaCode,name)键值对, 获取当前选中区域的父区域, 获取选中地区当前的子区域, getChildAreasUrl);
}
MVC地区多级联动扩展实现(非递归形式)的更多相关文章
- poj 3323 Matrix Power Series (矩阵乘法 非递归形式)
为了搞自动机+矩阵的题目,特来学习矩阵快速幂..........非递归形式的求Sum(A+A^2+...+A^k)不是很懂,继续弄懂................不过代码简洁明了很多,亮神很给力 # ...
- 二叉树前中后/层次遍历的递归与非递归形式(c++)
/* 二叉树前中后/层次遍历的递归与非递归形式 */ //*************** void preOrder1(BinaryTreeNode* pRoot) { if(pRoot==NULL) ...
- MVC实现多级联动
前言 多级联动(省级联动)的效果,网上现成的都有很多,各种JS实现,Jquery实现等等,今天我们要讲的是在MVC里面,如何更方便.更轻量的实现省级联动呢? 实现效果如下: 具体实现 如图所示,在HT ...
- 深度优先搜索(DFS)递归形式改为非递归形式
DFS将递归改为非递归这个方法的需求来自于一道三维积木组合的题目,还在苦苦调试中,暂且不提. 普通的认识对于递归向非递归的转化无非是使用栈,但是结合到深度搜索如何将栈很好利用,如何很好保存现场,都不是 ...
- 二叉树总结—建树和4种遍历方式(递归&&非递归)
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u013497151/article/details/27967155 今天总结一下二叉树.要考离散了 ...
- 扩展欧几里德算法(递归及非递归实现c++版)
今天终于弄懂了扩展欧几里德算法,有了自己的理解,觉得很神奇,就想着写一篇博客. 在介绍扩展欧几里德算法之前,我们先来回顾一下欧几里德算法. 欧几里德算法(辗转相除法): 辗转相除法求最大公约数,高中就 ...
- .net MVC 下拉多级联动及编辑
多级联动实现,附源码.当前,部分代码是参与博客园其它网友. 新增,前台代码: <script src="~/Scripts/jquery-1.10.2.js">< ...
- asp.net MVC 下拉多级联动及编辑
多级联动实现,附源码.当前,部分代码是参与博客园其它网友. 新增,前台代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 2 ...
- 八皇后非递归(仅使用一个数组且可扩展为N皇后问题)
</pre><pre name="code" class="cpp">/* Theme:八皇后(非递归) Coder:秒针的声音 Tim ...
随机推荐
- Django day13 form组件, 渲染错误信息, 全局钩子
一:from组件 二:渲染错误信息 三:全局钩子
- JavaScript中的+= 是什么?
+=表示相加并赋值,“i+=5”与“i=i+5”是等效的. 类似的运算符还有-=,*=,/=. i-=5等价于i=i-5; i*=5等价于i=i*5: i/=5等价于i=i/5.
- Cordova 开发环境搭建及创建第一个app
整理记录使用cordova创建app应用程序并将其部署至Android系统移动设备上操作过程,具体如下: 一.前期安装环境 1. 安装JDK(java开发工具包) 2. 安装gradle 3. 安装A ...
- XOJ测试 2016.5.22
哈哈 我是最先使用XOJ的人之一 膜拜zrt ing 首先是XOJ神奇的界面 还没有建设完的OJ是这个样子的 一共有5道题 这次小测有3道题 是T2T3T4 首先是骑士精神 (BZOJ1085) 上来 ...
- .net MVC成长记录(二)
今天上班的任务完成了,接下来写一下博客,巩固一下,再学习一些新知识. 闲话不多说,我们言归正传.昨天讲到了如何mvc框架在微软下,已经变成了一个非常灵活非常‘干净’的开发框架了, 同时也讲述了如何创建 ...
- ES6 arrow function
语法: () => { … } // 零个参数用 () 表示: x => { … } // 一个参数可以省略 (): (x, y) => { … } // 多参数不能省略 (): 当 ...
- bootstrap 图片 图标
一.图片 1.响应式图片:<img src=" " class="responsive"> 2.圆角图片:<img src=" ...
- Android高亮TextView
HighlightTextView Android文本高亮控件,基于View实现. 特点 文本高亮 单词自动换行 高亮词组保持在同一行显示 截图 Demo Java: public class Mai ...
- 【Oracle】解决oracle sqlplus 中上下左右backspace不能用
一. 解决输入 BACKSPACE 键变成 ^h 的问题 #su - oracle $stty erase ^h. 要永久生效,可以加入到用户环境配置文件.bash_profile中(vi .ba ...
- DE2之7-segment displays
以前课题用的是友晶的DE2-70,现在重拾FPGA,选了一款性价比高的DE2.恰逢闲来无事,于是尝试将各个Verilog模块翻译成VHDL,半算回顾以前的知识,半算练习VHDL. Verilog 01 ...