2023年2月

在上篇《
基于Metronic的Bootstrap开发框架经验总结(1)-框架总览及菜单模块的处理
》介绍了Bootstrap开发框架的一些基础性概括,包括总体界面效果,以及布局、菜单等内容,本篇继续这一主题,介绍页面内容常用到的数据分页处理,以及Bootstrap插件JSTree的使用。在数据的界面显示当中,表格数据的展示以及分页是非常常见的处理操作,利用Bootstrap的样式布局,以及JQuery的Ajax数据处理,就能很好实现数据的动态展示和分页处理。

1、列表展示和分页处理

1)数据的列表展示

在很多页面里面,我们一般都需要对数据库记录进行列表展示并进行分页。

左侧的树列表下面小节介绍,右边就是我们一般的数据查询显示区域,分为查询内容和数据列表两部分,查询内容,我们一般放在一个表单里面进行处理,用户触发查询的时候,我们对事件进行处理,并从MVC后台的控制器里面请求对应的数据返回给页面前端,对数据进行显示和分页处理即可。

如菜单页面的查询代码如下所示。

                    <formclass="form-horizontal"id="ffSearch">
                        <divclass="col-md-3 col-sm-3 col-xs-6">
                            <divclass="form-group">
                                <labelclass="control-label col-md-4">显示名称</label>
                                <divclass="col-md-8">
                                    <inputname="WHC_Name"type="text"class="form-control">
                                </div>
                            </div>
                        </div>
                        <divclass="col-md-3 col-sm-3 col-xs-6">
                            <divclass="form-group">
                                <labelclass="control-label col-md-4">功能ID</label>
                                <divclass="col-md-8">
                                    <inputname="WHC_FunctionId"type="text"class="form-control">
                                </div>
                            </div>
                        </div>
                        <divclass="col-md-3 col-sm-3 col-xs-6">
                            <divclass="form-group">
                                <labelclass="control-label col-md-4">Web连接地址</label>
                                <divclass="col-md-8">
                                    <inputname="WHC_Url"type="text"class="form-control">
                                </div>
                            </div>
                        </div>
                        <divclass="col-md-3 col-sm-3 col-xs-6">
                            <divclass="form-group">
                                <labelclass="control-label col-md-4">Web菜单图标</label>
                                <divclass="col-md-8">
                                    <inputname="WHC_WebIcon"type="text"class="form-control">
                                </div>
                            </div>
                        </div>
                    </form>

我们在页面的JS代码里面,处理页面初始化后,对数据进行查询的处理操作,如下脚本所示。

        //页面初始化
        $(function() {
initJsTree();
//初始化树 BindEvent();//绑定事件处理 Search(currentPage);//初始化第一页数据 InitDictItem(); //初始化字典信息 });

而数据的显示部分,HTML代码如下所示。主要就是显示了表头内容,表格的主体内容grid_body则有脚本动态构建并显示

                    <tableid="grid"class="table table-striped table-bordered table-hover"cellpadding="0"cellspacing="0"border="0"class="display"width="100%">
                        <theadid="grid_head">
                            <tr>
                                <thclass="table-checkbox"style="width:40px"><inputclass="group-checkable"type="checkbox"onclick="selectAll(this)"></th>
                                <th>显示名称</th>
                                <th>排序</th>
                                <th>功能ID</th>
                                <th>菜单可见</th>
                                <th>Web连接地址</th>
                                <th>Web菜单图标</th>
                                <th>系统编号</th>
                                <thstyle="width:90px">操作</th>
                            </tr>
                        </thead>
                        <tbodyid="grid_body"></tbody>
                    </table>
                    <divclass="paging-toolbar">
                        <ulid='grid_paging'></ul>
                    </div>

而数据的显示,是在页面准备完成后,通过Search脚本函数进行处理,处理的时候,先序列号表单的条件和分页的条件信息,传入MVC控制器,获取对应的列表数据,在界面上进行动态绑定即可完成整个处理过程了。具体代码截图如下所示。

而其中的代码

tr += getActionHtml(item.ID);

则是通过脚本生成一些操作按钮,界面如下所示。

2)数据分页处理

我们页面显示的数据一般不是固定的记录,因此分页也是很必要的处理,可以提高性能,也可以提高用户的友好体验,其中的数据分页是采用了Bootstrap的插件Bootstrap Paginator 进行处理的。这个控件用的很多,是一个很强大的分页插件。

Bootstrap Paginator 它的GitHub代码地址为:
https://github.com/lyonlai/bootstrap-paginator

它的使用例子介绍,可以参考:
http://lyonlai.github.io/bootstrap-paginator/

该控件使用的时候,引入Jquery和Bootstrap样式和类库后,通过下面的代码行即可添加使用。

<scriptsrc="/js/bootstrap-paginator.min.js"></script>

该控件分页可以通过处理
page-clicked和page-changed事件进行实现。

分页展示内容,我们通过在HTML代码里面添加一个DIV进行,声明一个ID为grid_paging的UL元素,代码如下所示。

  <divclass="paging-toolbar">
         <ulid='grid_paging'></ul>
    </div>

然后具体的JS里面处理代码如下所示。

在MVC的后台,我们需要获取用户在前端页面传入的分页条件和表单数据条件,这样我们就可以根据这些参数,获取到对应的数据返回给客户端了。

由于这些处理都是很通用的,因此我们可以放到基类控制器进行处理,如果需要特殊化处理,再在子类控制器里面重写分页函数 FindWithPager 即可。

        /// <summary>
        ///根据条件查询数据库,并返回对象集合(用于分页数据显示)/// </summary>
        /// <returns>指定对象的集合</returns>
        public virtualActionResult FindWithPager()
{
//检查用户是否有权限,否则抛出MyDenyAccessException异常 base.CheckAuthorized(AuthorizeKey.ListKey);string where =GetPagerCondition();
PagerInfo pagerInfo
=GetPagerInfo();
List
<T> list = baseBLL.FindWithPager(where, pagerInfo);//Json格式的要求{total:22,rows:{}}//构造成Json的格式传递 var result = new { total = pagerInfo.RecordCount, rows =list };returnToJsonContentDate(result);
}

其中GetPagerInfo就是获取用户传入进来的分页参数,还记得我们上面前端页面处理的URL参数吗,如下所示。

url = "/Menu/FindWithPager?page=" + page + "&rows=" + rows;

具体MVC控制器GetPagerInfo函数的实现代码如下所示。

        /// <summary>
        ///根据Request参数获取分页对象数据/// </summary>
        /// <returns></returns>
        protected virtualPagerInfo GetPagerInfo()
{
int pageIndex = Request["page"] == null ? 1 : int.Parse(Request["page"]);int pageSize = Request["rows"] == null ? 10 : int.Parse(Request["rows"]);

PagerInfo pagerInfo
= newPagerInfo();
pagerInfo.CurrenetPageIndex
=pageIndex;
pagerInfo.PageSize
=pageSize;returnpagerInfo;
}

然后获取到表单条件和分页条件后,传入给框架的业务逻辑类处理就可以了,这里已经是框架底层的支持范畴了,不在继续展开。

List<T> list = baseBLL.FindWithPager(where, pagerInfo);

最后的界面效果如下所示

2、插件JSTree

前面小节也提高的树列表的展示,在一般情况下,如果数据有层次的,那么通过树列表展示,可以很直观的显示出它们的结构,因此树列表在很多情况下,可以辅助我们对数据的分类展示。

如对于用户数据来说,我们可以根据用户的组织机构或者角色进行分类,他们两者可以通过树列表进行直观的展示,这样我们在寻找不同类型的用户列表的时候,就很好找了。

或者对于字典数据或者省份城市的数据,一样更可以通过树列表进行展示


JSTree 控件的官方地址为
https://www.jstree.com/

网站对JSTree控件的使用说明及案例讲解的已经很清晰了,一般情况下,我们直接参考例子就可以使用了。

简单的JSTree使用代码如下所示

$(function () { $('#jstree_demo_div').jstree(); });

对于JSTree的事件,我们一般可以通过下面代码进行绑定事件。

$('#jstree_demo_div').on("changed.jstree", function(e, data) {
console.log(data.selected);
});

如果我们需要获取JStree控件选中节点的内容,然后进行相关的处理操作,那么它的处理代码如下所示。

            //绑定双击事件
            $("#jstree_div").bind("dblclick.jstree", function(e, data) {
EditDept();
});
$(
"#jstree_tag").bind("dblclick.jstree", function(e, data) {
EditTag();
});

双击事件,其实是连续的单击事件处理,一般情况下,或先选中当前节点,我们也可以在双击的时候,获取对应的节点ID,如下代码所示。

            bindJsTree("jstree_div", "/Menu/GetMenuJsTreeJson");
$(
"#jstree_div").bind("dblclick.jstree", function(e, data) {var id = $(e.target).parents('li').attr('id');
EditViewById(id);
});

也就是可以通过

var id = $(e.target).parents('li').attr('id');

获取双击的节点ID,获取选择节点的名称则可以通过代码获取:

var eventNodeName = e.target.nodeName;

JSTree一般我们会通过JSON数据进行动态绑定,这个JSON的数据格式定义如下所示。

{
id :
"string" //required parent : "string" //required text : "string" //node text icon : "string" //string for custom state : {
opened :
boolean //is the node open disabled : boolean //is the node disabled selected : boolean //is the node selected },
li_attr : {}
//attributes for the generated LI node a_attr : {} //attributes for the generated A node }

一般情况下,我们通过下面的脚本进行数据的清空和绑定操作

$('#jstree_demo_div').data('jstree', false);//清空数据,必须

//异步进行JSON数据的绑定
$.getJSON(url, function(data) {
$(
'#jstree_demo_div').jstree({'core': {'data': data,"themes": {"responsive": false}
}
}).bind(
'loaded.jstree', loadedfunction);
});

如果我们需要给用户提供复选框,设置JSTree的选中状态,界面效果如下所示。

那么一般的初始化函数就需要变化一下,如下代码所示

        //带复选框的JSTree的初始化代码
        $.getJSON(url, function(data) {
control.jstree({
'plugins' : [ "checkbox" ], //出现选择框 'checkbox': { cascade: "", three_state: false }, //不级联 'core': {'data': data,"themes": {"responsive": false}
}
}).bind(
'loaded.jstree', loadedfunction);
});

综合两者,我们可以进一步把JSTree控件的初始化绑定提炼为一个JS的公共函数bindJsTree即可。

//以指定的Json数据,初始化JStree控件//treeName为树div名称,url为数据源地址,checkbox为是否显示复选框,loadedfunction为加载完毕的回调函数
functionbindJsTree(treeName, url, checkbox, loadedfunction) {var control = $('#' +treeName)
control.data(
'jstree', false);//清空数据,必须 var isCheck = arguments[2] || false; //设置checkbox默认值为false if(isCheck) {//复选框树的初始化 $.getJSON(url, function(data) {
control.jstree({
'plugins' : [ "checkbox" ], //出现选择框 'checkbox': { cascade: "", three_state: false }, //不级联 'core': {'data': data,"themes": {"responsive": false}
}
}).bind(
'loaded.jstree', loadedfunction);
});
}
else{//普通树列表的初始化 $.getJSON(url, function(data) {
control.jstree({
'core': {'data': data,"themes": {"responsive": false}
}
}).bind(
'loaded.jstree', loadedfunction);
});
}
}

