نمایش درختی (Tree View) با استفاده از Bootstrap در MVC

دوشنبه 2 آذر 1394

در این مقاله قصد داریم نشان دهیم چگونه می توان با استفاده از Bootstrap در MVC یک نمایش درختی پدر/فرزند ایجاد کنیم. این روش کاربردی را با پیاده سازی یک مثال نشان خواهیم داد .

نمایش درختی (Tree View) با استفاده از  Bootstrap  در MVC

 در این مقاله قصد داریم نشان دهیم چگونه می توان با استفاده از Bootstrap در  MVC یک نمایش درختی پدر/فرزند ایجاد کنیم. این روش کاربردی را با پیاده سازی یک مثال  که دارای اشیاء پدر است نشان خواهیم داد . شیء پدر با اشیاء فرزندان همراه خواهد شد.

این مثال دربردارنده نویسندگان و کتابهایشان خواهد بود.

یک پروژه  MVC ایجاد کرده و دو کلاس با نام های  AuthorViewModel و BookViewModel ایجاد کنید. AuthorViewModel کلاس اصلی است که با کلاس  BookViewModel پیوستگی دارد. به عبارت دیگر شی از کلاس AuthorViewModel یک لیست از اشیاء کلاس BookViewModel دارد. کد زیر را در کلاس  BookViewModel  اضافه کنید.

    namespace TreeView.Models   
    {  
        public class BookViewModel   
        {  
            public long Id   
            {  
                get;  
                set;  
            }  
            public string Title   
            {  
                get;  
                set;  
            }  
            public bool IsWritten   
            {  
                get;  
                set;  
            }  
        }  
    }   

کد زیر برای کلاس  AuthorViewModel است.

    using System.Collections.Generic;  
      
    namespace TreeView.Models {  
        public class AuthorViewModel   
        {  
            public AuthorViewModel()   
            {  
                BookViewModel = new List < BookViewModel > ();  
            }  
            public int Id   
            {  
                get;  
                set;  
            }  
            public string Name   
            {  
                get;  
                set;  
            }  
            public bool IsAuthor   
            {  
                get;  
                set;  
            }  
            public IList < BookViewModel > BookViewModel   
            {  
                get;  
                set;  
            }  
        }  
    }   

اکنون یک کنترلر با نام  Home  ایجاد میکنیم که دو متد  Get  و Post دارد.  متد Get هر زمان که متد Post داده های ارسال شده را از رابط کاربری بگیرد یک نمایش درختی بر میگرداند. کدهای زیر در HomeController قرار میگیرند.

    using System.Collections.Generic;  
    using System.Linq;  
    using System.Web.Mvc;  
    using TreeView.Models;  
      
    namespace TreeView.Controllers  
    {  
        public class HomeController : Controller  
        {  
            [HttpGet]  
            public ActionResult Index()  
            {  
                List<AuthorViewModel> model = new List<AuthorViewModel>();  
      
                AuthorViewModel firstAuthor = new AuthorViewModel  
                {  
                    Id = 1,  
                    Name = "John",  
                    BookViewModel = new List<BookViewModel>{  
                        new BookViewModel{  
                            Id=1,  
                            Title = "JQuery",  
                            IsWritten = false  
                        }, new BookViewModel{  
                            Id=1,  
                            Title = "JavaScript",  
                            IsWritten = false  
                        }  
                    }  
                };  
      
                AuthorViewModel secondAuthor = new AuthorViewModel  
                {  
                    Id = 2,  
                    Name = "Deo",  
                    BookViewModel = new List<BookViewModel>{  
                        new BookViewModel{  
                            Id=3,  
                            Title = "C#",  
                            IsWritten = false  
                        }, new BookViewModel{  
                            Id=4,  
                            Title = "Entity Framework",  
                            IsWritten = false  
                        }  
                    }  
                };  
                model.Add(firstAuthor);  
                model.Add(secondAuthor);  
                return View("Index", model);  
            }  
      
            [HttpPost]  
            public ActionResult Index(List<AuthorViewModel> model)  
            {  
                List<AuthorViewModel> selectedAuthors = model.Where(a => a.IsAuthor).ToList();  
                List<BookViewModel> selectedBooks = model.Where(a => a.IsAuthor)  
                                                    .SelectMany(a => a.BookViewModel.Where(b => b.IsWritten)).ToList();  
                return View();  
            }  
        }  
    }  

این کد نشان می دهد که چگونه کتابها با نویسندگان در متد Get ارتباط پیدا میکنند و چگونه گره های انتخاب شده درخت در درخواست Post گرفته می شوند.

 Bootstrap  به پروزه شما اضافه شده است اما یک  CSS سفارشی جدید برای طراحی نمایش درخت می نویسیم. کد های زیر برای این CSS است. 

.tree li {  
    margin: 0px 0;    
    list-style-type: none;  
    position: relative;  
    padding: 20px 5px 0px 5px;  
}  
  
.tree li::before{  
    content: '';  
    position: absolute;   
    top: 0;  
    width: 1px;   
    height: 100%;  
    right: auto;   
    left: -20px;  
    border-left: 1px solid #ccc;  
    bottom: 50px;  
}  
.tree li::after{  
    content: '';  
    position: absolute;   
    top: 30px;   
    width: 25px;   
    height: 20px;  
    right: auto;   
    left: -20px;  
    border-top: 1px solid #ccc;  
}  
.tree li a{  
    display: inline-block;  
    border: 1px solid #ccc;  
    padding: 5px 10px;  
    text-decoration: none;  
    color: #666;      
    font-family: 'Open Sans',sans-serif;  
    font-size: 14px;  
    font-weight :600;  
    border-radius: 5px;  
    -webkit-border-radius: 5px;  
    -moz-border-radius: 5px;  
}  
  
