wenmo8 发布的文章

在前面的一篇随笔《
基于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页面内容的打印预览和保存操作

在很多系统模块里面,我们可能都需要进行一定的数据交换处理,也就是数据的导入或者导出操作,这样的批量处理能给系统用户更好的操作体验,也提高了用户录入数据的效率。我在较早时期的EasyUI的Web框架上,也介绍过通过Excel进行的数据导入导出操作,随笔文章为《
基于MVC4+EasyUI的Web开发框架经验总结(10)--在Web界面上实现数据的导入和导出
》,本文基于Bootstrap的框架基础上,再对这个模块进行更新处理,以及Office文档或者图片等附件的查看处理。

1、数据的导入操作

一般系统模块里面,都有数据导入和导出操作,因此在界面自动生成的时候,我都倾向于给用户自动生成这些标准的查询、导入、导出等操作功能,界面效果如下所示。

导入操作,在Bootstrap框架里面,我把它作为一个层的,都统一放在index.cshtml文件里面,这样可以使得整个界面的处理更加紧密一点,示例代码如下所示。

下面这些代码一般情况下,都是自动生成的,包括所需的全部字段,我们一般是根据需要进行字段的裁剪,以适应我们的业务和实际需要。

<!--导入数据操作层-->
<divid="import"class="modal fade bs-modal-lg"tabindex="-1"role="dialog"aria-labelledby="myModalLabel"aria-hidden="true">
    <divclass="modal-dialog modal-lg">
        <divclass="modal-content">
            <divclass="modal-header bg-primary">
                <buttontype="button"class="close"data-dismiss="modal"aria-hidden="true"></button>
                <h4class="modal-title">文件导入</h4>
            </div>
            <divclass="modal-body">
                <divstyle="text-align:right;padding:5px">
                    <ahref="~/Content/Template/User-模板.xls"onclick="javascript:Preview();">
                        <imgalt="测试用户信息-模板"src="~/Content/images/ico_excel.png" />
                        <spanstyle="font-size:larger;font-weight:200;color:red">User-模板.xls</span>
                    </a>
                </div>
                <hr/>
                <formid="ffImport"method="post">
                    <divtitle="Excel导入操作"style="padding: 5px"data-options="iconCls:'icon-key'">
                        <inputclass="easyui-validatebox"type="hidden"id="AttachGUID"name="AttachGUID" />    
                        <inputid="file_upload"name="file_upload"type="file"multiple="multiple">                    
                        <ahref="javascript:;"class="btn btn-primary"id="btnUpload"onclick="javascript: $('#file_upload').uploadify('upload', '*')">上传</a>
                        <ahref="javascript:;"class="btn btn-default"id="btnCancelUpload"onclick="javascript: $('#file_upload').uploadify('cancel', '*')">取消</a>

                        <divid="fileQueue"class="fileQueue"></div>
                        <br/>                    
                        <hrstyle="width:98%" />                    
                        <divid="div_files"></div>
                        <br/>                    
                    </div>
                </form>

                <!--数据显示表格-->
                <tableid="gridImport"class="table table-striped table-bordered table-hover"cellpadding="0"cellspacing="0"border="0"class="display"width="100%">
                    <theadid="gridImport_head">
                        <tr>
                            <thclass="table-checkbox"style="width:40px"><inputclass="group-checkable"type="checkbox"onclick="selectAll(this)"></th>
                            <th>用户编码</th>
                            <th>用户名/登录名</th>
                            <th>真实姓名</th>
                            <th>职务头衔</th>
                            <th>移动电话</th>
                            <th>办公电话</th>
                            <th>邮件地址</th>
                            <th>性别</th>
                            <th>QQ号码</th>
                            <th>备注</th>
                        </tr>
                    </thead>
                    <tbodyid="gridImport_body"></tbody>
                </table>
            </div>
            <divclass="modal-footer">
                <buttontype="button"class="btn btn-default"data-dismiss="modal">关闭</button>
                <buttontype="button"class="btn btn-primary"onclick="SaveImport()">保存</button>
            </div>
        </div>
    </div>
