Preface: The previous two articles encapsulate some basic form components, and this article continues to encapsulate several other components based on bootstrap. Unlike the previous article, there are several components in this article that require support for certain js files.
BootstrapHelper series article catalog
C# Advanced Series - Encapsulate its own HtmlHelper component step by step: BootstrapHelper
C# Advanced Series - Encapsulate its own HtmlHelper component step by step: BootstrapHelper (II)
C# Advanced Series - Encapsulate its own HtmlHelper component step by step: BootstrapHelper (3: with source code)
1. NumberBoxExtensions
NumberBoxExtensions is a digital text box based on bootstrap style. It is encapsulated by spinner, a self-increaser digital component introduced by the blogger. Those who do not understand the spinner component can check out the second component introduced in http://www.VeVB.COM/article/88490.htm.
Through the previous introduction, we know that the initialization of the self-increasing component spinner does not require writing any JS code. It can be initialized directly by configuring the data attribute in the html. This brings great convenience to our encapsulation. We only need to pass the commonly used initialization parameters as parameters of the extension method, and then turn it into the corresponding data attribute in the background and return it to the front end.
Without further ado, put the encapsulated source code first.
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;namespace BootstrapExtensions{ public static class NumberBoxExtensions { /// <summary> /// Generate a number text box/// </summary> /// <param name="html">Extension method instance</param> /// <param name="id">id</param> /// <returns>Return the number text box</returns> public static MvcHtmlString NumberTextBox(this BootstrapHelper html, string id) { return NumberTextBox(html, id, null, null, null, null); } /// <summary> /// Generate a numeric text box/// </summary> /// <param name="html">Extension method example</param> /// <param name="id">id</param> /// <param name="value">text box value</param> /// <returns>Return the numeric text box</returns> public static MvcHtmlString NumberTextBox(this BootstrapHelper html, string id, object value) { return NumberTextBox(html, id, value, null, null, null); } /// <summary> /// Generate a numeric text box/// </summary> /// <param name="html">Extension method instance</param> /// <param name="value">The value of the text box</param> /// <param name="min">The minimum value of self-growth</param> /// <param name="max">Maximum value</param> /// <returns>Return the numeric text box</returns> public static MvcHtmlString NumberTextBox(this BootstrapHelper html, object value, int? min, int? max) { return NumberTextBox(html, null, value, min, max, null, null); } /// <summary> /// Generate a numeric text box/// </summary> /// <param name="html">Extension method instance</param> /// <param name="id">id</param> /// <param name="value">text box value</param> /// <param name="min">min self-growth</param> /// <param name="max">maximum self-growth</param> /// <returns>Return the number text box</returns> public static MvcHtmlString NumberTextBox(this BootstrapHelper html, string id, object value, int? min, int? max) { return NumberTextBox(html, id, value, min, max, null, null); } /// <summary> /// Generate a number text box/// </summary> /// <param name="html">Extension method instance</param> /// <param name="id">id</param> /// <param name="value">The value of the text box</param> //// <param name="min">min self-growth</param> /// <param name="max">maximum self-growth</param> /// <param name="step">number self-growth</param> /// <returns>Return the number text box</returns> 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); } /// <summary> /// Generate number text box/// </summary> /// <param name="html">Extension method example</param> /// <param name="id">id</param> /// <param name="value">text box value</param> /// <param name="min">min self-growth</param> /// <param name="max">maximum self-growth</param> /// <param name="step">number self-growth</param> /// <param name="rule">self-growth rule</param> /// <returns>Return the number text box</returns> 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("<input type='text' class='form-control text-center' value='1' data-min='-10' data-max='10' data-step='2' data-rule='quantity'>"); sb.Append("<input type='text' class='form-control text-center' "); 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("<span class='input-group-addon'>"); sb.Append("<a href='javascript;;' class='spin-up' data-spin='up'><i class='fa fa-caret-up'></i></a>"); sb.Append("<a href='javascript:;' class='spin-down' data-spin='down'><i class='fa fa-caret-down'></i></a>"); sb.Append("</span>"); tag.InnerHtml = sb.ToString(); return MvcHtmlString.Create(tag.ToString()); } } public enum SpinningRule { defaults, currency, quantity, percent, month, day, hour, minute, second, }}In addition to id and value, the parameters required for initialization of the component are mainly min, max, step, rule, etc., corresponding to the component's data-min, data-max, data-step, data-rule and other parameters.
Use is quite simple. First, refer to the relevant js and css files on the corresponding page, and then call it like this in cshtml:
Copy the code as follows: @Bootstrap.NumberTextBox(null, "1", 1, 10, 2, null)
Get the result:
This is much more convenient than copying a large piece of html code every time. Are you feeling a little moved?
2. DateTimeBoxExtensions
With the above digital components as the basis, the next step is to encapsulate the time components. The blogger also plans to use the data attribute to initialize it, but after searching for a long time, there is no way to initialize the data attribute in the datatimepicker. There is no way, so the blogger will only initialize the data attribute by himself.
1. Initial plan
Let's create a new file: bootstrap-datetimepicker-helper.js. The code inside is as follows
$(function () { var datetimedefault = { locale: 'zh-CN', //Chinese culture}; $.each($(".date"), function (index, item) { var data = $(item).data(); var param = $.extend({}, datetimedefault, data || {}); $(item).datetimepicker(param); });});Then write the html code like this
<div class='input-group date' data-format="YYYY-MM-DD" data-maxDate="2017-01-10" data-minDate="2010-01-10"> <input type='text' /> <span> <span></span> </span></div>
It seems that there is no problem, and at first the blogger thought there was no problem. But things went against my wishes! There is one thing that the blogger has not considered, that is, the attribute names obtained by the data() method in Jquery will be converted to lowercase. That is to say, the data-maxDate written in html, but the result obtained through the data() method becomes maxdate, as shown in the figure below:
Then, when the datetimepicker is initialized, a js exception is reported. This method does not work.
2. Improvement plan
Since the above method does not work, we need to improve it. Are there any parameters in the data() method that can prevent it from being lowercase? After searching around, I couldn't find any answers. In the end, there was no way, the blogger planned to transform it on his own, so the js code became like this:
$(function () { var datetimedefault = { format: 'YYYY-MM-DD',//Date formatting, only the date locale: 'zh-CN', //Chinese culture maxDate: '2017-01-01',//Maximum date minDate: '2010-01-01', //Minimum date 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); });});The principle is to compare the results obtained by the data() method with the attribute name of the datetimedefault after the lowercase conversion. If the same is true, the data attribute in the html will be overwritten. After debugging several times, I basically found no problems.
Writing the code like this can indeed solve our above problems, but our datetimedefault variable needs to contain enough default parameters to achieve the purpose of coverage. Of course, there are only a few parameters that are generally modified in the project, and only some default attributes that we often need to change are added here.
Okay, with the above as the theoretical basis, our DataTimeBox will be easily encapsulated. Just upload the code.
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;namespace BootstrapExtensions{ public static class DateTimeBoxExtensions { /// <summary> /// Generate date control/// </summary> /// <param name="html">Extension method instance</param> /// <param name="id">id of text box tag</param> /// <returns>Return the html tag that renders the date control</returns> public static MvcHtmlString DateTimeBox(this BootstrapHelper html, string id) { return DateTimeBox(html, id, null, null, null, null, null); } /// <summary> /// Generate date control/// </summary> /// <param name="html">Extension method instance</param> /// <param name="id">id of text box tag</param> /// <param name="value">Default value of text box tag</param> /// <returns>Return the html tag that renders the date control</returns> public static MvcHtmlString DateTimeBox(this BootstrapHelper html, string id, object value) { return DateTimeBox(html, id, value, null, null, null, null); } /// <summary> /// Generate date control/// </summary> /// <param name="html">Extension method instance</param> /// <param name="id">id of text box label</param> /// <param name="value">Default value of text box label</param> /// <param name="format">From format for display date</param> /// <param name="format"> <param name="maxDate">Minimum value of date</param> /// <param name="minDate">Maximum value of date</param> /// <returns>Return the html tag that renders the date control</returns> 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); } /// <summary> /// Generate date control/// </summary> /// <param name="html">Extension method example</param> /// <param name="id">id of text box label</param> /// <param name="value">Default value of text box label</param> /// <param name="format">Show date format</param> /// <param name="maxDate">Minimum value of date</param> /// <param name="minDate">Maximum value of date</param> /// <param name="viewMode">Browse mode of date control</param> /// <param name="showClear">Does the clear button be displayed</param> /// <returns>Returns the html tag that renders the date control</returns> 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("<input type='text' class='form-control'"); if(!string.IsNullOrEmpty(id)) { sb.Append("id='").Append(id).Append("' "); } if (value != null) { sb.Append("value='").Append(value.ToString()).Append("' "); } sb.Append("/>").Append("<span class='input-group-addon'>") .Append("<span class='glyphicon glyphicon-calendar'></span>") .Append("</span>"); tag.InnerHtml = sb.ToString(); return MvcHtmlString.Create(tag.ToString()); } }}Then our cshtml page only needs to reference our js and css
<link href="~/Content/bootstrap-datetimepicker/css/bootstrap-datetimepicker.css" rel="stylesheet" /><script src="~/Content/bootstrap-datetimepicker/js/moment-with-locales.js"></script><script src="~/Content/bootstrap-datetimepicker/js/bootstrap-datetimepicker-helper.js"></script>
Then use it directly
<div> @Bootstrap.DateTimeBox("starttime", null, null, null, null, null) </div> <div> @Bootstrap.DateTimeBox("endtime", null, null, null, null, null, null) </div>Get results
3. TextareExtensions
The encapsulation of textarea text field is relatively simple, because its structure is similar to that of TextBox. Let's directly give the encapsulation source code.
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;namespace BootstrapExtensions{ public static class TextareExtensions { /// <summary> /// textarea text field/// </summary> /// <param name="html">Extension method instance</param> /// <param name="id">id</param> /// <returns>html tag</returns> public static MvcHtmlString TextAreaBox(this BootstrapHelper html, string id) { return TextAreaBox(html, id, null, null, null); } /// <summary> /// textarea text field/// </summary> /// <param name="html">Extension method instance</param> /// <param name="id">id</param> /// <param name="value">value</param> /// <param name="cssClass">Style</param> /// <returns>html tag</returns> public static MvcHtmlString TextAreaBox(this BootstrapHelper html, string id, object value, string cssClass) { return TextAreaBox(html, id, value, cssClass, null, null); } /// <summary> /// textarea text field/// </summary> /// <param name="html">Extension method instance</param> /// <param name="id">id</param> /// <param name="value">value</param> /// <param name="cssClass">Style</param> /// <param name="rows">Number of rows</param> /// <returns>html tag</returns> public static MvcHtmlString TextAreaBox(this BootstrapHelper html, string id, object value, string cssClass, int? rows) { return TextAreaBox(html, id, value, cssClass, rows, null); } /// <summary> /// textarea text field/// </summary> /// <param name="html">Extension method instance</param> /// <param name="id">id</param> /// <param name="value">value</param> /// <param name="cssClass">Style</param> /// <param name="rows">Number of rows</param> /// <param name="cols">Number of columns</param> /// <returns>html tag</returns> 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()); } }}Only a few simplest parameters rows and cols are supported. If your project has some special needs, such as initializing into a rich text editing box, you can also improve it yourself.
How to use
<div> @Bootstrap.TextAreaBox("id", "", "", 3, 5) </div>There is a question to mention here, that is, we write it directly, but the result is:
It seems that our cols attribute does not work. It turns out that as long as your tag is added with class='form-control' style, it will fill the entire div, and the solution is also very simple. For example, we can do some processing on the div:
Copy the code as follows: <div> @Bootstrap.TextAreaBox("", "", "", 3, 5) </div>
Since the cols attribute does not work, the cols in the parameters can be considered to be removed.
4. SelectExtensions
It's time to the tangled select drop-down box again. Why do you say it is tangled? Because there are many issues to consider when encapsulating it, such as:
How to handle static option values? How to pass them to the background? Is it encapsulated the original select or encapsulated into select methods and events based on certain components (such as select2)?
Later, I thought about it, what is the purpose of encapsulation? Isn’t it just to be more convenient to use? If it is sealed too hard, will it be convenient to use? Fortunately, it was directly encapsulated into the simplest select. The blogger intends to do this:
If it is a static option, directly write the native select tag; if it is a dynamic option, pass the corresponding url to the background, and generate the option after obtaining the data. The encapsulated code is as follows:
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;namespace BootstrapExtensions{ public static class SelectExtensions { /// <summary> /// Return select tag/// </summary> /// <param name="html">Extension method instance</param> /// <param name="id">Tag id</param> /// <returns>select tag</returns> public static MvcHtmlString SelectBox(this BootstrapHelper html, string id) { return SelectBox(html, id, null, null, null, null, null); } /// <summary> /// Return select tag/// </summary> /// <param name="html">Extension method instance</param> /// <param name="id">Tag id</param> /// <param name="value">Tag selected value</param> /// <returns>select tag</returns> public static MvcHtmlString SelectBox(this BootstrapHelper html, string id, object value) { return SelectBox(html, id, value, null, null, null, null); } /// <summary> /// Return select tag/// </summary> /// <param name="html">Extension method instance</param> /// <param name="id">Tag id</param> /// <param name="value">Tag selected value</param> /// <param name="cssClass">Tag style</param> /// <returns>select tag</returns> public static MvcHtmlString SelectBox(this BootstrapHelper html, string id, object value, string cssClass) { return SelectBox(html, id, value, cssClass, null, null, null); } /// <summary> /// Return select tag/// </summary> /// <param name="html">Extension method instance</param> /// <param name="id">Tag id</param> /// <param name="value">Tag selected value</param> /// <param name="cssClass">Tag style</param> /// <param name="url">url for requesting data</param> /// <param name="url">url for requesting data</param> /// <param name="textField">Show field</param> /// <param name="valueField">Value field</param> /// <returns>select tag</returns> 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); } /// <summary> /// Return select tag/// </summary> /// <param name="html">Extension method instance</param> /// <param name="id">Tag id</param> /// <param name="value">Tag selected value</param> /// <param name="cssClass">Tag style</param> /// <param name="url">Request data url</param> /// <param name="param">Requested parameters</param> /// <param name="textField">Show fields</param> /// <param name="valueField">Value fields</param> /// <param name="valueField">Value fields</param> /// <param name="valueField">Value fields</param> /// <param name="valueField"> name="multiple">Is multiple choice</param> /// <returns>select tag</returns> 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(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()); } }}Then the front-end uses js to initialize, and there needs to be a js file utility.combobox.js:
(function ($) { //1. Define jquery extension method combobox $.fn.combobox = function (options, param) { if (typeof options == 'string') { return $.fn.combobox.methods[options](this, param); } //2. Merge the parameters passed in when calling and default parameters options = $.extend({}, $.fn.combobox.defaults, options || {}); //3. Add the default value var target = $(this); target.attr('valuefield', options.valueField); target.attr('textfield', options.textField); target.empty(); var option = $('<option></option>'); option.attr('value', ''); option.text(options.placeholder); target.append(option); //4. Determine whether the parameter list sent by the user contains data data data set. If it is included, do not send ajax to fetch data from the background, otherwise send ajax to fetch data from the background 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></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. If the string is passed, it means calling the method. $.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></option>'); option.attr('value', ''); option.text('Please select'); jq.append(option); $.each(data, function (i, item) { var option = $('<option></option>'); option.attr('value', item[jq.attr('valuefield')]); option.text(item[jq.attr('textfield')]); jq.append(option); }); }); }); } }; //6. Default parameter list $.fn.combobox.defaults = { url: null, param: null, data: null, valueField: 'value', textField: 'text', placeholder: 'Please select', onBeforeLoad: function (param) { }, onLoadSuccess: function () { }, onChange: function (value) { } }; //This paragraph is newly added, and the initialization method $(document).ready(function () { $('select').each(function () { var $combobox = $(this); $.fn.combobox.call($combobox, $combobox.data()); }) });})(jQuery);This js file comes from a previous article by the blogger //www.VeVB.COM/article/92595.htm
Then the front-end call
<div> @Bootstrap.SelectBox("sel", null, null, "/Home/GetDept", null, "Name", "Id") </div>5. Summary
At this point, the first version of our BootstrapHelper has been basically completed, and the main package components are as follows:
Of course, everyone likes the source code sharing the most. Source code address
If you think this article can help you, please recommend it.
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.