PageRenderTime 52ms CodeModel.GetById 44ms app.highlight 3ms RepoModel.GetById 1ms app.codeStats 0ms

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