jQuery.fill 数据填充插件

博客园的伙伴们,大家好,I‘m here,前段时间特别的忙,只有零星分散的时间碎片,有时候用来发呆,有时候用来写代码,正如下面给大家介绍的这个jQuery.fill插件,正是在这样的状态下写出来的。

主要功能

一直想要一个能解决前端拼接html代码的jQuery插件,但在网上搜来搜去都没找到满意的结果。还是老毛说的对,自己动手丰衣足食啊,设计的思路是通过在页面上排出模板,然后通过脚本向其填充数据,页面上的脚本不再关心版面的布局和样式,只关心数据,将数据从UI中分离出来,其主要的功能有:1、对DOM对象填充数据;2、将DOM对象反序列化为json对象;3、支持复杂的javascript对象提交至服务端;4、填充触发器和动作触发器,实现页面零脚本。

1、对DOM对象填充数据

fill方法向jQuery对象填充来自服务端的数据,服务端必须返回json格式的数据,来看一个栗子

html代码:

        <ul class="data1">
            <li class="fill-item">
                <label data-fill="name">bruce</label>:<span data-fill="title">hass</span>
                <span data-dateformat="{yyyy}年{MM}月{dd}日 星期{w:日,一,二,三,四,五,六},{hh}时{mm}分{ss}秒" data-fill="date">2014年12月26日 星期五,8时8分56秒</span>
                <div data-fill="books">
                    <h3>书籍</h3>
                    <div style="margin-bottom:1em;" class="fill-item">
                        <label data-fill="name">mvc 4.0</label>
                        作者:<span data-fill="author">feng</span>
                    </div><div style="margin-bottom:1em;" class="fill-item">
                        <label data-fill="name">jQuery 10</label>
                        作者:<span data-fill="author">Jonh</span>
                    </div><div style="margin-bottom:1em;" class="template">
                        <label data-fill="name">bruce</label>
                        作者:<span data-fill="author"></span>
                    </div>
                </div>
            </li>

            <li class="template">
                <label data-fill="name"></label>:<span data-fill="title"></span>
                <span data-fill="date"></span>
                <div>
                    <h3>书籍</h3>
                    <div class="template" style="margin-bottom:1em;">
                        <label data-fill="books.name"></label>
                        作者:<span data-fill="books.author"></span>
                    </div>
                </div>
            </li>
        </ul>

javascript代码:

        //填充来自数组模型
        var data = [{ "name": "kkkkkkkkk", "title": "hhhh", "date": "\/Date(1419466380000)\/", "books": [{ "name": "mvc 4.0 asdasd a", "author": "feng.wei.cai" }, { "name": "jQuery 10", "author": "Jonh" }] }, { "name": "bruce", "title": "hass", "date": "\/Date(1419552536000)\/", "books": [{ "name": "mvc 4.0", "author": "feng" }, { "name": "jQuery 10", "author": "Jonh" }] }, { "name": "jack", "title": "tit", "date": "\/Date(1419466380000)\/", "books": [{ "name": "mvc 4.0", "author": "feng" }, { "name": "jQuery 10", "author": "Jonh" }] }, { "name": "elon", "title": "boss", "date": "\/Date(1419466440000)\/", "books": [{ "name": "mvc 4.0", "author": "feng" }, { "name": "jQuery 10", "author": "Jonh" }] }]

        $(".data1").fill(
                data
                ,
                {

                    ///是否追加到列表上,默认是false
                    append: true
                  ,
                    ///自定义格式内容
                    formater: function (v,arg) {
                        if (arg.path == "date") {
                            v ="中文日期格式("+ v.getFullYear() + "年" + v.getMonth() + "月" + v.getDay() + "日)";
                        }
                        return v;
                    }
                    ,
                    ///填充完毕后执行的方法
                    complete: function () { alert("complete") }
                }
                )

脚本运行后的结果

<ul class="data1">
            <li class="fill-item">
                <label data-fill="name">bruce</label>:<span data-fill="title">hass</span>
                <span data-fill="date" data-dateformat="{yyyy}年{MM}月{dd}日 星期{w:日,一,二,三,四,五,六},{hh}时{mm}分{ss}秒">2014年12月26日 星期五,8时8分56秒</span>
                <div data-fill="books">
                    <h3>书籍</h3>
                    <div class="fill-item" style="margin-bottom:1em;">
                        <label data-fill="name">mvc 4.0</label>
                        作者:<span data-fill="author">feng</span>
                    </div><div class="fill-item" style="margin-bottom:1em;">
                        <label data-fill="name">jQuery 10</label>
                        作者:<span data-fill="author">Jonh</span>
                    </div><div class="template" style="margin-bottom:1em;">
                        <label data-fill="name">bruce</label>
                        作者:<span data-fill="author"></span>
                    </div>
                </div>
            </li>

            <li class="fill-item" style="">
                <label data-fill="name">kkkkkkkkk</label>:<span data-fill="title">hhhh</span>
                <span data-fill="date">中文日期格式(2014年11月4日)</span>
                <div>
                    <h3>书籍</h3>
                    <div style="margin-bottom: 1em;" class="fill-item">
                        <label data-fill="books.name">mvc 4.0 asdasd a</label>
                        作者:<span data-fill="books.author">feng.wei.cai</span>
                    </div><div style="margin-bottom: 1em;" class="fill-item">
                        <label data-fill="books.name">jQuery 10</label>
                        作者:<span data-fill="books.author">Jonh</span>
                    </div><div style="margin-bottom: 1em; display: none;" class="template">
                        <label data-fill="books.name"></label>
                        作者:<span data-fill="books.author"></span>
                    </div>
                </div>
            </li><li class="fill-item" style="">
                <label data-fill="name">bruce</label>:<span data-fill="title">hass</span>
                <span data-fill="date">中文日期格式(2014年11月5日)</span>
                <div>
                    <h3>书籍</h3>
                    <div style="margin-bottom: 1em;" class="fill-item">
                        <label data-fill="books.name">mvc 4.0</label>
                        作者:<span data-fill="books.author">feng</span>
                    </div><div style="margin-bottom: 1em;" class="fill-item">
                        <label data-fill="books.name">jQuery 10</label>
                        作者:<span data-fill="books.author">Jonh</span>
                    </div><div style="margin-bottom: 1em; display: none;" class="template">
                        <label data-fill="books.name"></label>
                        作者:<span data-fill="books.author"></span>
                    </div>
                </div>
            </li><li class="fill-item" style="">
                <label data-fill="name">jack</label>:<span data-fill="title">tit</span>
                <span data-fill="date">中文日期格式(2014年11月4日)</span>
                <div>
                    <h3>书籍</h3>
                    <div style="margin-bottom: 1em;" class="fill-item">
                        <label data-fill="books.name">mvc 4.0</label>
                        作者:<span data-fill="books.author">feng</span>
                    </div><div style="margin-bottom: 1em;" class="fill-item">
                        <label data-fill="books.name">jQuery 10</label>
                        作者:<span data-fill="books.author">Jonh</span>
                    </div><div style="margin-bottom: 1em; display: none;" class="template">
                        <label data-fill="books.name"></label>
                        作者:<span data-fill="books.author"></span>
                    </div>
                </div>
            </li><li class="fill-item" style="">
                <label data-fill="name">elon</label>:<span data-fill="title">boss</span>
                <span data-fill="date">中文日期格式(2014年11月4日)</span>
                <div>
                    <h3>书籍</h3>
                    <div style="margin-bottom: 1em;" class="fill-item">
                        <label data-fill="books.name">mvc 4.0</label>
                        作者:<span data-fill="books.author">feng</span>
                    </div><div style="margin-bottom: 1em;" class="fill-item">
                        <label data-fill="books.name">jQuery 10</label>
                        作者:<span data-fill="books.author">Jonh</span>
                    </div><div style="margin-bottom: 1em; display: none;" class="template">
                        <label data-fill="books.name"></label>
                        作者:<span data-fill="books.author"></span>
                    </div>
                </div>
            </li><li class="template" style="display: none;">
                <label data-fill="name"></label>:<span data-fill="title"></span>
                <span data-fill="date"></span>
                <div>
                    <h3>书籍</h3>
                    <div style="margin-bottom:1em;" class="template">
                        <label data-fill="books.name"></label>
                        作者:<span data-fill="books.author"></span>
                    </div>
                </div>
            </li>
        </ul>

