среда, 23 марта 2011 г.

jQuery checkbox tree menu

Недавно был озадачен написанием древовидного меню с чекбоксами, структура которого «сидит» в БД. Поискав на просторах сети, наткнулся на то, что меня устраивало. Оставалось только допилить это дело, чтоб структура автоматически бралась из БД.
В одной из прошлых статей использовался пример с библиотекой. Воспользуемся им для построения меню.
Для получения данных о структуре меню на клиенте воспользуемся приемом из другой прошлой статьи. А именно возьмем данные из БД через http handler. Данные тоже запакуем в JSON. Код handler'а приведен в листинге 1.

Листинг 1 – Код handler'а для формирования JSON со структурой меню
<%@ WebHandler Language="C#" Class="Hierarchy" %>

using System;
using System.Web;
using System.Web.Script.Serialization;
using System.Web.Configuration;
using System.Data.SqlClient;
using System.Net;
using System.Collections.Generic;
using System.Runtime.Serialization.Json;
using System.IO;

public class Hierarchy : IHttpHandler {
   
    // получение структуры всех объектов для построения меню
    public void ProcessRequest (HttpContext context) {
        Dictionary<string, List<string>> obj = new Dictionary<string, List<string>>();
       
        string connString = WebConfigurationManager.ConnectionStrings["connString"].ConnectionString;
        using (SqlConnection con = new SqlConnection(connString))
        {
            string sql = "exec [dbo].p_Get_Hierarchy";

            SqlCommand cmd = new SqlCommand(sql, con);
            con.Open();
            using (SqlDataReader reader = cmd.ExecuteReader())
            {

                while (reader.Read())
                {
                    obj.Add(reader.GetString(0), new List<string>());

                    using (SqlConnection con1 = new SqlConnection(connString))
                    {
                        string sql1 = "exec [dbo].p_Get_Hierarchy_Stand '" +
                                       reader.GetString(0) + "'";

                        SqlCommand cmd1 = new SqlCommand(sql1, con1);
                        con1.Open();

                        using (SqlDataReader reader1 = cmd1.ExecuteReader())
                        {
                            while (reader1.Read())
                            {
                                obj[reader.GetString(0)].Add(reader1.GetString(0));
                            }
                        }
                        con1.Close();
                    }
                   
                }

            }
            con.Close();
        }

        JavaScriptSerializer s = new JavaScriptSerializer();
        string str = s.Serialize(obj);

        context.Response.ContentType = "text/plain";
        context.Response.Write(str);
        context.Response.End();
    }

    public bool IsReusable {
        get {
            return false;
        }
    }
}

Как видно из листинга, в нем используются две sql-процедуры для получения структуры меню. Их код приведен в листинге 2.

Листинг 2Sql-процедуры для получения структуры меню
CREATE PROCEDURE [dbo].p_Get_Hierarchy
AS
BEGIN
    SELECT DISTINCT l.Stand
    FROM dbo.t_Library l
END

CREATE PROCEDURE [dbo].p_Get_Hierarchy_Stand
                      @Stand nvarchar(64) = NULL
AS
BEGIN
    SELECT DISTINCT l.Author
    FROM dbo.t_Library l
    WHERE l.Stand = @Stand
END

Осталось только «поймать» эти данные на клиенте и построить по ним меню. Код построения меню приведен в листинге 3.

Листинг 3 – Построение меню
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
    <link rel="stylesheet" type="text/css" href="jquery.checkboxtree.min.css" />
    <script type="text/javascript" src="jquery.checkboxtree.min.js"></script>
   
    <script type="text/javascript" >
       
        function load()
        {
            // создаем меню
            $.getJSON('Hierarchy.ashx',  '', function(response)
            {
                // ловим json
                var json = eval(response);
               
                // формируем меню
                var html = '<ul id="tree6">';
                for (var n in json) { // Each top-level entry
                    html += '<li><input type="checkbox" id ="check">' + n + '<ul>';

                   
                    for (var i = 0; i < json[n].length; i++)
                    {
                        html += '<li><input type="checkbox"  class="checkbox" id="check">' + json[n][i] + '</li>';
                    }
                   
                    html += '</ul></li>';
                }
                html += '</ul>';
                $('#menu').append(html);
               
                $('#tree6').checkboxTree({
                    initializeChecked: 'expanded',
                    initializeUnchecked: 'collapsed'
                });
            });
        }
       
    </script>

Не забываем тэгу <body> создать на onload «повесить» функцию load().Вот и все. В принципе, все довольно просто. Результат на рисунке 1.


Рисунок 1 – Древовидное меню с чекбоксами

Комментариев нет: