DCSIMG
Expand and Collapse asp.net TreeView using javascript - שלמה גולדברג (הרב דוטנט)

שלמה גולדברג (הרב דוטנט)

מרצה בסלע ויועץ בעולם ה - net.

Expand and Collapse asp.net TreeView using javascript

 

אנחנו מקימים כעת בסלע תת אתר חדש לרישום סטודנטים להסמכות.
 
באחד הדפים הפנימיים רצינו להשתמש ב - TreeView Control שקיים ב - Asp.net,
 
כשרצינו לבצע Collapse All ו - Expand All ל - tree, גילינו שיש לו פונקציות שיודעות לבצע את זה אבל זה בצד השרת, וזה לא נשמע לי הגיוני לללכת לשרת כדי לסגור או לפתוח את ה - tree,
 
ולכן בקשתי מאחי יוסי גולדברג לכתוב פונקציית java script שיודעת לפתוח ולסגור את ה - tree view,
 
הוא עשה עבודה מצויינת, וכתב קובץ JS שמכיל את הפונקציות הנדרשות, ואז חשבתי לעצמי למה שלא נירש מ - treeView ונוסיף את היכולת של להרחיב ולכווץ את ה - tree מ - java script,
 
אחרי שכתבתי את ה - control, יצרתי פרויקט ב - CodePlex בשם - AspNetControls (איך השם לא היה תפוס ?) את הפרויקט עצמו אפשר להוריד מכאן.
 
ואני אשמח לתת הרשאות לכל מי שרוצה להוסיף Controls לפרויקט. (אני מקווה שאני יוסיף לפרוייקט עוד controls)
 
 
הנה הקוד + הסברים (אחרי הקוד)
 
 

[assembly: WebResource(CollapseExpandTreeView.JS_URL, "text/javascript", PerformSubstitution = true)]

 

namespace Controls.CollapseExpandTreeView

{

    public class CollapseExpandTreeView : TreeView

    {

        #region Private Properties

        private HtmlInputButton Expand { get; set; }

        private HtmlInputButton Collapse { get; set; }

        #endregion

 

        #region Const

        private const string CSS_CLASS_EXPAND = "CssClassExpand";

        private const string CSS_CLASS_COLLAPSE = "CssClassCollapse";

        private const string EXPAND_TEXT = "ExpandText";

        private const string COLLAPSE_TEXT = "CollapseText";

        internal const string JS_URL = "Controls.CollapseExpandTreeView.ExpandCollapse.js";

        #endregion

 

        #region Ctor

        public CollapseExpandTreeView()

        {

            Expand = new HtmlInputButton();

            Collapse = new HtmlInputButton();

 

            ExpandText = "Expand All";

            CollapseText = "Collapse All";

        }

        #endregion

 

        #region Method

 

        /// <summary>

        /// Return string value from ViewState

        /// </summary>

        /// <param name="key">The key in The ViewState</param>

        /// <returns></returns>

        private string GetFromViewState(string key)

        {

            string s = (string)ViewState[key];

            return ((s == null) ? String.Empty : s);

        }

 

        /// <summary>

        /// Return string value of property that locate in the base type and it is not public

        /// </summary>

        /// <param name="propName">The property name</param>

        /// <returns></returns>

        private string GetValueFromReflaction(string propName)

        {

            Type type = GetType().BaseType;

            PropertyInfo pi = type.GetProperty(propName, BindingFlags.Instance | BindingFlags.NonPublic);

            object value = pi.GetValue(this, null);

            return value.ToString();

        }

 

        /// <summary>

        /// Gets the Expand Image Url

        /// </summary>

        private string ExpandImageUrlInternal

        {

            get

            {

                string url = GetValueFromReflaction("ExpandImageUrlInternal");

                if (url == "")

                {

                    // The default expand image url

                    url = "/WebResource.axd?d=wheI3Jge_pneveLkEraSoYxlmKNnqYa0X1_njXGO0bg1&t=633744831123074071";

                }

 

                return url;

            }

        }

 

        /// <summary>

        /// Gets the Collapse Image Url

        /// </summary>

        private string CollapseImageUrlInternal

        {

            get

            {

                string url = GetValueFromReflaction("CollapseImageUrlInternal");

                if (url == "")

                {

                    // The default collapse image url

                    url = "/WebResource.axd?d=wheI3Jge_pneveLkEraSoeJ2AkLjYF7aizzZ7NzLi441&t=633744831123074071";

                }

                return url;

            }

        }

 

        #endregion

 

        #region Public Properties

        [Category("Collapse Expand")]

        [Description("Css Class for the expand button")]

        public string CssClassExpand

        {

            get

            {

                return GetFromViewState(CSS_CLASS_EXPAND);

            }

            set

            {

                ViewState[CSS_CLASS_EXPAND] = value;

            }

        }

 

        [Category("Collapse Expand")]

        [Description("Css Class for the collapse button")]

        public string CssClassCollapse

        {

            get

            {

                return GetFromViewState(CSS_CLASS_COLLAPSE);

            }

            set

            {

                ViewState[CSS_CLASS_COLLAPSE] = value;

            }

        }

 

        [Category("Collapse Expand")]

        [Description("Text for the expand button")]

        [DefaultValue("Expand All")]

        public string ExpandText

        {

            get

            {

                return GetFromViewState(EXPAND_TEXT);

            }

            set

            {

                ViewState[EXPAND_TEXT] = value;

            }

        }

 

        [Category("Collapse Expand")]

        [Description("Text for the collapse button")]

        [DefaultValue("Collapse All")]

        public string CollapseText

        {

            get

            {

                return GetFromViewState(COLLAPSE_TEXT);

            }

            set

            {

                ViewState[COLLAPSE_TEXT] = value;

            }

        }

        #endregion

 

        #region Override

 

        protected override void Render(HtmlTextWriter writer)

        {

            // Add the data for the collapse button

            Collapse.Attributes["class"] = CssClassCollapse;

            Collapse.Value = CollapseText;

            // Register the onclick evenr to the ChnageTreeViewStatus function

            Collapse.Attributes["onclick"] = string.Format("ChnageTreeViewStatus('{0}', '{1}')", ClientID, CollapseImageUrlInternal);

 

            // Add the data for the expand button

            Expand.Attributes["class"] = CssClassExpand;

            Expand.Value = ExpandText;

            // Register the onclick evenr to the ChnageTreeViewStatus function

            Expand.Attributes["onclick"] = string.Format("ChnageTreeViewStatus('{0}', '{1}')", ClientID, ExpandImageUrlInternal);

 

            // Start rendering the tree

            // we render a table with two rows, in the first row we render two cells, in each cell we render one button,

            // and in other row we render a cell with the tree.

            writer.RenderBeginTag(HtmlTextWriterTag.Table);

            writer.RenderBeginTag(HtmlTextWriterTag.Tr);

            writer.RenderBeginTag(HtmlTextWriterTag.Td);

            Expand.RenderControl(writer);

            writer.RenderEndTag();  //HtmlTextWriterTag.Td

            writer.RenderBeginTag(HtmlTextWriterTag.Td);

            Collapse.RenderControl(writer);

            writer.RenderEndTag();  //HtmlTextWriterTag.Td

            writer.RenderEndTag();  //HtmlTextWriterTag.Tr

            writer.RenderBeginTag(HtmlTextWriterTag.Tr);

            writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "2");

            writer.RenderBeginTag(HtmlTextWriterTag.Td);

            base.Render(writer);

            writer.RenderEndTag();  //HtmlTextWriterTag.Td

            writer.RenderEndTag();  //HtmlTextWriterTag.Tr

            writer.RenderEndTag();  //HtmlTextWriterTag.Table

        }

 

        protected override void OnPreRender(EventArgs e)

        {

            // Register the ExpandCollpase.js in the page

            Page.ClientScript.RegisterClientScriptResource(GetType(), JS_URL);

 

            base.OnPreRender(e);

        }

        #endregion

    }

}

 
 
הסברים:
 
בהתחלה אנחנו רושמים את קובץ ה - JS כ - WebResource של ה - assembly (הקובץ מסומן כ - Embedded Resource)
 
אנחנו מחזיקים שני HtmlInputButton וב - Ctor אנחנו מייצרים אותם, ונותנים למאפיינים את הערך ברירת מחדל.
 
שני המאפיינים -  ExpandImageUrlInternal ו - CollapseImageUrlInternal מחזירים את ה - ImageUrl שלהם על ידי Reflection, אנחנו צריכים אותם היות וה - TreeView ב - JS יש לו מתודה של - Toggle, והוא אינו מחזיק את המצב של ה - Node, ולכן כדי לדעת האם צריך להחליף את המצב, אני צריך לשלוח את ה - Url של התמונה כדי לבדוק מול זה האם צריך להפעיל את ה - Toggle.
 
לאחריו יש מספר מאפיינים עבור הלחצנים, (Css  ו - Text)
 
במתודת ה - PreRender אנחנו רושמים לדף את קובץ ה - JS
 
ובמתודת ה - Render אנחנו מייצרים טבלה שבשורה הראשונה אנחנו מיצרים שני עמודות ובכל עמודה אחד מהלחצנים, ובשורה השנייה את ה - Tree.
השורה החשובה ב - Render היא הרישום ל - onclick של הלחצנים.
 
 

Collapse.Attributes["onclick"] = string.Format("ChnageTreeViewStatus('{0}', '{1}')", ClientID, CollapseImageUrlInternal)

 
כעת נראה את קובץ ה - JS
 
 

// Collapse or Expand all nodes/

// param: treeId - The id of the treeView to perform the operation

// param: imgUrl - The Collapse or Expand image url, if send the Collapse image, then all nodes will collapse

function ChnageTreeViewStatus(treeId, imgUrl) {

 

    // Get all nodes ids that have children

    var parentIds = GetAllParentIds(treeId);

 

    for (var i = 0; i < parentIds.length; i++) {

 

        // Get the iamge of each node

        var parentImg = GetParentImg(treeId, parentIds[i]);

 

        // If the mode image is the same like imgUrl, we need to toggle

        if (parentImg.src.indexOf(imgUrl) > -1) {

 

            // Get the node object

            var parent = GetParentObject(treeId, parentIds[i]);

            // Get the child node object (to send as parameter for ToggleNode function)

            var childe = document.getElementById(GetChildeId(treeId, parentIds[i]));

            // Get the TreeView javascript object

            var obj = eval(treeId + "_Data");

 

            // Perform the ToggleNode function

            TreeView_ToggleNode(obj, treeId[i], parent, ' ', childe);

        }

    }

}

 

function GetParentImg(treeId, nodeId) {

    var node = GetParentObject(treeId, nodeId);

    var imgNode = node.getElementsByTagName('img');

 

    return imgNode.length > 0 ? imgNode[0] : null;

}

 

function GetParentObject(treeId, nodeId) {

    var id = treeId + 'n' + nodeId;

    return document.getElementById(id);

}

 

function GetChildeId(treeId, NodeId) {

    return treeId + 'n' + NodeId + 'Nodes';

}

 

function GetAllParentIds(treeId) {

    var aElements = document.getElementById(treeId).getElementsByTagName('a');

    var parentIds = new Array();

    var j = 0;

 

    for (var i = 0; i < aElements.length; i++) {

        if (aElements[i].id.indexOf('Nodes') < 0 && aElements[i].id.indexOf(treeId + 'n') > -1) {

            parentIds[j] = aElements[i].id.substr(treeId.length + 1);

            j++;

        }

    }

    return parentIds;

}

 
הפונקציה הראשית ChangeTreeViewStatus מקבלת את ה - Id של ה - tree view ואת התמונה שלפיה אנחנו יודעים מה לעשות.
 
אנחנו מקבלים את כל ה - nodes שיש להם ילדים.
 
בודקים האם התמונה שלהם היא אותו תמונה שקבלנו.
 
נמצא את האובייקט ונפעיל עליו את המתודה Toggle_Node.

תוכן התגובה

Rotem Bloom כתב/ה:

נראה מאוד נחמד וגם שימושי רק יש טעות כתיב ב:

ChnageTreeViewStatus

ה-change כתוב לא נכון chnage

אבל שטויות :-)

# June 7, 2009 4:56 PM

Shlomo כתב/ה:

תודה אני אתקן

# June 7, 2009 9:16 PM

יבגני כתב/ה:

אחלה פוסט

# November 11, 2010 8:14 AM

אלדר כתב/ה:

שאלות לא כל-כך קשורות:

1. האם TreeView מתאים גם לעץ אפשרויות שאינם דפים שונים באתר אלא בקשות שונים לנתונים שמתקבלות כולן בדף אחד? אם-כן איך עושים זאת? אם-לא איזה פקד כן מתאים לכך?

2.

# November 22, 2011 11:53 PM

Shlomo כתב/ה:

לא כל כך הבנתי את השאלה - אתה מוזמן לפנות אלי דרך דף צור קשר

# November 23, 2011 7:54 AM
שלח תגובה

(שדה חובה)  

(שדה חובה)  

(אופציונלי)

(שדה חובה) 

Please add 3 and 1 and type the answer here:


Enter the numbers above: