一步一步封装自己的HtmlHelper组件BootstrapHelper(三)

网友投稿 188 2023-07-06


一步一步封装自己的HtmlHelper组件BootstrapHelper(三)

前言:之前的两篇封装了一些基础的表单组件,这篇继续来封装几个基于bootstrap的其他组件。和上篇不同的是,这篇的有几个组件需要某些js文件的支持。

BootstrapHelper系列文章目录

C#进阶系列——一步一步封装自己的HtmlHelper组件:BootstrapHelper

C#进阶系列——一步一步封装自己的HtmlHelper组件:BootstrapHelper(二)

C#进阶系列——一步一步封装自己的HtmlHelper组件:BootstrapHelper(三:附源码)

一、NumberBoxExtensions

NumberBoxExtensions是一个基于bootstrap风格的数字文本框,基于之前博主介绍的自增器数字组件spinner去做的封装,不了解spinner组件的园友可以看看//jb51.net/article/88490.htm里面介绍的第二个组件。

通过之前的介绍我们知道,自增组件spinner的初始化不需要写任何的js代码,直接通过配置html里面的data属性即可实现它的初始化,这样给我们的封装就带来了很大的方便,我们只需要将常用的初始化参数作为扩展方法的参数传进来,然后在后台变成相应的data属性返回到前端。

废话不多说,先将封装的源码摆上来。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

namespace BootstrapExtensions