因此在页面的绑定JSTree的时候,代码可以简化一下

        //初始化组织机构列表
        functioninitDeptTreeview() {var treeUrl = '/User/GetMyDeptJsTreeJson?userId=@Session["UserId"]';
bindJsTree(
"jstree_div", treeUrl);//树控件的变化事件处理 $('#jstree_div').on("changed.jstree", function(e, data) {var icon =data.node.icon;
loadDataByOu(data.selected);
});
}

对于复选框的列表,初始化代码如下所示。

            //初始化所有该用户的所有功能集合
            var treeUrl = '/Function/GetRoleFunctionJsTreeByUser?userId=@Session["UserId"]';
bindJsTree(
"tree_function", treeUrl, true);//角色数据权限,先初始化所有部门 treeUrl = '/User/GetMyDeptJsTreeJson?userId=@Session["UserId"]';
bindJsTree(
"tree_roledata", treeUrl, true);

对于复选框,我们一般是初始化数据,然后在根据需要设置树列表的选中状态,这种不用频繁初始化树,可以有效提高性能和响应体验。

那么我们在初始化树列表后,就需要清空选择项,然后设置我们所需要的选择项即可,具体代码如下所示,注意其中的uncheck_all和check_node事件的处理。

        //初始化角色数据权限集合(组织机构)
        functioninitRoleData(id) {if (id != "") {var treeMenu = "tree_roledata";
$(
'#' + treeMenu).jstree("uncheck_all");//取消所有选中 //勾选指定内容 $.getJSON("/RoleData/GetRoleDataList?r=" + Math.random() + "&roleId=" + id, function(json) {
$.each(json,
function(i, item) {
$(
'#' + treeMenu).jstree('check_node', item);//将节点选中 });
});
}
}

数据保存的时候,我们获得JSTree的节点选中列表就可以进行数据的保存了,具体代码如下所示。

        //保存角色数据权限
        functionsaveRoleData(roleid) {var ouList = $('#tree_roledata').jstree('get_selected');var url = '/RoleData/UpdateData?r=' +Math.random();var postData = { roleId: roleid, ouList: ouList.join(',')};

$.post(url, postData,
function(json) {
initRoleData(roleid);
}).error(
function() {
showTips(
"您未被授权使用该功能,请联系管理员进行处理。");
});
}

好了,介绍到这里,基本上也把常规的数据展示,数据分页;JSTree的绑定、事件处理,数据保存等操作介绍的相对完整了,希望得到大家的继续支持,我会继续详细介绍Bootstrap开发里面涉及到的要点和各个插件的使用,以便把学习更加具体化,实用化,能够给我们实价开发项目做有用的参考。

如果有兴趣,可以继续参考系列文章:

基于Metronic的Bootstrap开发框架经验总结(1)-框架总览及菜单模块的处理

基于Metronic的Bootstrap开发框架经验总结(2)--列表分页处理和插件JSTree的使用


基于Metronic的Bootstrap开发框架经验总结(3)--下拉列表Select2插件的使用

基于Metronic的Bootstrap开发框架经验总结(4)--Bootstrap图标的提取和利用

基于Metronic的Bootstrap开发框架经验总结(5)--Bootstrap文件上传插件File Input的使用


基于Metronic的Bootstrap开发框架经验总结(6)--对话框及提示框的处理和优化

基于Metronic的Bootstrap开发框架经验总结(7)--数据的导入、导出及附件的查看处理


基于Metronic的Bootstrap开发框架经验总结(8)--框架功能总体界面介绍


基于Metronic的Bootstrap开发框架经验总结(9)--实现Web页面内容的打印预览和保存操作

在上篇《
基于Metronic的Bootstrap开发框架经验总结(2)--列表分页处理和插件JSTree的使用
》介绍了数据的分页处理,使用了Bootstrap Paginator插件,另外对树形列表,采用了JSTree插件,本篇继续介绍在编辑页面中常用到的控件Select2,这个控件可以更加丰富传统的Select下拉列表控件,提供更多的功能和更好的用户体验。

1、Select2控件介绍

这个插件是基于Select的扩展插件,能够提供更加丰富的功能和用户体验,它的github官网地址为:
https://select2.github.io/
,具体的使用案例,可以参考地址:
https://select2.github.io/examples.html

我们在整个框架里面,用到了很多Select2控件来处理内容的显示,包括单选的下拉列表(包括级联选择框)、复选的下拉列表、树形下拉列表等方式,界面效果如下所示。

1)编辑界面下的省份、城市、所在行政区的级联界面效果,选择省份,会加载对应省份下的城市,选择城市,会继续加载城市下的行政区,从而实现多级关联的下拉列表效果。

2)编辑界面下的多项选择下拉列表

但我们选择其中的内容的时候,系统自动显示出没有选择的列表数据,非常直观友好,如下所示。

3)树形列表的下拉列表

有时候,我们的一些数据可能有层次关系的,如所属机构、上层列表等等。

2、Select2控件的实际使用代码分析

1)基础界面代码及操作

使用select2控件,一般是在常规的select控件上,设置一下即可(设置它的class为
select2
)。

 <divclass="col-md-6">
    <divclass="form-group">
        <labelclass="control-label col-md-4">重要级别</label>
        <divclass="col-md-8">
            <selectid="Importance"name="Importance"class="form-control select2"placeholder="重要级别..."></select>
        </div>
    </div>
</div>
 <divclass="col-md-6">
    <divclass="form-group">
        <labelclass="control-label col-md-4">认可程度</label>
        <divclass="col-md-8">
            <selectid="Recognition"name="Recognition"class="form-control select2"placeholder="认可程度..."></select>
        </div>
    </div>
</div>

如果是固定列表,那么也就是设置它的Option内容即可,如下所示。

 <divclass="col-md-6">
    <divclass="form-group">
        <labelclass="control-label col-md-4">吸烟</label>
        <divclass="col-md-8">
            <selectid="Smoking"name="Smoking"type="text"class="form-control select2"placeholder="吸烟...">
                <option>吸烟</option>
                <option>不吸烟</option>
            </select>
        </div>
    </div>
</div>

简单的select2控件初始化代码如下所示。

$(document).ready(function() {
$(
".js-example-basic-single").select2();
});

一般情况下,如果允许复选多个项目,那么设置 multiple="multiple"即可,如下代码所示。

 <selectid="ResponseDemand"name="ResponseDemand"multiple="multiple"class="form-control select2"></select>

2)异步数据绑定操作

一般情况下,我们的select控件的数据,是从数据库里面动态加载的,因此一般是通过Ajax方式获取数据并进行绑定即可。

基于代码可重用性的考虑,我们编写一个公用的JS函数,用来减少绑定操作的代码,提高代码重用性。

//绑定字典内容到指定的Select控件
functionBindSelect(ctrlName, url) {var control = $('#' +ctrlName);//设置Select2的处理
control.select2({
allowClear:
true,
formatResult: formatResult,
formatSelection: formatSelection,
escapeMarkup:
function(m) {returnm;
}
});
//绑定Ajax的内容 $.getJSON(url, function(data) {
control.empty();
//清空下拉框 $.each(data, function(i, item) {
control.append(
"<option value='" + item.Value + "'>&nbsp;" + item.Text + "</option>");
});
});
}

这样,绑定公用字典模块的数据,也就可以通过下面进一步封装处理即可。

//绑定字典内容到指定的控件
functionBindDictItem(ctrlName, dictTypeName) {var url = '/DictData/GetDictJson?dictTypeName=' +encodeURI(dictTypeName);
BindSelect(ctrlName, url);
}

这样我们初始化Select2 控件,并动态绑定对应的字典值或者其他数据,则可以通过下面初始化代码即可实现。其中BindDictItem就是直接绑定字典内容的操作,BindSelect则是根据URL进行数据的获取并绑定,而$("#Province").on("change", function (e) {});这样的函数处理,就是处理选择内容变化的联动操作了。

        //初始化字典信息(下拉列表)
        functionInitDictItem() {//部分赋值参考
            BindDictItem("Area","市场分区");
BindDictItem(
"Industry", "客户行业");
BindDictItem(
"Grade","客户级别");
BindDictItem(
"CustomerType", "客户类型");
BindDictItem(
"Source", "客户来源");
BindDictItem(
"CreditStatus", "信用等级");
BindDictItem(
"Stage","客户阶段");
BindDictItem(
"Status", "客户状态");
BindDictItem(
"Importance", "重要级别");//绑定省份、城市、行政区(联动处理) BindSelect("Province", "/Province/GetAllProvinceNameDictJson");
$(
"#Province").on("change", function(e) {var provinceName = $("#Province").val();
BindSelect(
"City", "/City/GetCitysByProvinceNameDictJson?provinceName="+provinceName);
});

$(
"#City").on("change", function(e) {var cityName = $("#City").val();
BindSelect(
"District", "/District/GetDistrictByCityNameDictJson?cityName="+cityName);
});
}

而其中MVC控制器返回的数据,我们是返回一个JSON数据列表给前端页面的,他们的数据格式如下所示。

[ { "Text": "", "Value": "" }, { "Text": "学术会议", "Value": "学术会议" }, { "Text": "朋友介绍", "Value": "朋友介绍" }, { "Text": "广告媒体", "Value": "广告媒体" } ]

这样前端页面绑定Select2控件的时候,就使用了JSON对象的属性即可。

    //绑定Ajax的内容
    $.getJSON(url, function(data) {
control.empty();
//清空下拉框 $.each(data, function(i, item) {
control.append(
"<option value='" + item.Value+ "'>&nbsp;" + item.Text+ "</option>");
});
});

控制器的实现代码如下:

        /// <summary>
        ///根据字典类型获取对应的字典数据,方便UI控件的绑定/// </summary>
        /// <param name="dictTypeName">字典类型名称</param>
        /// <returns></returns>
        public ActionResult GetDictJson(stringdictTypeName)
{
List
<CListItem> treeList = new List<CListItem>();
CListItem pNode
= new CListItem("", "");
treeList.Insert(
0, pNode);

Dictionary
<string, string> dict = BLLFactory<DictData>.Instance.GetDictByDictType(dictTypeName);foreach (string key indict.Keys)
{
treeList.Add(
newCListItem(key, dict[key]));
}
returnToJsonContent(treeList);
}

3)树形列表的绑定操作

对于属性列表,如所属公司、所属部门机构等有层次性的数据,它的绑定操作也是类似的,如下代码所示。

            //绑定添加界面的公司、部门、直属经理
            BindSelect("Company_ID", "/User/GetMyCompanyDictJson?userId="+@Session["UserId"]);
$(
"#Company_ID").on("change", function(e) {var companyid = $("#Company_ID").val();
BindSelect(
"Dept_ID", "/User/GetDeptDictJson?parentId="+companyid);
});
$(
"#Dept_ID").on("change", function(e) {var deptid = $("#Dept_ID").val();
BindSelect(
"PID", "/User/GetUserDictJson?deptId="+deptid);
});

只是它们返回的数据,我们把它作为有缩进的显示内容而已。

[ { "Text": "爱奇迪集团", "Value": "1" }, { "Text": " 广州分公司", "Value": "3" }, { "Text": " 上海分公司", "Value": "4" }, { "Text": " 北京分公司", "Value": "5" } ]

或者如下所示

[ { "Text": "广州分公司", "Value": "3" }, { "Text": "总经办", "Value": "6" }, { "Text": "财务部", "Value": "7" }, { "Text": "工程部", "Value": "8" }, { "Text": "产品研发部", "Value": "9" }, { "Text": "  开发一组", "Value": "14" }, { "Text": "  开发二组", "Value": "15" }, { "Text": "  测试组", "Value": "16" }, { "Text": "市场部", "Value": "10" }, { "Text": "  市场一部", "Value": "23" }, { "Text": "  市场二部", "Value": "24" }, { "Text": "综合部", "Value": "11" }, { "Text": "生产部", "Value": "12" }, { "Text": "人力资源部", "Value": "13" } ]

综上两个部分,我们可以看到它们的Text的内容,是根据层次关系进行空格增加,从而实现了层次关系的显示。

不过从这个界面效果上讲,这样的处理确实没有EasyUI里面,对下拉列表树的展示好看,也许可以利用更好的Bootstrap插件进行这个树形内容的展示。


4)select2控件的赋值处理

上面介绍的方法,都是介绍select2控件的初始化,绑定相关的数据,那么如果初始化界面后,我们绑定编辑界面的值的时候,就需要赋值给控件,让它显示真正需要显示的项目了。

如清空控件的方法如下所示。

            //清空Select2控件的值
            $("#PID").select2("val", "");
$(
"#Company_ID").select2("val", "");
$(
"#Dept_ID").select2("val", "");

如果对于多个控件,需要清除,则可以使用集合进行处理

            var select2Ctrl = ["Area","Industry","Grade","CustomerType","Source","CreditStatus","Stage","Status","Importance"];
$.each(select2Ctrl,
function(i, item) {var ctrl = $("#" +item);
ctrl.select2(
"val", "");
});

给Select2 控件赋值,让它显示对应值内容的项目,那么操作也就和上面的类似了。

                 $("#CustomerType").select2("val", info.CustomerType);
$(
"#Grade").select2("val", info.Grade);
$(
"#CreditStatus").select2("val", info.CreditStatus);
$(
"#Importance").select2("val", info.Importance);
$(
"#IsPublic").select2("val", info.IsPublic);

如果需要级联显示的,那么做法增加一个onchange的函数处理就可以了,如下级联代码的赋值处理如下。

 $("#Province").select2("val", info.Province);
$(
"#Province").trigger('change');//联动 $("#City").select2("val", info.City);
$(
"#City").trigger('change');//联动 $("#District").select2("val", info.District);

$(
"#Company_ID1").select2("val", info.Company_ID);
$(
"#Company_ID1").trigger('change');
$(
"#Dept_ID1").select2("val", info.Dept_ID);
$(
"#Dept_ID1").trigger('change');
$(
"#PID1").select2("val", info.PID);

多个列表项目数据的绑定。

我们从案例里面可以看到,Select2支持多项值的选择,它们保存后会以逗号分开,如果我们需要在编辑的时候显示存储的多个记录,那么需要把字符串转换为数组列表才能进行正确绑定,如下所示。

$("#Permission").select2("val", info.Permission.split(','));

最后来两个整体性的界面效果,供参考。

如果有兴趣,可以继续参考系列文章:

基于Metronic的Bootstrap开发框架经验总结(1)-框架总览及菜单模块的处理

基于Metronic的Bootstrap开发框架经验总结(2)--列表分页处理和插件JSTree的使用


基于Metronic的Bootstrap开发框架经验总结(3)--下拉列表Select2插件的使用

基于Metronic的Bootstrap开发框架经验总结(4)--Bootstrap图标的提取和利用

基于Metronic的Bootstrap开发框架经验总结(5)--Bootstrap文件上传插件File Input的使用


基于Metronic的Bootstrap开发框架经验总结(6)--对话框及提示框的处理和优化

基于Metronic的Bootstrap开发框架经验总结(7)--数据的导入、导出及附件的查看处理


基于Metronic的Bootstrap开发框架经验总结(8)--框架功能总体界面介绍


基于Metronic的Bootstrap开发框架经验总结(9)--实现Web页面内容的打印预览和保存操作

在前面的一篇随笔《
基于Metronic的Bootstrap开发框架经验总结(1)-框架总览及菜单模块的处理
》介绍了菜单模块的处理,主要介绍如何动态从数据库里面获取记录并构建菜单列表。其中菜单信息的图标样式,也是从数据库里面获取的,因此要求我们能够动态取得Bootstrap里面的各种图标定义了。本篇主要介绍如何提取Bootstrap的图标信息,存储到数据库里面为我所用。

1、菜单的显示及各种Bootstrap图标

我们从下图可以看到,为了菜单的美观,每个菜单项(这里分了三级菜单)都有一个图标,虽然大小不同,我们利用Bootstrap的图标,都是从Bootstrap图标库里面的内容。

Bootstrap图标库里面分为了三类内容:

Font Awesome
:Bootstrap专用图标字体,Font Awesome 中包含的所有图标都是矢量的,也就可以任意缩放,避免了一个图标做多种尺寸的麻烦。CSS对字体可以设置的样式也同样能够运用到这些图标上了。

如下面是部分Font Awesome 的图标:


Simple Icons
:收集众多网站的Logo,并提供高质量、不同尺寸的png格式图片给广大网友,所有Icon版权归其所属公司。

如下面所示是Simple Icons的部分图标:


Glyphicons
:包括200个符号字体格式图表集合,由Glyphicons提供,Glyphicons Halflings 一般是收费的,但是经过Bootstrap和Glyphicons作者之间的协商,允许开发人员不需要支付费用即可使用。

如下是部分Glyphicons内容:

利用这几种图标内容,我们引入下面几种样式就可以了。

<linkhref="/Content/metronic/font-awesome/css/font-awesome.min.css"rel="stylesheet"/>
<linkhref="/Content/metronic/simple-line-icons/simple-line-icons.min.css"rel="stylesheet"/>
<linkhref="/Content/metronic/bootstrap/css/bootstrap.min.css"rel="stylesheet"/>

这几种图标,都是支持各种Bootstrap的主题化显示的,如下面几种效果所示。

或者也可以把图标变大一些:

2、各种Bootstrap的图标的提取

我们通过上面的介绍,估计对这几种Bootstrap的图标有了一定的了解,但是我们如果要能够在菜单编辑里面选择图标,那么我们还是需要把这些信息提取到数据库里面,然后展示出来给我进行选择的,否则无法做到动态配置。

如上面的编辑界面,对菜单的Web图标提供了动态的选择,那么我们如果数据库里面记录了上面几种图标的集合,那么我们就可以把它在界面进行展示,并可以从中选择合适的图表了。

根据上面的几个样式文件,我们分析一下,如对于font-awesome.min.css的文件内容,它对于图标定义部分如下所示。

而对于simple-line-icons来说,它的样式定义也差不多,如下所示。

对于Glyphicons来说,它的样式定义也是很类似的,如下所示。

根据这几种信息,我们就可以通过正则表达式匹配的方式,把我们所需要的信息提取出来,并存储在数据库里面即可实现图标动态显示和选择的第一步了。

例如,我们定义部分变量和正则表达式来处理这些文件内容:

            string regex = "^\\.(?<name>.*?):before\\s*\\{";
List
<string> filePathList = new List<string>()
{
"~/Content/themes/metronic/assets/global/plugins/bootstrap/css/bootstrap.css","~/Content/themes/metronic/assets/global/plugins/font-awesome/css/font-awesome.css","~/Content/themes/metronic/assets/global/plugins/simple-line-icons/simple-line-icons.css",
};

然后通过读取文件内容,并进行匹配记录获取即可提取出来集合内容了。

    string content =FileUtil.FileToString(realPath);
List
<string> matchList = CRegex.GetList(content, regex, 1);

最后我们把这些信息保存到数据库表里面即可。

    BootstrapIconInfo info = newBootstrapIconInfo()
{
DisplayName
=item,
ClassName
= prefix +item,
CreateTime
=DateTime.Now,
SourceType
=sourceType,
};

BLLFactory
<BootstrapIcon>.Instance.Insert(info);

最后记录存储在数据库里面,效果如下所示,里面已经记录我们所需的图标信息了,这样在实际使用的时候,就可以利用各个字段的信息,显示出好看的界面了。

3、
Bootstrap的图标显示和选择

我们通过文件读取并以正则表达式提取出内容,然后保存到数据库后,这些图标信息就可以为我们使用了,可以在页面里面分类显示出来,每类的图标进行分页处理,方便查询,如下所示。

这部分的显示页面代码和常规的数据显示差不多的,只是不需要表头信息而已,我们来看看页面代码如下所示。

        <divclass="portlet box green-meadow">
            <divclass="portlet-title">
                <divclass="caption"> <iclass="fa fa-filter"></i>图标信息</div>
            </div>
            <divclass="portlet-body flip-scroll">
                <div>
                    <span>每页显示</span>
                    <selectid="rows"onchange="ChangeRows()">
                        <option>50</option>
                        <optionselected>100</option>
                        <option>200</option>
                        <option>1000</option>
                    </select>
                    <span>条记录</span>&nbsp;&nbsp;
                    <span>共有记录:</span><spanid='totalCount'class="label label-success">0</span>条,总页数:<spanid='totalPageCount'class="label label-success">0</span>页。</div>
                <hr/>
                <divclass="row"style="padding-left:20px">
                    <divclass="portlet-body"id="grid_body"></div>
                    <divclass="paging-toolbar">
                        <ulid='grid_paging'></ul>
                    </div>
                </div>
            </div>
        </div>

其中主要的图标显示内容在上面这部分的HTML里面。

<divclass="portlet-body"id="grid_body"></div>

动态获取并生成HTML代码显示在界面上的处理脚本如下所示。

            $.getJSON(iconUrl + "&" + condition, function(data) {
$(
"#icon_body").html("");
$.each(data.rows,
function(i, item) {var tr = "<a href=\"javascript:;\" onclick=\"GetIcon('" + item.ClassName + "')\" class=\"icon-btn\" title=\"" + item.DisplayName + "\">";
tr
+= " <i class=\"" + item.ClassName + " \" style=\"font-size: 2.2em\"></i>";// //tr += "<div>" + item.DisplayName + "</div>"; tr += "</a>";
$(
"#icon_body").append(tr);
});

用户选择对应的图标后,我们可以通过脚本设置Span的样式就可以显示出来我们选中的图标了,如下所示。

$("#i_WebIcon").attr("class", classname);

当然我们选择图标的时候,提供一个弹出的对话框显示分类不同的图标,让用户选择后返回即可。

这样我们就完成了,从图标文件里面提取不同类型的图表,然后存储在数据库里面,并在页面里面显示出来,可供我们动态选择和设置了。

如果有兴趣,可以继续参考系列文章:

基于Metronic的Bootstrap开发框架经验总结(1)-框架总览及菜单模块的处理

基于Metronic的Bootstrap开发框架经验总结(2)--列表分页处理和插件JSTree的使用


基于Metronic的Bootstrap开发框架经验总结(3)--下拉列表Select2插件的使用

基于Metronic的Bootstrap开发框架经验总结(4)--Bootstrap图标的提取和利用

基于Metronic的Bootstrap开发框架经验总结(5)--Bootstrap文件上传插件File Input的使用


基于Metronic的Bootstrap开发框架经验总结(6)--对话框及提示框的处理和优化

基于Metronic的Bootstrap开发框架经验总结(7)--数据的导入、导出及附件的查看处理


基于Metronic的Bootstrap开发框架经验总结(8)--框架功能总体界面介绍


基于Metronic的Bootstrap开发框架经验总结(9)--实现Web页面内容的打印预览和保存操作

Bootstrap文件上传插件File Input是一个不错的文件上传控件,但是搜索使用到的案例不多,使用的时候,也是一步一个脚印一样摸着石头过河,这个控件在界面呈现上,叫我之前使用过的Uploadify 好看一些,功能也强大些,本文主要基于我自己的框架代码案例,介绍其中文件上传插件File Input的使用。关于Uploadify的控件介绍,可以参考我之前的随笔介绍《
基于MVC4+EasyUI的Web开发框架形成之旅--附件上传组件uploadify的使用
》。

1、文件上传插件File Input介绍

这个插件主页地址是:
http://plugins.krajee.com/file-input
,可以从这里看到很多Demo的代码展示:
http://plugins.krajee.com/file-basic-usage-demo

这是一个增强的 HTML5 文件输入控件,是一个 Bootstrap 3.x 的扩展,实现文件上传预览,多文件上传等功能。

一般情况下,我们需要引入下面两个文件,插件才能正常使用:

bootstrap-fileinput/css/fileinput.min.css

bootstrap-fileinput/js/fileinput.min.js

简单的界面效果如下所示,和众多上传文件控件一样,可以接受各种类型的文件。当然,我们也可以指定具体接受的文件类型等功能。

如果需要考虑中文化,那么还需要引入文件:

bootstrap-fileinput/js/fileinput_locale_zh.js

这样基于MVC的Bundles集合,我们把它们所需要的文件加入到集合里面即可。

            //添加对bootstrap-fileinput控件的支持
            css_metronic.Include("~/Content/MyPlugins/bootstrap-fileinput/css/fileinput.min.css");
js_metronic.Include(
"~/Content/MyPlugins/bootstrap-fileinput/js/fileinput.min.js");
js_metronic.Include(
"~/Content/MyPlugins/bootstrap-fileinput/js/fileinput_locale_zh.js");

这样我们在页面里面,就可以呈现出中文的界面说明和提示了,如下界面所示。

2、文件上传插件File Input的使用

一般情况下,我们可以定义一个JS的通用函数,用来初始化这个插件控件的,如下JS的函数代码所示。

//初始化fileinput控件(第一次初始化)
functioninitFileInput(ctrlName, uploadUrl) {var control = $('#' +ctrlName); 

control.fileinput({
language:
'zh', //设置语言 uploadUrl: uploadUrl, //上传的地址 allowedFileExtensions : ['jpg', 'png','gif'],//接收的文件后缀 showUpload: false, //是否显示上传按钮 showCaption: false,//是否显示标题 browseClass: "btn btn-primary", //按钮样式 previewFileIcon: "<i class='glyphicon glyphicon-king'></i>",
});
}

页面代码里面,我们放置一个文件上传控件,如下代码所示。

  <divclass="row"style="height: 500px">
           <inputid="file-Portrait1"type="file">
    </div>

这样我们脚本代码的初始化代码如下:

            //初始化fileinput控件(第一次初始化)
            initFileInput("file-Portrait", "/User/EditPortrait");

这样就完成了控件的初始化了,如果我们需要上传文件,那么还需要JS的代码处理客户端上传的事件,同时也需要MVC后台控制器处理文件的保存操作。

例如我对窗体数据的保存处理代码如下所示。

            //添加记录的窗体处理
            formValidate("ffAdd", function(form) {
$(
"#add").modal("hide");//构造参数发送给后台 var postData = $("#ffAdd").serializeArray();
$.post(url, postData,
function(json) {var data =$.parseJSON(json);if(data.Success) {//增加肖像的上传处理 initPortrait(data.Data1);//使用写入的ID进行更新 $('#file-Portrait').fileinput('upload');//保存成功 1.关闭弹出层,2.刷新表格数据 showTips("保存成功");
Refresh();
}
else{
showError(
"保存失败:" + data.ErrorMessage, 3000);
}
}).error(
function() {
showTips(
"您未被授权使用该功能,请联系管理员进行处理。");
});
});

其中我们注意到文件保存的处理逻辑代码部分:

   //增加肖像的上传处理
   initPortrait(data.Data1);//使用写入的ID进行更新
   $('#file-Portrait').fileinput('upload');

第一行代码就是重新构建上传的附加内容,如用户的ID信息等,这样我们就可以根据这些ID来构建一些额外的数据给后台上传处理了。

这个函数主要就是重新给ID赋值,方便上传的时候,获取最新的附加参数,这个和Uploadify的处理模式一样的。

        //初始化图像信息
        functioninitPortrait(ctrlName, id) {var control = $('#' +ctrlName);var imageurl = '/PictureAlbum/GetPortrait?id=' + id + '&r=' +Math.random();//重要,需要更新控件的附加参数内容,以及图片初始化显示
            control.fileinput('refresh', {
uploadExtraData: { id: id },
initialPreview: [
//预览图片的设置 "<img src='" + imageurl + "' class='file-preview-image' alt='肖像图片' title='肖像图片'>",
],
});
}

前面我们看到,我上传的地址为:"/User/EditPortrait",这个后台的函数我也公布一下,希望给大家一个完整的案例代码学习。

        /// <summary>
        ///上传用户头像图片/// </summary>
        /// <param name="id">用户的ID</param>
        /// <returns></returns>
        public ActionResult EditPortrait(intid)
{
CommonResult result
= newCommonResult();try{var files =Request.Files;if (files != null && files.Count > 0)
{
UserInfo info
= BLLFactory<User>.Instance.FindByID(id);if (info != null)
{
var fileData = ReadFileBytes(files[0]);
result.Success
= BLLFactory<User>.Instance.UpdatePersonImageBytes(UserImageType.个人肖像, id, fileData);
}
}
}
catch(Exception ex)
{
result.ErrorMessage
=ex.Message;
}
returnToJsonContent(result);
}

这样我们就构建了上面的用户肖像的保存处理逻辑了,文件可以正常的保存到后台的文件系统里面,同时数据库里面记录一些必备的信息。

当然,除了用来处理用户的肖像图片,我们也可以用来构建图片相册的处理操作的,具体界面如下所示。

这部分的初始化代码如下所示:

            //初始化fileinput控件(第一次初始化)
            $('#file-Portrait').fileinput({
language:
'zh', //设置语言 uploadUrl: "/FileUpload/Upload", //上传的地址 allowedFileExtensions : ['jpg', 'png','gif'],//接收的文件后缀, maxFileCount: 100,
enctype:
'multipart/form-data',
showUpload:
true, //是否显示上传按钮 showCaption: false,//是否显示标题 browseClass: "btn btn-primary", //按钮样式 previewFileIcon: "<i class='glyphicon glyphicon-king'></i>",
msgFilesTooMany:
"选择上传的文件数量({n}) 超过允许的最大数值{m}!",
});

如果有兴趣,可以继续参考系列文章:

基于Metronic的Bootstrap开发框架经验总结(1)-框架总览及菜单模块的处理

基于Metronic的Bootstrap开发框架经验总结(2)--列表分页处理和插件JSTree的使用


基于Metronic的Bootstrap开发框架经验总结(3)--下拉列表Select2插件的使用

基于Metronic的Bootstrap开发框架经验总结(4)--Bootstrap图标的提取和利用

基于Metronic的Bootstrap开发框架经验总结(5)--Bootstrap文件上传插件File Input的使用


基于Metronic的Bootstrap开发框架经验总结(6)--对话框及提示框的处理和优化

基于Metronic的Bootstrap开发框架经验总结(7)--数据的导入、导出及附件的查看处理


基于Metronic的Bootstrap开发框架经验总结(8)--框架功能总体界面介绍


基于Metronic的Bootstrap开发框架经验总结(9)--实现Web页面内容的打印预览和保存操作

在各种Web开发过程中,对话框和提示框的处理是很常见的一种界面处理技术,用得好,可以给用户很好的页面体验,Bootstrap开发也一样,我们往往在页面新增、编辑、查看详细等界面使用弹出对话框层的方式进行显示数据,删除则可能使用一个提示确认框,如果操作成功,我们可以使用更丰富的提示框来处理,本篇主要对比说明在Bootstrap开发中用到的这些技术要点。

1、Bootstrap对话框的使用

常规的Bootstrap有几种尺寸的对话框,包括默认状态的小对话框,中等宽度的对话框,和全尺寸的对话框几种,Bootstrap的对话框界面非常友好, 当我们使用ESC键或者鼠标单击其他空白处,则会自动隐藏对话框的。

它们的定义只是class不同,如下面是默认的小对话框界面代码:

<!--------------------------添加/修改信息的弹出层---------------------------->
<divid="add"class="modal fade"tabindex="-1"role="dialog"aria-labelledby="myModalLabel"aria-hidden="true">
    <divclass="modal-dialog">
        <divclass="modal-content">
            <divclass="modal-header bg-primary">
                <buttontype="button"class="close"data-dismiss="modal"aria-hidden="true"></button>
                <h4class="modal-title">
                    <iclass="icon-pencil"></i>
                    <spanid="lblAddTitle"style="font-weight:bold">添加信息</span>
                </h4>
            </div>
            <formclass="form-horizontal form-bordered form-row-strippe"id="ffAdd"action=""data-toggle="validator"enctype="multipart/form-data">
                <divclass="modal-body">
                    <divclass="row">
                        <divclass="col-md-12">
                            <divclass="form-group">
                                <labelclass="control-label col-md-2">父ID</label>
                                <divclass="col-md-10">
                                    <selectid="PID"name="PID"type="text"class="form-control select2"placeholder="父ID..." ></select>
                                </div>
                            </div>
                        </div>
                        <divclass="col-md-12">
                            <divclass="form-group">
                                <labelclass="control-label col-md-2">名称</label>
                                <divclass="col-md-10">
                                    <inputid="Name"name="Name"type="text"class="form-control"placeholder="名称..." />
                                </div>
                            </div>
                        </div>
                        <divclass="col-md-12">
                            <divclass="form-group">
                                <labelclass="control-label col-md-2">备注</label>
                                <divclass="col-md-10">
                                    <textareaid="Note"name="Note"class="form-control"placeholder="备注..."></textarea>
                                </div>
                            </div>
                        </div>

                    </div>
                </div>
                <divclass="modal-footer bg-info">
                    <inputtype="hidden"id="ID"name="ID" />
                    <buttontype="submit"class="btn blue">确定</button>
                    <buttontype="button"class="btn green"data-dismiss="modal">取消</button>
                </div>
            </form>
        </div>
    </div>
</div>

大概的界面如下所示:

注意上面代码里面的对话框样式代码,如下:

<divclass="modal-dialog">

如果是其他两个尺寸的数据库,也只需要修改这里即可,如下所示两种代码分别是:

    <divclass="modal-dialog modal-lg">

以及

    <divclass="modal-dialog modal-full">

我们可以根据界面元素的布局,来决定采用哪个尺寸的对话框层定义,不过他们这几个对话框的调用方式是一致的。

打开对话框界面如下所示:

//显示可以选择客户
$("#btnSelectCustomer").show();

关闭对话框界面如下所示:

$("#add").modal("hide");

一般情况下,我们弹出的对话框就是一个表单,可以执行类似保存数据的提交操作的,因此需要对表单的数据进行验证,如果有错误,我们可能需要在界面上提醒,因此在页面初始化的时候,需要初始化表单的验证规则,下面是我们常规的表单初始化操作。

        //绑定相关事件
        functionBindEvent() {//判断表单的信息是否通过验证
            $("#ffAdd").validate({
meta:
"validate",
errorElement:
'span',
errorClass:
'help-block help-block-error',
focusInvalid:
false,
highlight:
function(element) {
$(element).closest(
'.form-group').addClass('has-error');
},
success:
function(label) {
label.closest(
'.form-group').removeClass('has-error');
label.remove();
},
errorPlacement:
function(error, element) {
element.parent(
'div').append(error);
},
submitHandler:
function(form) {
$(
"#add").modal("hide");//构造参数发送给后台 var postData = $("#ffAdd").serializeArray();
$.post(url, postData,
function(json) {var data =$.parseJSON(json);if(data.Success) {//增加肖像的上传处理 $('#file-Portrait').fileinput('upload');//保存成功 1.关闭弹出层,2.刷新表格数据 showTips("保存成功");
Refresh();
}
else{
showError(
"保存失败:" + data.ErrorMessage, 3000);
}
}).error(
function() {
showTips(
"您未被授权使用该功能,请联系管理员进行处理。");
});
}
});
}

但是一般这些代码都会重复很多,因此我们可以封装函数的方式,重用部分代码,从而使用更简洁的处理代码,但同样能达到目的。

        //绑定相关事件
        functionBindEvent() {//添加、编辑记录的窗体处理
            formValidate("ffAdd", function(form) {
$(
"#add").modal("hide");//构造参数发送给后台 var postData = $("#ffAdd").serializeArray();
$.post(url, postData,
function(json) {var data =$.parseJSON(json);if(data.Success) { //保存成功 1.关闭弹出层,2.刷新表格数据 showTips("保存成功");
Refresh();
}
else{
showError(
"保存失败:" + data.ErrorMessage, 3000);
}
}).error(
function() {
showTips(
"您未被授权使用该功能,请联系管理员进行处理。");
});
});
}

2、删除确认的对话框处理

1)bootbox插件的使用

除了上面的常规对话框,我们还经常碰到一种简洁的确认对话框,虽然也可以使用上面的代码来构建一个确认对话框,不过一般情况下不需要这么麻烦的,可以使用插件bootbox的确认对话框来进行处理。

Bootbox.js是一个小的JavaScript库,它帮助您在使用bootstrap框架的时候快速的创建一个对话框,也可以帮您创建,管理或删除任何所需的DOM元素或js事件处理程序。

bootbox.js使用三方法设计模仿他们的本地JavaScript一些方法。他们确切的方法签名是灵活的每个可以采取各种参数定制标签和指定缺省值,但它们通常被称为一样:

  • bootbox.alert(message, callback)
  • bootbox.prompt(message, callback)
  • bootbox.confirm(message, callback)

唯一需要的参数是alert是 message; callback是必需的 confirm 和 prompt 调用以确定用户的响应。甚至当调用警报回调是确定当用户 驳回对话框由于我们的包装方法不能不要块 像他们的母语是有用的:他们是异步而非同步。

这三种方法调用四分之一个公共方法,你也可以使用你自己的自定义对话框创建 :

bootbox.dialog(options)

更多api帮助文档请参见:
http://bootboxjs.com/documentation.html

Alert

bootbox.alert("Hello world!", function() {
Example.show("Hello world callback");
});

Confirm

bootbox.confirm("Are you sure?", function(result) {
Example.show("Confirm result: "+result);
});
或者代码
                bootbox.confirm("您确认删除选定的记录吗?", function(result) {if(result) {//最后去掉最后的逗号,
                       ids = ids.substring(0, ids.length - 1);//然后发送异步请求的信息到后台删除数据
                       var postData ={ Ids: ids };
$.get(
"/Province/DeletebyIds", postData, function(json) {var data =$.parseJSON(json);if(data.Success) {
showTips(
"删除选定的记录成功");
Refresh();
//刷新页面数据 }else{
showTips(data.ErrorMessage);
}
});
}
});

Prompt

bootbox.prompt("What is your name?", function(result) {
if (result === null) {
   Example.show("Prompt dismissed");
} else {
   Example.show("Hi <b>"+result+"</b>");
}
});

Custom Dialog

使用代码和界面效果如下所示:

bootbox.dialog(…)

2)sweetalert插件的使用

虽然上面的效果非常符合Bootstrap的风格,不过界面略显单调。上面的效果不是我很喜欢这种风格,我遇到一个看起来更加美观的效果,如下所示。

这个效果是引入插件sweetalert(
http://t4t5.github.io/sweetalert/
)实现的。

swal({
title:
"操作提示",
text: newtips,
type:
"warning", showCancelButton: true,
confirmButtonColor:
"#DD6B55",
cancelButtonText:
"取消",
confirmButtonText:
"是的,执行删除!",
closeOnConfirm:
true},function() {
delFunction();
});

上面的界面效果类似的实现代码如下所示:

一般它的弹出框代码可以做的很简单,如下所示。

3、信息提示框的处理

上面两种处理,都是利用弹出对话框进行实现的,而且对界面有阻塞的,一般情况下,我们做信息提示效果,希望它不要影响我们进一步的操作,或者至少提供一个很短的自动消失效果。

那么这里我们就来介绍下
jNotify
插件和
toastr
插件了。

1)jNotify提示框的使用

jNotify
提示框,一款优秀的jQuery结果提示框插件。我们在提交表单后,通过Ajax响应后台返回结果,并在前台显示返回信息,jNotify能非常优雅的显示操作结果信息。jNotify是一款基于jQuery的信息提示插件,它支持操作成功、操作失败和操作提醒三种信息提示方式。jNotify浏览器兼容性非常好,支持更改提示内容,支持定位提示框的位置,可配置插件参数。

