Archive for the ‘jquery’ Category

最近花了一周搞定报表模块

report_list

报表列表

报表编辑

报表编辑

报表显示

报表显示

当任务布置下来的时候,我完全不知道报表是个啥东东。开始做的那个单表的完全就是自己yy出来的结果,最后不满意,只有重新做过。

思路简单也造成了这个报表模块功能的局限性。在写代码的过程中碰到了很多的问题,并一一解决掉。

这个模块使用两个表report_info和report_field。

report_info记录报表的基本信息,包括报表名称、说明、模板、建立的用户、创建时间等。

report_field通过report_id和report_info的id是关联字段,包括主要保存每个需要调出数据的sql语句。

report_field填写好的数据,通过模板上的[#keyword#]关键字来替换,就得到了一个简单的报表。

界面的问题

开始全部使用div,发现排版很乱,最后碰巧找到了<fieldset>这个不是很流行的标签。报表信息填写、sql语句生成、模板、已添加字段都有条不紊的排好了,<fieldset>里面放一个<legend> 就知道这个字段集合主要是用来做啥的了。

用javascript表单生成sql语句的问题

开始本来打算自己制作一个表单用来自动生成sql语句,但是后来越想越复杂,有and有or,多表的时候有left join,right join,full join,还有括号表示优先级,比如数据类型是数字还得验证、是日期类型至少也得弹出一个js的日期选择框吧。最后找到了codeslave哥写的highquery,这东西就是我所需要的,完全可以满足这个报表模块的需求,但是在后来发现了一个棘手的问题。highquery初始化的时候里面的字段列表是通过它自己写的Field对象new出来的。这样每次页面加载后,从request.querystring传过来的表名就固定了,无法动态的载入其他表单字段信息,最后只有弄成弹窗了。

级联下拉菜单问题

我使用级联下拉菜单来让用户选定需要查询指定表的指定字段的指定函数 比如db1.max(field1)。也需要通过无刷新页面取数据,所以临时看了一下jquery调用ajax的相关文章,下面这段代码用了一下午才憋出来,囧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    $("#selectTableInner").change(function(){
        var fieldName=this.options[this.selectedIndex].value;
        $.ajax({
            type    :"GET",
            url     :"getData.asp?table_name="+fieldName,
            dataType:"json",
            success :function(msg){  
                $("#selectFieldInner").empty();
                $("#selectTableInner option").each(function(i){  
                        selectFieldInner.options.add(new Option(msg.fieldlist[i].FIELD_ALIASES,msg.fieldlist[i].FIELD_NAME));
                });
            }
        });
        document.getElementById("condition_en").value="";
    });

还有一个javascript原生版本ajax

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
        sel.onchange=function(){
            var fieldName=this.options[this.selectedIndex].value;
            var url="getData.asp?table_name="+fieldName;
            if(window.ActiveXObject)
                xhr=new ActiveXObject("Microsoft.XMLHTTP");
            else if(window.XMLHttpRequest)
                xhr=new XMLHttpRequest();
            xhr.open("GET",url);
            xhr.onreadystatechange=callback;
            xhr.send(null);
        };
        function callback()
        {
            msg2=xhr.responseText;
            var func=new Function("return"+msg2);
            var json=func();
            var selectFieldInner=document.getElementById("selectFieldInner");
            for(i=0;i<json.fieldlist.length;i++){
                FieldList.add(new Field(json.fieldlist[i].FIELD_ALIASES,json.fieldlist[i].FIELD_NAME,'varchar','100','',''));
            }  
                   
        }

我是通过json格式来传输数据。在服务器端将asp对象转换成json对象又让我犯难了。找到了一个项目:aspjson,同时包含里面的JSON.asp和JSON_UTIL.asp 可以直接将sql执行出来的数据转换成json对象。因为javascript对json原生支持,所以javascript对json的访问也是非常简单的。因为aspjson是老外开发的,自称是支持unicode,但在写代码的时候出现asp下标越界错误。最后搞了半天找到原因,提交了一个issue,并被作者fixed了。很快,貌似他一直都在线,恩,是个宅男。

开网上的文章所jquery对象不能被赋值,最后在写代码的时候也出现这个问题。所在最后在包含了jquery.js的页面里面写了很多的getElementById(),代码混杂,这就是jquery没学好的后果。

接下来的博文我会将一些具体问题记录一下。

 

(function($){})(jQuery)含义

这里实际上是匿名函数

function(arg){…}
这就定义了一个匿名函数,参数为arg

而调用函数时,是在函数后面写上括号和实参的,由于操作符的优先级,函数本身也需要用括号,即:
(function(arg){…})(param)
这就相当于定义了一个参数为arg的匿名函数,并且将param作为参数来调用这个匿名函数

而(function($){…})(jQuery)则是一样的,之所以只在形参使用$,是为了不与其他库冲突,所以实参用jQuery

via

 

jquery.treeview插件绑定数据库(php+oracle)

公司的HOA系统有个人员组织选定的功能,用的是MzTreeView这个js库,后台的人员信息表也是根据MzTreeView来设计的,也就是任意一条记录有一个id来唯一标识这条记录和一个parentId来记录它的父节点。

mztreeview

最近在学习jquery,找到了很多实用的插件,比如今天要说的是jquery.treeview

打算将jquery.treeview插件绑定到数据库,从数据库中取数据,用的脚本是php,后台数据库将就系统本来的oracle。

在功能上其实mztreeview比jquery.treeview要强大一些,效率还高点。唯一好点就是js压缩后只有6k,而mztreeview有20多k。总之没事干,just 4 fun。

表结构:

Name Type Nullable Default Comments
————- ————- ——– ——- ——–
ID_ROLE NUMBER(10)
CHAR_ROLENAME NVARCHAR2(30)
INT_ROLETYPE NUMBER(10)
ID_UPLEVEL NUMBER(10)
CHAR_REMARK VARCHAR2(50) Y
B_DELETE NUMBER(2)
INT_ORDER NUMBER(10) Y
DEPT_CODE NVARCHAR2(30) Y ’se’

ID_ROLE是unique id,ID_UPLEVEL是parent id。

jquery下载下来之后,解压放到web目录,然后把下面的脚本文件放入demo目录。
php脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>

    <meta http-equiv="content-type" content="text/html; charset=gb2312"/>
    <title>treeview test on hoa</title>
   
    <link rel="stylesheet" href="../jquery.treeview.css" />
    <link rel="stylesheet" href="../red-treeview.css" />
    <link rel="stylesheet" href="screen.css" />
   
    <script src="../lib/jquery.js" type="text/javascript"></script>
    <script src="../lib/jquery.cookie.js" type="text/javascript"></script>
    <script src="../jquery.treeview.js" type="text/javascript"></script>
   
    <script type="text/javascript">
    $(document).ready(function(){
        $("#browser").treeview({  //调用jquery.tree的代码
            collapsed:true,  //默认把组织树收缩起来
        });
    });
    </script>
    </head>
    <body>
   
    <h1 id="banner"> Demo</h1>
    <div id="main">
    <ul id="browser" class="treeview-red">
    <?php

function read($uplevel){ //递归函数,用来遍历树
    $conn = oci_connect('ora_user', 'ora_pass', 'orcl');  
    if(!$conn)
    {
        print ("conn error");
    }
    $query = "SELECT * FROM sa_role where id_uplevel=".$uplevel." and b_delete='0' order by id_role";
    //echo $query;
    $stid = oci_parse($conn, $query);

    $r = oci_execute($stid, OCI_DEFAULT);
    while ($row = oci_fetch_array($stid, OCI_RETURN_NULLS))
    {  
        if($row[2]==2) //$row[2]是INT_ROLETYPE,2是下面有子节点,1是叶子(就是没有子节点的节点)
        {  
            print "<li> <span class=\"folder\">";
            print $row[1]."</span> \n"; //$row[1]是节点内容,这个字段是CHAR_ROLENAME
            print "\n\t<ul>";
            $uplevel=$row[0];
            read($uplevel); //再调用自己继续读节点
        }
        if($row[2]==1) //如果是叶子
        {  
           
            print "<li> <span class=\"file\">";
            print $row[1]."</span> ";
            print "</li>";  
        }
    }
    print "</ul>";
    oci_close($conn);
}
read(-1);//假设根节点id为-1
print "</li>";
?>
    </ul>  
    </div>
 
</body></html>

其中修改

1
<ul id="browser" class="treeview-red">

中class的值为treeview-red,treeview-default,treeview-black,treeview-gray,treeview-famfamfam,这些是jquery.treeview自带的样式。

可以在

1
2
        $("#browser").treeview({  
        });

中,可以加入参数自定义,具体参数用法参照:http://docs.jquery.com/Plugins/Treeview/treeview#options
参数解释:
animated: “fast” 树的展开速度为快
collapsed: true 收缩树的所有节点
unique: true 保持每次展开1个节点,关闭之前打开的兄弟节点
persist: “location” 把进入的节点位置通过url保存

1
2
3
4
        branches = $("<li class='closed'><span class='folder'>New Sublist</span><ul><li><span class='file'>Item1</span></li><li><span class='file'>Item2</span></li></ul></li>").prependTo("#folder21");
        $("#browser").treeview({
            add: branches
        });

插入新节点

persist: “cookie” 把进入的节点位置通过cookie保存,需要jquery插件jquery.cookie.js
cookieId: “treeview-black” 设置cookie名
control: “#treecontrol” 把树的控制交给id为treecontrol

toggle: function() {
window.console && console.log(“%o was toggled”, this);
}
设定一个交替函数

———
最后效果:
jquery.treeview.demo

这里只做到了树的查看,还有有些问题需要解决,比如节点插入,删除,编辑与数据库的交互,貌似需要用到牛逼的ajax。

 

基于jQuery的图片幻灯插件:soChange

介绍一个基于jquery的插件soChange,下载地址、demo、文档:

http://www.ceshile.cn/lxProject/ceshi/soChange/soChange.html

压缩后的js只有1.6k。其实不仅仅是一个图片切换,所有的对象都可以实现切换。

可以自定义是否自动切换,切换时间,鼠标悬停等待,自定义切换按钮,自定义缩略图,还有其他更多的能用到的地方需要用到css的一些页面特效技巧。

这是作者的主页:http://hi.baidu.com/bujichong