1 // Copyright 2004-2007 Castle Project - http://www.castleproject.org/
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle
.MonoRail
.Framework
.ViewComponents
18 using System
.Collections
;
20 using Castle
.MonoRail
.Framework
.Helpers
;
23 /// Creates a digg style pagination.
25 /// Based on Alex Henderson work. See
26 /// (Monorail Pagination with Base4.Net)
27 /// http://blog.bittercoder.com/PermaLink,guid,579711a8-0b16-481b-b52b-ebdfa1a7e225.aspx
34 /// <c>adjacents</c>: number of links to show around the current page <br/>
35 /// <c>page</c> (required): <see cref="IPaginatedPage"/> instance (<see cref="PaginationHelper"/>) <br/>
36 /// <c>url</c>: url to link to<br/>
37 /// <c>useInlineStyle</c>: defines if the outputted content will use inline style or css classnames (defaults to true)<br/>
38 /// <c>renderIfOnlyOnePage</c>: should the pagination render if there's only one page (defaults to true)<br/>
39 /// <c>paginatefunction</c>: a javascript function name to invoke on the page links (instead of a URL)<br/>
43 /// Supported sections: <br/>
44 /// <c>startblock</c>: invoked with <c>page</c> <br/>
45 /// <c>endblock</c>: invoked with <c>page</c> <br/>
46 /// <c>link</c>: invoked with <c>pageIndex</c>, <c>url</c> and <c>text</c>
47 /// so you can build a custom link <br/>
48 /// <c>prev</c>: text displayed instead of "<%lt;prev" <br/>
49 /// <c>next</c>: text displayed instead of "next>%gt;" <br/>
53 [ViewComponentDetails("DiggStylePagination", Sections
= "startblock,endblock,next,prev,link")]
54 public class DiggStylePagination
: AbstractPaginationViewComponent
56 private const string LinkSection
= "link";
57 private const string NextSection
= "next";
58 private const string PrevSection
= "prev";
60 private int adjacents
= 2;
61 private bool renderIfOnlyOnePage
= true;
64 /// Gets or sets the adjacents (number of links to show).
66 /// <value>The adjacents.</value>
70 get { return adjacents; }
71 set { adjacents = value; }
75 /// Gets or sets a value indicating whether the component should render links even if there is only one page.
78 /// <c>true</c> if it should render; otherwise, <c>false</c>.
81 public bool RenderIfOnlyOnePage
83 get { return renderIfOnlyOnePage; }
84 set { renderIfOnlyOnePage = value; }
88 /// Called by the framework so the component can
89 /// render its content
91 public override void Render()
93 if (renderIfOnlyOnePage
|| Page
.LastIndex
> 1)
95 StringWriter writer
= new StringWriter();
100 if (Page
.LastIndex
< (4 + (adjacents
* 2))) // not enough links to make it worth breaking up
102 WriteNumberedLinks(writer
, 1, Page
.LastIndex
);
106 if ((Page
.LastIndex
- (adjacents
* 2) > Page
.CurrentIndex
) && // in the middle
107 (Page
.CurrentIndex
> (adjacents
* 2)))
109 WriteNumberedLinks(writer
, 1, 2);
110 WriteElipsis(writer
);
111 WriteNumberedLinks(writer
, Page
.CurrentIndex
- adjacents
, Page
.CurrentIndex
+ adjacents
);
112 WriteElipsis(writer
);
113 WriteNumberedLinks(writer
, Page
.LastIndex
- 1, Page
.LastIndex
);
115 else if (Page
.CurrentIndex
< (Page
.LastIndex
/ 2))
117 WriteNumberedLinks(writer
, 1, 2 + (adjacents
* 2));
118 WriteElipsis(writer
);
119 WriteNumberedLinks(writer
, Page
.LastIndex
- 1, Page
.LastIndex
);
123 WriteNumberedLinks(writer
, 1, 2);
124 WriteElipsis(writer
);
125 WriteNumberedLinks(writer
, Page
.LastIndex
- (2 + (adjacents
* 2)), Page
.LastIndex
);
131 RenderText(writer
.ToString());
135 private void WritePrev(StringWriter writer
)
137 string caption
= "« prev";
138 if (Context
.HasSection(PrevSection
))
140 TextWriter capWriter
= new StringWriter();
141 Context
.RenderSection(PrevSection
, capWriter
);
142 caption
= capWriter
.ToString().Trim();
144 WriteLink(writer
, Page
.PreviousIndex
, caption
, !Page
.HasPrevious
);
147 private void WriteNext(StringWriter writer
)
149 string caption
= "next »";
150 if (Context
.HasSection(NextSection
))
152 TextWriter capWriter
= new StringWriter();
153 Context
.RenderSection(NextSection
, capWriter
);
154 caption
= capWriter
.ToString().Trim();
156 WriteLink(writer
, Page
.NextIndex
, caption
, !Page
.HasNext
);
159 private void WriteElipsis(TextWriter writer
)
161 writer
.Write("…");
164 private void WriteNumberedLinks(TextWriter writer
, int startIndex
, int endIndex
)
166 for (int i
= startIndex
; i
<= endIndex
; i
++)
168 WriteNumberedLink(writer
, i
);
172 private void WriteLink(TextWriter writer
, int index
, string text
, bool disabled
)
178 writer
.Write(String
.Format("<span style=\"color: #DDD; padding: 2px 5px 2px 5px; margin: 2px; border: 1px solid #EEE;\">{0}</span>", text
));
182 writer
.Write(String
.Format("<span class=\"disabled\">{0}</span>", text
));
187 WritePageLink(writer
, index
, text
, null);
191 private void WriteNumberedLink(TextWriter writer
, int index
)
193 if (index
== Page
.CurrentIndex
)
197 writer
.Write(String
.Format("\r\n<span class=\"font-weight: bold; background-color: #000099; color: #FFF; padding: 2px 5px 2px 5px; margin: 2px; border: 1px solid #000099;\">{0}</span>\r\n", index
));
201 writer
.Write(String
.Format("\r\n<span class=\"current\">{0}</span>\r\n", index
));
206 WritePageLink(writer
, index
, index
.ToString(), null);
211 /// Writes the Page link.
213 /// <param name="writer">The writer.</param>
214 /// <param name="pageIndex">Index of the page.</param>
215 /// <param name="text">The text.</param>
216 /// <param name="htmlAttributes">The HTML attributes.</param>
217 protected void WritePageLink(TextWriter writer
, int pageIndex
, String text
, IDictionary htmlAttributes
)
219 string url
= CreateUrlForPage(pageIndex
);
221 if (Context
.HasSection(LinkSection
))
223 PropertyBag
["pageIndex"] = pageIndex
;
224 PropertyBag
["text"] = text
;
225 PropertyBag
["url"] = url
;
227 Context
.RenderSection(LinkSection
, writer
);
233 if (PaginateFunction
!= null)
235 href
= "javascript:" + PaginateFunction
+ "(" + pageIndex
+ ");void(0);";
244 writer
.Write(String
.Format("<a style=\"color: #000099;text-decoration: none;padding: 2px 5px 2px 5px;margin: 2px;border: 1px solid #AAAFEE;\" href=\"{0}\">{1}</a>\r\n", href
, text
));
248 writer
.Write(String
.Format("<a href=\"{0}\">{1}</a>\r\n", href
, text
));