通过这个栗子可以看出,简单的几行javascript代码就完成了一个列表的填充,其中需要注意的是在data1元素上定义了li.template节点作为填充模板,对应的数据由data-fill属性指定,是不是很简单呢!除了可以填充列表之外还可以填充表单、树形结构的列表,表格,同时也支持表格排序分页等功能,具体详细留意文章底部的Git项目地址,在Git项目中有更详细的API文档和演示栗子。

2、将DOM对象反序列化为json对象

前面介绍了由json对象的数据填充到DOM对象中,这一小节介绍它的反向操作,遗憾的是对于填充的列表暂时是不支持的,只支持PlainObject类型的数据或者表单,对于input[type=‘file‘]控件反序列化时会获取文件句柄,而不是文件的本地路径,除非浏览器不支持html5的File api,通过modelState方法实现反序列化,反序列化过程中支持验证,验证失败时将错误信息添加到返回结果的errors属性里面,下面来看一个栗子:

html 代码:

   <form action="/home/formPost">
                <h2>填充表单</h2>
                <div class="data2">

                    <div>
                        <label><input name="Gender" type="radio" value="true" />男 </label>
                        <label><input name="Gender" type="radio" value="false" />女 </label>
                    </div>
                    <div>
                        <label>name:</label><input name="name" required minlength="5" />
                    </div>
                    <div>
                        <label>title:</label><input name="title" />
                    </div>
                    <div>
                        <label>date:</label><input name="date" />
                    </div>
                    <h3>书籍</h3>
                    <div data-fill="book">
                        <div>
                            <label>name:</label><input name="book.name" />
                        </div>
                        <div>
                            <label>author:</label><input name="book.author" />
                        </div>
                        <input name="book.ID" type="hidden" value="52" />
                    </div>

                    <input name="ID" type="hidden" value="25" />
                </div>
       </form>

       <a href="javascript:" id="btnSubmit">提交</a>

javascript代码:

    $(‘#btnSubmit‘).click(function () {
                var frm = $(‘form‘), ms = frm.modelState();                console.debug(ms);
                ///如果没有错误
                if (!ms.errors) {
                    //提交表单
                    $.ajaxFormData(‘/home/formPost‘, {
                        data: ms.model, success: function (r) {
                            //在控制台中输出返回结果
                            console.debug(r);
                            ///清空表单
                            frm.clearModel();
                        }
                    })
                }

            })

调用modelState方法返回一个PlainObject对象,包含有errors属性和model属性,运行一下在firebug里面看它的值,如下:

errors属性是null 表示验证通过,来看一下为通过验证是怎么样子的,如下图:

由上图可以看出errors包含了错误信息的一个数组,数组的第一个元素的element指定了出错的控件(input[name=‘name‘]),labels包含错误标签正是this field is required,这个验证机制采用jQuery.validate的验证机制,具体用法请参照相关文档,当然modelState方法也支持自定义的验证处理函数,具体详细说明请参照Git说明里的文档。

3、支持复杂的javascript对象提交至服务端

可以将一个复杂的javascript对象提交至服务端,但在提交之前需要通过静态的toNameValues方法做一个转换,或者通过ajaxFormData方法提交数据,看来还是要弄个栗子才能讲得清道得明啊

javascript代码:

        //提交复杂的数据模型,转换成键值对,服务端可以直接使用mvc的默认模型绑定器
        $("#btnSubmit").click(function () {
            var model = {
                ids: [1, 5, 8, 45]
                    ,
                create: new Date("2011/4/25")
                ,
                children: [{ name: "hh", id: 54 }
                    , { name: "ccc", id: 545 }
                    , { name: "lll", id: 58, createdate: new Date("2015/1/29 15:25:59") }]
            };
            $.ajax({ url: "/home/Post", type: "POST", data: $.toNameValues(model) })
        });

服务端代码,这里用C#语言asp.net mvc的技术

namespace jQuery.Fill.Controllers
{
   //模型

    public class Aa {
        public int id { get; set; }
        public string name { get; set; }
        public DateTime CreateDate { get; set; }
    }
    public class KKK
    {
        public List<int> Ids { get; set; }
        public DateTime create { get; set; }
        public List<Aa> children { get; set; }
    }

    //控制器
   public class HomeController : Controller
    {
        /// <summary>
        /// 模型绑定器测试
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        //public ActionResult post(KKK entity)
        //{
        //    return Json(entity);
        //}

       public ActionResult post(int[] ids,DateTime create, List<Aa> children)
        {
            return Json(new { ids, create, children });
        }

    }

}    

javascript对象model通过toNameValues方法转换之后可以通过ajax提交到了服务端,与之对应的是服务端的KKK类型,服务端上有两个post方法,其中有一个被注释了,两个方法都能正常工作,直接使用默认的模型绑定器,简化了模型绑定的过程;还有一个静态的ajaxFormData方法,它ajax方法类似,但他可以提交文件,将字段转为FormData数据类型后提交,增加了progress事件,使你在提交一个表单的时候添加一个真实的酷炫的进度条,您可以到我的GIT项目里面下载演示栗子,这方法有个缺点是对于不支持html5的FormData类型的浏览器自动以传统的ajax方法提交。

4、填充触发器和动作触发器,实现页面零脚本

到目前为止无论是表单提交或者是数据填充,javascript代码都是简短的一句就完成了,其实还可以再少,甚至不用写javascript代码,使用这个插件的触发器就能做到,来看下面的栗子:

html代码:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>填充列表:分页和排序的测试</title>
    <link href="Content/bootstrap.min.css" rel="stylesheet" />
    <style>
        .loading {
            position:fixed;top:50%;left:50%;text-align:center;line-height:2em;margin-top:-1em;z-index:99999;display:none;font-size:25px;background-color:#0094ff;color:white;margin-left:-5em;padding:0 .25em;
        }
        .sort {position:relative;cursor:pointer;}
        .sort>.glyphicon,.sort.active.desc > .glyphicon-arrow-up  {display:none;}
        .sort.active > .glyphicon-arrow-up,.sort.active.desc > .glyphicon-arrow-down{display:inline-block;}
    </style>
</head>
<body>

    <table class="table" data-src="/Pagination/index" data-toggle="load" data-postparams="{pageSize:20}" data-options="{pager:true,loading:‘.loading‘,sort:true}">
        <thead>
            <tr class="thead">
                <th>#</th>
                <th class="sort active" data-sortexpression="Name">
                    书名
                    <span class="glyphicon glyphicon-arrow-down"></span><span class="glyphicon glyphicon-arrow-up"></span>
                </th>
                <th class="sort" data-sortexpression="Name">作者
                    <span class="glyphicon glyphicon-arrow-down"></span><span class="glyphicon glyphicon-arrow-up"></span></th>
                <th class="sort" data-sortexpression="Publisher">出版社
                    <span class="glyphicon glyphicon-arrow-down"></span><span class="glyphicon glyphicon-arrow-up"></span></th>
                <th>时间</th>
            </tr>
        </thead>
        <tbody>
            <tr class="template" style="display:none;">
                <td>
                    <label>
                        <input type="checkbox" data-fill="ID" />
                        <text data-fill="Number"></text>
                    </label>
                </td>
                <td data-fill="Name">书名</td>
                <td data-fill="Author">作者</td>
                <td data-fill="Publisher">出版社</td>
                <td data-fill="DateTime" data-dateformat="{yyyy}-{MM}-{dd} 星期{w:日,一,二,三,四,五,六},{hh}:{mm}:{ss}">时间</td>
            </tr>
        </tbody>
        <tfoot>
            <tr>
                <td colspan="5" style="text-align:center;">
                    <ul class="pagination" style="display:none;">
                        <li class="first">
                            <a href="javascript:">
                                <span aria-hidden="true">&laquo;</span>
                            </a>
                        </li>
                        <li class="number"><a href="javascript:"></a></li>
                        <li class="last">
                            <a href="javascript:">
                                <span aria-hidden="true">&raquo;</span>
                            </a>
                        </li>
                    </ul>
                </td>
            </tr>
        </tfoot>
    </table>
    <div class="loading">
        loading...
    </div>
    <script src="Scripts/jquery-1.10.2.min.js"></script>
    <script src="Scripts/jquery.fill.1.0-dev.js"></script>
</body>
</html>

注意在table元素上设置了触发器的配置: data-src="/Pagination/index" data-toggle="load" data-postparams="{pageSize:20}" data-options="{pager:true,loading:‘.loading‘,sort:true}" 关于触发器的配置请参照我的GIT项目。

服务端代码(C#语言asp.net mvc)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web;
using System.Web.Mvc;

namespace jQuery.Fill.Controllers
{
   //模型

    public class Book
    {
        public int ID { get; set; }
        public string Number { get; set; }
        public string Name { get; set; }
        public string Publisher { get; set; }
        public string Author { get; set; }
        public DateTime DateTime { get; set; }

        public static IEnumerable<Book> CreateList(int number)
        {
            if (number <= 0) { number = 10; }
            for (int i = 0; i < number; i++)
            {
                yield return new Book() { ID = i, Number = "00808" + i.ToString(), Author = "Author" + i, DateTime = DateTime.Now.AddHours(new Random(Guid.NewGuid().GetHashCode()).Next(100)*-1), Name = "BookName" + i, Publisher = "Publisher" + i };
            }
        }
    }

    //控制器
    public class PaginationController : Controller
    {
        IEnumerable<T> CreateOrderByQuery<T>(IQueryable<T> list, string sortExpression)
        {
            System.Diagnostics.Contracts.Contract.Requires(sortExpression != null);
            bool desc =(sortExpression= sortExpression.Trim()).EndsWith(" desc", StringComparison.OrdinalIgnoreCase);
            int len= sortExpression.LastIndexOf(‘ ‘);
            string sort = sortExpression.Substring(0, len < 0 ? sortExpression.Length : len);

            Type type = list.ElementType;
            var property = type.GetProperty(sort.Trim());
            var parameter = Expression.Parameter(type, string.Empty);
            var orderByExp = Expression.Lambda(Expression.MakeMemberAccess(parameter, property), parameter);
            MethodCallExpression resultExp = Expression.Call(typeof(Queryable)
                , desc ? "OrderByDescending" : "OrderBy"
                , new Type[] { type, property.PropertyType }
                , list.Expression, Expression.Quote(orderByExp));

            return list.Provider.CreateQuery<T>(resultExp);

        }
        // GET: Pagination
        public ActionResult Index(int pageSize = 10, int pageIndex = 0, string sortExpression=null)
        {
            //System.Threading.Thread.Sleep(1000);
            var data = Book.CreateList(100);
            var total = data.Count();

            if (!string.IsNullOrWhiteSpace(sortExpression))
            {
                data = CreateOrderByQuery<Book>(data.AsQueryable(), sortExpression);
            }

            return Json(new { rows = data.Skip(pageSize * pageIndex).Take(pageSize), pager = new { pageIndex = pageIndex, pageSize = pageSize, total, pageCount = total / pageSize + (total % pageSize > 0 ? 1 : 0) } });
        }
    }
}

在web前端您可以看到除了引用两个脚本文件之外,再也没有看到其他的javascript脚本了,这个页面实现了分页,排序等功能全部是通过ajax实现的,大大减少了web前端的工作量,正如董明珠说的那句广告词那样,用jQuery.fill,不用写代码,呵呵呵。。。(装逼一下)

GIT项目地址

好了又到了跟大家说再见的时候了,如果您对这个项目感兴趣可以到下面的地址下载源代码,项目还包含了api文档和栗子演示

https://github.com/JacksonBruce/UI

时间: 2024-12-28 11:12:18

jQuery.fill 数据填充插件的相关文章

使用jQuery将数据快速填充到表单

作为WEB程序员,我们经常与表单打交道.例如在通过表单编辑一些数据时,读取后台数据并填充到表单是一件繁琐的事情,尤其是表单域很多而且包含radio,checkbox,select等的时候.你一定见过下面的代码: <select name="area"> <option value="nankai" <?php if($area=='nankai') echo 'selected="selected"';?>>南

【ECharts】SSH+JQueryAjax+Json+JSP将数据库中数据填充到ECharts中

1导入包,搭建SSH框架. 导入JQuery的JS包,<script src="JS/jquery-1.7.1.js"></script> 导入ECharts的包.<script src="http://s1.bdstatic.com/r/www/cache/ecom/esl/1-6-10/esl.js"></script> 前提你的SSH已经搭好了,数据已经传递到了Struts层. 2在Action层,将数据封装成J

20+个很有用的 jQuery 的 Google 地图插件

Google 地图在寻找我们想要了解的商店或者其它有趣的地方这种用途方面很流行和实用. 地图被一些商店特地集成到了它们的网站上面,这样就可以让人们容易找到它们的所在. 尽管其并不容易被集成,Google 地图使用起来还是简单且引人注目的. 在你的站点上集成它需要一个漫长且复杂的过程. 但多亏了拥有一个许多实用Google地图插件资源库的jQuery. 你只需要将jQeury地图插件安装到你的站点上,然后就可以开始根据你的业务需要来设计简单但能吸引人的地图了. 在本文中,我会列出一堆实用的jQue

基于jquery的ajax分页插件(demo+源码)

前几天打开自己的博客园主页,无意间发现自己的园龄竟然有4年之久了.可是看自己的博客列表却是空空如也,其实之前也有写过,但是一直没发布(然而好像并没有什么卵用).刚开始学习编程时就接触到博客园,且在博客园学习了很多的知识,看过很多人的分享.说来也惭愧,自己没能为园友们分享自己的所学所得(毕竟水平比较差). 过去的一年也是辗转了几个城市换了几份工作(注定本命年不太平?).八月份来到现在所在的公司(OTA行业),公司是做互联网的,所以可能大家的前端都屌屌的?之前一直从事.NET开发(现在在这边也是),

支持多文件上传的jQuery文件上传插件Uploadify

支持多文件上传的jQuery文件上传插件Uploadify,目前此插件有两种版本即Flash版本和HTML5版本,对于HTML5版本会比较好的支持手机浏览器,避免苹果手机Safari浏览器不支持Flash,主要特性:支持多文件上传.HTML5版本可拖拽上传.实时上传进度条显示.强大的参数定制功能,如文件大小.文件类型.按钮图片定义.上传文件脚本等. Flash版本使用方法: 1.加载JS和CSS ? 1 2 3 <script src="jquery/1.7.1/jquery.min.js

强大的支持多文件上传的jQuery文件上传插件Uploadify

支持多文件上传的jQuery文件上传插件Uploadify,目前此插件有两种版本即Flash版本和HTML5版本,对于HTML5版本会比较好的支持手机浏览器,避免苹果手机Safari浏览器不支持Flash,主要特性:支持多文件上传.HTML5版本可拖拽上传.实时上传进度条显示.强大的参数定制功能,如文件大小.文件类型.按钮图片定义.上传文件脚本等. Flash版本使用方法: 1.加载JS和CSS ? 1 2 3 <script src="jquery/1.7.1/jquery.min.js

jQuery打造智能提示插件二(可编辑下拉框)

在上一篇 jQuery打造智能提示插件 上改进,增加下拉按钮,修复点击下拉区域外不隐藏BUG 效果 下拉按钮素材: js封装,注意红色部分为BUG修复,然后传入boxwidth不带px: /* /// <reference path="jquery-autocomplete2.0.js" /> zhangs 20140516 */ (function($) { $.fn.combox = function(options) { var KEY = { UP: 38, DOW

出位的template.js 基于jquery的模板渲染插件,简单、好用

找了好几款基于jquery的模板渲染插件,无一感觉很难用(教程较少.绑定不统一),也可能我智商问题,比如jquery template.js .jtemplate.js. 然后在github上找到这一款,和我在公司之前用的差不多(apicloud云端开发app,致敬[百小僧]大神封装的HUI,简化了在公司很多工作), 这款模板渲染和HUI的很相似,也比较简单  基于jquery的模板渲染插件. 附上github https://github.com/yanhaijing/template.js

C# 将Excel里面的数据填充到DataSet中

/// <summary> /// 将Excel表里的数据填充到DataSet中 /// </summary> /// <param name="filenameurl">Excel文件的路径(包含文件名)</param> /// <param name="table">Excel的文件名</param> /// <returns></returns> public st