/wheels/view/links.cfm

http://raihan.googlecode.com/ · ColdFusion · 327 lines · 305 code · 10 blank · 12 comment · 37 complexity · bf88c379e5155034ec43b092ff2d2fff MD5 · raw file

  1. <cffunction name="linkTo" returntype="string" access="public" output="false" hint="Creates a link to another page in your application. Pass in the name of a `route` to use your configured routes or a `controller`/`action`/`key` combination. Note: Pass any additional arguments like `class`, `rel`, and `id`, and the generated tag will also include those values as HTML attributes."
  2. examples=
  3. '
  4. ##linkTo(text="Log Out", controller="account", action="logout")##
  5. -> <a href="/account/logout">Log Out</a>
  6. <!--- if you''re already in the `account` controller, Wheels will assume that''s where you want the link to point --->
  7. ##linkTo(text="Log Out", action="logout")##
  8. -> <a href="/account/logout">Log Out</a>
  9. ##linkTo(text="View Post", controller="blog", action="post", key=99)##
  10. -> <a href="/blog/post/99">View Post</a>
  11. ##linkTo(text="View Settings", action="settings", params="show=all&sort=asc")##
  12. -> <a href="/account/settings?show=all&amp;sort=asc">View Settings</a>
  13. <!--- Given that a `userProfile` route has been configured in `config/routes.cfm` --->
  14. ##linkTo(text="Joe''s Profile", route="userProfile", userName="joe")##
  15. -> <a href="/user/joe">Joe''s Profile</a>
  16. <!--- Link to an external website --->
  17. ##linkTo(text="ColdFusion Framework", href="http://cfwheels.org/")##
  18. -> <a href="http://cfwheels.org/">ColdFusion Framework</a>
  19. <!--- Give the link `class` and `id` attributes --->
  20. ##linkTo(text="Delete Post", action="delete", key=99, class="delete", id="delete-99")##
  21. -> <a class="delete" href="/blog/delete/99" id="delete-99">Delete Post</a>
  22. '
  23. categories="view-helper,links" chapters="linking-pages" functions="URLFor,buttonTo,mailTo">
  24. <cfargument name="text" type="string" required="false" default="" hint="The text content of the link.">
  25. <cfargument name="confirm" type="string" required="false" default="" hint="Pass a message here to cause a JavaScript confirmation dialog box to pop up containing the message.">
  26. <cfargument name="route" type="string" required="false" default="" hint="See documentation for @URLFor.">
  27. <cfargument name="controller" type="string" required="false" default="" hint="See documentation for @URLFor.">
  28. <cfargument name="action" type="string" required="false" default="" hint="See documentation for @URLFor.">
  29. <cfargument name="key" type="any" required="false" default="" hint="See documentation for @URLFor.">
  30. <cfargument name="params" type="string" required="false" default="" hint="See documentation for @URLFor.">
  31. <cfargument name="anchor" type="string" required="false" default="" hint="See documentation for @URLFor.">
  32. <cfargument name="onlyPath" type="boolean" required="false" hint="See documentation for @URLFor.">
  33. <cfargument name="host" type="string" required="false" hint="See documentation for @URLFor.">
  34. <cfargument name="protocol" type="string" required="false" hint="See documentation for @URLFor.">
  35. <cfargument name="port" type="numeric" required="false" hint="See documentation for @URLFor.">
  36. <cfargument name="href" type="string" required="false" hint="Pass a link to an external site here if you want to bypass the Wheels routing system altogether and link to an external URL.">
  37. <cfscript>
  38. var loc = {};
  39. $args(name="linkTo", args=arguments);
  40. if (Len(arguments.confirm))
  41. {
  42. loc.onclick = "return confirm('#JSStringFormat(arguments.confirm)#');";
  43. arguments.onclick = $addToJavaScriptAttribute(name="onclick", content=loc.onclick, attributes=arguments);
  44. }
  45. if (!StructKeyExists(arguments, "href"))
  46. arguments.href = URLFor(argumentCollection=arguments);
  47. arguments.href = toXHTML(arguments.href);
  48. if (!Len(arguments.text))
  49. arguments.text = arguments.href;
  50. loc.skip = "text,confirm,route,controller,action,key,params,anchor,onlyPath,host,protocol,port";
  51. if (Len(arguments.route))
  52. loc.skip = ListAppend(loc.skip, $routeVariables(argumentCollection=arguments)); // variables passed in as route arguments should not be added to the html element
  53. loc.returnValue = $element(name="a", skip=loc.skip, content=arguments.text, attributes=arguments);
  54. </cfscript>
  55. <cfreturn loc.returnValue>
  56. </cffunction>
  57. <cffunction name="buttonTo" returntype="string" access="public" output="false" hint="Creates a form containing a single button that submits to the URL. The URL is built the same way as the @linkTo function."
  58. examples=
  59. '
  60. ##buttonTo(text="Delete Account", action="perFormDelete", disable="Wait...")##
  61. '
  62. categories="view-helper,links" functions="URLFor,linkTo,mailTo">
  63. <cfargument name="text" type="string" required="false" hint="The text content of the button.">
  64. <cfargument name="confirm" type="string" required="false" hint="See documentation for @linkTo.">
  65. <cfargument name="image" type="string" required="false" hint="If you want to use an image for the button pass in the link to it here (relative from the `images` folder).">
  66. <cfargument name="disable" type="any" required="false" hint="Pass in `true` if you want the button to be disabled when clicked (can help prevent multiple clicks), or pass in a string if you want the button disabled and the text on the button updated (to ""please wait..."", for example).">
  67. <cfargument name="route" type="string" required="false" default="" hint="See documentation for @URLFor.">
  68. <cfargument name="controller" type="string" required="false" default="" hint="See documentation for @URLFor.">
  69. <cfargument name="action" type="string" required="false" default="" hint="See documentation for @URLFor.">
  70. <cfargument name="key" type="any" required="false" default="" hint="See documentation for @URLFor.">
  71. <cfargument name="params" type="string" required="false" default="" hint="See documentation for @URLFor.">
  72. <cfargument name="anchor" type="string" required="false" default="" hint="See documentation for @URLFor.">
  73. <cfargument name="onlyPath" type="boolean" required="false" hint="See documentation for @URLFor.">
  74. <cfargument name="host" type="string" required="false" hint="See documentation for @URLFor.">
  75. <cfargument name="protocol" type="string" required="false" hint="See documentation for @URLFor.">
  76. <cfargument name="port" type="numeric" required="false" hint="See documentation for @URLFor.">
  77. <cfscript>
  78. var loc = {};
  79. $args(name="buttonTo", reserved="method", args=arguments);
  80. arguments.action = URLFor(argumentCollection=arguments);
  81. arguments.action = toXHTML(arguments.action);
  82. arguments.method = "post";
  83. if (Len(arguments.confirm))
  84. {
  85. loc.onsubmit = "return confirm('#JSStringFormat(arguments.confirm)#');";
  86. arguments.onsubmit = $addToJavaScriptAttribute(name="onsubmit", content=loc.onsubmit, attributes=arguments);
  87. }
  88. loc.content = submitTag(value=arguments.text, image=arguments.image, disable=arguments.disable);
  89. loc.skip = "disable,image,text,confirm,route,controller,key,params,anchor,onlyPath,host,protocol,port";
  90. if (Len(arguments.route))
  91. loc.skip = ListAppend(loc.skip, $routeVariables(argumentCollection=arguments)); // variables passed in as route arguments should not be added to the html element
  92. loc.returnValue = $element(name="form", skip=loc.skip, content=loc.content, attributes=arguments);
  93. </cfscript>
  94. <cfreturn loc.returnValue>
  95. </cffunction>
  96. <cffunction name="mailTo" returntype="string" access="public" output="false" hint="Creates a `mailto` link tag to the specified email address, which is also used as the name of the link unless name is specified."
  97. examples=
  98. '
  99. ##mailTo(emailAddress="webmaster@yourdomain.com", name="Contact our Webmaster")##
  100. -> <a href="mailto:webmaster@yourdomain.com">Contact our Webmaster</a>
  101. '
  102. categories="view-helper,links" functions="URLFor,linkTo,buttonTo">
  103. <cfargument name="emailAddress" type="string" required="true" hint="The email address to link to.">
  104. <cfargument name="name" type="string" required="false" default="" hint='A string to use as the link text ("Joe" or "Support Department", for example).'>
  105. <cfargument name="encode" type="boolean" required="false" hint="Pass `true` here to encode the email address, making it harder for bots to harvest it for example.">
  106. <cfscript>
  107. var loc = {};
  108. $args(name="mailTo", reserved="href", args=arguments);
  109. arguments.href = "mailto:#arguments.emailAddress#";
  110. if (Len(arguments.name))
  111. loc.content = arguments.name;
  112. else
  113. loc.content = arguments.emailAddress;
  114. loc.returnValue = $element(name="a", skip="emailAddress,name,encode", content=loc.content, attributes=arguments);
  115. if (arguments.encode)
  116. {
  117. loc.js = "document.write('#Trim(loc.returnValue)#');";
  118. loc.encoded = "";
  119. loc.iEnd = Len(loc.js);
  120. for (loc.i=1; loc.i LTE loc.iEnd; loc.i=loc.i+1)
  121. {
  122. loc.encoded = loc.encoded & "%" & Right("0" & FormatBaseN(Asc(Mid(loc.js,loc.i,1)),16),2);
  123. }
  124. loc.content = "eval(unescape('#loc.encoded#'))";
  125. loc.returnValue = $element(name="script", content=loc.content, type="text/javascript");
  126. }
  127. </cfscript>
  128. <cfreturn loc.returnValue>
  129. </cffunction>
  130. <cffunction name="paginationLinks" returntype="string" access="public" output="false" hint="Builds and returns a string containing links to pages based on a paginated query. Uses @linkTo internally to build the link, so you need to pass in a `route` name or a `controller`/`action`/`key` combination. All other @linkTo arguments can be supplied as well, in which case they are passed through directly to @linkTo. If you have paginated more than one query in the controller, you can use the `handle` argument to reference them. (Don't forget to pass in a `handle` to the @findAll function in your controller first.)"
  131. examples=
  132. '
  133. <!--- Example 1: List authors page by page, 25 at a time --->
  134. <!--- Controller code --->
  135. <cfparam name="params.page" default="1">
  136. <cfset allAuthors = model("author").findAll(page=params.page, perPage=25, order="lastName")>
  137. <!--- View code --->
  138. <ul>
  139. <cfoutput query="allAuthors">
  140. <li>##firstName## ##lastName##</li>
  141. </cfoutput>
  142. </ul>
  143. <cfoutput>##paginationLinks(action="listAuthors")##</cfoutput>
  144. <!--- Example 2: Using the same model call above, show all authors with a window size of 5 --->
  145. <!--- View code --->
  146. <cfoutput>##paginationLinks(action="listAuthors", windowSize=5)##</cfoutput>
  147. <!--- Example 3: If more than one paginated query is being run, then you need to reference the correct `handle` in the view --->
  148. <!--- Controller code --->
  149. <cfset allAuthors = model("author").findAll(handle="authQuery", page=5, order="id")>
  150. <!--- View code --->
  151. <ul>
  152. <cfoutput>##paginationLinks(action="listAuthors", handle="authQuery", prependToLink="<li>", appendToLink="</li>")##</cfoutput>
  153. </ul>
  154. <!--- Example 4: Call to `paginationLinks` using routes --->
  155. <!--- Route setup in config/routes.cfm --->
  156. <cfset addRoute(name="paginatedCommentListing", pattern="blog/[year]/[month]/[day]/[page]", controller="theBlog", action="stats")>
  157. <cfset addRoute(name="commentListing", pattern="blog/[year]/[month]/[day]", controller="theBlog", action="stats")>
  158. <!--- Ccontroller code --->
  159. <cfparam name="params.page" default="1">
  160. <cfset comments = model("comment").findAll(page=params.page, order="createdAt")>
  161. <!--- View code --->
  162. <ul>
  163. <cfoutput>##paginationLinks(route="paginatedCommentListing", year=2009, month="feb", day=10)##</cfoutput>
  164. </ul>
  165. '
  166. categories="view-helper,links" chapters="getting-paginated-data,displaying-links-for-pagination" functions="pagination,setPagination,linkTo,findAll">
  167. <cfargument name="windowSize" type="numeric" required="false" hint="The number of page links to show around the current page.">
  168. <cfargument name="alwaysShowAnchors" type="boolean" required="false" hint="Whether or not links to the first and last page should always be displayed.">
  169. <cfargument name="anchorDivider" type="string" required="false" hint="String to place next to the anchors on either side of the list.">
  170. <cfargument name="linkToCurrentPage" type="boolean" required="false" hint="Whether or not the current page should be linked to.">
  171. <cfargument name="prepend" type="string" required="false" hint="String or HTML to be prepended before result.">
  172. <cfargument name="append" type="string" required="false" hint="String or HTML to be appended after result.">
  173. <cfargument name="prependToPage" type="string" required="false" hint="String or HTML to be prepended before each page number.">
  174. <cfargument name="prependOnFirst" type="boolean" required="false" hint="Whether or not to prepend the `prependToPage` string on the first page in the list.">
  175. <cfargument name="prependOnAnchor" type="boolean" required="false" hint="Whether or not to prepend the `prependToPage` string on the anchors.">
  176. <cfargument name="appendToPage" type="string" required="false" hint="String or HTML to be appended after each page number.">
  177. <cfargument name="appendOnLast" type="boolean" required="false" hint="Whether or not to append the `appendToPage` string on the last page in the list.">
  178. <cfargument name="appendOnAnchor" type="boolean" required="false" hint="Whether or not to append the `appendToPage` string on the anchors.">
  179. <cfargument name="classForCurrent" type="string" required="false" hint="Class name for the current page number (if `linkToCurrentPage` is `true`, the class name will go on the `a` element. If not, a `span` element will be used).">
  180. <cfargument name="handle" type="string" required="false" default="query" hint="The handle given to the query that the pagination links should be displayed for.">
  181. <cfargument name="name" type="string" required="false" hint="The name of the param that holds the current page number.">
  182. <cfargument name="showSinglePage" type="boolean" required="false" hint="Will show a single page when set to `true`. (The default behavior is to return an empty string when there is only one page in the pagination).">
  183. <cfargument name="pageNumberAsParam" type="boolean" required="false" hint="Decides whether to link the page number as a param or as part of a route. (The default behavior is `true`).">
  184. <cfscript>
  185. var loc = {};
  186. $args(name="paginationLinks", args=arguments);
  187. loc.skipArgs = "windowSize,alwaysShowAnchors,anchorDivider,linkToCurrentPage,prepend,append,prependToPage,prependOnFirst,prependOnAnchor,appendToPage,appendOnLast,appendOnAnchor,classForCurrent,handle,name,showSinglePage,pageNumberAsParam";
  188. loc.linkToArguments = Duplicate(arguments);
  189. loc.iEnd = ListLen(loc.skipArgs);
  190. for (loc.i=1; loc.i <= loc.iEnd; loc.i++)
  191. StructDelete(loc.linkToArguments, ListGetAt(loc.skipArgs, loc.i));
  192. loc.currentPage = pagination(arguments.handle).currentPage;
  193. loc.totalPages = pagination(arguments.handle).totalPages;
  194. loc.start = "";
  195. loc.middle = "";
  196. loc.end = "";
  197. if (StructKeyExists(arguments, "route"))
  198. {
  199. // when a route name is specified and the name argument is part
  200. // of the route variables specified, we need to force the
  201. // arguments.pageNumberAsParam to be false
  202. loc.routeConfig = $findRoute(argumentCollection=arguments);
  203. if (ListFindNoCase(loc.routeConfig.variables, arguments.name))
  204. {
  205. arguments.pageNumberAsParam = false;
  206. }
  207. }
  208. if (arguments.showSinglePage || loc.totalPages > 1)
  209. {
  210. if (Len(arguments.prepend))
  211. loc.start = loc.start & arguments.prepend;
  212. if (arguments.alwaysShowAnchors)
  213. {
  214. if ((loc.currentPage - arguments.windowSize) > 1)
  215. {
  216. loc.pageNumber = 1;
  217. if (!arguments.pageNumberAsParam)
  218. {
  219. loc.linkToArguments[arguments.name] = loc.pageNumber;
  220. }
  221. else
  222. {
  223. loc.linkToArguments.params = arguments.name & "=" & loc.pageNumber;
  224. if (StructKeyExists(arguments, "params"))
  225. loc.linkToArguments.params = loc.linkToArguments.params & "&" & arguments.params;
  226. }
  227. loc.linkToArguments.text = loc.pageNumber;
  228. if (Len(arguments.prependToPage) && arguments.prependOnAnchor)
  229. loc.start = loc.start & arguments.prependToPage;
  230. loc.start = loc.start & linkTo(argumentCollection=loc.linkToArguments);
  231. if (Len(arguments.appendToPage) && arguments.appendOnAnchor)
  232. loc.start = loc.start & arguments.appendToPage;
  233. loc.start = loc.start & arguments.anchorDivider;
  234. }
  235. }
  236. loc.middle = "";
  237. for (loc.i=1; loc.i <= loc.totalPages; loc.i++)
  238. {
  239. if ((loc.i >= (loc.currentPage - arguments.windowSize) && loc.i <= loc.currentPage) || (loc.i <= (loc.currentPage + arguments.windowSize) && loc.i >= loc.currentPage))
  240. {
  241. if (!arguments.pageNumberAsParam)
  242. {
  243. loc.linkToArguments[arguments.name] = loc.i;
  244. }
  245. else
  246. {
  247. loc.linkToArguments.params = arguments.name & "=" & loc.i;
  248. if (StructKeyExists(arguments, "params"))
  249. loc.linkToArguments.params = loc.linkToArguments.params & "&" & arguments.params;
  250. }
  251. loc.linkToArguments.text = loc.i;
  252. if (Len(arguments.classForCurrent) && loc.currentPage == loc.i)
  253. loc.linkToArguments.class = arguments.classForCurrent;
  254. else
  255. StructDelete(loc.linkToArguments, "class");
  256. if (Len(arguments.prependToPage))
  257. loc.middle = loc.middle & arguments.prependToPage;
  258. if (loc.currentPage != loc.i || arguments.linkToCurrentPage)
  259. {
  260. loc.middle = loc.middle & linkTo(argumentCollection=loc.linkToArguments);
  261. }
  262. else
  263. {
  264. if (Len(arguments.classForCurrent))
  265. loc.middle = loc.middle & $element(name="span", content=loc.i, class=arguments.classForCurrent);
  266. else
  267. loc.middle = loc.middle & loc.i;
  268. }
  269. if (Len(arguments.appendToPage))
  270. loc.middle = loc.middle & arguments.appendToPage;
  271. }
  272. }
  273. if (arguments.alwaysShowAnchors)
  274. {
  275. if (loc.totalPages > (loc.currentPage + arguments.windowSize))
  276. {
  277. if (!arguments.pageNumberAsParam)
  278. {
  279. loc.linkToArguments[arguments.name] = loc.totalPages;
  280. }
  281. else
  282. {
  283. loc.linkToArguments.params = arguments.name & "=" & loc.totalPages;
  284. if (StructKeyExists(arguments, "params"))
  285. loc.linkToArguments.params = loc.linkToArguments.params & "&" & arguments.params;
  286. }
  287. loc.linkToArguments.text = loc.totalPages;
  288. loc.end = loc.end & arguments.anchorDivider;
  289. if (Len(arguments.prependToPage) && arguments.prependOnAnchor)
  290. loc.end = loc.end & arguments.prependToPage;
  291. loc.end = loc.end & linkTo(argumentCollection=loc.linkToArguments);
  292. if (Len(arguments.appendToPage) && arguments.appendOnAnchor)
  293. loc.end = loc.end & arguments.appendToPage;
  294. }
  295. }
  296. if (Len(arguments.append))
  297. loc.end = loc.end & arguments.append;
  298. }
  299. if (Len(loc.middle))
  300. {
  301. if (Len(arguments.prependToPage) && !arguments.prependOnFirst)
  302. loc.middle = Mid(loc.middle, Len(arguments.prependToPage)+1, Len(loc.middle)-Len(arguments.prependToPage));
  303. if (Len(arguments.appendToPage) && !arguments.appendOnLast)
  304. loc.middle = Mid(loc.middle, 1, Len(loc.middle)-Len(arguments.appendToPage));
  305. }
  306. loc.returnValue = loc.start & loc.middle & loc.end;
  307. </cfscript>
  308. <cfreturn loc.returnValue>
  309. </cffunction>