/*Remove connectors before root*/  
.tree > ul > li::before, .tree > ul > li::after{  
    border: 0;  
}  
/*Remove connectors after last child*/  
.tree li:last-child::before{   
      height: 30px;  
}  
  
/*Time for some hover effects*/  
/*We will apply the hover effect the the lineage of the element also*/  
.tree li a:hover, .tree li a:hover+ul li a {  
    background: #dd4814; color: #ffffff; border: 1px solid #dd4814;  
}  
/*Connector styles on hover*/  
.tree li a:hover+ul li::after,   
.tree li a:hover+ul li::before,   
.tree li a:hover+ul::before,   
.tree li a:hover+ul ul::before{  
    border-color:  #dd4814;  
}  
.tree-checkbox{  
    margin :4px !important;  
}  
  
   
.tree:before {  
    border-left:  1px solid #ccc;  
    bottom: 16px;  
    content: "";  
    display: block;  
    left: 0;  
    position: absolute;  
    top: -21px;  
    width: 1px;  
    z-index: 1;  
}  
  
.tree ul:after {  
    border-top: 1px solid #ccc;  
    content: "";  
    height: 20px;  
    left: -29px;  
    position: absolute;  
    right: auto;  
    top: 37px;  
    width: 34px;  
}  
*:before, *:after {  
    box-sizing: border-box;  
}  
*:before, *:after {  
    box-sizing: border-box;  
}  
.tree {  
    overflow: auto;  
    padding-left: 0px;  
    position: relative;  
} 

اکنون یک Index View را ایجاد میکنیم که در مرورگر ارائه شود و درخت را برای کتابها و نویسندگان نمایش دهد. کدهای زیر را درون  View قرار می دهیم.

@model List  
<TreeView.Models.AuthorViewModel>  
@section head{  
@Styles.Render("~/Content/css/tree.css")  
}  
  
  
    <div class="panel panel-primary">  
        <div class="panel-heading panel-head">Author Book Tree View</div>  
        <div id="frm-author" class="panel-body">  
@using (Html.BeginForm())  
{  
  
            <div class="tree">  
@for (int i = 0; i < Model.Count(); i++)  
{  
  
                <ul>  
                    <li>  
                        <a href="#">  
@Html.CheckBoxFor(model => model[i].IsAuthor, new { @class = "tree-checkbox parent", @id = @Model[i].Id })  
  
                            <label for=@i>  
                                <strong>Author:</strong>  
@Html.DisplayFor(model => model[i].Name)  
  
                            </label>  
                        </a>  
                        <ul>  
@for (int j = 0; j < Model[i].BookViewModel.Count(); j++)  
{  
int k = 1 + j;  
@Html.HiddenFor(model => model[i].BookViewModel[j].Id)  
  
                            <li>  
                                <a href="#">  
@Html.CheckBoxFor(model => model[i].BookViewModel[j].IsWritten, new { @class = "tree-checkbox node-item", @iid = i + "" + j })  
  
                                    <label for=@i@j>  
                                        <strong>Book @(k):</strong> @Html.DisplayFor(model => model[i].BookViewModel[j].Title)  
                                    </label>  
                                </a>  
                            </li>  
  
}  
  
                        </ul>  
                    </li>  
                </ul>  
}  
  
            </div>  
            <div class="form-group">  
                <div class="col-lg-9"></div>  
                <div class="col-lg-3">  
                    <button class="btn btn-success" id="btnSubmit" type="submit">  
Submit  
</button>  
                </div>  
            </div>  
}  
  
        </div>  
    </div>  
  
@section scripts{  
@Scripts.Render("~/Scripts/tree.js")  
} 

پس از آن یکی از بخش های مهم این مثال را ایجاد میکنیم. فایل JavaScript  با نام  tree.js را با استفاده از کدهای زیر ایجاد میکنیم.

    (function($)   
    {  
        function Tree() {  
            var $this = this;  
      
            function treeNodeClick()   
            {  
                $(document).on('click', '.tree li a input[type="checkbox"]', function() {  
                    $(this).closest('li').find('ul input[type="checkbox"]').prop('checked', $(this).is(':checked'));  
                }).on('click', '.node-item', function() {  
                    var parentNode = $(this).parents('.tree ul');  
                    if ($(this).is(':checked')) {  
                        parentNode.find('li a .parent').prop('checked', true);  
                    } else {  
                        var elements = parentNode.find('ul input[type="checkbox"]:checked');  
                        if (elements.length == 0) {  
                            parentNode.find('li a .parent').prop('checked', false);  
                        }  
                    }  
                });  
            };  
      
            $this.init = function() {  
                treeNodeClick();  
            }  
        }  
        $(function() {  
            var self = new Tree();  
            self.init();  
        })  
    }(jQuery))   

با توجه به کد بالا ، نمایش درخت امکانات زیر را دارا می باشد .

     1. زمانی که یک نویسنده والد را انتخاب میکنیم همه کتابهای آن انتخاب خواهند شد.

     2. زمانی که یک کتاب را انتخاب میکنیم ، نویسنده والد به صورت خودکار انتخاب خواهد شد.

     3. زمانی که همه کتابهای فرزند انتخاب شوند برای یک نویسنده والد انتنخاب شوند ، گره والد نیز انتخاب می شود.

     4. زمانی که گره والد انتخاب نشده است کتابهای فرزند نیز انتخاب شده نخواهند بود.

تصویر زیر خروجی برنامه می باشد.

آموزش بوت استرپ

فایل های ضمیمه

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید