ASP .NET MVC 5’de Bootstrap ve KnockoutJS
Selamlar;
Öncelikle bu güzel tatil gününde herkesin bayramını kutlar, sağlık, esenlik ve huzur dolu nice bayramlar dilerim.
Bugün front-end web uygulamaları geliştirmede popüler ASP.NET MVC 5’de, Bootstrap ve KnockoutJS’in nasıl kullanıldığını hep beraber inceleyeceğız.
Twitter Bootstrap, biz web developerlara hatasız, güçlü ve kullanışlı bir HTML, CSS, JavaScript framework’ü sunar. Bu yapı günümüzde hali hazırdaki birçok browser ile uyumlu çalışır. Bootstarp kullanmanın en büyük avantajı, bize Form, Table, List gibi kullanıma hazır UI elemanları sağlamasıdır.
Bugünkü örneğimizde işe alım için başvuran kişilerin bilgilerini kaydettiğimiz bir form hazırlayacağız. Öncelikle aşağıdaki gibi PersonInformation tablosu oluşturulur.
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 |
USE [Survey] GO /****** Object: Table [dbo].[PersonInformation] Script Date: 09/20/2015 11:13:37 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET ANSI_PADDING ON GO CREATE TABLE [dbo].[PersonInformation]( [PersonID] [int] IDENTITY(1,1) NOT NULL, [FirstName] [varchar](50) NULL, [LastName] [varchar](50) NULL, [Address] [varchar](100) NULL, [City] [varchar](50) NULL, [PhoneNo] [varchar](50) NULL, [MobileNo] [varchar](50) NULL, [EmailAddress] [varchar](50) NULL, [Occupation] [varchar](50) NULL, CONSTRAINT [PK_PersonInformation] PRIMARY KEY CLUSTERED ( [PersonID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO SET ANSI_PADDING OFF GO |
Visual Studio 2015’de aşağıda görüldüğü gibi Asp.Net Web App boş bir Mvc projesi yaratılır.
Database işlemleri için Entity Framework ve CodeFirst kullanılmıştır. Solution’a aşağıdaki gibi bir DAL projesi yaratılıp eklenir.
PersonInformation poco’su aşağıdaki gibi oluşturulur.
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 |
namespace DAL { using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Data.Entity.Spatial; [Table("PersonInformation")] public partial class PersonInformation { [Key] public int PersonID { get; set; } [StringLength(50)] public string FirstName { get; set; } [StringLength(50)] public string LastName { get; set; } [StringLength(100)] public string Address { get; set; } [StringLength(50)] public string City { get; set; } [StringLength(50)] public string PhoneNo { get; set; } [StringLength(50)] public string MobileNo { get; set; } [StringLength(50)] public string EmailAddress { get; set; } [StringLength(50)] public string Occupation { get; set; } } } |
Şimdi form ekranları için yeni bir proje yaratıp, HTML UI için Knockout.js Javascript kütüpahanesini kullanacağız. KnockoutJs client side tarafta MVVM design patternini kullanan lightweight bir web arayüz aracıdır. NuGet’den aşağıdaki gibi indirilir.
Bootstarp ve Jquery Library de NuGet’den aşağıdaki gibi indirilir. Önemli bir nokta ben bootstrap package’ı indirdiğimde fontlar gelmedi. Sanırım bu ufak bir bug:) Bunun için bootstrap.com adresinden bootstrap’in son geçerli versiyonu v3.3.5’i indirilip, fonts altındaki tüm “glyphicons-halflings” ile başlıyan font dosyaları projedeki “Content” folder altına atılır. Böylece sayfada gelmeyen simgeler görünmeye başlar.
Şimdi geldik javascript tarafında KnockoutJs ile yazacağımız kodlara. Öncelikle aşağıdaki javascript kütüpahaneleri PersonInfo.js dosyasına eklenir.
1 2 |
/// <reference path="jquery-2.1.4.min.js" /> /// <reference path="knockout-3.3.0.js" /> |
Aşağıdaki kodda öncelikle bir ViewModel oluşturulur. Ve bu model sayfa yüklemesi tamamlandığında ($(document).ready()) durumunda bind edilir. “self” dediğimiz, ViewModel’in kendisidir. Belirlenen user propertyleri “self”‘e atanır. Daha sonra “PersonInfo”‘a ait tanımlanan dinamic propertyler’e ilgili ViewModel’deki değerler atanır. Böylece “Edit”, “Update” gibi işlemler için dönüş tipi “PersonalInfo” şeklinde belirlenmiş olunur. İlgili kişi üzerinde çalışalacağı zaman buna bind olan ViewModel ve ona bağlı olan PersonInfo bundan etkilenir.
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 |
(function () { var viewModel = function () { var self = this; var IsUpdatable = false; self.PersonID = ko.observable(0); self.FirstName = ko.observable(""); self.LastName = ko.observable(""); self.Address = ko.observable(""); self.City = ko.observable(""); self.PhoneNo = ko.observable(""); self.MobileNo = ko.observable(""); self.EmailAddress = ko.observable(""); self.Occupation = ko.observable(""); var PersonInfo = { PersonID: self.PersonID, FirstName: self.FirstName, LastName: self.LastName, Address: self.Address, City: self.City, PhoneNo: self.PhoneNo, MobileNo: self.MobileNo, EmailAddress: self.EmailAddress, Occupation: self.Occupation }; } $(document).ready(function () { ko.applyBindings(new viewModel()); }); })(); |
Script ilk yüklenirken “self”‘e yani ViewModel’e, dinamik yeni propertyler tanımlanırken default değerler aşağıdaki gibi atanır. Mesela “Persons”‘ın bir dizi olacağı “[]” ataması ile belirlenir. Ayrıca “Occupations” meslekler ve “City” array propertyleri dropdown olarak açılacak listeye datasource olması amaçlı default olarak doldurulan alanlardır. Ayrıca script ilk yüklendiğinde kayıtlı kişileri çekip listelemek için, “loadInformation()” methodu kullanılır. Ilgili method “GetPerson()”‘a request atarak “self.Persons” array property’sini doldurur. Bir önemli nokta da “SelectedOccupation” propertysi dir. Bu değişken, seçilen mesleği üzerine alır. Ve değişim durumunda, yani “subscribe” event’i tetiklenince, ilgili değişmiş değer “Occupation” değerine aşağıdaki gibi atanır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
self.Persons = ko.observable([]); self.Message = ko.observable(""); self.Occupations = ko.observable(["İşveren", "Mühendis", "Doktor", "Öğretmen", "Diğer"]); self.SelectedOccupation = ko.observable(); self.SelectedOccupation.subscribe(function (text) { self.Occupation(text); }); self.City == ko.observable(["İstanbul", "Ankara", "İzmir", "Bursa", "Trabzon", "Adana"]); loadInformation(); function loadInformation() { $.ajax({ url: "/Home/GetPerson/", type: "GET", }).done(function (resp) { self.Persons(resp); }).error(function (err) { self.Message("Error!" + err.status); }); } |
Şimdi sıra geldi seçilen bir kişinin ViewModel’e atanıp ilgili alanda gösterilmesine: (per) gelen kişi bilgilerini içeren yukarıda tanımladığımız “PersonInfo” sınıfına aittir. “modal(‘show’)” özelliğine bootstarp konusunda değineceğiz. “IsUpdatable” tanımlı değişkeni, ilgili PersonInfo’nun kaydetme durumunda “Update” mi “Insert” mü olucağına karar veren bir parametredir. Mesela burada “true” değeri atanmıştır. Çünkü edit işlemi gerçekleşecektir, yani databasede “Update” yapılacaktır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
self.getSelected = function (per) { self.PersonID(per.PersonID) self.FirstName(per.FirstName); self.LastName(per.LastName); self.Address(per.Address); self.City(per.City); self.PhoneNo(per.PhoneNo); self.MobileNo(per.MobileNo); self.EmailAddress(per.EmailAddress); self.SelectedOccupation(per.Occupation); IsUpdatable = true; $("#personPage").modal("show"); } |
İlgili PersonInfo sınıfının kaydetme işleminde “Update” mi “Insert” mü olacağının kararını yukarıda belirtiğimiz “IsUpdatable” parametresi ile belirleyip, Insert için “SavePerson()” “Update” için “UpdatePerson()” methodlarına, ilgili sınıf json olarak ajax “Post” edilmiştir. Her iki methodda da olumlu sonuçlanması durumunda, tüm kayıtlar tekrardan çekilip, ViewModel doldurulmuş ve bunu kullanan tüm elementler bundan etkilenerek ilgili datayı yapılan değişiklikle birlikte tekrardan göstermiştir. Ayrıca “IsUpdatable”‘in tekrardan false’a atanması ihmal edilmemiştir.
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 |
self.save = function () { if (!IsUpdatable) { $.ajax({ url: "/Home/SavePerson/", type: "POST", data: PersonInfo, datatype: "json", contenttype: "application/json;utf-8" }).done(function (resp) { self.PersonID(resp.PersonID); $("#personPage").modal("hide"); loadInformation(); }).error(function (err) { self.Message("Error! " + err.status); }); } else { $.ajax({ url: "/Home/UpdatePerson", type: "POST", data: PersonInfo, datatype: "json", contenttype: "application/json;utf-8" }).done(function () { $("#personPage").modal("hide"); loadInformation(); IsUpdatable = false; }).error(function (err) { self.Message("Error! " + err.status); IsUpdatable = false; }); } } |
Son olarak kayıt silindiği zaman aşağıdaki function çağrılmakta ve silinecek PersonInfo ajax “Post” ile “PersonID” parametresi “DelPerson()” methoduna gönderilmektedir.
1 2 3 4 5 6 7 8 9 10 |
self.delete = function (per) { $.ajax({ url: "/Home/DelPerson?personID=" + per.PersonID, type: "POST", }).done(function (resp) { loadInformation(); }).error(function (err) { self.Message("Error! " + err.status); }); } |
PersonInfo.js(Full):
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 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
/// <reference path="jquery-2.1.4.min.js" /> /// <reference path="knockout-3.3.0.js" /> (function () { var viewModel = function () { var self = this; var IsUpdatable = false; self.PersonID = ko.observable(0); self.FirstName = ko.observable(""); self.LastName = ko.observable(""); self.Address = ko.observable(""); self.City = ko.observable(""); self.PhoneNo = ko.observable(""); self.MobileNo = ko.observable(""); self.EmailAddress = ko.observable(""); self.Occupation = ko.observable(""); var PersonInfo = { PersonID: self.PersonID, FirstName: self.FirstName, LastName: self.LastName, Address: self.Address, City: self.City, PhoneNo: self.PhoneNo, MobileNo: self.MobileNo, EmailAddress: self.EmailAddress, Occupation: self.Occupation }; self.Persons = ko.observable([]); self.Message = ko.observable(""); self.Occupations = ko.observable(["İşveren", "Mühendis", "Doktor", "Öğretmen", "Diğer"]); self.SelectedOccupation = ko.observable(); self.SelectedOccupation.subscribe(function (text) { self.Occupation(text); }); self.City == ko.observable(["İstanbul", "Ankara", "İzmir", "Bursa", "Trabzon", "Adana"]); loadInformation(); function loadInformation() { $.ajax({ url: "/Home/GetPerson/", type: "GET", }).done(function (resp) { self.Persons(resp); }).error(function (err) { self.Message("Error!" + err.status); }); } self.getSelected = function (per) { self.PersonID(per.PersonID) self.FirstName(per.FirstName); self.LastName(per.LastName); self.Address(per.Address); self.City(per.City); self.PhoneNo(per.PhoneNo); self.MobileNo(per.MobileNo); self.EmailAddress(per.EmailAddress); self.SelectedOccupation(per.Occupation); IsUpdatable = true; $("#personPage").modal("show"); } self.save = function () { if (!IsUpdatable) { $.ajax({ url: "/Home/SavePerson/", type: "POST", data: PersonInfo, datatype: "json", contenttype: "application/json;utf-8" }).done(function (resp) { self.PersonID(resp.PersonID); $("#personPage").modal("hide"); loadInformation(); }).error(function (err) { self.Message("Error! " + err.status); }); } else { $.ajax({ url: "/Home/UpdatePerson", type: "POST", data: PersonInfo, datatype: "json", contenttype: "application/json;utf-8" }).done(function () { $("#personPage").modal("hide"); loadInformation(); IsUpdatable = false; }).error(function (err) { self.Message("Error! " + err.status); IsUpdatable = false; }); } } self.delete = function (per) { $.ajax({ url: "/Home/DelPerson?personID=" + per.PersonID, type: "POST", }).done(function (resp) { loadInformation(); }).error(function (err) { self.Message("Error! " + err.status); }); } } $(document).ready(function () { ko.applyBindings(new viewModel()); }); })(); |
Şimdi sıra geldi server side tarafında ilgili kayıt için yapılan C.R.U.D işlemlerine: Database işlemleri için Entity framework ve Linq kullanılmıştır.
Aşağıda görüldüğü gibi “GetPerson()” methodu için “PersonInformation” listesi çekilip “JsonResult” olarak döndümüştür. “UpdatePerson()” methodunda “PersonInformation” tipinde parametre alınıp ilgili kayıt güncellenir. Aynı şekilde “SavePerson()” methodunda yeni kişi kaydedilir. “DelPerson()”‘da da silinecek kişinin “ID” değeri parametre olarak alınıp silinir.
HomeController.cs(Full) :
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 |
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using DAL; namespace Bootstarp.Controllers { public class HomeController : Controller { // GET: Home public ActionResult Index() { return View(); } public JsonResult GetPerson() { using (SurveyContext data = new SurveyContext()) { var model = data.PersonInformation.ToList(); return Json(model, JsonRequestBehavior.AllowGet); ; } } public void UpdatePerson(PersonInformation data) { using (SurveyContext dataContext = new SurveyContext()) { var person = dataContext.PersonInformation.Where(per => per.PersonID == data.PersonID).FirstOrDefault(); person.Address = data.Address; person.City = data.City; person.EmailAddress = data.EmailAddress; person.FirstName = data.FirstName; person.LastName = data.LastName; person.MobileNo = data.MobileNo; person.Occupation = data.Occupation; person.PhoneNo = data.PhoneNo; dataContext.SaveChanges(); } } public JsonResult SavePerson(PersonInformation data) { using (SurveyContext dataContext = new SurveyContext()) { dataContext.PersonInformation.Add(data); dataContext.SaveChanges(); } return GetPerson(); } public void DelPerson(int personID) { using (SurveyContext dataContext = new SurveyContext()) { var person = dataContext.PersonInformation.Where(per => per.PersonID == personID).FirstOrDefault(); dataContext.PersonInformation.Remove(person); dataContext.SaveChanges(); } } } } |
Şimdi sıra geldi UI ekrana. Öncelikle “<head>” altına alttaki script kütüphaneleri ve css dosyaları include edilir. Böylece jquery, knockoutjs, bootstarp ve yazdığımız PersonInfo.js projemize eklenmiş olur.
1 2 3 4 5 |
<script src="~/Scripts/jquery-2.1.4.min.js"></script> <script src="~/Scripts/bootstrap.min.js"></script> <script src="~/Scripts/knockout-3.3.0.js" defer="defer"></script> <script src="~/Scripts/PersonInfo.js"></script> <link href="~/Content/bootstrap.min.css" rel="stylesheet" /> |
Öncelikle aşağıda görüldüğü gibi kayıtlı kişileri sıralayan tabloyu oluşturalım. Bunun için DataBinding UI kullanılmıştır. Yukarıda, sayfa ilk yüklenirken PersonInfo.js’de “loadInformation()” function’ını çağırılmıştır. ViewModel’deki “Persons” property’si tek tek gezilerek herbir “PersonInfo” modeli ilgili text alana “data-bind” edilir. Tabloda 2 tane işlem kolonu vardır. “Güncelleme ve Silme”. Bir de yukarıda “Yeni Çalışan Ekle” şeklinde bir button bulunmaktadır. Güncelle ve Silme işlemlerinde root’a yani ViewModel le bağlı yukarıda tanımlanan (“getSelect()” ve “delete()”) functionları çağrılmıştır.
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 |
<div class="panel panel-primary"> <h1>Çalışan Kayıtları</h1> </div> <input type="button" id="btnaddperson" class="btn btn-small btn-primary" value="Yeni Çalışan Ekle"/> <hr /> <div class="panel panel-default pre-scrollable"> <table class="table table-striped table-bordered table-responsive table-condensed table-hover"> <thead> <tr> <th>Id</th> <th>Adı</th> <th>Soyad</th> <th>Şehir</th> <th>MobileNo</th> </tr> </thead> <tbody data-bind="foreach:Persons"> <tr> <td> <span data-bind="text:PersonID"></span> </td> <td> <span data-bind="text:FirstName"></span> </td> <td> <span data-bind="text:LastName"></span> </td> <td> <span data-bind="text:City"></span> </td> <td> <span data-bind="text:MobileNo"></span> </td> <td> <button class="glyphicon glyphicon-pencil" data-bind="click:$root.getSelected" /> </td> <td> <button class="glyphicon glyphicon-trash" data-bind="click:$root.delete" /> </td> </tr> </tbody> </table> </div> |
Yeni kayıt eklemek için “btnaddperson” idli button’un, tıklanma durumunda bootstrap ile tanımlı gelen “modal()” functionın kullanım şekli aşağıdaki gibidir. Bu sayede ilerde tanımlayacağımız görünmeyen div, sanki popup bir sayfa gibi gözükecektir.
1 2 3 4 5 6 7 8 |
<script type="text/javascript"> $(function () { var model = function () { $("#personPage").modal("show"); }; $("#btnaddperson").on('click', model); }); </script> |
Aşağıda “personPage” divinin altına yeni kullanıcı girişi için farklı tipte input elemanları konmuştur. “class=’modal'” bootstarp’den gelen bir css dir. “modal(‘show’)” ve “modal(‘hide’)” functionları, tanımlı “personPage” divini popup gibi gösterip, gizler. PersonInfo’ya ait giriş elementleri ilgili div altına tanımlanmış ve view model’e knockoutJs sayesinde bind edilmişlerdir. Burda diğerlerinden farklı olarak “Occupations” yani işler combosu data-bind için”options:Occupations (listenin çekileceği alan),optionsCaption:’Birini Seçiniz’ (default başta görünecek text), value: SelectedOccupation (seçli elemanın bağlanacağı property)” attributeları ile tanımlanmıştır. “SelectedOccupation” değişince “subscribe()” functionı tetiklenir ve “Occupation” buna bağlı olarak değişir. PersonInfo sınıfı da ilgili değişiklikten etkileneceği için kaydetme ve güncelleme işlemleri de, doğru bir şekilde yapılmış olunur. Kaydetme işlemi için “save()” methodu çağrılır. Yeni kayıt girişinde “IsUpdatable” “false” olduğı için “SavePerson()” methodu çağrılarak yeni kayıt girişi sağlanır.
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 |
<div id="personPage" class="modal"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h1>Yeni Kayıt Gir</h1> </div> <div class="modal-body"> <table class="table table-condensed table-striped table-bordered"> <tr> <td>Adı:</td> <td> <input type="text" data-bind="value:FirstName" class="form-control" /> </td> </tr> <tr> <td>Soyadı:</td> <td> <input type="text" data-bind="value:LastName" class="form-control" /> </td> </tr> <tr> <td>Address</td> <td> <textarea data-bind="value:Address" class="form-control"></textarea> </td> </tr> <tr> <td>Şehir:</td> <td> <input type="text" data-bind="value:City" class="form-control" /> </td> </tr> <tr> <td>Tel No:</td> <td> <input type="text" data-bind="value:PhoneNo" class="form-control" /> </td> </tr> <tr> <td>Mobile No:</td> <td> <input type="text" data-bind="value:MobileNo" class="form-control" /> </td> </tr> <tr> <td>Email:</td> <td> <input type="email" data-bind="value:EmailAddress" class="form-control" /> </td> </tr> <tr> <td>İşi:</td> <td> <select type="text" data-bind="options:Occupations,optionsCaption:'Birini Seçiniz', value: SelectedOccupation" class="form-control" /> </td> </tr> </table> </div> <div class="modal-footer"> <button class="btn btn-default" data-dismiss="modal">Close</button> <button class="btn btn-primary" data-bind="click:save">Ok</button> </div> </div> </div> </div> |
Index.cshtml(Full):
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 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
@{ Layout = null; } <!DOCTYPE html> <html> <head> <script src="~/Scripts/jquery-2.1.4.min.js"></script> <script src="~/Scripts/bootstrap.min.js"></script> <script src="~/Scripts/knockout-3.3.0.js" defer="defer"></script> <script src="~/Scripts/PersonInfo.js"></script> <link href="~/Content/bootstrap.min.css" rel="stylesheet" /> <script type="text/javascript"> $(function () { var model = function () { $("#personPage").modal("show"); }; $("#btnaddperson").on('click', model); }); </script> <meta name="viewport" content="width=device-width" /> <title>Kayıtlar</title> </head> <body> <div class="panel panel-primary"> <h1>Çalışan Kayıtları</h1> </div> <input type="button" id="btnaddperson" class="btn btn-small btn-primary" value="Yeni Çalışan Ekle"/> <hr /> <div class="panel panel-default pre-scrollable"> <table class="table table-striped table-bordered table-responsive table-condensed table-hover"> <thead> <tr> <th>Id</th> <th>Adı</th> <th>Soyad</th> <th>Şehir</th> <th>MobileNo</th> </tr> </thead> <tbody data-bind="foreach:Persons"> <tr> <td> <span data-bind="text:PersonID"></span> </td> <td> <span data-bind="text:FirstName"></span> </td> <td> <span data-bind="text:LastName"></span> </td> <td> <span data-bind="text:City"></span> </td> <td> <span data-bind="text:MobileNo"></span> </td> <td> <button class="glyphicon glyphicon-pencil" data-bind="click:$root.getSelected" /> </td> <td> <button class="glyphicon glyphicon-trash" data-bind="click:$root.delete" /> </td> </tr> </tbody> </table> </div> <div id="personPage" class="modal"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h1>Yeni Kayıt Gir</h1> </div> <div class="modal-body"> <table class="table table-condensed table-striped table-bordered"> <tr> <td>Adı:</td> <td> <input type="text" data-bind="value:FirstName" class="form-control" /> </td> </tr> <tr> <td>Soyadı:</td> <td> <input type="text" data-bind="value:LastName" class="form-control" /> </td> </tr> <tr> <td>Address</td> <td> <textarea data-bind="value:Address" class="form-control"></textarea> </td> </tr> <tr> <td>Şehir:</td> <td> <input type="text" data-bind="value:City" class="form-control" /> </td> </tr> <tr> <td>Tel No:</td> <td> <input type="text" data-bind="value:PhoneNo" class="form-control" /> </td> </tr> <tr> <td>Mobile No:</td> <td> <input type="text" data-bind="value:MobileNo" class="form-control" /> </td> </tr> <tr> <td>Email:</td> <td> <input type="email" data-bind="value:EmailAddress" class="form-control" /> </td> </tr> <tr> <td>İşi:</td> <td> <select type="text" data-bind="options:Occupations,optionsCaption:'Birini Seçiniz', value: SelectedOccupation" class="form-control" /> </td> </tr> </table> </div> <div class="modal-footer"> <button class="btn btn-default" data-dismiss="modal">Close</button> <button class="btn btn-primary" data-bind="click:save">Ok</button> </div> </div> </div> </div> </body> </html> |
Güncelle yani kalem ikonlu buttona basıldığında “getSelected()” methodu çağrılır. İlgili kayıt çekilip “IsUpdatable”‘a “true” değeri atanır. Böylece update işleminin yapılacağı anlaşılır ve “UpdatePerson()” methodu çağrılır.
Böylece geldik bir makalenin daha sonuna. Bu makalede bootstrap sayesinde tasarım anlamında nerede ise hiç bir çalışma yapılmadan , ayrıca knockoutJS ile UI Databinding kullanılarak single page bir uygulama nasıl yapılır hep beraber inceledik.
Yeni bir makalede görüşmek üzere hoşçakalın.
Source Code: http://www.borakasmer.com/projects/Bootstarp.rar
Harikasınız hocam,
Sizi tanıdığıma çok memnun oldum.Verimli bir blog yaratıyorsunuz ve sizden bu konuda oldukça feyz alıyorum.
Kaliteli içeriklerinizde bilgi konusunda oldukça bonkör olduğunuz için teşekkür ederim.
Saygılarımla…
Teşekkürler;
Bu güzel yorumlarınızla, ben de feyz(gaz) alıyorum:)
Sanada iyi bayramlar kaptan (geçte olsa)
Ellerine sağlık Bora, çok güzel bir anlatım olmuş.
Teşekkürler Cihan:)
Harikulade bir yazı olmuş, ellerinize gönlünüze sağlık, böyle bilinmedik, kaynak sıkıntısı çekilen noktalarda yeni yazılar görmek dileğiyle, iyi çalışmalar dilerim.
Teşekkürler Mustafa;
Sizin gibi kıymet bilen insanların da olması güzel şey…
Çok güzel bir paylaşım olmuş. Elinize sağlık hocam.
Teşekkürler Emre.
merhaba. projeyi indiremedim link yanlış sanıırım düzeltir misiniz
Hocam çok güzel bir paylaşım gerçekten teşekkür ederim. Sorum şu şekilde,
düzenleme yapmak için seçilen kaydın işinin dropdown listte seçili gelmesini knockout js de nasıl yaparım teşekkürler.
Selamlar Melih,
Öncelikle teşekkürler. Bir dropdown listeki bir elemanı seçili olarak getirmek için, örneğin bu makalede işi diye bir dropdown var. ==> “”
Buradaki “self.SelectedOccupation”‘a ilgili value değerini set eder isen, set edilen eleman comboda seçili olarak gelir.
İyi çalışmalar.
hocam iyi akşamlar öncelikle teşekkür ederim. Şöyle bir problemim var . Ürünlerin listelendiği bir sayfam ve bu ürünlerin edit edilebileceği modal dan oluşmuş bir popup var. Burada ki ürünün kategorisinin selectedCategory özelliği elle başka bir değer set etmeme rağmen hala kategori listesinde ki ilk kategori seçili geliyor. Debug olarak baktığım zaman pop up açılırken selectedCategory iki kez tetikleniyor. ilkinde benim set ettiğim değer gelirken, ikincisinde kategorilerin ilk elemanı geldiği için sorun yaşıyorum. Yardımcı olur musunuz. iyi çalışmalar