</div>

我们如果要显示导入操作界面,那么只需要把这个层显示出来即可,如下脚本所示。

        //显示导入界面
        functionShowImport() {
$(
"#import").modal("show");
}

这里的文件上传处理,主要使用了Uploadify的这个控件进行处理的,当然也可以利用我前面介绍过的File Input上传控件进行处理,都可以很好实现这些导入操作。

一般情况下的Uploadify控件的初始化代码如下所示

        $(function() {//添加界面的附件管理
            $('#file_upload').uploadify({'swf': '/Content/JQueryTools/uploadify/uploadify.swf',  //FLash文件路径
                'buttonText': '浏  览',                                 //按钮文本
                'uploader': '/FileUpload/Upload',                       //处理上传的页面
                'queueID': 'fileQueue',                         //队列的ID
                'queueSizeLimit': 1,                            //队列最多可上传文件数量,默认为999
                'auto': false,                                  //选择文件后是否自动上传,默认为true
                'multi': false,                                 //是否为多选,默认为true
                'removeCompleted': true,                        //是否完成后移除序列,默认为true
                'fileSizeLimit': '10MB',                        //单个文件大小,0为无限制,可接受KB,MB,GB等单位的字符串值
                'fileTypeDesc': 'Excel Files',                  //文件描述
                'fileTypeExts': '*.xls',                        //上传的文件后缀过滤器
                'onQueueComplete': function (event, data) {     //所有队列完成后事件
                    //业务处理代码
                    //提示用户Excel格式是否正常,如果正常加载数据
},'onUploadStart': function(file) {
InitUpFile();
//上传文件前 ,重置GUID,每次不同 $("#file_upload").uploadify("settings", 'formData', { 'folder': '数据导入文件', 'guid': $("#AttachGUID").val() }); //动态传参数 },'onUploadError': function(event, queueId, fileObj, errorObj) {//alert(errorObj.type + ":" + errorObj.info); }
});
});

关键的逻辑就是:

//业务处理代码

一般情况下,我们在这里已经在服务器里面获得了Excel文件了,因此需要对这个文件的格式进行处理,如果格式正确,那么我们把数据显示出来,供导入用户进行记录的选择,决定导入那些记录即可。

处理检查Excel数据格式的代码如下所示。

                    //提示用户Excel格式是否正常,如果正常加载数据
$.ajax({
url:
'/User/CheckExcelColumns?guid=' +guid,
type:
'get',
dataType:
'json',
success:
function(data) {if(data.Success) {
InitGrid();
//重新刷新表格数据 showToast("文件已上传,数据加载完毕!");
}
else{
showToast(
"上传的Excel文件检查不通过。请根据页面右上角的Excel模板格式进行数据录入。", "error");
}
}
});

我们就是在后台增加一个CheckExcelColumns的方法,用来检查Excel文件的字段格式的,只有符合格式要求的文件,才被获取数据并显示在界面上。

显示在界面上的JS代码,也就是主要把Excel文件的内容提取出来,并绑定在Table元素上即可。

        //根据条件查询并绑定结果
        functionInitGrid() {var guid = $("#AttachGUID").val();var url = "/User/GetExcelData?guid=" +guid;
$.getJSON(url,
function(data) {
$(
"#gridImport_body").html("");

$.each(data.rows,
function(i, item) {var tr = "<tr>";
tr
+= "<td><input class='checkboxes' type=\"checkbox\" name=\"checkbox\" ></td>";
tr
+= "<td>" + item.HandNo + "</td>";
tr
+= "<td>" + item.Name + "</td>";
tr
+= "<td>" + item.FullName + "</td>";
tr
+= "<td>" + item.Title + "</td>";
tr
+= "<td>" + item.MobilePhone + "</td>";
tr
+= "<td>" + item.OfficePhone + "</td>";
tr
+= "<td>" + item.Email + "</td>";
tr
+= "<td>" + item.Gender + "</td>";
tr
+= "<td>" + item.QQ + "</td>";
tr
+= "<td>" + item.Note + "</td>";

tr
+= "</tr>";
$(
"#gridImport_body").append(tr);
});
});
}

为了更进一步获取用户导入到具体的部门,那么我们还可以弹出一个对话框用然后选择具体的信息,最后才提交数据到后台进行处理。

操作代码如下所示。

        //保存导入的数据
        functionSaveImport() {//赋值给对象
            $("#Company_ID3").select2("val", @Session["Company_ID"]).trigger('change');
$(
"#Dept_ID3").select2("val", @Session["Dept_ID"]).trigger('change');


$(
"#selectDept").modal("show");
}

这样我们确认保存的时候,只需要通过Ajax把数据提交给后台处理即可,具体JS代码如下所示。

$.ajax({
url:
'/User/SaveExcelData',
type:
'post',
dataType:
'json',
contentType:
'application/json;charset=utf-8',
traditional:
true,
success:
function(data) {if(data.Success) {//保存成功 1.关闭弹出层,2.清空记录显示 3.刷新主列表 showToast("保存成功");

$(
"#import").modal("hide");
$(bodyTag).html(
"");
Refresh();
}
else{
showToast(
"保存失败:" + data.ErrorMessage, "error");
}
},
data: postData
});

Uploadify的处理在我之前基于EasyUI的界面里面也有说明,有兴趣可以参考《
基于MVC4+EasyUI的Web开发框架经验总结(10)--在Web界面上实现数据的导入和导出
》、《
基于MVC4+EasyUI的Web开发框架形成之旅--附件上传组件uploadify的使用
》以及《
Web开发中的文件上传组件uploadify的使用
》。

2、数据的导出操作

数据的导出操作相对比较简单,一般情况下,我们把数据写入一个固定的Excel表里面,然后提供URL给用户下载即可。

        //导出Excel数据
        functionShowExport() {var url = "/User/Export";var condition = $("#ffSearch").serialize();//获取条件
executeExport(url, condition);//执行导出
        }

具体的逻辑代码如下所示

//执行导出操作,输出文件
functionexecuteExport(url, condition) {
$.ajax({
type:
"POST",
url: url,
data: condition,
success:
function(filePath) {var downUrl = '/FileUpload/DownloadFile?file=' +filePath;
window.location
=downUrl;
}
});
}

3、附件的查看处理

多数情况下,我们可能需要查看上传的文件,包括Office文档、图片等可以进行预览的,是在不行,可以提供下载本地打开查看。

我在基于EasyUI的Web开发也介绍了Office的预览处理:《
基于MVC4+EasyUI的Web开发框架经验总结(8)--实现Office文档的预览
》,这里我们改进一下即可实现具体的Office预览和图片查看功能了。

上篇文件介绍了Office的预览有两种途径,一种是利用微软Office的预览地址进行预览,一种是用控件生成HTML进行预览,两种可以结合使用,根据需要进行配置即可。

        /// <summary>
        ///根据附件ID,获取对应查看的视图URL。///一般规则如果是图片文件,返回视图URL地址'/FileUpload/ViewAttach';///如果是Office文件(word、PPT、Excel)等,可以通过微软的在线查看地址进行查看:'http://view.officeapps.live.com/op/view.aspx?src=',///也可以进行本地生成HTML文件查看。如果是其他文件,可以直接下载地址。/// </summary>
        /// <param name="id">附件的ID</param>
        /// <returns></returns>
        public ActionResult GetAttachViewUrl(stringid)
{
string viewUrl = "";
FileUploadInfo info
= BLLFactory<FileUpload>.Instance.FindByID(id);if (info != null)
{
string ext = info.FileExtend.Trim('.').ToLower();string filePath =GetFilePath(info);bool officeInternetView = false;//是否使用互联网在线预览 string hostName = HttpUtility.UrlPathEncode("http://www.iqidi.com/");//可以配置一下,如果有必要 if (ext == "xls" || ext == "xlsx" || ext == "doc" || ext == "docx" || ext == "ppt" || ext == "pptx")
{
if(officeInternetView)
{
//返回一个微软在线浏览Office的地址,需要加上互联网域名或者公网IP地址 viewUrl = string.Format("http://view.officeapps.live.com/op/view.aspx?src={0}{1}", hostName, filePath);
}
else{#region 动态第一次生成文件 //检查本地Office文件是否存在,如不存在,先生成文件,然后返回路径供查看 string webPath = string.Format("/GenerateFiles/Office/{0}.htm", info.ID);string generateFilePath =Server.MapPath(webPath);if (!FileUtil.FileIsExist(generateFilePath))
{
string templateFile = BLLFactory<FileUpload>.Instance.GetFilePath(info);
templateFile
= Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, templateFile.Replace("\\", "/"));if (ext == "doc" || ext == "docx")
{
Aspose.Words.Document doc
= newAspose.Words.Document(templateFile);
doc.Save(generateFilePath, Aspose.Words.SaveFormat.Html);
}
else if (ext == "xls" || ext == "xlsx")
{
Workbook workbook
= newWorkbook(templateFile);
workbook.Save(generateFilePath, SaveFormat.Html);
}
else if (ext == "ppt" || ext == "pptx")
{
templateFile
= templateFile.Replace("/", "\\");
PresentationEx pres
= newPresentationEx(templateFile);
pres.Save(generateFilePath, Aspose.Slides.Export.SaveFormat.Html);
}
}
#endregionviewUrl=webPath;
}
}
else{
viewUrl
=filePath;
}
}
returnContent(viewUrl);
}

通过这个后台处理代码,我们可以正确知道Office预览的时候,使用的是哪个URL了。

这样在前端页面,我们只需要判断具体是那种文件,然后进行展示即可了。

        if(type =="image") {var imgContent = '<img src="'+ viewUrl + '" />';
$(
"#divViewFile").html(imgContent);
$(
"#file").modal("show");
}
else{
$.ajax({
type:
'GET',
url: viewUrl,
//async: false, //同步 //dataType: 'json', success: function(json) {
$(
"#divViewFile").html(json);
$(
"#file").modal("show");
},
error:
function(xhr, status, error) {
showError(
"操作失败" + xhr.responseText); //xhr.responseText }
});
}

其中的代码

$("#file").modal("show");

是我们调用全局对话框,用来展示具体的内容的,效果如下所示。

word文档预览效果如下所示:

或者我们查看图片文件的时候,可以获得界面效果如下所示:

以上就是 数据的导入、导出及附件的查看处理的介绍内容,希望对大家学习有帮助。

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

基于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开发框架经验总结》的随笔文章,随笔主要是介绍各个知识点的内容,对框架的总体性界面没有很好的阐述,本篇随笔主要介绍这个Bootstrap框架的总体性功能界面,介绍其中用到的知识点和整体性的界面。希望读者对框架有一个更加直观、真实的认识了解,界面设计以及相关思路可以借鉴提高,也可以对相关的内容进行相互探讨,共同提高。

1、《基于Metronic的Bootstrap开发框架》技术特点

1)采用最新最炫的Bootstrap响应式框架技术

整个基于Metronic的Bootstrap开发框架,界面部分采用较新的Bootstrap技术,采用当前最新的Bootstrap3.x,集成了众多功能强大的Bootstrap控件。

Bootstrap
是一个前端的技术框架,很多平台都可以采用,JAVA/PHP/.NET都可以用来做前端界面,整合JQuery可以实现非常丰富的界面效果,目前也有很多Bootstrap的插件能够提供给大家使用,本框架集合了众多最为优秀的插件,能给我们Web的用户体验提升到一个前所未有的水平。

Metronic
是一个国外的基于HTML、JS等技术的Bootstrap开发框架整合,整合了很多Bootstrap的前端技术和插件的使用,是一个非常不错的技术框架。本框架以这个为基础,结合我对MVC的Web框架的研究,整合了基于MVC的Bootstrap开发框架,使之能够符合实际项目的结构需要。

框架后台采用基于C#的MVC技术,是目前.NET开发最为成熟流行的技术,框架后台数据库支持Oracle、SqlServer、MySql、Sqlite、Access等常规数据库,可通过配置进行自由切换,使用Enterprise Library模块进行数据访问的控制,使得数据访问更方便轻松。

整体框架开发采用Visual Studuio 2013以及页面编辑工具Sublime Text结合开发,页面以及后台代码,通过代码生成工具Database2Sharp进行快速开发,实现整体性开发的最大效率提高。

框架的总体结构如下所示:

控制器设计:
Bootstrap开发框架沿用了我的《
Winform开发框架
》和《
基于EasyUI的Web框架》
的很多架构设计思路和特点,对Controller进行了封装。使得控制器能够获得很好的继承关系,并能以更少的代码,更高效的开发效率,实现Web项目的开发工作,整个控制器的设计思路如下所示。

权限控制:
良好的控制器设计规则,可以为Web开发框架本身提供了很好用户访问控制和权限控制,使得用户界面呈现菜单、Web界面的按钮和内容、Action的提交控制,均能在总体权限功能分配和控制之下。

代码快速生成:
良好的架构使得无论在业务逻辑层、控制器层、Web界面的UI层,均能提供统一的代码逻辑,这些代码均能通过代码生成工具Database2Sharp进行生成。Web界面代码可以充分利用代码生成工具Database2Sharp的元数据信息,实现Web界面的快速生成。有效减少出错的几率,提高Web界面编码的开发效率和乐趣,更可以使得企业内部的编码模式进行高效的统一。

Enterprise Library代码生成,可以快速生成除界面外的整体性的框架代码,Bootstrap的Web界面代码生成,可以快速生成基于Metronic的Bootstrap的前端界面代码和后台控制器代码,界面部分包括查询、分页、数据展示、数据导入导出、新增、编辑、查看、删除等基础功能界面,生成后我们可以基于这个基础上进行简单、快速的修改即可符合实际需要,极大提高我们Web界面的开发效率。

框架布局:
以下是我整体性项目的总的效果图。

【系统菜单栏】的内容,是动态从数据库里面获取的菜单;【系统顶栏】放置一些信息展示,以及提供用户对个人数据快速处理,如查看个人信息、注销、锁屏等操作内容;内容区一般包括【树列表区】、【条件查询区】和【列表数据及分页】内容,内容区域主要是可视化展示的数据,可以通过树列表控件、表格控件进行展示,一般数据还有增删改查、以及分页的需要,因此需要整合各种功能的处理。另外,用户的数据,除了查询展示外,还需要有导入、导出等相关操作,这些是常规性的数据处理功能。

菜单的处理和展示:一般为了管理方便,菜单分为三级,选中的菜单和别的菜单样式有所区分,菜单可以折叠最小化,效果如下所示。


2、《基于Metronic的Bootstrap开发框架》模块界面介绍

2.1 首页图表模块界面

2.2 系统顶栏功能

2.3 行业动态功能(政策法规、通知公告、动态信息)

政策法规/通知公告/动态信息 列表界面

编辑界面如下所示:

查看内容界面如下所示:

2.4 客户信息管理

客户列表界面如下所示:

客户信息编辑界面:

客户信息导入界面:

2.5 客户联系人管理

客户联系人添加/编辑界面

客户联系人查看界面

附件信息界面

2.6 通讯录管理

通讯录列表

通讯录编辑界面如下所示。

2.7 权限管理

1) 系统用户 列表界面

系统用户导入界面

系统用户编辑界面

系统用户的肖像上传和编辑

系统用户删除确认对话框。

系统用户的RDLC报表界面。

2)机构管理界面

组织机构包含用户编辑界面

3)用户角色管理

角色可操作功能集合展示

角色可访问数据权限控制:

角色包含机构管理:

4)系统功能管理

5)系统菜单管理

编辑菜单信息界面:

选择菜单图标界面:

6)系统登录日志管理

7)通用字典管理

8)菜单图标管理

9)图片相册管理

编辑图片界面如下所示:

图片查看界面

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

基于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页面内容的打印预览和保存操作