jSuccess(message,{option});


jError(
"操作失败,请重试!!");


jNotify(
"注意:请完善你的<strong>个人资料!</strong>");

jNotify的参数详细配置:

autoHide : true,                //是否自动隐藏提示条
clickOverlay : false,            //是否单击遮罩层才关闭提示条
MinWidth : 200,                    //最小宽度
TimeShown : 1500,                 //显示时间:毫秒
ShowTimeEffect : 200,             //显示到页面上所需时间:毫秒
HideTimeEffect : 200,             //从页面上消失所需时间:毫秒
LongTrip : 15,                    //当提示条显示和隐藏时的位移
HorizontalPosition : "right",     //水平位置:left, center, right
VerticalPosition : "bottom",     //垂直位置:top, center, bottom
ShowOverlay : true,                //是否显示遮罩层
ColorOverlay : "#000",            //设置遮罩层的颜色
OpacityOverlay : 0.3,            //设置遮罩层的透明度
onClosed:fn            //关闭提示框后执行函数,可以再次调用其他jNotify。如上面的三个依次调用。

下面是我在脚本类里面封装的饿公用方法,用来实现提示效果的显示的。

//显示错误或提示信息(需要引用jNotify相关文件)
functionshowError(tips, TimeShown, autoHide) {
jError(
tips,
{
autoHide: autoHide
|| true, //added in v2.0 TimeShown: TimeShown || 1500,
HorizontalPosition:
'center',
VerticalPosition:
'top',
ShowOverlay:
true,
ColorOverlay:
'#000',
onCompleted:
function () { //added in v2.0 //alert('jNofity is completed !'); }
}
);
}
//显示提示信息 functionshowTips(tips, TimeShown, autoHide) {
jSuccess(
tips,
{
autoHide: autoHide
|| true, //added in v2.0 TimeShown: TimeShown || 1500,
HorizontalPosition:
'center',
VerticalPosition:
'top',
ShowOverlay:
true,
ColorOverlay:
'#000',
onCompleted:
function () { //added in v2.0 //alert('jNofity is completed !'); }
}
);
}

这样我们在使用Ajax的POST方法的时候,我们可以根据不同的需要进行提示。

                    var postData = $("#ffAdd").serializeArray();
$.post(url, postData,
function(json) {var data =$.parseJSON(json);if(data.Success) {//增加肖像的上传处理 $('#file-Portrait').fileinput('upload');//保存成功 1.关闭弹出层,2.刷新表格数据 showTips("保存成功");
Refresh();
}
else{
showError(
"保存失败:" + data.ErrorMessage, 3000);
}
}).error(
function() {
showTips(
"您未被授权使用该功能,请联系管理员进行处理。");
});

2)toastr插件的使用

toastr
是一个Javascript库用于创建Gnome/Growl风格,非阻塞的页面消息提醒。,toastr可设定四种通知模式:成功,出错,警告,提示,而提示窗口的位置,动画效果都可以通过能数来设置,在官方站可以通过勾选参数来生成JS,非常的方便使用。

插件地址是:
http://codeseven.github.io/toastr/

它可以分别创建如下几种效果:警告、危险、成功、提示的对话框信息,效果如下所示。

它的使用JS代码如下所示。

//显示一个警告,没有标题
toastr.warning('My name is Inigo Montoya. You killed my father, prepare to die!')//显示一个成功,标题
toastr.success('Have fun storming the castle!', 'Miracle Max Says')//显示错误标题
toastr.error('I do not think that word means what you think it means.', 'Inconceivable!')//清除当前的列表
toastr.clear()

这个插件的参数定义说明如下所示。

    //参数设置,若用默认值可以省略以下面代
    toastr.options ={"closeButton": false, //是否显示关闭按钮
        "debug": false, //是否使用debug模式
        "positionClass": "toast-top-full-width",//弹出窗的位置
        "showDuration": "300",//显示的动画时间
        "hideDuration": "1000",//消失的动画时间
        "timeOut": "5000", //展现时间
        "extendedTimeOut": "1000",//加长展示时间
        "showEasing": "swing",//显示时的动画缓冲方式
        "hideEasing": "linear",//消失时的动画缓冲方式
        "showMethod": "fadeIn",//显示时的动画方式
        "hideMethod": "fadeOut" //消失时的动画方式
};//成功提示绑定
        $("#success").click(function(){
toastr.success(
"祝贺你成功了");
})

以上就是我在项目里面,对对话框及提示框的处理和优化的经验总结,希望对大家学习改进Web界面有帮助。

如果有兴趣,可以继续参考系列文章:

如果有兴趣,可以继续参考系列文章:

基于Metronic的Bootstrap开发框架经验总结(1)-框架总览及菜单模块的处理

基于Metronic的Bootstrap开发框架经验总结(2)--列表分页处理和插件JSTree的使用


基于Metronic的Bootstrap开发框架经验总结(3)--下拉列表Select2插件的使用

基于Metronic的Bootstrap开发框架经验总结(4)--Bootstrap图标的提取和利用

基于Metronic的Bootstrap开发框架经验总结(5)--Bootstrap文件上传插件File Input的使用


基于Metronic的Bootstrap开发框架经验总结(6)--对话框及提示框的处理和优化

基于Metronic的Bootstrap开发框架经验总结(7)--数据的导入、导出及附件的查看处理


基于Metronic的Bootstrap开发框架经验总结(8)--框架功能总体界面介绍


基于Metronic的Bootstrap开发框架经验总结(9)--实现Web页面内容的打印预览和保存操作