- CFML Reference User Guide
- ColdFusion functions
- ColdFusion functions by category
- Functions a-b
- Abs
- ACos
- AddSOAPRequestHeader
- AddSOAPResponseHeader
- AjaxLink
- AjaxOnLoad
- ApplicationStop
- ArrayAppend
- ArrayAvg
- ArrayClear
- ArrayContains
- ArrayContainsNoCase
- ArrayDelete
- ArrayDeleteAt
- ArrayDeleteNoCase
- ArrayEach
- ArrayFilter
- ArrayFind
- ArrayFindAll
- ArrayFindAllNoCase
- ArrayFindNoCase
- ArrayInsertAt
- ArrayIsDefined
- ArrayIsEmpty
- ArrayLen
- ArrayMap
- ArrayMax
- ArrayMin
- ArrayNew
- ArrayPrepend
- ArrayReduce
- ArrayResize
- ArraySet
- ArraySetMetadata
- ArraySlice
- ArraySort
- ArraySum
- ArraySwap
- ArrayToList
- Asc
- ASin
- Atn
- AuthenticatedContext
- AuthenticatedUser
- BinaryDecode
- BinaryEncode
- BitAnd
- BitMaskClear
- BitMaskRead
- BitMaskSet
- BitNot
- BitOr
- BitSHLN
- BitSHRN
- BitXor
- BooleanFormat
- Abs
- Functions-c-d
- CacheGet
- CacheGetAllIds
- CacheGetMetadata
- CacheGetProperties
- CacheGetSession
- CacheIdExists
- CachePut
- CacheRegionExists
- CacheRegionNew
- CacheRegionRemove
- CacheRemove
- CacheRemoveAll
- CacheSetProperties
- CallStackDump
- CallStackGet
- CanDeSerialize
- Canonicalize
- CanSerialize
- Ceiling
- CharsetDecode
- CharsetEncode
- Chr
- CJustify
- Compare
- CompareNoCase
- Cos
- CreateDate
- CreateDateTime
- CreateObject
- CreateObject: .NET object
- CreateObject: COM object
- CreateObject: component object
- CreateObject: CORBA object
- CreateObject: Java or EJB object
- CreateObject: web service object
- CreateODBCDate
- CreateODBCDateTime
- CreateODBCTime
- CreateSignedJWT
- CreateEncryptedJWT
- CreateTime
- CreateTimeSpan
- CreateUUID
- CSRFGenerateToken
- CSRFVerifyToken
- CSVRead
- CSVWrite
- CSVProcess
- DateAdd
- DateCompare
- DateConvert
- DateDiff
- DateFormat
- DatePart
- DateTimeFormat
- Day
- DayOfWeek
- DayOfWeekAsString
- DayOfYear
- DaysInMonth
- DaysInYear
- DE
- DecimalFormat
- DecodeForHTML
- DecodeFromURL
- DecrementValue
- Decrypt
- DecryptBinary
- DeleteClientVariable
- Deserialize
- DeserializeJSON
- DeserializeXML
- DirectoryCopy
- DirectoryCreate
- DirectoryDelete
- DirectoryExists
- DirectoryList
- DirectoryRename
- DollarFormat
- DotNetToCFType
- Duplicate
- Functions-e-g
- EncodeForCSS
- EncodeForDN
- EncodeForHTML
- EncodeForHTMLAttribute
- EncodeForJavaScript
- EncodeForLDAP
- EncodeForURL
- EncodeForXML
- EncodeForXMLAttribute
- EncodeForXpath
- Encrypt
- EncryptBinary
- EntityDelete
- EntityLoad
- EntityLoadByExample
- EntityLoadByPK
- EntityMerge
- EntityNew
- EntityReload
- EntitySave
- EntityToQuery
- Evaluate
- Exp
- ExpandPath
- FileClose
- FileCopy
- FileDelete
- FileExists
- FileGetMimeType
- FileIsEOF
- FileMove
- FileOpen
- FileRead
- FileReadBinary
- FileReadLine
- FileSeek
- FileSetAccessMode
- FileSetAttribute
- FileSetLastModified
- FileSkipBytes
- FileUpload
- FileUploadAll
- FileWrite
- FileWriteLine
- Find
- FindNoCase
- FindOneOf
- FirstDayOfMonth
- Fix
- Floor
- FormatBaseN
- GeneratePBKDFKey
- GenerateSecretKey
- GetApplicationMetadata
- GetAuthUser
- GetBaseTagData
- GetBaseTagList
- GetBaseTemplatePath
- GetClientVariablesList
- GetComponentMetaData
- GetContextRoot
- GetCPUUsage
- GetCurrentTemplatePath
- GetCSPNonce
- GetDirectoryFromPath
- GetEncoding
- GetException
- GetFileFromPath
- GetFileInfo
- GetFreeSpace
- GetFunctionCalledName
- GetFunctionList
- GetGatewayHelper
- GetHttpRequestData
- GetHttpTimeString
- GetK2ServerDocCount
- GetK2ServerDocCountLimit
- GetLocale
- GetLocaleDisplayName
- GetLocalHostIP
- GetMetaData
- GetMetricData
- GetPageContext
- GetPropertyString
- GetPropertyFile
- GetPrinterInfo
- GetPrinterList
- GetProfileSections
- GetProfileString
- GetReadableImageFormats
- GetSafeHTML
- GetSAMLAuthRequest
- GetSAMLLogoutRequest
- Generate3DesKey
- GenerateSAMLSPMetadata
- GetSOAPRequest
- GetSOAPRequestHeader
- GetSOAPResponse
- GetSOAPResponseHeader
- GetSystemFreeMemory
- GetSystemTotalMemory
- GetTempDirectory
- GetTempFile
- GetTemplatePath
- GetTickCount
- GetTimeZoneInfo
- GetToken
- GetTotalSpace
- GetUserRoles
- GetVFSMetaData
- GetWriteableImageFormats
- Functions-h-im
- Hash
- HMac
- Hour
- HQLMethods
- HTMLCodeFormat
- HTMLEditFormat
- IIf
- ImageAddBorder
- ImageBlur
- ImageClearRect
- ImageCopy
- ImageCreateCaptcha
- ImageCrop
- ImageDrawArc
- ImageDrawBeveledRect
- ImageDrawCubicCurve
- ImageDrawLine
- ImageDrawLines
- ImageDrawOval
- ImageDrawPoint
- ImageDrawQuadraticCurve
- ImageDrawRect
- ImageDrawRoundRect
- ImageDrawText
- ImageFlip
- ImageGetBlob
- ImageGetBufferedImage
- ImageGetEXIFMetadata
- ImageGetEXIFTag
- ImageGetHeight
- ImageGetIPTCMetadata
- ImageGetIPTCTag
- ImageGetMetadata
- ImageGetWidth
- ImageGrayscale
- ImageInfo
- ImageMakeColorTransparent
- ImageMakeTranslucent
- ImageNegative
- ImageNew
- ImageOverlay
- ImagePaste
- ImageRead
- ImageReadBase64
- ImageResize
- ImageRotate
- ImageRotateDrawingAxis
- ImageScaleToFit
- ImageSetAntialiasing
- ImageSetBackgroundColor
- ImageSetDrawingColor
- ImageSetDrawingStroke
- ImageSetDrawingTransparency
- ImageSharpen
- ImageShear
- ImageShearDrawingAxis
- ImageTranslate
- ImageTranslateDrawingAxis
- ImageWrite
- ImageWriteBase64
- ImageXORDrawingMode
- Functions-in-k
- IncrementValue
- InputBaseN
- Insert
- Int
- InterruptThread
- InvalidateOauthAccesstoken
- Invoke
- InitSAMLAuthRequest
- InitSAMLLogoutRequest
- InvokeCFClientFunction
- IsArray
- IsAuthenticated
- IsAuthorized
- IsBinary
- IsBoolean
- IsClosure
- IsCustomFunction
- IsDate
- IsDateObject
- IsDDX
- IsDebugMode
- IsDefined
- IsImage
- IsImageFile
- IsInstanceOf
- IsIPv6
- IsJSON
- IsK2ServerABroker
- IsK2ServerDocCountExceeded
- IsK2ServerOnline
- IsLeapYear
- IsLocalHost
- IsNull
- IsNumeric
- IsNumericDate
- IsObject
- isOnline
- IsPDFArchive
- IsPDFFile
- IsPDFObject
- IsProtected
- IsQuery
- isSamlLogoutResponse
- isSafeHTML
- IsSimpleValue
- IsSOAPRequest
- IsSpreadsheetFile
- IsSpreadsheetObject
- IsStruct
- isThreadInterrupted
- IsUserInAnyRole
- IsUserInRole
- IsUserLoggedIn
- IsValid
- IsValidOauthAccesstoken
- IsWDDX
- IsXML
- IsXmlAttribute
- IsXmlDoc
- IsXmlElem
- IsXmlNode
- IsXmlRoot
- JavaCast
- JSStringFormat
- Functions-l
- LCase
- Left
- Len
- ListAppend
- ListChangeDelims
- ListContains
- ListContainsNoCase
- ListDeleteAt
- ListEach
- ListFilter
- ListFind
- ListFindNoCase
- ListFirst
- ListGetAt
- ListGetDuplicates
- ListInsertAt
- ListLast
- ListLen
- ListMap
- ListPrepend
- ListQualify
- ListReduce
- ListRemoveDuplicates
- ListRest
- ListSetAt
- ListSort
- ListToArray
- ListValueCount
- ListValueCountNoCase
- LJustify
- Location
- Log
- Log10
- LSCurrencyFormat
- LSDateFormat
- LSDateTimeFormat
- LSEuroCurrencyFormat
- LSIsCurrency
- LSIsDate
- LSIsNumeric
- LSNumberFormat
- LSParseCurrency
- LSParseDateTime
- LSParseEuroCurrency
- LSParseNumber
- LSTimeFormat
- LTrim
- Functions-m-r
- Max
- Mid
- Min
- Minute
- Month
- MonthAsString
- Now
- NumberFormat
- ObjectEquals
- ObjectLoad
- ObjectSave
- OnWSAuthenticate
- ORMClearSession
- ORMCloseAllSessions
- ORMCloseSession
- ORMEvictCollection
- ORMEvictEntity
- ORMEvictQueries
- ORMExecuteQuery
- ORMFlush
- ORMFlushall
- ORMGetSession
- ORMGetSessionFactory
- ORMIndex
- ORMIndexPurge
- ORMReload
- ORMSearch
- ORMSearchOffline
- ParagraphFormat
- ParameterExists
- ParseDateTime
- Pi
- PrecisionEvaluate
- ProcessSAMLResponse
- ProcessSAMLLogoutRequest
- Quarter
- PreserveSingleQuotes
- QueryAddColumn
- QueryAddRow
- QueryConvertForGrid
- QueryExecute
- QueryFilter
- QueryGetResult
- QueryGetRow
- QueryKeyExists
- QueryMap
- QueryNew
- QueryReduce
- QuerySetCell
- QuotedValueList
- QueryEach
- Rand
- Randomize
- RandRange
- ReEscape
- REFind
- REFindNoCase
- ReleaseComObject
- REMatch
- REMatchNoCase
- RemoveCachedQuery
- RemoveChars
- RepeatString
- Replace
- ReplaceList
- ReplaceNoCase
- REReplace
- REReplaceNoCase
- RestDeleteApplication
- RestSetResponse
- RestInitApplication
- Reverse
- Right
- RJustify
- Round
- RTrim
- Functions-s
- Second
- SendGatewayMessage
- SendSAMLLogoutResponse
- Serialize
- SerializeJSON
- SerializeXML
- SessionInvalidate
- SessionRotate
- SessionGetMetaData
- SessionInvalidate
- SessionRotate
- SetDay
- SetEncoding
- SetHour
- SetLocale
- SetMonth
- SetProfileString
- SetPropertyString
- SetVariable
- SetYear
- Sgn
- Sin
- Sleep
- SpanExcluding
- SpanIncluding
- SpreadsheetAddAutoFilter
- SpreadsheetAddColumn
- SpreadsheetAddFreezePane
- SpreadsheetAddImage
- SpreadsheetAddInfo
- SpreadsheetAddPageBreaks
- SpreadsheetAddRow
- SpreadsheetAddRows
- SpreadsheetAddSplitPane
- SpreadsheetCreateSheet
- SpreadsheetDeleteColumn
- SpreadsheetDeleteColumns
- SpreadsheetDeleteRow
- SpreadsheetDeleteRows
- SpreadsheetFormatCell
- SpreadsheetFormatColumn
- SpreadsheetFormatCellRange
- SpreadsheetFormatColumn
- SpreadsheetFormatColumns
- SpreadsheetFormatRow
- SpreadsheetFormatRows
- SpreadsheetGetCellComment
- SpreadsheetGetCellFormula
- SpreadsheetGetCellValue
- SpreadsheetGetColumnCount
- SpreadsheetInfo
- SpreadsheetMergeCells
- SpreadsheetNew
- SpreadsheetRead
- SpreadsheetReadBinary
- SpreadsheetRemoveSheet
- SpreadsheetSetActiveSheet
- SpreadsheetSetActiveSheetNumber
- SpreadsheetSetCellComment
- SpreadsheetSetCellFormula
- SpreadsheetSetCellValue
- SpreadsheetSetColumnWidth
- SpreadsheetSetFooter
- SpreadsheetSetHeader
- SpreadsheetSetRowHeight
- SpreadsheetShiftColumns
- SpreadsheetShiftRows
- SpreadsheetWrite
- StreamingSpreadsheetNew
- StreamingSpreadsheetCleanup
- StreamingSpreadsheetRead
- StreamingSpreadsheetProcess
- SpreadsheetSetFooterImage
- SpreadsheetSetHeaderImage
- SpreadsheetSetFittoPage
- SpreadsheetUngroupColumns
- SpreadsheetGroupColumns
- SpreadsheetUngroupRows
- SpreadsheetGroupRows
- SpreadsheetRemoveColumnBreak
- SpreadsheetSetColumnBreak
- SpreadsheetRemoveRowBreak
- SpreadsheetSetRowBreak
- SpreadsheetRemovePrintGridlines
- SpreadsheetAddPrintGridlines
- SpreadsheetGetColumnWidth
- SpreadsheetSetColumnHidden
- SpreadsheetSetRowHidden
- SpreadsheetisColumnHidden
- SpreadsheetisRowHidden
- SpreadsheetisStreamingXmlFormat
- SpreadsheetisXmlFormat
- SpreadsheetisBinaryFormat
- SpreadsheetRenameSheet
- SpreadsheetRemoveSheetNumber
- SpreadsheetGetLastRowNumber
- SpreadsheetGetPrintOrientation
- Sqr
- StripCR
- StructAppend
- StructClear
- StructCopy
- StructCount
- StructDelete
- StructEach
- StructFilter
- StructFind
- StructFindKey
- StructFindValue
- StructGet
- StructGetMetadata
- StructInsert
- StructIsEmpty
- StructKeyArray
- StructKeyExists
- StructKeyList
- StructMap
- StructNew
- StructReduce
- StructSetMetadata
- StructSort
- StructToSorted
- StructUpdate
- StructValueArray
- StoreSetMetadata
- StoreGetACL
- StoreGetMetadata
- StoreAddACL
- StoreSetACL
- Functions-t-z
- Tan
- ThreadJoin
- ThreadTerminate
- Throw
- TimeFormat
- ToBase64
- ToBinary
- ToScript
- ToString
- Trace
- Transactionandconcurrency
- TransactionCommit
- TransactionRollback
- TransactionSetSavePoint
- Trim
- UCase
- URLDecode
- URLEncodedFormat
- URLSessionFormat
- Val
- ValueList
- VerifyClient
- Week
- Wrap
- WriteDump
- WriteLog
- WriteOutput
- WSGetAllChannels
- WSGetSubscribers
- WSPublish
- WSSendMessage
- XmlChildPos
- XmlElemNew
- XmlFormat
- XmlGetNodeType
- XmlNew
- XmlParse
- XmlSearch
- XmlTransform
- XmlValidate
- Year
- YesNoFormat
- ColdFusion tags
- ColdFusion tag summary
- ColdFusion tags by category
- Application framework tags
- Communications tags
- Database manipulation tags
- Data output tags
- Debugging tags
- Exception handling tags
- Extensibility tags
- File management tags
- Flow-control tags
- Forms tags
- Internet Protocol tags
- Page processing tags
- Security tags
- Variable manipulation tags
- Other tags
- Tags a-b
- Tags c
- cfcache
- cfcalendar
- cfcase
- cfcatch
- cfchart
- cfchart tag in ColdFusion
- Get started with cfchart
- Customize a chart using cfchart
- Advanced cfchart customization options
- Create an area chart in ColdFusion
- Create line charts in ColdFusion
- Create bar charts in ColdFusion
- Create floating bar charts in ColdFusion
- Create histograms in ColdFusion
- Create pie charts in ColdFusion
- Create funnel charts in ColdFusion
- Create pyramid charts in ColdFusion
- Create curve charts in ColdFusion
- Create boxplots in ColdFusion
- Create donut charts in ColdFusion
- Create bubble charts in ColdFusion
- Create scatterplots in ColdFusion
- Create radar charts in ColdFusion
- Other chart types in ColdFusion (Cone, Cylinder, Piano, and Bullet)
- Advanced customization options in cfchart
- cfchartdata
- cfchartseries
- cfchartset
- cfclient
- cfclientsettings
- cfcol
- cfcollection
- cfcomponent
- cfcontent
- cfcontinue
- cfcookie
- Tags f
- cffeed
- cffile
- cffile action = "append"
- cffile action = "copy"
- cffile action = "delete"
- cffile action = "move"
- cffile action = "read"
- cffile action = "readBinary"
- cffile action = "rename"
- cffile action = "upload"
- cffile action = "uploadAll"
- cffile action = "write"
- cffileupload
- cffinally
- cfflush
- cfform
- cfformgroup
- cfformitem
- cfftp
- cfftp: Connection: file and directory operations
- cfftp: Opening and closing FTP server connections
- cfftp : Opening and closing secure FTP server connections
- cfftp action = "listDir"
- cffunction
- Tags g-h
- Tags i
- Tags j-l
- cfjava
- cflayout
- cflayoutarea
- cfldap
- cflocation
- cflock
- cflog
- cflogin
- cfloginuser
- cflogout
- cfloop
- cfloop : conditional loop
- cfloop : index loop
- cfloop : looping over a COM collection or structure
- cfloop : looping over a date or time range
- cfloop : looping over a list, a file, or an array
- cfloop : looping over a query
- Tags m-o
- cfmail
- cfmailparam
- cfmailpart
- cfmap
- cfmapitem
- cfmediaplayer
- cfmenu
- cfmenuitem
- cfmessagebox
- cfmodule
- cfNTauthenticate
- cfoauth
- cfobject
- cfobject: .NET object
- cfobject: COM object
- cfobject: component object
- cfobject: CORBA object
- cfobject: Java or EJB object
- cfobject: web service object
- cfobjectcache
- cfoutput
- Tags p-q
- Tags r-s
- Tags t
- Tags u-z
- CFML Reference
- Reserved words and variables
- Ajax JavaScript functions
- Ajax JavaScript functions
- Function summary Ajax
- ColdFusion.Ajax.submitForm
- ColdFusion.Autosuggest.getAutosuggestObject
- ColdFusion.Layout.enableSourceBind
- ColdFusion.MessageBox.getMessageBoxObject
- ColdFusion.ProgressBar.getProgressBarObject
- ColdFusion.MessageBox.isMessageBoxDefined
- JavaScriptFunctionsinColdFusion9Update1
- ColdFusion ActionScript functions
- ColdFusion mobile functions
- Application.cfc reference
- Script functions implemented as CFCs
- ColdFusion Flash Form style reference
- Styles valid for all controls
- Styles for cfform
- Styles for cfformgroup with horizontal or vertical type attributes
- Styles for box-style cfformgroup elements
- Styles for cfformgroup with accordion type attribute
- Styles for cfformgroup with tabnavigator type attribute
- Styles for cfformitem with hrule or vrule type attributes
- Styles for cfinput with radio, checkbox, button, image, or submit type attributes
- Styles for cftextarea tag and cfinput with text, password, or hidden type attributes
- Styles for cfselect with size attribute value of 1
- Styles for cfselect with size attribute value greater than 1
- Styles for cfcalendar tag and cfinput with dateField type attribute
- Styles for the cfgrid tag
- Styles for the cftree tag
- ColdFusion Flash Form Style Reference
- ColdFusion event gateway reference
- ColdFusion Event Gateway reference
- addEvent
- CFEvent
- CFEventclass
- Constructor
- Gateway development interfaces and classes
- getStatus
- setCFCPath
- setCFCMethod
- getOriginatorID
- getLogger
- getBuddyList
- getBuddyInfo
- IM gateway message sending commands
- IM Gateway GatewayHelper class methods
- onIncomingMessage
- onIMServerMessage
- onBuddyStatus
- onAddBuddyResponse
- onAddBuddyRequest
- IM Gateway CFC incoming message methods
- IM gateway methods and commands
- CFML CFEvent structure
- warn
- info
- setOriginatorID
- data command
- submit Multi command
- submit command
- setGatewayType
- setGatewayID
- setData
- setCFCListeners
- outgoingMessage
- getStatusTimeStamp
- numberOfMessagesReceived
- numberOfMessagesSent
- removeBuddy
- removeDeny
- removePermit
- setNickName
- setPermitMode
- setStatus
- SMS Gateway CFEvent structure and commands
- SMS Gateway incoming message CFEvent structure
- getStatusAsString
- getProtocolName
- getPermitMode
- getPermitList
- getNickName
- getName
- getDenyList
- getCustomAwayMessage
- getQueueSize
- getMaxQueueSize
- getHelper
- getGatewayType
- getGatewayServices
- getGatewayID_1
- getGatewayID
- getData
- getCFCTimeout
- setCFCTimeout
- getCFCPath
- getCFCMethod
- GatewayServices class
- Gateway interface
- GatewayHelper interface
- addPermit
- addDeny
- addBuddy
- error
- debug
- Logger class
- stop
- start
- CFML event gateway SendGatewayMessage data parameter
- restart
- fatal
- SMS gateway message sending commands
- ColdFusion C++ CFX Reference
- ColdFusion Java CFX reference
- WDDX JavaScript Objects
- Cloud services
- ColdFusion and GCP Storage
- ColdFusion and GCP Firestore
- ColdFusion and GCP PubSub
- ColdFusion and Amazon S3
- ColdFusion and DynamoDB
- ColdFusion and Amazon SQS
- ColdFusion and Amazon SNS
- ColdFusion and MongoDB
- ColdFusion and Azure Blob
- ColdFusion and Azure Service Bus
- Multi-cloud storage services
- Multi-cloud RDS databases
- ColdFusion and Azure Cosmos DB
Description
Displays output that can contain the results of processing ColdFusion variables and functions. Can loopover the results of a database query.
Category
Syntax
<cfoutput> group = "query column" encodefor= "encoding type" groupCaseSensitive = "yes|no" maxRows = "maximum rows to display" query = "query name" startRow = "start row" </cfoutput>
You can specify this tag's attributes in an attributeCollection attribute whose value is a structure. Specify the structure name in the attributeCollection attribute and use the tag's attribute names as structure keys.
See also
History
ColdFusion 4.5.0: Added the groupCaseSensitive attribute.
Attributes
Attribute |
Req/Opt |
Default |
Description |
|---|---|---|---|
group |
Optional |
|
Query column to use to group sets of records. Eliminates adjacent duplicate rows when data is sorted. Use if you retrieved a record set ordered on one or more a query columns. For example, if a record set is ordered on "Customer_ID" in the cfquery tag, you can group the output on "Customer_ID." |
encodefor |
Optional |
|
Based on the value, encodefor will be invoked for each expression inside the cfoutput tag body except the expression which is already wrapped using encodefor function. Possible values are html , htmlattribute , url , javascript, css , xml , xmlattribute , xpath , ldap , and dn . |
groupCaseSensitive |
Optional |
no |
Boolean. Whether to consider the case in grouping rows. |
maxRows |
Optional |
Displays all rows |
Maximum number of rows to display. |
query |
Optional |
|
Name of cfquery from which to draw data for output section. |
startRow |
Optional |
1 |
Row from which to start output. |
If you face any issues in line breaks, use the <pre> tag wrapped inside cfoutput,. Then the new lines will show up in HTML.
For example,
<cfoutput>
<pre>#variables.signature#</pre>
</cfoutput>
Usage
In the cfoutput tag body, ColdFusion treats text that is surrounded by number signs (#) as a ColdFusion variable or function call. For example, the following code displays the text "Hello World!":
<cfoutput>#myVar#</cfoutput>
When you specify a query attribute, this tag loops over the query rows and produces output for each row within the range specified by the startRow and maxRows values, and groups or eliminates duplicate entries as specified by the grouping attribute values, if any. It also sets the query.currentRow variable to the current row being processed.
If you nest cfoutput blocks that process a query, you specify the query and group attributes at the top-most level; you can specify a group attribute for each inner block except the innermost cfoutput block.
This tag requires an end tag.
Example
<!--- Run a sample query. --->
<cfquery name = "GetCourses" dataSource = "cfdocexamples">
SELECT Dept_ID, CorName, CorLevel
FROM courseList
ORDER by Dept_ID, CorLevel, CorName
</cfquery>
<h3>cfoutput Example</h3>
<p>cfoutput tells ColdFusion Server to begin processing, and then to hand back control of page rendering to the web server.
<p>For example, to show today's date, you could write #DateFormat("#Now()#"). If you enclosed that expression in cfoutput, the result would be<cfoutput>#DateFormat(Now())#</cfoutput>.
<p>In addition, cfoutput may be used to show the results of a query operation, or only a partial result, as shown:
<p>There are <cfoutput>#getCourses.recordCount#</cfoutput> total records in our query. Using the maxRows parameter, we are limiting our display to 4 rows.
<p><cfoutput query = "GetCourses" maxRows = 4>
#Dept_ID# #CorName# #CorLevel#<br>
</cfoutput>
<p>EXAMPLE: The next example uses the group attribute to eliminate duplicate lines from a
list of course levels taught in each department.</p>
<p><cfquery name = "GetCourses" dataSource = "cfdocexamples"></p>
SELECT Dept_ID, CorLevel
FROM courseList
ORDER by Dept_ID, CorLevel
</cfquery>
<p><cfoutput query = "GetCourses" group="CorLevel" GroupCaseSensitive="True">
#Dept_ID# #CorLevel#<br></p>
</cfoutput>
<p>cfoutput can also show the results of a more complex expression,
such as getting the day of the week from today's date. We first
extract the integer representing the Day of the Week from
the server function Now() and then apply the result to
the DayofWeekAsString function:</p>
<br>Today is #DayofWeekAsString(DayofWeek(Now()))#
<br>Today is <cfoutput>#DayofWeekAsString(DayofWeek(Now()))#</cfoutput>
<p> EXAMPLE: This last example shows nested cfoutput tags:</p>
<cfquery datasource="cfdocexamples" name="empSalary">
SELECT Emp_ID, firstname, lastname, e.dept_id, salary, d.dept_name
FROM employee e, departmt d
WHERE e.dept_id = d.dept_id
ORDER BY d.dept_name
</cfquery>
<!--- Outer cfoutput. --->
<cfoutput query="empSalary" group="dept_id">
<h2>#dept_name#</h2>
<table width="95%" border="2" cellspacing="2" cellpadding="2" >
<tr>
<th>Employee</th>
<th>Salary</th>
</tr>
<cfset deptTotal = 0 >
<!--- Inner cfoutput. --->
<cfoutput>
<tr>
<td>#empSalary.lastname#, #empSalary.firstname#</td>
<td align="right">#DollarFormat(empSalary.salary)#</td>
</tr>
<cfset deptTotal = deptTotal + empSalary.salary>
</cfoutput>
<tr>
<td align="right">Total</td>
<td align="right">#DollarFormat(deptTotal)#</td>
</tr>
<cfset deptTotal = 0>
</table>
</cfoutput>
Examples with encodeFor parameter
<cfset name="sample!@$">
<cfoutput encodeFor="URL">
#name#<br>
</cfoutput>
The above sample produces the following output:
sample%21%40%24
<cfset name="sample!@$">
<cfoutput encodeFor="CSS">
#name#<br>
</cfoutput>
The above sample produces the following output:
sample\21 \40 \24
<!--- In this case, the EncodeForURL takes precedence over the EncodeForJavascript that would normally occur for just what it is wrapped around --->
<cfset name="sample!@$">
<cfset type = "javascript">
<cfoutput encodefor="#type#">
encoded using encodeforjavascript:#name#; encoded using encodeforurl:#EncodeForURL(name)# adobe
</cfoutput>
The above sample produces the following output:
encoded using encodeforjavascript:sample\x21\x40\x24; encoded using encodeforurl:sample%21%40%24 adobe
Example with groupCaseSensitive attribute
<cfscript>
colors = queryNew("id,color","integer,varchar",
[
{"id":1,"color":"RED"},
{"id":2,"color":"Red"},
{"id":3,"color":"red"}
]);
</cfscript>
<b>Default:</b><br>
<cfoutput query="colors" group="color">
#color#<br>
</cfoutput>
<b>Explicit:</b><br>
<cfoutput query="colors" group="color" groupcasesensitive="yes">
#color#<br>
</cfoutput>
<cfscript>
colors = queryNew("id,color","integer,varchar",
[
{"id":1,"color":"RED"},
{"id":2,"color":"Red"},
{"id":3,"color":"red"}
]);
</cfscript>
<b>Default:</b><br>
<cfoutput query="colors" group="color">
#color#<br>
</cfoutput>
<b>Explicit:</b><br>
<cfoutput query="colors" group="color" groupcasesensitive="no">
#color#<br>
</cfoutput>
Output
Default:
RED
Explicit:
RED
Real-world uses of the cfoutput tag
E-commerce product listing page
Your online store needs to display product information including names, prices, descriptions, and availability. The product data comes from variables and needs to be formatted properly for web display with currency formatting, date formatting, and conditional messages based on stock levels.
Problem statement
- Product data stored in variables and structs needs to be displayed on web pages
- Prices must be formatted as currency
- Dates need proper formatting
- Stock status requires conditional display logic
- Need to output dynamic content mixed with static HTML
Solution
The cfoutput tag calculates and displays results online, formats data with functions like numberFormat and dateFormat, and displays product data.
<h1>Product Catalog Display Demo</h1>
<p><strong>What This Demo Shows:</strong> How to use cfoutput to display variables, format data, and mix dynamic content with HTML.</p>
<hr>
<h2>Example 1: Basic Product Information Display</h2>
<cfscript>
// Define product data
productName = "Wireless Bluetooth Headphones";
regularPrice = 79.99;
salePrice = 59.99;
stockQuantity = 42;
productSKU = "WBH-2024-001";
launchDate = createDate(2024, 10, 15);
</cfscript>
<cfoutput>
<div style="border: 1px solid ##ccc; padding: 15px; margin: 10px 0; background-color: ##f9f9f9;">
<h3>#productName#</h3>
<p><strong>SKU:</strong> #productSKU#</p>
<p><strong>Regular Price:</strong> <span style="text-decoration: line-through;">$#numberFormat(regularPrice, "0.00")#</span></p>
<p><strong>Sale Price:</strong> <span style="color: red; font-size: 1.2em; font-weight: bold;">$#numberFormat(salePrice, "0.00")#</span></p>
<p><strong>You Save:</strong> $#numberFormat(regularPrice - salePrice, "0.00")# (#numberFormat((regularPrice - salePrice) / regularPrice * 100, "0")#% off)</p>
<p><strong>Stock:</strong> #stockQuantity# units available</p>
<p><strong>Launch Date:</strong> #dateFormat(launchDate, "mmmm d, yyyy")#</p>
</div>
</cfoutput>
<hr>
<h2>Example 2: Conditional Stock Status Display</h2>
<cfscript>
// Multiple products with different stock levels
products = [
{name: "Laptop Computer", price: 899.99, stock: 15},
{name: "USB-C Cable", price: 12.99, stock: 3},
{name: "Wireless Mouse", price: 29.99, stock: 0},
{name: "Monitor Stand", price: 45.50, stock: 8}
];
</cfscript>
<cfloop array="#products#" index="product">
<cfoutput>
<div style="border: 1px solid ##ddd; padding: 10px; margin: 5px 0;">
<strong>#product.name#</strong> - $#numberFormat(product.price, "0.00")#
<cfif product.stock GT 10>
<span style="color: green; font-weight: bold;"> ✓ In Stock (#product.stock# available)</span>
<cfelseif product.stock GT 0 AND product.stock LTE 10>
<span style="color: orange; font-weight: bold;"> ⚠ Low Stock (Only #product.stock# left!)</span>
<cfelse>
<span style="color: red; font-weight: bold;"> ✗ Out of Stock</span>
</cfif>
</div>
</cfoutput>
</cfloop>
<hr>
<h2>Example 3: Product Details with Calculations</h2>
<cfscript>
// Product with multiple attributes
product = {
name: "4K Smart TV",
brand: "TechVision",
model: "TV-4K-55",
price: 599.99,
taxRate: 0.085,
shippingCost: 25.00,
weight: 35.5,
rating: 4.5,
reviewCount: 328
};
</cfscript>
<cfoutput>
<div style="border: 2px solid ##333; padding: 20px; background-color: ##fff;">
<h3>#product.brand# #product.name#</h3>
<p><strong>Model:</strong> #product.model#</p>
<h4>Pricing Breakdown:</h4>
<ul>
<li>Base Price: $#numberFormat(product.price, "0.00")#</li>
<li>Tax (#numberFormat(product.taxRate * 100, "0.0")#%): $#numberFormat(product.price * product.taxRate, "0.00")#</li>
<li>Shipping: $#numberFormat(product.shippingCost, "0.00")#</li>
<li style="font-weight: bold; font-size: 1.1em;">Total: $#numberFormat(product.price + (product.price * product.taxRate) + product.shippingCost, "0.00")#</li>
</ul>
<p><strong>Weight:</strong> #product.weight# lbs</p>
<p><strong>Customer Rating:</strong> #product.rating# / 5.0 (#product.reviewCount# reviews)</p>
<p><strong>Average Review:</strong>
<cfif product.rating GTE 4.5>
⭐⭐⭐⭐⭐ Excellent
<cfelseif product.rating GTE 4.0>
⭐⭐⭐⭐ Very Good
<cfelseif product.rating GTE 3.0>
⭐⭐⭐ Good
<cfelse>
⭐⭐ Fair
</cfif>
</p>
</div>
</cfoutput>
<hr>
<h2>Example 4: Multiple Products Summary</h2>
<cfscript>
// Cart items
cartItems = [
{name: "Keyboard", price: 89.99, quantity: 1},
{name: "Mouse Pad", price: 15.99, quantity: 2},
{name: "USB Hub", price: 34.99, quantity: 1}
];
cartTotal = 0;
itemCount = 0;
</cfscript>
<h3>Shopping Cart Summary</h3>
<table border="1" cellpadding="8" cellspacing="0" style="border-collapse: collapse; width: 100%;">
<tr style="background-color: ##f0f0f0;">
<th>Product</th>
<th>Price</th>
<th>Quantity</th>
<th>Subtotal</th>
</tr>
<cfloop array="#cartItems#" index="item">
<cfset itemSubtotal = item.price * item.quantity>
<cfset cartTotal = cartTotal + itemSubtotal>
<cfset itemCount = itemCount + item.quantity>
<cfoutput>
<tr>
<td>#item.name#</td>
<td>$#numberFormat(item.price, "0.00")#</td>
<td>#item.quantity#</td>
<td>$#numberFormat(itemSubtotal, "0.00")#</td>
</tr>
</cfoutput>
</cfloop>
<cfoutput>
<tr style="background-color: ##e6ffe6; font-weight: bold;">
<td colspan="2">Total (#itemCount# items)</td>
<td colspan="2">$#numberFormat(cartTotal, "0.00")#</td>
</tr>
</cfoutput>
</table>
<hr>
Corporate employee directory system
Your HR department needs an employee directory that displays all employees organized by department. The directory should show department names as headers with all employees listed under their respective departments. The data comes from a database query and needs to be grouped by department to avoid repeating department headers.
Problem statement
- Query results contain employee data with department information
- Need to display employees grouped by department
- Department names should appear as headers (not repeated for each employee)
- Results must be sorted properly for grouping to work
Solution
The cfoutput tag uses the query attribute to loop through the query results, group attribute to group by department and eliminate duplicates, and references columns directly with #queryName.columnName#.
<h1>Employee Directory with Department Grouping Demo</h1>
<p><strong>What This Demo Shows:</strong> How to use cfoutput with query results and group attribute for organized display.</p>
<hr>
<h2>Example 1: Basic Query Loop (No Grouping)</h2>
<cfscript>
// Create mock employee data
employees = queryNew("employeeID,firstName,lastName,email,department",
"integer,varchar,varchar,varchar,varchar",
[
{employeeID: 101, firstName: "John", lastName: "Smith", email: "john.smith@company.com", department: "Sales"},
{employeeID: 102, firstName: "Jane", lastName: "Doe", email: "jane.doe@company.com", department: "Marketing"},
{employeeID: 103, firstName: "Bob", lastName: "Johnson", email: "bob.johnson@company.com", department: "Sales"},
{employeeID: 104, firstName: "Alice", lastName: "Williams", email: "alice.williams@company.com", department: "IT"},
{employeeID: 105, firstName: "Charlie", lastName: "Brown", email: "charlie.brown@company.com", department: "Marketing"}
]
);
</cfscript>
<cfoutput>
<p><strong>Total Employees:</strong> #employees.recordCount#</p>
</cfoutput>
<table border="1" cellpadding="8" cellspacing="0" style="border-collapse: collapse; width: 100%;">
<tr style="background-color: ##f0f0f0;">
<th>ID</th>
<th>Name</th>
<th>Email</th>
<th>Department</th>
</tr>
<cfoutput query="employees">
<tr>
<td>#employeeID#</td>
<td>#firstName# #lastName#</td>
<td>#email#</td>
<td>#department#</td>
</tr>
</cfoutput>
</table>
<hr>
<h2>Example 2: Grouped by Department</h2>
<cfscript>
// Create sorted employee data for proper grouping
employeesByDept = queryNew("employeeID,firstName,lastName,title,department,phone",
"integer,varchar,varchar,varchar,varchar,varchar",
[
{employeeID: 206, firstName: "Emily", lastName: "Taylor", title: "IT Manager", department: "IT", phone: "555-0301"},
{employeeID: 207, firstName: "James", lastName: "Thomas", title: "Developer", department: "IT", phone: "555-0302"},
{employeeID: 208, firstName: "Maria", lastName: "Garcia", title: "System Admin", department: "IT", phone: "555-0303"},
{employeeID: 204, firstName: "Lisa", lastName: "Anderson", title: "Marketing Director", department: "Marketing", phone: "555-0201"},
{employeeID: 205, firstName: "David", lastName: "Martinez", title: "Content Specialist", department: "Marketing", phone: "555-0202"},
{employeeID: 202, firstName: "Mike", lastName: "Davis", title: "Sales Rep", department: "Sales", phone: "555-0102"},
{employeeID: 201, firstName: "Sarah", lastName: "Johnson", title: "Sales Manager", department: "Sales", phone: "555-0101"},
{employeeID: 203, firstName: "Tom", lastName: "Wilson", title: "Senior Sales Rep", department: "Sales", phone: "555-0103"}
]
);
</cfscript>
<p><strong>Employee Directory Grouped by Department</strong></p>
<cfoutput query="employeesByDept" group="department">
<h3 style="background-color: ##0066cc; color: white; padding: 10px; margin-top: 15px;">#department# Department</h3>
<table border="1" cellpadding="8" cellspacing="0" style="border-collapse: collapse; width: 100%; margin-bottom: 15px;">
<tr style="background-color: ##e6f2ff;">
<th>Employee ID</th>
<th>Name</th>
<th>Title</th>
<th>Phone</th>
</tr>
<cfoutput>
<tr>
<td>#employeeID#</td>
<td>#firstName# #lastName#</td>
<td>#title#</td>
<td>#phone#</td>
</tr>
</cfoutput>
</table>
</cfoutput>
<hr>
<h2>Example 3: Department Employee Count</h2>
<cfscript>
// Larger dataset for counting - pre-sorted by department
allEmployees = queryNew("employeeID,firstName,lastName,department,hireDate",
"integer,varchar,varchar,varchar,date",
[
{employeeID: 304, firstName: "Diana", lastName: "Evans", department: "Engineering", hireDate: createDate(2020, 9, 5)},
{employeeID: 301, firstName: "Alex", lastName: "Brown", department: "Engineering", hireDate: createDate(2022, 3, 15)},
{employeeID: 302, firstName: "Beth", lastName: "Clark", department: "Engineering", hireDate: createDate(2021, 7, 22)},
{employeeID: 303, firstName: "Chris", lastName: "Davis", department: "Engineering", hireDate: createDate(2023, 1, 10)},
{employeeID: 307, firstName: "Henry", lastName: "King", department: "Finance", hireDate: createDate(2020, 2, 14)},
{employeeID: 308, firstName: "Iris", lastName: "Lee", department: "Finance", hireDate: createDate(2022, 8, 25)},
{employeeID: 309, firstName: "Jack", lastName: "Moore", department: "Finance", hireDate: createDate(2023, 5, 7)},
{employeeID: 305, firstName: "Frank", lastName: "Green", department: "HR", hireDate: createDate(2019, 4, 18)},
{employeeID: 306, firstName: "Grace", lastName: "Hill", department: "HR", hireDate: createDate(2021, 11, 30)}
]
);
</cfscript>
<cfoutput query="allEmployees" group="department">
<div style="border: 2px solid ##333; padding: 15px; margin: 10px 0; background-color: ##f9f9f9;">
<h3>#department# Department</h3>
<cfset deptCount = 0>
<ul>
<cfoutput>
<li>#firstName# #lastName# - Hired: #dateFormat(hireDate, "mm/dd/yyyy")#</li>
<cfset deptCount = deptCount + 1>
</cfoutput>
</ul>
<cfoutput>
<p style="font-weight: bold; color: ##0066cc;">Total Employees in #department#: #deptCount#</p>
</cfoutput>
</div>
</cfoutput>
<hr>
<h2>Example 4: Limiting Results with maxRows</h2>
<cfscript>
// Large dataset
largeQuery = queryNew("id,name,department",
"integer,varchar,varchar",
[
{id: 1, name: "Employee 1", department: "Sales"},
{id: 2, name: "Employee 2", department: "Sales"},
{id: 3, name: "Employee 3", department: "Marketing"},
{id: 4, name: "Employee 4", department: "Marketing"},
{id: 5, name: "Employee 5", department: "IT"},
{id: 6, name: "Employee 6", department: "IT"},
{id: 7, name: "Employee 7", department: "HR"},
{id: 8, name: "Employee 8", department: "HR"}
]
);
</cfscript>
<cfoutput>
<p><strong>Total Records:</strong> #largeQuery.recordCount#</p>
<p><strong>Displaying First 5 Records Only (using maxRows attribute)</strong></p>
</cfoutput>
<cfset displayLimit = 5>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse;">
<tr style="background-color: ##f0f0f0;">
<th>ID</th>
<th>Name</th>
<th>Department</th>
</tr>
<cfoutput query="largeQuery" maxRows="#displayLimit#">
<tr>
<td>#id#</td>
<td>#name#</td>
<td>#department#</td>
</tr>
</cfoutput>
</table>
<hr>
Regional sales performance report
Your sales management team needs detailed reports showing sales data organized by region, then by sales representative within each region. The report must calculate subtotals for each sales rep and grand totals for each region. This requires nested grouping with calculations at each level.
Problem statement
- Sales data needs multi-level grouping (region → sales rep → individual sales)
- Must calculate subtotals at each grouping level
- Need running totals and averages
- Hierarchy must be visually clear
- Data sorted by multiple columns for proper nested grouping
Solution
The nested cfoutput tags provide outer cfoutput groups by region, inner groups by rep, nesting structure matches data hierarchy, and track totals at each grouping level.
<h1>Sales Report with Nested Output Demo</h1>
<p><strong>What This Demo Shows:</strong> How to use nested cfoutput tags for multi-level grouping and hierarchical reports.</p>
<hr>
<h2>Example 1: Two-Level Grouping (Region → Sales Rep)</h2>
<cfscript>
// Create sales data pre-sorted by region and salesRep
salesData = queryNew("region,salesRep,orderID,customerName,amount,orderDate",
"varchar,varchar,integer,varchar,decimal,date",
[
// East Region - Alice Johnson
{region: "East", salesRep: "Alice Johnson", orderID: 1001, customerName: "ABC Corp", amount: 1500.00, orderDate: createDate(2024, 11, 1)},
{region: "East", salesRep: "Alice Johnson", orderID: 1003, customerName: "Tech Solutions", amount: 1800.00, orderDate: createDate(2024, 11, 5)},
{region: "East", salesRep: "Alice Johnson", orderID: 1002, customerName: "XYZ Inc", amount: 2300.00, orderDate: createDate(2024, 11, 3)},
// East Region - Bob Smith
{region: "East", salesRep: "Bob Smith", orderID: 1004, customerName: "Global Systems", amount: 3200.00, orderDate: createDate(2024, 11, 2)},
{region: "East", salesRep: "Bob Smith", orderID: 1005, customerName: "Data Corp", amount: 2100.00, orderDate: createDate(2024, 11, 4)},
// West Region - Carol Davis
{region: "West", salesRep: "Carol Davis", orderID: 1006, customerName: "Pacific Tech", amount: 2800.00, orderDate: createDate(2024, 11, 1)},
{region: "West", salesRep: "Carol Davis", orderID: 1007, customerName: "Coast Industries", amount: 1900.00, orderDate: createDate(2024, 11, 6)},
// West Region - David Lee
{region: "West", salesRep: "David Lee", orderID: 1008, customerName: "Mountain Corp", amount: 4100.00, orderDate: createDate(2024, 11, 2)},
{region: "West", salesRep: "David Lee", orderID: 1009, customerName: "Valley Systems", amount: 3500.00, orderDate: createDate(2024, 11, 7)}
]
);
</cfscript>
<cfset grandTotal = 0>
<!--- Outer cfoutput: Group by region --->
<cfoutput query="salesData" group="region">
<div style="border: 3px solid ##0066cc; margin: 15px 0; padding: 15px; background-color: ##e6f2ff;">
<h2 style="color: ##0066cc; margin-top: 0;">#region# Region</h2>
<cfset regionTotal = 0>
<!--- Inner cfoutput: Group by sales rep --->
<cfoutput group="salesRep">
<h3 style="color: ##333; margin-left: 20px;">#salesRep#</h3>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse; margin-left: 40px; margin-bottom: 15px; width: 90%;">
<tr style="background-color: ##f0f0f0;">
<th>Order ID</th>
<th>Customer</th>
<th>Date</th>
<th style="text-align: right;">Amount</th>
</tr>
<cfset repTotal = 0>
<!--- Innermost cfoutput: Individual orders --->
<cfoutput>
<tr>
<td>#orderID#</td>
<td>#customerName#</td>
<td>#dateFormat(orderDate, "mm/dd/yyyy")#</td>
<td style="text-align: right;">$#numberFormat(amount, "0,000.00")#</td>
</tr>
<cfset repTotal = repTotal + amount>
<cfset regionTotal = regionTotal + amount>
<cfset grandTotal = grandTotal + amount>
</cfoutput>
<cfoutput>
<tr style="background-color: ##ffffe0; font-weight: bold;">
<td colspan="3" style="text-align: right;">Sales Rep Total:</td>
<td style="text-align: right;">$#numberFormat(repTotal, "0,000.00")#</td>
</tr>
</cfoutput>
</table>
</cfoutput>
<cfoutput>
<p style="margin-left: 40px; font-size: 1.1em;"><strong>Region Total: $#numberFormat(regionTotal, "0,000.00")#</strong></p>
</cfoutput>
</div>
</cfoutput>
<cfoutput>
<div style="background-color: ##003366; color: white; padding: 15px; font-size: 1.2em; font-weight: bold; text-align: right;">
GRAND TOTAL: $#numberFormat(grandTotal, "0,000.00")#
</div>
</cfoutput>
<hr>
<h2>Example 2: Summary Report with Counts</h2>
<cfscript>
// Department sales data - pre-sorted by department and salesRep
deptSales = queryNew("department,salesRep,productCategory,units,revenue",
"varchar,varchar,varchar,integer,decimal",
[
// Electronics Department
{department: "Electronics", salesRep: "Jane Smith", productCategory: "Laptops", units: 20, revenue: 30000.00},
{department: "Electronics", salesRep: "Jane Smith", productCategory: "Phones", units: 35, revenue: 17500.00},
{department: "Electronics", salesRep: "John Doe", productCategory: "Laptops", units: 15, revenue: 22500.00},
{department: "Electronics", salesRep: "John Doe", productCategory: "Tablets", units: 25, revenue: 12500.00},
// Furniture Department
{department: "Furniture", salesRep: "Mike Brown", productCategory: "Desks", units: 12, revenue: 9600.00},
{department: "Furniture", salesRep: "Mike Brown", productCategory: "Chairs", units: 30, revenue: 6000.00},
{department: "Furniture", salesRep: "Sarah Wilson", productCategory: "Tables", units: 8, revenue: 4800.00}
]
);
</cfscript>
<cfoutput query="deptSales" group="department">
<h2 style="background-color: ##4CAF50; color: white; padding: 10px;">#department# Department</h2>
<cfset deptRevenue = 0>
<cfset deptUnits = 0>
<cfset repCount = 0>
<cfoutput group="salesRep">
<cfset repCount = repCount + 1>
<div style="margin-left: 30px; margin-bottom: 15px;">
<h4>#repCount#. #salesRep#</h4>
<ul>
<cfset repRevenue = 0>
<cfset repUnits = 0>
<cfoutput>
<li>#productCategory#: #units# units = $#numberFormat(revenue, "0,000.00")#</li>
<cfset repRevenue = repRevenue + revenue>
<cfset repUnits = repUnits + units>
<cfset deptRevenue = deptRevenue + revenue>
<cfset deptUnits = deptUnits + units>
</cfoutput>
</ul>
<cfoutput>
<p style="margin-left: 20px; color: ##0066cc;"><strong>Rep Total: #repUnits# units, $#numberFormat(repRevenue, "0,000.00")#</strong></p>
</cfoutput>
</div>
</cfoutput>
<cfoutput>
<div style="background-color: ##f0f0f0; padding: 10px; margin: 10px 0;">
<p><strong>Department Summary:</strong></p>
<ul>
<li>Sales Reps: #repCount#</li>
<li>Total Units: #deptUnits#</li>
<li>Total Revenue: $#numberFormat(deptRevenue, "0,000.00")#</li>
</ul>
</div>
</cfoutput>
</cfoutput>
<hr>
<h2>Example 3: Three-Level Grouping (Year → Quarter → Month)</h2>
<cfscript>
// Time-based sales data - pre-sorted by year DESC, quarter, month
timeSales = queryNew("year,quarter,month,sales",
"integer,integer,integer,decimal",
[
// Year 2024
{year: 2024, quarter: 1, month: 1, sales: 45000},
{year: 2024, quarter: 1, month: 2, sales: 52000},
{year: 2024, quarter: 1, month: 3, sales: 48000},
{year: 2024, quarter: 2, month: 4, sales: 61000},
{year: 2024, quarter: 2, month: 5, sales: 58000},
{year: 2024, quarter: 2, month: 6, sales: 63000},
// Year 2023
{year: 2023, quarter: 4, month: 10, sales: 55000},
{year: 2023, quarter: 4, month: 11, sales: 59000},
{year: 2023, quarter: 4, month: 12, sales: 67000}
]
);
</cfscript>
<!--- Level 1: Year --->
<cfoutput query="timeSales" group="year">
<h2 style="background-color: ##2196F3; color: white; padding: 10px;">Year #year#</h2>
<cfset yearTotal = 0>
<!--- Level 2: Quarter --->
<cfoutput group="quarter">
<h3 style="margin-left: 20px; color: ##1976D2;">Q#quarter#</h3>
<cfset quarterTotal = 0>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse; margin-left: 40px; margin-bottom: 10px;">
<tr style="background-color: ##E3F2FD;">
<th>Month</th>
<th style="text-align: right;">Sales</th>
</tr>
<!--- Level 3: Month --->
<cfoutput>
<tr>
<td>Month #month#</td>
<td style="text-align: right;">$#numberFormat(sales, "0,000")#</td>
</tr>
<cfset quarterTotal = quarterTotal + sales>
<cfset yearTotal = yearTotal + sales>
</cfoutput>
<cfoutput>
<tr style="background-color: ##BBDEFB; font-weight: bold;">
<td>Quarter Total</td>
<td style="text-align: right;">$#numberFormat(quarterTotal, "0,000")#</td>
</tr>
</cfoutput>
</table>
</cfoutput>
<cfoutput>
<p style="margin-left: 40px; font-size: 1.1em;"><strong>Year Total: $#numberFormat(yearTotal, "0,000")#</strong></p>
</cfoutput>
</cfoutput>
<hr>