{

public static class NumberBoxExtensions

{

///

/// 生成数字文本框

///

/// 扩展方法实例

/// id

/// 返回数字文本框

public static MvcHtmlString NumberTextBox(this BootstrapHelper html, string id)

{

return NumberTextBox(html, id, null, null, null, null, null);

}

///

/// 生成数字文本框

///

/// 扩展方法实例

/// id

/// 文本框的value值

/// 返回数字文本框

public static MvcHtmlString NumberTextBox(this BootstrapHelper html, string id, object value)

{

return NumberTextBox(html, id, value, null, null, null, null);

}

///

/// 生成数字文本框

///

/// 扩展方法实例

/// 文本框的value值

/// 自增长的最小值

/// 自增长的最大值

/// 返回数字文本框

public static MvcHtmlString NumberTextBox(this BootstrapHelper html, object value, int? min, int? max)

{

return NumberTextBox(html, null, value, min, max, null, null);

}

///

/// 生成数字文本框

///

/// 扩展方法实例

/// id

/// 文本框的value值

/// 自增长的最小值

/// 自增长的最大值

/// 返回数字文本框

public static MvcHtmlString NumberTextBox(this BootstrapHelper html, string id, object value, int? min, int? max)

{

return NumberTextBox(html, id, value, min, max, null, null);

}

///

/// 生成数字文本框

///

/// 扩展方法实例

/// id

/// 文本框的value值

/// 自增长的最小值

/// 自增长的最大值

/// 每次自增的数字

/// 返回数字文本框

public static MvcHtmlString NumberTextBox(this BootstrapHelper html, string id, object value, int? min, int? max, int? step)

{

return NumberTextBox(html, id, value, min, max, step, null);

}

///

/// 生成数字文本框

///

/// 扩展方法实例

/// id

/// 文本框的value值

/// 自增长的最小值

/// 自增长的最大值

/// 每次自增的数字

/// 自增规则

/// 返回数字文本框

public static MvcHtmlString NumberTextBox(this BootstrapHelper html, string id, object value, int? min, int? max, int? step, SpinningRule? rule)

{

TagBuilder tag = new TagBuilder("div");

tag.MergeAttribute("class", "input-group spinner");

tag.MergeAttribute("data-trigger", "spinner");

System.Text.StringBuilder sb = new System.Text.StringBuilder();

//sb.Append("");

sb.Append("

if (!string.IsNullOrEmpty(id))

{

sb.Append("id='").Append(id).Append("' ");

}

if (value != null)

{

sb.Append("value='").Append(value.ToString()).Append("' ");

}

else

{

sb.Append("value='1' ");

}

if (min != null)

{

sb.Append("data-min='").Append(min).Append("' ");

}

if (max != null)

{

sb.Append("data-max='").Append(max).Append("' ");

}

if (step != null)

{

sb.Append("data-step='").Append(step).Append("' ");

}

if (rule != null)

{

sb.Append("data-rule='").Append(rule.ToString()).Append("' ");

}

else

{

sb.Append("data-rule='quantity' ");

}

sb.Append("/>");

sb.Append("");

sb.Append("");

sb.Append("");

sb.Append("");

tag.InnerHtml = sb.ToString();

return MvcHtmlString.Create(tag.ToString());

}

}

public enum SpinningRule

{

defaults,

currency,

quantity,

percent,

month,

day,

hour,

minute,

second,

}

}

除去id、value,我们自增组件初始化需要的参数主要有min、max、step、rule等,分别对应组件的data-min、data-max、data-step、data-rule等参数。

使用相当简单,首先在对应的页面引用相关的js和css文件,然后在cshtml里面这样调用即可:

复制代码 代码如下:

@Bootstrap.NumberTextBox(null, "1", 1, 10, 2, null)

得到结果:

这样比我们每次都去copy一大段html代码要方便多了吧,你有没有一丝心动呢~~

二、DateTimeBoxExtensions

有了上面的数字组件作为基础,接下来就是封装时间组件了。博主同样打算使用data属性去做初始化,可是找了半天文档,datatimepicker里面没有自带data属性初始化的方式,没办法,只有博主自己去做data属性的初始化了。

1、初始方案

我们新建一个文件:bootstrap-datetimepicker-helper.js。里面的代码如下

$(function () {

var datetimedefault = {

locale: 'zh-CN', //中文化

};

$.each($(".date"), function (index, item) {

var data = $(item).data();

var param = $.extend({}, datetimedefault, data || {});

$(item).datetimepicker(param);

});

});

然后html代码这样写

貌似都没有问题,起初博主也以为没有任何问题。可是事与愿违!这里有一点博主没有考虑到,那就是jquery里面的data()方法取到的属性名会全部转小写,也就是说,我们html里面写的data-maxDate,可是通过data()方法得到的结果却变成了maxdate,如下图:

然后在初始化datetimepicker的时候就报了js异常。此法行不通。

2、改进方案

既然上面的方法行不通,那我们就要改进啊,data()方法是否存在什么参数可以让它不转小写的?找了一圈,没找到啥答案。最后没办法,博主打算自行改造,于是js代码变成了这样:

$(function () {

var datetimedefault = {

format: 'YYYY-MM-DD',//日期格式化,只显示日期

locale: 'zh-CN', //中文化

maxDate: '2017-01-01',//最大日期

minDate: '2010-01-01', //最小日期

viewMode: 'days',

defaultDate: false,

disabledDates: false,

enabledDates: false,

};

$.each($(".date"), function (index, item) {

var data = $(item).data();

$.each(data, function (key, value) {

for (i in datetimedefault) {

if (key == i.toLowerCase()) {

datetimedefault[i] = value;

break;

}

}

});

//var param = $.extend({}, datetimedefault, data || {});

$(item).datetimepicker(datetimedefault);

});

});

原理就是比较data()方法得到的结果和datetimedefault的属性名转小写后进行对比,如果相同,则将html里面的data属性覆盖默认的属性。调试了几遍,基本没发现什么问题。

代码写成这样,确实可以解决我们上面的问题,但是需要我们的datetimedefault变量里面包含足够多的默认参数,这样才能达到覆盖的目的,当然项目中一般修改的就那么几个参数,这里只需要加上一些我们经常需要变化的默认属性即可。

好了,有上面的作为理论基础,我们的DataTimeBox也就好封装了。直接上代码吧。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

namespace BootstrapExtensions

{

public static class DateTimeBoxExtensions

{

///

/// 生成日期控件

///

/// 扩展方法实例

/// 文本框标签的id

/// 返回呈现日期控件的html标签

public static MvcHtmlString DateTimeBox(this BootstrapHelper html, string id)

{

return DateTimeBox(html, id, null, null, null, null, null, null);

}

///

/// 生成日期控件

///

/// 扩展方法实例

/// 文本框标签的id

/// 文本框标签的默认值

/// 返回呈现日期控件的html标签

public static MvcHtmlString DateTimeBox(this BootstrapHelper html, string id, object value)

{

return DateTimeBox(html, id, value, null, null, null, null, null);

}

///

/// 生成日期控件

///

/// 扩展方法实例

/// 文本框标签的id

/// 文本框标签的默认值

/// 显示日期的格式

/// 日期的最小值

/// 日期的最大值

/// 返回呈现日期控件的html标签

public static MvcHtmlString DateTimeBox(this BootstrapHelper html, string id, object value, string format, string maxDate, string minDate)

{

return DateTimeBox(html, id, value, format, maxDate, minDate, null, null);

}

///

/// 生成日期控件

///

/// 扩展方法实例

/// 文本框标签的id

/// &http://lt;param name="value">文本框标签的默认值

/// 显示日期的格式

/// 日期的最小值

/// 日期的最大值

/// 日期控件的浏览模式

/// 是否显示清空按钮

/// 返回呈现日期控件的html标签

public static MvcHtmlString DateTimeBox(this BootstrapHelper html, string id, object value, string format, string maxDate, string minDate, string viewMode, bool? showClear)

{

TagBuilder tag = new TagBuilder("div");

tag.MergeAttribute("class", "input-group date");

if (!string.IsNullOrEmpty(format))

{

tag.MergeAttribute("data-format", format);

}

if (!string.IsNullOrEmpty(maxDate))

{

tag.MergeAttribute("data-maxDate", maxDate);

}

if (!string.IsNullOrEmpty(minDate))

{

tag.MergeAttribute("data-minDate", minDate);

}

if (!string.IsNullOrEmpty(viewMode))

{

tag.MergeAttribute("data-viewMode", viewMode);

}

if (showClear!=null)

{

tag.MergeAttribute("data-showClear", showClear.ToString());

}

System.Text.StringBuilder sb = new System.Text.StringBuilder();

sb.Append("

if(!string.IsNullOrEmpty(id))

{

sb.Append("id='").Append(id).Append("' ");

}

if (value != null)

{

sb.Append("value='").Append(value.ToString()).Append("' ");

}

sb.Append("/>").Append("")

.Append("")

.Append("");

tag.InnerHtml = sb.ToString();

return MvcHtmlString.Create(tag.ToString());

}

}

}

然后我们的cshtml页面只需要引用我们的js和css

然后直接使用

@Bootstrap.DateTimeBox("starttime", null, null, null, null, null, null)

@Bootstrap.DateTimeBox("endtime", null, null, null, null, null, null)

得到结果

三、TextareExtensions

关于textarea文本域的封装相对来说是比较简单的,因为本身它的结构和TextBox就差不多,我们直接给出封装的源码吧。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

namespace BootstrapExtensions

{

public static class TextareExtensions

{

///

/// textarea文本域

///

/// 扩展方法实例

/// id

/// html标签

public static MvcHtmlString TextAreaBox(this BootstrapHelper html, string id)

{

return TextAreaBox(html, id, null, null, null, null);

}

///

/// textarea文本域

///

/// 扩展方法实例

/// id

/// value

/// 样式

/// html标签

public static MvcHtmlString TextAreaBox(this BootstrapHelper html, string id, object value, string cssClass)

{

return TextAreaBox(html, id, value, cssClass, null, null);

}

///

/// textarea文本域

///

/// 扩展方法实例

/// id

/// value

/// 样式

/// 行数

/// html标签

public static MvcHtmlString TextAreaBox(this BootstrapHelper html, string id, object value, string cssClass, int? rows)

{

return TextAreaBox(html, id, value, cssClass, rows, null);

}

///

/// textarea文本域

///

/// 扩展方法实例

/// id

/// value

/// 样式

/// 行数

/// 列数

/// html标签

public static MvcHtmlString TextAreaBox(this BootstrapHelper html, string id, object value, string cssClass, int? rows, int? cols)

{

TagBuilder tag = new TagBuilder("textarea");

tag.AddCssClass("form-control");

if (!string.IsNullOrEmpty(id))

{

tag.MergeAttribute("id", id);

}

if (value != null)

{

tag.MergeAttribute("value", value.ToString());

}

if (!string.IsNullOrEmpty(cssClass))

{

tag.AddCssClass(cssClass);

}

if (rows != null)

{

tag.MergeAttribute("rows", rows.ToString());

}

if (cols != null)

{

tag.MergeAttribute("cols", cols.ToString());

}

return MvcHtmlString.Create(tag.ToString());

}

}

}

只支持几个最简单的参数rows和cols,如果你的项目有一些特殊的需求,比如需要初始化成富文本编辑框,你也可以自己去改进。

使用方法

@Bootstrap.TextAreaBox("id", "", "", 3, 5)

这里有一个问题要提一下,就是我们直接这样写,得到的结果却是:

貌似我们的cols属性没有起作用,原来,只要你的标签加了class='form-control'样式,那它就会在满撑整个div,解决的方法也很简单,比如我们可以在div上面做些处理:

复制代码 代码如下:

既然cols属性没有起作用,其实参数里面的cols可以考虑去掉。

四、SelectExtensions

又到了纠结的select下拉框。为什么说它纠结呢,因为封装它的时候要考虑很多问题,比如:

后来转念一想,封装的目的是为了什么?不就是为了使用起来更加方便吗,如果封得太死,使用起来能够方便吗?后来所幸直接封装成最简单的select算了。博主打算这样做:

如果是静态的option,直接写原生的select标签;如果是动态的option,则传递对应的url到后台,取到数据后生成option。封装的代码如下:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

namespace BootstrapExtensions

{

public static class SelectExtensions

{

///

/// 返回select标签

///

/// 扩展方法实例

/// 标签id

/// select标签

public static MvcHtmlString SelectBox(this BootstrapHelper html, string id)

{

return SelectBox(html, id, null, null, null, null, null, null);

}

///

/// 返回select标签

///

/// 扩展方法实例

/// 标签id

/// 标签选中值

/// select标签

public static MvcHtmlString SelectBox(this BootstrapHelper html, string id, object value)

{

return SelectBox(html, id, value, null, null, null, null, null);

}

///

/// 返回select标签

///

/// 扩展方法实例

/// 标签id

/// 标签选中值

/// 标签样式

/// select标签

public static MvcHtmlString SelectBox(this BootstrapHelper html, string id, object value, string cssClass)

{

return SelectBox(html, id, value, cssClass, null, null, null, null);

}

///

/// 返回select标签

///

/// 扩展方法实例

/// 标签id

/// 标签选中值

/// 标签样式

/// 请求数据的url

/// 显示字段

/// 值字段

/// select标签

public static MvcHtmlString SelectBox(this BootstrapHelper html, string id, object value, string cssClass, string url, string textField, string valueField)

{

return SelectBox(html, id, value, cssClass, url, null, textField, valueField);

}

///

/// 返回select标签

///

/// 扩展方法实例

/// 标签id

/// 标签选中值

/// 标签样式

/// 请求数据的url

/// 请求的参数

/// 显示字段

/// 值字段

/// 是否多选

/// select标签

public static MvcHtmlString SelectBox(this BootstrapHelper html, string id, object value, string cssClass, string url, string param, string textField, string valueField, bool multiple = false)

{

TagBuilder tag = new TagBuilder("select");

tag.AddCssClass("form-control");

if (!string.IsNullOrEmpty(id))

{

tag.MergeAttribute("id", id);

}

if (value != null)

{

tag.MergeAttribute("value", value.ToString());

}

if (!string.IsNullOrEmpty(cssClass))

{

tag.AddCssClass(cssClass);

}

if (!string.IsNullOrEmpty(url))

{

tag.MergeAttribute("data-url", url);

}

if (!string.IsNullOrEmpty(param))

{

tag.MergeAttribute("data-param", param);

}

if (!string.IsNullOrEmpty(valueField))

{

tag.MergeAttribute("data-value-field", valueField);

}

if (!string.IsNullOrEmpty(textField))

{

tag.MergeAttribute("data-text-field", textField);

}

if (multiple)

{

tag.MergeAttribute("multiple", "multiple");

}

return MvcHtmlString.Create(tag.ToString());

}

}

}

然后前端使用js去初始化,需要有一个js文件utility.combobox.js:

(function ($) {

//1.定义jquery的扩展方法combobox

$.fn.combobox = function (options, param) {

if (typeof options == 'string') {

return $.fn.combobox.methods[options](this, param);

}

//2.将调用时候传过来的参数和default参数合并

options = $.extend({}, $.fn.combobox.defaults, options || {});

//3.添加默认值

var target = $(this);

target.attr('valuefield', options.valueField);

target.attr('textfield', options.textField);

target.empty();

var option = $('');

option.attr('value', '');

option.text(options.placeholder);

target.append(option);

//4.判断用户传过来的参数列表里面是否包含数据data数据集,如果包含,不用发ajax从后台取,否则否送ajax从后台取数据

if (options.data) {

init(target, options.data);

}

else {

//var param = {};

options.onBeforeLoad.call(target, options.param);

if (!options.url) return;

if (typeof options.param == "string") {

options.param = JSON.parse(options.param);

}

$.getJSON(options.url, options.param, function (data) {

init(target, data);

});

}

function init(target, data) {

$.each(data, function (i, item) {

var option = $('');

option.attr('value', item[options.valueField]);

option.text(item[options.textField]);

target.append(option);

});

options.onLoadSuccess.call(target);

}

target.unbind("change");

target.on("change", function (e) {

if (options.onChange)

return options.onChange(target.val());

});

}

//5.如果传过来的是字符串,代表调用方法。

$.fn.combobox.methods = {

getValue: function (jq) {

return jq.val();

},

setValue: function (jq, param) {

jq.val(param);

},

load: function (jq, url) {

$.getJSON(url, function (data) {

jq.empty();

var option = $('');

option.attr('value', '');

option.text('请选择');

jq.append(option);

$.each(data, function (i, item) {

var option = $('');

option.attr('value', item[jq.attr('valuefield')]);

option.text(item[jq.attr('textfield')]);

jq.append(option);

});

});

}

};

//6.默认参数列表

$.fn.combobox.defaults = {

url: null,

param: null,

data: null,

valueField: 'value',

textField: 'text',

placeholder: '请选择',

onBeforeLoad: function (param) { },

onLoadSuccess: function () { },

onChange: function (value) { }

};

//这一段是新加的,在页面初始化完成之后调用初始化方法

$(document).ready(function () {

$('select').each(function () {

var $combobox = $(this);

$.fn.combobox.call($combobox, $combobox.data());

})

});

})(jQuery);

这个js文件来源于博主之前的一篇文章//jb51.net/article/92595.htm

然后前端调用

@Bootstrap.SelectBox("sel", null, null, "/Home/GetDept", null, "Name", "Id")

五、总结

至此,我们BootstrapHelper第一个版本的封装基本算是完成了,主要封装的组件有如下几个:

当然还有大家最喜欢源码分享了。源码地址

如果你觉得本文能够帮到你,请帮忙推荐吧。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Angular Module声明和获取重载实例代码
下一篇:一步一步封装自己的HtmlHelper组件BootstrapHelper(二)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~