CHAPTER 07 Ajax ( ) (Silverlight) Ajax RIA(Rich Internet Application) Firefox 4 Ajax MVC Ajax ActionResult Ajax jquery Ajax HTML (Partial View) 7 3 GetOrganized Ajax GetOrganized Ajax HTTP POST
154 CHAPTER 07 _ Suggest Ajax MVC jquery HTTP POST Todo Ajax jquery API Visual Studio Ajax Ajax Ajax jquery Ajax (Graceful degradation) Ajax 7 2 Ajax Ajax MVC IsAjaxRequest() Create() CreateWithAjax()
7.1 155 Ajax jquery jquery Visual Studio 2008 C# jquery http://jquery.com Visual Studio 2010 GetOrganized Ajax HTTP POST Todo Ajax 3 4 : Todo Ajax HTTP POST // GET: /Todo/Delete/Title={ } [AcceptVerbs(HttpVerb.Post)] public ActionResult Delete(string title) { 5 Todo.ThingsToBeDone. Remove( Todo.ThingsToBeDone.Find(todo => todo.title == title)); if (Request.IsAjaxRequest()) 10 return new EmptyResult(); return RedirectToAction( Index ); } http://code.msdn.microsoft.com/kb958502/release/projectreleases.aspx?releaseid=1736
156 CHAPTER 07 _ 2 Delete() HTTP POST HTTP POST /Views/ Todo/Index.aspx HTTP GET 9 Ajax Ajax EmptyResult jquery HTML /Views/Todo/Index.aspx Grid Grid HTML id class <A> NUnit LinkHelper ViewHelpers using System.Web.Mvc; using System.Web.Routing; namespace GetOrganized.ViewHelpers 5 { public static class LinkHelper { public static string Link(this HtmlHelper helper, string linktext, string url, object htmlattributes) 10 { var builder = new TagBuilder( a ); builder.mergeattributte( new RouteValueDictionary(htmlAttributes)); 15 builder.attributes.add( href, url); builder.setinnertext(linktext); return builder.tostring(); } 20 } }
7.1 157 HTML 6 2 9 6 1 HTML CSS id class Html.ActionLink( name, action, new { @class = SomeCssClass }) TagBuilder 14 RouteValueDictionary IDictionary <String Object> HTML jquery <head> <meta httpequiv= ContentType content= text/html; charset=iso88591 /> <link href=../../content/colorpicker.cssv 5 rel= Stylesheet type= text/css /> <link href=../../content/site.css rel= stylesheet type= text/css /> <link href=../../content/colorpicker.css rel= stylesheet type= text/css /> 10 <script type= text/javascript src=../../scripts/jquery1.4.1.js ></script> <script type= text/javascript src=../../scripts/colorpicker.js ></script> 15 <script type= text/javascript src=../../scripts/jquery.autocomplete.js ></script> <link href=../../content/jquery.autocomplete.css rel= stylesheet type= text/css /> 20 <script type= text/javascript src=../../scripts/jqueryui1.8rc3.min.js ></script> <script type= text/javascript src=../../scripts/jquery.livequery.js ></script> 25
158 CHAPTER 07 _ <asp:contentplaceholder ID= Head runat= server /> </head> jquery Site.Master 16 jquery AutoComplete jquery UI Live Query AutoComplete CSS CSS /Views/Todo/Index aspx HTTP POST <%@ Page Title= Language= C# MasterPageFile= ~/Views/Shared/Site.Master Inherits= System.Web.Mvc.ViewPage<IEnumerable<Todo>> %> <%@ Import Namespace= System.Drawing %> 5 <%@ Import Namespace= GetOrganized.Models %> <%@ Import Namespace= GetOrganized.ViewHelpers %> <%@ Import Namespace= MvcContrib.UI.Grid %> <asp:content ID= Content1 10 ContentPlaceHolderID= head runat= server > <title>index</title> <script type= text/javascript language= javascript > $(document).ready(function() { $(.deletetodolink ).click(function() { var element = $(this); var todotitle = element.attr( id ); $.post( Todo/Delete, 20 { title: todotitle }, function() { element.closest( tr ). fadeout( slow, function() { $(this).remove(); }); http://www.pengoworks.com/workshop/jquery/autocomplete.htm http://jqueryui.com/download http://plugins.jquery.com/project/livequery
7.1 159 25 } ); }); }); </script> 30 </asp:content> <asp:content ID= Content2 ContentPlaceHolderID= MainContent runat= server > <h2><%= ViewData[ UserName ] %> </h2> 35 <%= Html.Grid(Model).Columns(column => { column.for( x => Html.Link(, #, new { id = x.title, 40 @class = deletetodolink })).DoNotEncode(); column.for( x => Html.ActionLink(, Edit, new { x.title })). Named( ).DoNotEncode(); 45 column.for(x => x.title); }).Attributes(style => textalign: center; ).Empty(! ) %> 50 <p> <%= Html.ActionLink(, Create ) %> </p> </asp:content> jquery head ID ContentPlaceHolder jquery 6 GetOrganized ViewHelpers 39 Grid LinkHelper (Anonymous Object Initializer) class id jquery jquery
160 CHAPTER 07 _ 15 this jquery jquery HTML <A> id Todo Title Ajax 18 $ post() jquery HTTP POST URL HTTP POST Todo 22 element.closest( tr ) <TR> 24 remove() jquery fade() HTML F5 Todo Ajax Ajax GetOrganized jquery MVC
7.2 161 jquery 7 1 HTTP POST Site.Master jquery jquery JSON JQ Autocomplete jquery ThoughtController [Test] 2 public void Should_Find_Thoughts_By_Text_Match_Case_Insensitive() 3 { 4 var learncsharp = Thought.CurrentThoughts[0]; 5 var contentresult = ((ContentResult) 6 new ThoghtController().Search( ); 7 8 Assert.AreEqual(learnCsharp.Name, contentresult.content); 9 } C# 3 5 Thought jquery 6 Search ContentResult Search http://www.devbridge.com/projects/autocomplete/jquery/
162 CHAPTER 07 _ public ActionResult Search(string q) { var searchresults = Thought.CurrentThoughts.FindAll( thought => thought.name.tolower().contains(q.tolower())); 5 var autocompleteresults = String.Join( \n, searchresults.convertall(g => g.name).toarray()); 10 return Content(autoCompleteResults); } 1 q jquery q ( ) 4 ToLower() 167 TIP 8 Thought Name String Join \n Content(object result) Thought Id Thought Thought Name /Views/Thought/Detail/Id [Test] 2 public void Should_Find_Thought_By_Name_And_Redirect_To_Details_View() 3 { 4 var routevaluedictionary = new ThoughtController(). 5 FindDetails( C# 3.5 ). 6 AssertActionRedirect().RouteValues; 7 8 Assert.AreEqual( Details, routevaluedictionary[ action ]);
7.2 163 9 Assert.AreEqual(1, routevaluedictionary[ id ]); 10 } ThoughtController FindDetails() 4 Dictionary<String Object> RouteValueDictionary Id Thought FindDetails() // // GET: /Thought/FindDetails?nameOfThought={name} public ActionResult FindDetails(string nameofthought) 5 { var thought = Thought.CurrentThoughts. Find(x => x.name == nameofthought); return RedirectToAction( Details, 10 new { id = thought.id }); } Thought Id 10 Id Id LinkHelper MVC RouteValueDictionary jquery <asp:content ID= indexhead ContentPlaceHolderID= head runat= server > <title> </title> <script type= text/javascript language= javascript > 5 $(document).ready(function() { $( #searchthoughtstextbox ). autocomplete( Thought/Search, { minchars: 1 }); $( #searchbutton ).click(function() { window.location = Thought/FindDetails?nameOfThought= + 10 escape($( #searchthoughtstextbox )[0].value); }); }); </script>
164 CHAPTER 07 _ </asp:content> 15 <asp:content ID= indexcontent ContentPlaceHolderID= MainContent runat= server > <! > 20 <h2> </h2> <input id= searchthoughtstextbox name= title type= text /> <input id= searchbutton type= submit value= /> </asp:content> 21 Thought 7 HTTP GET URL {minchars: 1} 9 jquery window location 10 getelementbyid() jquery jquery $( class )[0] escape() URL 7 1
7.2 165 jquery UI ( 4 3 jquery ) jquery Ajax ( 7 2 ) MVC MVC http://www.uploadify.com/ http://www.codenothing.com/archives/jquery/inlinetextedit/ http://blog.threedubmedia.com/2008/08/eventspecialdrag.html http://bassistance.de/jqueryplugins/jquerypluginvalidation/
166 CHAPTER 07 _ Ajax (Partial View) ASP NET (User Control) Views/Shared LogOnUserControl ascx Site Master GetOrganized /Views/Todo/Create aspx Todo /Views/Todo/Create aspx (DRY ) Create aspx Create aspx ( 7 3 ) Create aspx CreateElements aspx
7.3 167 TIP http://lucene.apache.org/java/docs/index.html http:// ayende.com/blog/archive/2007/03/18/googlizeyourentitiesnhibernatelucene.netintegration.aspx <%@ Control Language= C# Inherits= System.Web.Mvc.ViewUserControl %> <% using (Html.BeginForm()) { %> <fieldset> <legend>fields</legend> 5 <div class= editorlabel > <%= Html.LablFor(model => model.title) %> </div> <div class= editorfield > <%= Html.TextBoxFor(model => model.title) %> 10 <%= Html.ValidationMessageFor(model => model.title) %> </div> <p> <input type= submit value= /> </p> 15 </fieldset> <% } %>
168 CHAPTER 07 _ HTML 1 System.Web.Mvc.ViewUserControl id CreateTodo jquery Ajax Create aspx <asp:content ID= Content2 ContentPlaceHolderID= MainContent runat= server > <h2> </h2> 5 <%= Html.ValidationSummary() %> <% Html.RenderPartial( CreateElements ); %> <div> 10 <%= Html.ActionLink(, Index ) %> </div> </asp:content>
7.3 169 7 RenderPartial(string partialname) /Views/Todo/CreateElements aspx MVC WebFormViewEngine /Views/Todo /Views/Shared MVC (! ) http://code.google.com/p/nhaml/ http://code.google.com/p/stringtemplateviewenginemvc/ if/else ViewData F5 Create aspx Ajax
170 CHAPTER 07 _ CreateElement.aspx /Views/Todo/Index aspx Todo /Views/Todo/Index aspx <div> <asp:content ID= Content1 ContentPlaceHolderID= Head runat= server > <script type= text/javascript language= javascript > $(document).ready(function() { // $( #Create_Link ).click(function() { $( #Create_Div ).slidetoggle( slow ); }); $( #Create_Link )[0].href = # ; }); </script> </asp:content> <asp:content ID= Content2 ContentPlaceHolderID= MainContent runat= server > <! Grid > <p> <%= Html.ActionLink(, Create, null, new { id= Create_Link }) %> </p> <div id= Create_Div style= display:none > <% Html.RenderPartial( CreateElements ); %> </div> </asp:content> 22 display none 19 <div> <div> id jquery 8 slidetoggle(var speed) <div>
7.3 171 10 Create aspx 7 4 /Views/Todo/Create aspx Todo jquery post() TodoController JSON // POST: /Todo/Create [AcceptVerbs(HttpVerbs.Post)] public ActionResult Create(Todo todo) { 5 todo.validate(modelstate); if (ModelState.IsValid) {
172 CHAPTER 07 _ CreateTodo(todo); 10 if (Request.IsAjaxRequest()) return Json(todo); return RedirectToAction( Index ); } else 15 { return View(); } } 10 IsAjaxRequest() Ajax 7 1 Ajax Ajax Ajax HTTP X Requested With: XMLHttpRequest IsAjaxRequest() true Ajax JSON Index aspx jquery Todo <asp:content ID= Content1 ContentPlaceHolderID= head runat= server > <script type= text/javascript language= javascript > $(document).ready(function() { 5 $( #CreateTodo ).submit(function() { $.post( $(this).attr( action ), $( #CreateTodo ).serialize(), 10 function(data, textstatus) { var html = <tr><td><a id=\ + data.title + \ + class=\ deletetodolink\ href=\ #\ > + </a></td> + 15 <td><a href=\ /Todo/Edit?Title= + data.title + \ > </a></td> + <td> + data.title + </td></tr> ; $(html).appendto($( #main table )).
7.3 173 10 effect( highlight, {}, 3000); }, // json ); 25 return false; }); } Todo HTML (DOM: Document Object Model) 5 submit jquery post() HTML action URL Ajax serialize() <input> 8 post() post() Todo 11 JSON Todo 20 jquery JSON 23 post() jquery jquery (Live Query) <script type= text/javascript language= javascript > $(document).ready(function() { $(.deletetodolink ).livequery( click, function() { var element = $(this);
174 CHAPTER 07 _ 5 var todotitle = element.attr( id ): $.post( Todo/Delete, { title : todotitle }, 10 function() { element.closest( tr ). fadeout( slow, function() { $(this).remove(); }); } 15 ); }); }); </script> </asp:content> 3 click(function()) livequery( click function()) DOM append() addclass() DOM jquery DOM jquery Ajax 2 0! jquery $.post() Ajax ASP NET ORM SQL NHibernate ORM