ASP.NET MVC4+BootStrap 实战(十)

年过完了,也该收心了。想想过年这几天都是每天睡到12:00,实在是腐化。大家都沉浸在抢红包的喜悦之中。

不说了,今天我们主要看一下新闻链接管理界面。先上图,无图无真相。

上半部分主要是对已经添加的外链接进行修改删除,设置优先级,下半部分是新增外链接网站。

首先我们先看一下上半部分。

<div id="div_newsManage" class="panel panel-primary" ng-app="newsLinkManageModule" ng-controller="newsLinkManageController">
    <div class="panel-heading">
        <h3 class="panel-title">
            <img class="img-panel-title" src="~/Images/Base/newslink.png" />
            <b>新闻链接管理</b>
        </h3>
    </div>
    <div class="panel-body">
        <fieldset>
            <legend>
                <h5><b>外链接管理</b></h5>
            </legend>
            <div class="row">
                <div class="col-md-1">
                    <input type="checkbox" ng-model="IsSelectAll" />
                </div>
                <label class="col-md-5" style="color:#333333">网站名称</label>
                <label class="col-md-2" style="color:#333333">TOP(X)</label>
                <label class="col-md-2" style="color:#333333">操作</label>
                <label class="col-md-2" style="color:#333333">优先级</label>
            </div>
            <div class="line-seperate-style-main"></div>
            <div ng-repeat="website in WebSites" class="a-list">
                <div class="row" style="line-height:40px">
                    <div class="col-md-1">
                        <input class="chklist-vertical-align" type="checkbox" ng-model="website.IsChecked" />
                    </div>
                    <div class="col-md-5">
                        <a href="{{website.WebSiteURL}}">{{website.WebSiteName}}</a>
                    </div>
                    <div class="col-md-2">
                        <select class="form-control" ng-model="website.TopNewsCount" ng-options="number for number in numbers">
                            @*<option ng-repeat="num in numbers" label="{{num}}" value="{{num}}"></option>*@
                        </select>
                    </div>
                    <div class="col-md-2">
                        <span style="cursor: pointer;" class="glyphicon glyphicon-pencil span-grid"></span>
                        <span ng-click="newslinkdeleteSingle(website.TransactionNumber)" style="cursor:pointer;margin-left:5px;" class="glyphicon glyphicon-trash span-grid"></span>
                    </div>
                    <div class="col-md-2">
                        <span style="cursor:pointer;" class="glyphicon glyphicon-arrow-up span-grid"></span>
                        <span style="cursor: pointer; margin-left: 5px;" class="glyphicon glyphicon-arrow-down span-grid"></span>
                    </div>
                </div>
                <div class="line-seperate-style"></div>
            </div>
            <input type="button" value="移除" ng-click="newslinkdelete()" style="margin-top:10px" class="btn btn-danger" />
        </fieldset>

还是bootStrap布局,将div分成1,5,2,2,2比例的五等份。我们通过ng-repeat生成多行div。在这里需要注意的是这里的select标签的ng-options,在这里如果不使用ng-options的话,ng-model是无法选中的。OK,我们看到头部有一个复选框,那个复选框是用来全选和反选的。OK,我们看一下js代码

var appModule = angular.module(‘newsLinkManageModule‘, []);
appModule.controller("newsLinkManageController", function ($scope, $http, $filter) {
    initData();

    $scope.AddedWebSites = [];

    $scope.numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

    $scope.IsSelectAll = false;

在页面加载以后,我们首先会调用initData方法。

function initData() {
    $http.get("/NewsManage/NewsLinkList").success(function (data) {
         $scope.WebSites = data;
    });
};

其实就是调用一个后台action,得到WebSites。

[HttpGet]
[OutputCache(Duration = 60)]
public JsonResult NewsLinkList()
{
     var newsEntityList = NewsMngBiz.GetInstance().GetNewsLinkList();
     if (newsEntityList == null) return null;

     return Json(newsEntityList, JsonRequestBehavior.AllowGet);
}

在这里,实体的定义如下

public class NewsLinkEntity
    {
        public int TransactionNumber { get; set; }
        public string WebSiteName { get; set; }
        public string WebSiteURL { get; set; }
        public int TopNewsCount { get; set; }
        public int Priority { get; set; }
    }

就是将这样一个实体list以json格式返回到客户端。全选和全不选的js代码如下

$scope.$watch("IsSelectAll", setCheckState);
function setCheckState(newValue, oldValue) {
     angular.forEach($scope.WebSites, function (obj, key) {
           obj.IsChecked = newValue;
     });
}

我们通过监控IsSelectAll的值来实时设置列表中的选中状态。

接着我们看一下这里移除按钮的实现。

var linkIDs = [];
$scope.newslinkdelete = function () {
     linkIDs = [];
     angular.forEach(
          $filter(‘filter‘)($scope.WebSites, { IsChecked: true }),
                function (v) {
                    linkIDs.push(v.TransactionNumber);
                }
     );

     if (linkIDs.length == 0) {
          alert("请选择要删除的数据!");
          return;
     }

     if (confirm("您确定要删除吗?")) {
          var param = { requestJson: JSON.stringify({ linkIDs: linkIDs }) };
          newsLinkDelete(param);
     }
};

在这里先拿到选中的TransactionNumber,然后发送到服务端进行处理。

function newsLinkDelete(param) {
      $http({
                method: "Delete",
                url: "/NewsManage/DeleteNewsLink",
                headers: { ‘Content-Type‘: ‘application/x-www-form-urlencoded‘ },
                data: $.param(param)
            }).success(function (data, status, headers, config) {
                alert(data.msg);
                if (data.suc == 1) {
                    initData();
                }
            }).error(function (data, status, headers, config) {
                alert(status);
      });
}

我们看一下服务端的处理

[HttpDelete]
public JsonResult DeleteNewsLink()
{
     string requestJson = Request["requestJson"];
     string[] linkIDArray = JsonBuilder.BuildStringArray(requestJson, "linkIDs");
     int suc = NewsMngBiz.GetInstance().DeleteNewsLinks(linkIDArray);

     if (suc >= 0)
     {
         return GetJsonMessage("CM_002", JsonMsgType.SUCCESS);
     }

     return GetJsonMessage("CM_005");
}

DAL层调用如下的脚本进行处理

DECLARE @NewsLinkIDTable TABLE
(
    ID INT IDENTITY(1,1),
    TransactionNumber INT NOT NULL
)

INSERT INTO @NewsLinkIDTable
(
    TransactionNumber
)
SELECT short_str
FROM dbo.F_SQLSERVER_SPLIT(@NewsLinkIDs,‘,‘)

DELETE A FROM dbo.InformationNewsLink A
WHERE EXISTS(
    SELECT TOP 1 1
    FROM @NewsLinkIDTable B
    WHERE B.TransactionNumber = A.TransactionNumber
)

OK,接下来我们看一下下半部分。下半部分,当用户点击新增按钮的时候,会动态增加一个用于添加链接网站的div。

看一下代码

<fieldset style="margin-top:20px">
            <legend>
                <h5><b>外链接新增</b></h5>
            </legend>
            <div class="row">
                <label class="col-md-1">序号</label>
                <label class="col-md-1">勾选</label>
                <label class="col-md-4">网站名称</label>
                <label class="col-md-6">网站URL</label>
            </div>
            <div class="line-seperate-style-main"></div>
            <div class="row" style="line-height:40px">
                <div class="col-md-1">
                    <div class="div-circal-list">1</div>
                </div>
                <div class="col-md-1">
                    <input disabled type="checkbox" ng-model="IsChecked" class="chklist-vertical-align" />
                </div>
                <div class="col-md-4">
                    <input type="text" ng-model="WebSiteName" maxlength="30" style="width:100%" class="form-control" />
                </div>
                <div class="col-md-6">
                    <input type="text" placeholder="请以http或者https开头" maxlength="200" ng-model="WebSiteURL" style="width:100%" class="form-control" />
                </div>
            </div>
            <div ng-repeat="website in AddedWebSites">
                <div class="row" style="line-height:40px">
                    <div class="col-md-1">
                        <div class="div-circal-list">{{$index + 2}}</div>
                        @*<img src="~/Images/orderedList{{$index + 1}}.png" />*@
                    </div>
                    <div class="col-md-1">
                        <input type="hidden" value="{{$index + 1}}" ng-model="website.Index" />
                        <input type="checkbox" ng-model="website.IsChecked" class="chklist-vertical-align" />
                    </div>
                    <div class="col-md-4">
                        <input type="text" ng-model="website.LinkName" maxlength="30" style="width:100%" class="form-control" />
                    </div>
                    <div class="col-md-6">
                        <input type="text" placeholder="请以http或者https开头" maxlength="200" ng-model="website.URL" style="width:100%" class="form-control" />
                    </div>
                </div>
            </div>
            <div style="margin-top:20px">
                <input type="button" class="btn btn-primary" value="新增" ng-click="addnewlink()" />
                <input type="button" class="btn btn-info" value="保存" />
                <input type="button" class="btn btn-danger" value="移除" ng-click="removelink()" />
            </div>
        </fieldset>

这个界面上第一个复选框是disabled,因为我们始终要保持一个表单在。在这里我们表单的新增其实就是通过更新model实现的。当我们给数组中新增一个对象时,界面就会自动新增一行。我们看一下实现

$scope.addnewlink = function () {
      if ($scope.AddedWebSites.length >= 9) {
           alert("您一次最多只能添加10个网站链接!");
           return;
      }

      $scope.AddedWebSites.push({ URL: "", LinkName: "" });
};

很简单,前面的圆圈序列号是由如下div实现的。

<div class="div-circal-list">{{$index + 2}}</div>

css代码很简单。

.div-circal-list {
    width:30px;
    height:30px;
    border-radius:50%;
    background-color:#428bca;
    text-align:center;
    line-height:30px;
    color:white;
}

我们再看一下移除。

$scope.removelink = function () {
      var selectedIDs = [];
      angular.forEach($scope.AddedWebSites, function (obj, key) {
           if (obj.IsChecked) {
                 selectedIDs.push(key);
           }
      });

      var num = 0;
      angular.forEach(selectedIDs, function (value, key) {
          $scope.AddedWebSites.splice(value - num, 1);
                ++num;
      });
};

在这里我们根据数组的下标进行删除。因为每删除一行,会重新生成一个$index,所以我们必须先把选中的index放到一个数组中,然后循环从列表中删除。因为每删除一个index就会减1,所以我们就每次value-num。OK,本篇到此结束。

最后我们看一下上节遗留的Excel导出功能,其实就是将form提交到如下action

[OutputCache(Duration = 60, NoStore = true)]
        [HttpPost]
        public FileResult Export(FormCollection fc)
        {
            string userID = fc["searchUserID"];
            string userName = fc["searchUserName"];
            string userSex = fc["searchUserSex"];
            string birthDayStart = fc["searchStartDate"];
            string birthDayEnd = fc["searchEndDate"];

            string pageIndex = fc["hfdPageIndex"];
            string pageSize = fc["hfdPageSize"];

            UserSearchRequest userSearchRequest = new UserSearchRequest()
            {
                UserID = userID,
                UserName = userName,
                UserSex = userSex,
                StartDate = string.IsNullOrEmpty(birthDayStart) ? null : (DateTime?)DateTime.Parse(birthDayStart),
                EndDate = string.IsNullOrEmpty(birthDayEnd) ? null : (DateTime?)DateTime.Parse(birthDayEnd),
                PageIndex = int.Parse(pageIndex),
                PageSize = int.Parse(pageSize)
            };

            byte[] fileBytes = UserInfoBiz.GetInstance().GetExportFileBytes(userSearchRequest);
            if (fileBytes == null) return File("~/NoData.xls", "application/ms-excel");

            return File(fileBytes, "application/ms-excel", string.Concat("UserInfo", Guid.NewGuid().ToString(), ".xls"));
        }

在这里我们通过NPOI组件返回个byte数组,通过Biz层调用得到数组,在action中输出到客户端。

public static byte[] ExportExcel(DataTable dt, string title)
        {
            HSSFWorkbook workbooks = new HSSFWorkbook();
            HSSFSheet worksheet = (HSSFSheet)workbooks.CreateSheet(title);

            if (dt.Rows.Count == 0)
            {
                return null;
            }
            //标题
            int titleCell = dt.Columns.Count;

            worksheet.AddMergedRegion(new Region(0, 0, 0, titleCell - 1));//合并单元格,第0行0列开始到第0行titleCell-1列
            HSSFCell cell = (HSSFCell)worksheet.CreateRow(0).CreateCell(0);//创建单元格
            cell.SetCellValue(title);
            //设置样式
            HSSFCellStyle style = (HSSFCellStyle)workbooks.CreateCellStyle();
            HSSFFont font = (HSSFFont)workbooks.CreateFont();
            font.Boldweight = (short)FontBoldWeight.BOLD;//粗体
            font.Color = HSSFColor.RED.index;//字体颜色 red
            font.FontHeightInPoints = 18;//字体大小
            style.SetFont(font);
            style.Alignment = HorizontalAlignment.CENTER;
            cell.CellStyle = style;

            //设置样式
            HSSFCellStyle style1 = (HSSFCellStyle)workbooks.CreateCellStyle();
            HSSFFont font1 = (HSSFFont)workbooks.CreateFont();
            font1.Boldweight = (short)FontBoldWeight.BOLD;//粗体

            font1.FontHeightInPoints = 12;//字体大小
            style1.SetFont(font1);
            style1.WrapText = false;
            style1.Alignment = HorizontalAlignment.LEFT;
            HSSFRow row1 = (HSSFRow)worksheet.CreateRow(1);
            //写入字段
            for (int i = 0; i < dt.Columns.Count; i++)
            {
                HSSFCell cell1 = (HSSFCell)row1.CreateCell(i);//创建单元格
                cell1.SetCellValue(dt.Columns[i].ColumnName);
                cell1.CellStyle = style1;
            }

            for (int r = 0; r < dt.Rows.Count; r++)
            {
                HSSFRow rowr = (HSSFRow)worksheet.CreateRow(r + 2);
                for (int c = 0; c < dt.Columns.Count; c++)
                {
                    HSSFCell cell2 = (HSSFCell)rowr.CreateCell(c);//创建单元格
                    var aa = dt.Columns[c].DataType.ToString();
                    var cellvalue = dt.Rows[r][dt.Columns[c].ColumnName].ToString();
                    #region
                    switch (dt.Columns[c].DataType.ToString())
                    {
                        case "System.String"://字符串类型
                            cell2.SetCellValue(cellvalue);
                            break;
                        case "System.Nullable`1[System.DateTime]"://日期类型
                        case "System.DateTime":
                            DateTime dateV;
                            DateTime.TryParse(cellvalue, out dateV);
                            cell2.SetCellValue(cellvalue);
                            break;
                        case "System.Boolean"://布尔型
                            bool boolV = false;
                            bool.TryParse(cellvalue, out boolV);
                            cell2.SetCellValue(cellvalue);
                            break;
                        case "System.Int16"://整型
                        case "System.Int32":
                        case "System.Int64":
                        case "System.Byte":
                            int intV = 0;
                            int.TryParse(cellvalue, out intV);
                            cell2.SetCellValue(cellvalue);
                            break;
                        case "System.Decimal"://浮点型
                        case "System.Double":
                            double doubV = 0;
                            double.TryParse(cellvalue, out doubV);
                            cell2.SetCellValue(cellvalue);
                            break;
                        case "System.DBNull"://空值处理
                            cell2.SetCellValue("");
                            break;
                        default:
                            cell2.SetCellValue("");
                            break;
                    }

                    #endregion
                }
            }

            try
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    workbooks.Write(ms);
                    ms.Flush();
                    ms.Position = 0;
                    worksheet.Dispose();
                    workbooks.Dispose();

                    byte[] data = ms.ToArray();
                    GC.Collect();
                    return data;
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteExceptionLog(MethodBase.GetCurrentMethod(),ex);
                return null;
            }
        }

Ok,我们看一下效果

打开Excel,结果如下,样式没有细调。

最后祝大家在新的一年里一顺百顺事事顺,欢天喜地迎新年。

时间: 2024-08-03 11:11:32

ASP.NET MVC4+BootStrap 实战(十)的相关文章

ASP.NET MVC4+BootStrap 实战(十二)

最近实在是太忙,没时间写博客,只能夜里等孩子睡着了再写.感觉最近一个月又是在浪费时间,心里万分焦急.感觉自己的技术还不行,但是却没有时间去加强.吉日嘎啦的<程序员你伤不起>一书中讲到要孩子要晚了的坏处,比如自己30岁要的孩子,自己60岁了,孩子都30岁了,可能谁也照顾不上谁.其实我想说的是生早了也同样有坏处,比如现在只能晚上12点后写博客写程序. 好了,不多说了,来点高兴的,第一次也是第一个获得组内季度之星奖杯的我,终于觉得自己这三个月来当Master并且承担Coding任务的艰辛得到了很好的

ASP.NET MVC4+BootStrap 实战(十四)

今年没涨工资,心里些许有些不爽.看了吉日嘎拉写的<程序员你伤不起>,觉得自己的经历和老吉比起来,还是相差甚远.心里的那些不爽也渐渐的没了,人一生也就短短的这么几十年,何必把自己搞的不高兴,心情郁闷,要学会自己调节.那些当和尚的,一辈子也就那么回事,开法拉利天天泡妞的也不就那么回事.最终都是一个结局,那就是从哪里来到哪里去.人生来,汲取大自然的各种化学元素保持生命,人死后,将汲取的化学元素再还给大自然.也许被动物吃了,也许被植物吸收了.大家有时间还是要看一下吉日嘎啦的这本书,人家现在可是年薪80

ASP.NET MVC4+BootStrap 实战(二)

上一篇文章我们讲述了页面初始加载数据的一些东西,本篇我们来讲一下查询按钮和分页按钮.在很久以前我写过一篇ASP.NET MVC4切近实战的文章,有关于分页的代码,本篇我们不采用微软的AJAX框架. 先看一下查询效果,在点击Get按钮之后,会进行AJAX请求. js代码如下 jQuery(document).ready(function () {     setRowBackColor();     $("#btnsearch").click(function () {         

ASP.NET MVC4+BootStrap 实战(六)

最近面试了一个西安电子科技大学刚毕业的,不是计算机系毕业,却喜欢编程.除了书本上的知识以外,其他一窍不通,笔试题答得不错.经验欠佳,编程也只懂书本上的一些例子.本来不打算录用,但是后来聊到高等数学和物理是她学的最好的两门,那必须收下.人家都说了能考上西电,就能证明她的学习能力,我和项目经理也就相信人家了.毕竟当年面试的时候我面试的是南京擎天科技,有个西电的面试的是南京联创,人家和我聊了两句,得知我是二本院校的,人家说了句他同学面试的都是腾讯,阿里,百度,新浪,说完直接放弃面试,我去南京擎天还害怕

ASP.NET MVC4+BootStrap 实战(七)

连续三年年会中奖,第一年二等奖,价值2600元的魔音耳机,到现在才用了10几次.第二年中了个价值260元的飞利浦烧水壶,到现在还没用.今年中了个飞利浦挂烫机,也没查是多少钱,反正觉得奖项一年不如一年.在此我就给大家上一张年会热图. 男人的肚皮舞,嗨爆全场.好了,废话不多说,我们进入正题吧. 今天我们要说的就是主页面以及用户注册界面,功能做的都比较简单,我们先看一下Index界面. <div id="div_navigation" style="margin-top:10

ASP.NET MVC4+BootStrap 实战(三)

上节我们剩余Compare和Fix按钮没有讲,本节我们就来讲一下Compare按钮的功能,年底了,要开年会了,一个个积极的跟邱少云似得,给员工涨工资的时候能不能也积极点.不说了,说多了都是泪. 还记得我之前写的大数据实战之环境搭建,我们今天主要是拿DB的数据和solr的数据作比较,得出比较结果.首先,先启动centOS,启动tomcat,这样我们才能利用SolrNet调用solr公开的API.关于solr的启动再次我就不再赘述. OK,我们将solr实例启动起来后,用firefox浏览管理界面,

[转]ASP.NET MVC4+BootStrap 实战(一)

本文转自:http://leelei.blog.51cto.com/856755/1587301 好久没有写关于web开发的文章了,进到这个公司一直就是winform和Silverlight,实在是没有实战web项目的机会.大D也辞职了,去搞web app了.自己也该闲暇时间多学习学习,每天进步一点点. OK,不多说了,看一下Solution的截图 基本上一看就明白了,控制器调用Biz层,Biz层调用DAL层,DAL层进行数据的CURD.Utility是一些公用的类库.ok,为什么程序集的命名都

ASP.NET MVC4+BootStrap 实战(八)

今天西安下雪了,贼冷,我去.今年的年终奖还没发,都快揭不开锅了. 今天的话我们来看一下用户删除和修改,天太冷,先调一下胃口,上图,无图无真相. 看到了吧,新增了选择列,操作列,以及页面最下面的全选,反选,新增,删除按钮. 我们先来看一下全选反选吧,经过修改之后,我们的Table变成如下的代码 <table class="table table-bordered table-striped table-hover" ng-init="load()">   

ASP.NET MVC4+BootStrap 实战(九)

哄孩子睡觉哄到现在,要两个孩子真的是不容易.孩子不睡觉,我没办法写博客.孩子睡着了,我一写就要写到半夜2点.6点起床,6:30骑自行车去上班,呼吸着雾霾,头皮冻得僵硬.到了软件园楼底下,还要排队买胡辣汤,排队上电梯.唉,生活不易. 今天,我们要说的当然是用户信息修改,请看下图. 看到一龙了么,重庆功夫盛典和日本变装拳手战成平手,打裂了日本拳手的眉骨.OK,我们点击铅笔,弹出用户信息修改界面.那么,我们在弹出用户信息修改界面之前,先要给弹出界面的form赋值.那么这一步要怎么做,当然了,是使用an