- 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
Tests for the existence of a parameter (that is, a variable), validates its data, and, if a default value is not assigned, optionally provides one.
History
ColdFusion 10: Added the attribute {{maxLength}}
ColdFusion MX 7:
- Added min, max, and pattern attributes.
- Added creditcard, email, eurodate, float, integer, range, regex, regular_expression, ssn, social_security_number, time, URL, USdate, XML, and zipcode values of the type attribute.
Category
Syntax
<cfparam name = "parameter name" default = "value" max = "value" maxLength = "number" min = "value" pattern = "regular expression" type = "data_type">
See also
cfcookie, cfregistry, cfsavecontent, cfschedule, cfset; Validating data with the IsValid function and the cfparam tag in the Developing ColdFusion Applications
Attributes
Attribute |
Req/Opt |
Default |
Description |
|---|---|---|---|
name |
Required |
|
Name of the parameter (variable) to test (such as "Client.Email " or "Cookie.BackgroundColor "). If omitted, and if the parameter does not exist, an error is thrown. |
default |
Optional |
|
Value to set parameter to if it does not exist. Any expression used for the default attribute is evaluated, even if the parameter exists. The result is not assigned if the parameter exists, but if the expression has side effects, they still occur. |
max |
Optional |
|
The maximum valid value; used only for range validation. |
maxLength |
Optional |
|
Used to specify the maximum character length of email, url, and string. |
min |
Optional |
|
The minimum valid value; used only for range validation. |
pattern |
Optional |
|
A JavaScript regular expression that the parameter must match; used only for regex or regular_expression validation. |
type |
Optional |
any |
The valid format for the data; one of the following. For detailed information on validation algorithms, see Validating form data using hidden fields in Validating data in the Developing ColdFusion Applications.
|
Usage
You can use this tag to make the following tests:
- To test whether a required variable exists, use this tag with only the name attribute. If it does not exist, ColdFusion stops processing the page and returns an error.
- To test whether a required variable exists, and that it is of the specified type, use this tag with the name and type attributes. If the variable does not exist or its value is not of the specified type, ColdFusion returns an error.
To set a default value for the variable, use this tag with the name and default attributes. If the variable does not exist, it is created and set to the default attribute value. If the variable exists, processing continues; the value is not changed.
If you specify variableName for the typeattribute, the parameter's value must be a string that is in ColdFusion variable name format; that is, starts with a letter, underscore (_), or Unicode currency symbol, and contains letters, numbers, underscores, periods, and Unicode currency symbols, only. ColdFusion does not check whether the parameter value corresponds to an existing ColdFusion variable.
To improve performance, avoid using the cfparam tag in ColdFusion functions, including in CFC methods. Instead, place the cfparam tags in the body of the CFML pages.
Example
<!--- This example shows how to use CFPARAM to define default values for page variables. --->
<cfparam name = "storeTempVar" default = "my default value">
<cfparam name = "tempVar" default = "my default value">
<!--- Check if form.tempVar was passed. --->
<cfif IsDefined("form.tempVar") is "True">
<!--- Check if form.tempVar is not blank. --->
<cfif form.tempVar is not "">
<!--- If not, set tempVar to value of form.tempVar --->
<cfset tempVar = form.tempVar>
</cfif>
</cfif>
<body>
<h3>cfparam Example</h3>
<p>cfparam is used to set default values so that a developer does not have to
check for the existence of a variable using a function like IsDefined.</p>
<p>The default value of our tempVar is "<cfoutput>#StoreTempVar# </cfoutput>"</p>
<!--- Check if tempVar is still the same as StoreTempVar and that tempVar is not blank. --->
<cfif tempVar is not #StoreTempVar#
and tempVar is not "">
<h3>The value of tempVar has changed: the new value is
<cfoutput>#tempVar#</cfoutput></h3>
</cfif>
<p>
<form action = "cfparam.cfm" method = "post">
Type in a new value for tempVar, and hit submit:<br>
<input type = "Text" name = "tempVar">
<input type = "Submit" name = "" value = "submit">
</form>
Real-world uses of the cfparam function
Contact form with optional fields
Your website has a contact form where users can submit inquiries. Some fields are optional, and you want to provide default values for fields that aren't filled in. You also need to ensure required fields exist and are of the correct type before processing the form.
Problem statement
- Need to handle optional form fields gracefully
- Must provide sensible default values for missing fields
- Should validate that required fields exist
- Need to ensure data types are correct (email, phone, and so on)
Solution
The cfparam tag sets defaults for optional fields automatically, ensures fields match expected types (email, numeric, and so on), or verifies required variables exist before processing.
<h1>Form Input Validation with Defaults Demo</h1>
<p><strong>What This Demo Shows:</strong> How to use cfparam to set defaults and validate form inputs.</p>
<hr>
<!--- Set default values for form fields using cfparam --->
<cfparam name="form.fullName" default="">
<cfparam name="form.email" default="">
<cfparam name="form.phone" default="">
<cfparam name="form.subject" default="General Inquiry">
<cfparam name="form.priority" default="Normal">
<cfparam name="form.message" default="">
<cfparam name="form.newsletter" default="false">
<h2>Example 1: Contact Form with Default Values</h2>
<cfif structKeyExists(form, "submit")>
<!--- Validate required fields with type checking --->
<cftry>
<!--- Ensure required fields exist and are not empty --->
<cfif len(trim(form.fullName)) EQ 0>
<cfthrow message="Full Name is required" type="ValidationError">
</cfif>
<cfif len(trim(form.email)) EQ 0>
<cfthrow message="Email is required" type="ValidationError">
</cfif>
<cfif len(trim(form.message)) EQ 0>
<cfthrow message="Message is required" type="ValidationError">
</cfif>
<!--- Basic email validation --->
<cfif NOT findNoCase("@", form.email) OR NOT findNoCase(".", form.email)>
<cfthrow message="Please enter a valid email address" type="ValidationError">
</cfif>
<div style="background-color: ##d4edda; border: 1px solid ##c3e6cb; padding: 15px; margin: 15px 0;">
<h3 style="color: ##155724; margin-top: 0;">✓ Form Submitted Successfully!</h3>
<cfoutput>
<p><strong>Name:</strong> #form.fullName#</p>
<p><strong>Email:</strong> #form.email#</p>
<p><strong>Phone:</strong> #len(form.phone) GT 0 ? form.phone : "(Not provided)"#</p>
<p><strong>Subject:</strong> #form.subject#</p>
<p><strong>Priority:</strong> #form.priority#</p>
<p><strong>Message:</strong> #form.message#</p>
<p><strong>Newsletter Opt-in:</strong> #form.newsletter EQ "true" ? "Yes" : "No"#</p>
</cfoutput>
</div>
<cfcatch type="ValidationError">
<div style="background-color: ##f8d7da; border: 1px solid ##f5c6cb; padding: 15px; margin: 15px 0;">
<h3 style="color: ##721c24; margin-top: 0;">✗ Validation Error</h3>
<cfoutput><p>#cfcatch.message#</p></cfoutput>
</div>
</cfcatch>
<cfcatch type="any">
<div style="background-color: ##f8d7da; border: 1px solid ##f5c6cb; padding: 15px; margin: 15px 0;">
<h3 style="color: ##721c24; margin-top: 0;">✗ Error</h3>
<cfoutput><p>#cfcatch.message#</p></cfoutput>
</div>
</cfcatch>
</cftry>
</cfif>
<form method="post">
<table cellpadding="8">
<tr>
<td><label>Full Name: <span style="color: red;">*</span></label></td>
<td><input type="text" name="fullName" value="<cfoutput>#form.fullName#</cfoutput>" size="40"></td>
</tr>
<tr>
<td><label>Email: <span style="color: red;">*</span></label></td>
<td><input type="text" name="email" value="<cfoutput>#form.email#</cfoutput>" size="40"></td>
</tr>
<tr>
<td><label>Phone: (optional)</label></td>
<td><input type="text" name="phone" value="<cfoutput>#form.phone#</cfoutput>" size="40"></td>
</tr>
<tr>
<td><label>Subject:</label></td>
<td>
<select name="subject">
<cfset subjects = ["General Inquiry", "Sales", "Support", "Feedback"]>
<cfloop array="#subjects#" index="subj">
<cfoutput>
<option value="#subj#" #form.subject EQ subj ? "selected" : ""#>#subj#</option>
</cfoutput>
</cfloop>
</select>
</td>
</tr>
<tr>
<td><label>Priority:</label></td>
<td>
<cfset priorities = ["Low", "Normal", "High", "Urgent"]>
<cfloop array="#priorities#" index="pri">
<cfoutput>
<input type="radio" name="priority" value="#pri#" #form.priority EQ pri ? "checked" : ""#> #pri#
</cfoutput>
</cfloop>
</td>
</tr>
<tr>
<td><label>Message: <span style="color: red;">*</span></label></td>
<td><textarea name="message" rows="5" cols="40"><cfoutput>#form.message#</cfoutput></textarea></td>
</tr>
<tr>
<td colspan="2">
<input type="checkbox" name="newsletter" value="true" <cfif form.newsletter EQ "true">checked</cfif>>
Subscribe to newsletter
</td>
</tr>
<tr>
<td colspan="2">
<button type="submit" name="submit">Submit Form</button>
</td>
</tr>
</table>
</form>
<hr>
<h2>Example 2: Default Values Demonstration</h2>
<!--- These cfparam tags demonstrate different default values --->
<cfparam name="url.testString" default="Default Text">
<cfparam name="url.testNumber" default="100">
<cfparam name="url.testBoolean" default="false">
<cfparam name="url.testList" default="apple,banana,orange">
<p><strong>Current Values (add URL parameters to change them):</strong></p>
<table border="1" cellpadding="8" cellspacing="0" style="border-collapse: collapse;">
<tr style="background-color: ##f0f0f0;">
<th>Parameter</th>
<th>Value</th>
<th>Default</th>
</tr>
<cfoutput>
<tr>
<td>url.testString</td>
<td>#url.testString#</td>
<td>Default Text</td>
</tr>
<tr>
<td>url.testNumber</td>
<td>#url.testNumber#</td>
<td>100</td>
</tr>
<tr>
<td>url.testBoolean</td>
<td>#url.testBoolean#</td>
<td>false</td>
</tr>
<tr>
<td>url.testList</td>
<td>#url.testList#</td>
<td>apple,banana,orange</td>
</tr>
</cfoutput>
</table>
<p><strong>Try it:</strong> <a href="?testString=Hello&testNumber=500&testBoolean=true&testList=cat,dog,bird">Click here to see custom values</a></p>
<hr>
Product listing with pagination
Your e-commerce site displays products with pagination. Users can navigate through pages, sort results, and filter by category. URL parameters control these features, and you need default values for clean, error-free navigation.
Problem statement
- Need to handle missing URL parameters gracefully
- Must validate page numbers are numeric and within range
- Should provide default sort order and items per page
- Need to prevent errors from invalid URL parameters
- Must ensure clean URLs work without all parameters
Solution
The cfparam tag sets the correct defaults for pagination, ensures page numbers are numeric, or validates values are within acceptable ranges.
<h1>URL Pagination Parameters Demo</h1>
<p><strong>What This Demo Shows:</strong> How to use cfparam to handle URL parameters for pagination and filtering.</p>
<hr>
<!--- Set default values for URL parameters --->
<cfparam name="url.page" default="1">
<cfparam name="url.perPage" default="10">
<cfparam name="url.sortBy" default="name">
<cfparam name="url.sortOrder" default="asc">
<cfparam name="url.category" default="all">
<!--- Validate and sanitize page number --->
<cftry>
<cfset url.page = val(url.page)>
<cfif url.page LT 1>
<cfset url.page = 1>
</cfif>
<cfcatch type="any">
<cfset url.page = 1>
</cfcatch>
</cftry>
<!--- Validate perPage --->
<cftry>
<cfset url.perPage = val(url.perPage)>
<cfif url.perPage LT 5 OR url.perPage GT 100>
<cfset url.perPage = 10>
</cfif>
<cfcatch type="any">
<cfset url.perPage = 10>
</cfcatch>
</cftry>
<!--- Create sample product data --->
<cfscript>
allProducts = [];
categories = ["Electronics", "Clothing", "Books", "Home", "Sports"];
for (i = 1; i LTE 47; i++) {
categoryIndex = ((i - 1) MOD 5) + 1;
arrayAppend(allProducts, {
id: i,
name: "Product " & i,
price: randRange(10, 500),
category: categories[categoryIndex]
});
}
// Filter by category
filteredProducts = [];
if (url.category NEQ "all") {
for (product in allProducts) {
if (product.category EQ url.category) {
arrayAppend(filteredProducts, product);
}
}
} else {
filteredProducts = allProducts;
}
// Sort products
if (url.sortBy EQ "name") {
filteredProducts.sort(function(a, b) {
if (url.sortOrder EQ "asc") {
return compare(a.name, b.name);
} else {
return compare(b.name, a.name);
}
});
} else if (url.sortBy EQ "price") {
filteredProducts.sort(function(a, b) {
if (url.sortOrder EQ "asc") {
return a.price - b.price;
} else {
return b.price - a.price;
}
});
}
// Calculate pagination
totalProducts = arrayLen(filteredProducts);
totalPages = ceiling(totalProducts / url.perPage);
// Ensure page is within range
if (url.page GT totalPages AND totalPages GT 0) {
url.page = totalPages;
}
startRow = ((url.page - 1) * url.perPage) + 1;
endRow = min(url.page * url.perPage, totalProducts);
// Get products for current page
pageProducts = [];
if (totalProducts GT 0) {
for (i = startRow; i LTE endRow; i++) {
arrayAppend(pageProducts, filteredProducts[i]);
}
}
</cfscript>
<h2>Product Listing with Pagination</h2>
<!--- Display current settings --->
<div style="background-color: ##f0f0f0; padding: 15px; margin: 15px 0;">
<cfoutput>
<p><strong>Current Settings:</strong></p>
<p>Page: #url.page# of #totalPages# | Items per page: #url.perPage# | Sort by: #url.sortBy# (#url.sortOrder#) | Category: #url.category#</p>
<p>Showing products #startRow# to #endRow# of #totalProducts# total</p>
</cfoutput>
</div>
<!--- Filter and Sort Controls --->
<form method="get" style="background-color: ##e3f2fd; padding: 15px; margin: 15px 0;">
<table>
<tr>
<td><label>Category:</label></td>
<td>
<select name="category">
<cfoutput>
<option value="all" #url.category EQ "all" ? "selected" : ""#>All Categories</option>
</cfoutput>
<cfloop array="#categories#" index="cat">
<cfoutput>
<option value="#cat#" #url.category EQ cat ? "selected" : ""#>#cat#</option>
</cfoutput>
</cfloop>
</select>
</td>
<td style="padding-left: 20px;"><label>Sort by:</label></td>
<td>
<select name="sortBy">
<cfoutput>
<option value="name" #url.sortBy EQ "name" ? "selected" : ""#>Name</option>
<option value="price" #url.sortBy EQ "price" ? "selected" : ""#>Price</option>
</cfoutput>
</select>
</td>
<td>
<select name="sortOrder">
<cfoutput>
<option value="asc" #url.sortOrder EQ "asc" ? "selected" : ""#>Ascending</option>
<option value="desc" #url.sortOrder EQ "desc" ? "selected" : ""#>Descending</option>
</cfoutput>
</select>
</td>
<td style="padding-left: 20px;"><label>Per Page:</label></td>
<td>
<select name="perPage">
<cfset perPageOptions = [5, 10, 20, 50]>
<cfloop array="#perPageOptions#" index="option">
<cfoutput>
<option value="#option#" #url.perPage EQ option ? "selected" : ""#>#option#</option>
</cfoutput>
</cfloop>
</select>
</td>
<td style="padding-left: 20px;">
<button type="submit">Apply</button>
</td>
</tr>
</table>
</form>
<!--- Product Grid --->
<table border="1" cellpadding="10" cellspacing="0" style="border-collapse: collapse; width: 100%;">
<tr style="background-color: ##0066cc; color: white;">
<th>ID</th>
<th>Product Name</th>
<th>Category</th>
<th style="text-align: right;">Price</th>
</tr>
<cfif arrayLen(pageProducts) GT 0>
<cfloop array="#pageProducts#" index="product">
<cfoutput>
<tr>
<td>#product.id#</td>
<td>#product.name#</td>
<td>#product.category#</td>
<td style="text-align: right;">$#numberFormat(product.price, "0.00")#</td>
</tr>
</cfoutput>
</cfloop>
<cfelse>
<tr>
<td colspan="4" style="text-align: center; padding: 20px;">No products found</td>
</tr>
</cfif>
</table>
<!--- Pagination Controls --->
<cfif totalPages GT 1>
<div style="margin: 20px 0; text-align: center;">
<cfoutput>
<!--- Previous button --->
<cfif url.page GT 1>
<a href="?page=#url.page - 1#&perPage=#url.perPage#&sortBy=#url.sortBy#&sortOrder=#url.sortOrder#&category=#url.category#" style="padding: 5px 10px; background-color: ##0066cc; color: white; text-decoration: none;">« Previous</a>
<cfelse>
<span style="padding: 5px 10px; background-color: ##ccc; color: ##666;">« Previous</span>
</cfif>
<!--- Page numbers --->
<cfloop from="1" to="#totalPages#" index="pageNum">
<cfif pageNum EQ url.page>
<strong style="padding: 5px 10px; background-color: ##0066cc; color: white;">#pageNum#</strong>
<cfelse>
<a href="?page=#pageNum#&perPage=#url.perPage#&sortBy=#url.sortBy#&sortOrder=#url.sortOrder#&category=#url.category#" style="padding: 5px 10px; text-decoration: none; border: 1px solid ##ddd;">#pageNum#</a>
</cfif>
</cfloop>
<!--- Next button --->
<cfif url.page LT totalPages>
<a href="?page=#url.page + 1#&perPage=#url.perPage#&sortBy=#url.sortBy#&sortOrder=#url.sortOrder#&category=#url.category#" style="padding: 5px 10px; background-color: ##0066cc; color: white; text-decoration: none;">Next »</a>
<cfelse>
<span style="padding: 5px 10px; background-color: ##ccc; color: ##666;">Next »</span>
</cfif>
</cfoutput>
</div>
</cfif>
<hr>
<h2>Try Different URLs:</h2>
<ul>
<li><a href="?page=1&perPage=5">5 items per page</a></li>
<li><a href="?page=2&perPage=10">Page 2 with 10 items</a></li>
<li><a href="?sortBy=price&sortOrder=desc">Sort by price descending</a></li>
<li><a href="?category=Electronics">Electronics only</a></li>
<li><a href="?category=Books&sortBy=name&sortOrder=asc">Books sorted by name</a></li>
<li><a href="?page=99">Invalid page number (auto-corrects)</a></li>
</ul>
<hr>
Product search with multiple filters
Your e-commerce application has a search feature with multiple filters (price range, rating, availability, etc.). Users can apply various combinations of filters, and you need to handle all possible combinations gracefully with sensible defaults.
Problem statement
- Need to handle multiple optional search parameters
- Must provide default values for all filter options
- Should handle missing or invalid filter values
- Need to maintain filter state during pagination
Solution
The cfparam tag sets defaults for all filter parameters, validates filter values, handles missing parameters gracefully, or maintains filter state across parameters.
<h1>Search Filter Management Demo</h1>
<p><strong>What This Demo Shows:</strong> How to use cfparam to manage multiple search filters with defaults.</p>
<hr>
<!--- Set default values for all search/filter parameters --->
<cfparam name="url.keyword" default="">
<cfparam name="url.category" default="all">
<cfparam name="url.minPrice" default="0">
<cfparam name="url.maxPrice" default="1000">
<cfparam name="url.minRating" default="0">
<cfparam name="url.inStock" default="false">
<cfparam name="url.onSale" default="false">
<cfparam name="url.sortBy" default="relevance">
<!--- Validate numeric parameters --->
<cfset url.minPrice = val(url.minPrice)>
<cfset url.maxPrice = val(url.maxPrice)>
<cfset url.minRating = val(url.minRating)>
<!--- Ensure min/max are in correct order --->
<cfif url.minPrice GT url.maxPrice>
<cfset temp = url.minPrice>
<cfset url.minPrice = url.maxPrice>
<cfset url.maxPrice = temp>
</cfif>
<!--- Create sample product data --->
<cfscript>
allProducts = [
{name: "Laptop Pro 15", category: "Electronics", price: 899, rating: 4.5, inStock: true, onSale: false},
{name: "Wireless Mouse", category: "Electronics", price: 29, rating: 4.0, inStock: true, onSale: true},
{name: "Office Chair", category: "Furniture", price: 199, rating: 4.2, inStock: true, onSale: false},
{name: "Standing Desk", category: "Furniture", price: 449, rating: 4.8, inStock: false, onSale: false},
{name: "USB-C Cable", category: "Electronics", price: 12, rating: 3.5, inStock: true, onSale: true},
{name: "Monitor 27in", category: "Electronics", price: 349, rating: 4.6, inStock: true, onSale: false},
{name: "Keyboard Mechanical", category: "Electronics", price: 89, rating: 4.3, inStock: true, onSale: true},
{name: "Desk Lamp", category: "Furniture", price: 45, rating: 4.1, inStock: true, onSale: false},
{name: "Bookshelf", category: "Furniture", price: 129, rating: 3.9, inStock: false, onSale: false},
{name: "Webcam HD", category: "Electronics", price: 79, rating: 4.4, inStock: true, onSale: true},
{name: "Filing Cabinet", category: "Furniture", price: 159, rating: 4.0, inStock: true, onSale: false},
{name: "Headphones", category: "Electronics", price: 149, rating: 4.7, inStock: true, onSale: false}
];
// Apply filters
filteredProducts = [];
for (product in allProducts) {
matchesFilters = true;
// Keyword search
if (len(trim(url.keyword)) GT 0) {
if (NOT findNoCase(url.keyword, product.name)) {
matchesFilters = false;
}
}
// Category filter
if (url.category NEQ "all" AND product.category NEQ url.category) {
matchesFilters = false;
}
// Price range filter
if (product.price LT url.minPrice OR product.price GT url.maxPrice) {
matchesFilters = false;
}
// Rating filter
if (product.rating LT url.minRating) {
matchesFilters = false;
}
// In stock filter
if (url.inStock EQ "true" AND NOT product.inStock) {
matchesFilters = false;
}
// On sale filter
if (url.onSale EQ "true" AND NOT product.onSale) {
matchesFilters = false;
}
if (matchesFilters) {
arrayAppend(filteredProducts, product);
}
}
// Sort results
if (url.sortBy EQ "price_asc") {
filteredProducts.sort(function(a, b) { return a.price - b.price; });
} else if (url.sortBy EQ "price_desc") {
filteredProducts.sort(function(a, b) { return b.price - a.price; });
} else if (url.sortBy EQ "rating") {
filteredProducts.sort(function(a, b) { return b.rating - a.rating; });
}
totalResults = arrayLen(filteredProducts);
</cfscript>
<h2>Product Search</h2>
<!--- Search Form --->
<form method="get" style="background-color: ##f0f0f0; padding: 20px; margin: 15px 0;">
<table cellpadding="8">
<tr>
<td><label><strong>Keyword:</strong></label></td>
<td colspan="3">
<input type="text" name="keyword" value="<cfoutput>#url.keyword#</cfoutput>" size="40" placeholder="Search products...">
</td>
</tr>
<tr>
<td><label><strong>Category:</strong></label></td>
<td>
<select name="category">
<cfoutput>
<option value="all" #url.category EQ "all" ? "selected" : ""#>All Categories</option>
<option value="Electronics" #url.category EQ "Electronics" ? "selected" : ""#>Electronics</option>
<option value="Furniture" #url.category EQ "Furniture" ? "selected" : ""#>Furniture</option>
</cfoutput>
</select>
</td>
<td><label><strong>Sort by:</strong></label></td>
<td>
<select name="sortBy">
<cfoutput>
<option value="relevance" #url.sortBy EQ "relevance" ? "selected" : ""#>Relevance</option>
<option value="price_asc" #url.sortBy EQ "price_asc" ? "selected" : ""#>Price: Low to High</option>
<option value="price_desc" #url.sortBy EQ "price_desc" ? "selected" : ""#>Price: High to Low</option>
<option value="rating" #url.sortBy EQ "rating" ? "selected" : ""#>Rating</option>
</cfoutput>
</select>
</td>
</tr>
<tr>
<td><label><strong>Price Range:</strong></label></td>
<td colspan="3">
<cfoutput>
$<input type="text" name="minPrice" value="#url.minPrice#" size="6"> to
$<input type="text" name="maxPrice" value="#url.maxPrice#" size="6">
</cfoutput>
</td>
</tr>
<tr>
<td><label><strong>Min Rating:</strong></label></td>
<td>
<select name="minRating">
<cfloop from="0" to="4" index="rating">
<cfoutput>
<option value="#rating#" #url.minRating EQ rating ? "selected" : ""#>
#rating GT 0 ? rating & "+ Stars" : "Any"#
</option>
</cfoutput>
</cfloop>
</select>
</td>
<td colspan="2">
<cfoutput>
<input type="checkbox" name="inStock" value="true" #url.inStock EQ "true" ? "checked" : ""#> In Stock Only
<input type="checkbox" name="onSale" value="true" #url.onSale EQ "true" ? "checked" : ""#> On Sale Only
</cfoutput>
</td>
</tr>
<tr>
<td colspan="4">
<button type="submit" style="padding: 8px 20px;">Search</button>
<a href="?" style="padding: 8px 20px; background-color: ##ccc; color: ##333; text-decoration: none; display: inline-block;">Clear Filters</a>
</td>
</tr>
</table>
</form>
<!--- Active Filters Display --->
<cfif len(url.keyword) GT 0 OR url.category NEQ "all" OR url.minPrice GT 0 OR url.maxPrice LT 1000 OR url.minRating GT 0 OR url.inStock EQ "true" OR url.onSale EQ "true">
<div style="background-color: ##fff3cd; padding: 10px; margin: 15px 0; border-left: 4px solid ##ff9800;">
<strong>Active Filters:</strong>
<cfoutput>
<cfif len(url.keyword) GT 0><span style="background-color: white; padding: 3px 8px; margin: 2px; border: 1px solid ##ddd;">Keyword: "#url.keyword#"</span></cfif>
<cfif url.category NEQ "all"><span style="background-color: white; padding: 3px 8px; margin: 2px; border: 1px solid ##ddd;">Category: #url.category#</span></cfif>
<cfif url.minPrice GT 0 OR url.maxPrice LT 1000><span style="background-color: white; padding: 3px 8px; margin: 2px; border: 1px solid ##ddd;">Price: $#url.minPrice# - $#url.maxPrice#</span></cfif>
<cfif url.minRating GT 0><span style="background-color: white; padding: 3px 8px; margin: 2px; border: 1px solid ##ddd;">Rating: #url.minRating#+ Stars</span></cfif>
<cfif url.inStock EQ "true"><span style="background-color: white; padding: 3px 8px; margin: 2px; border: 1px solid ##ddd;">In Stock</span></cfif>
<cfif url.onSale EQ "true"><span style="background-color: white; padding: 3px 8px; margin: 2px; border: 1px solid ##ddd;">On Sale</span></cfif>
</cfoutput>
</div>
</cfif>
<!--- Results Count --->
<p><cfoutput><strong>Found #totalResults# product<cfif totalResults NEQ 1>s</cfif></strong></cfoutput></p>
<!--- Results Grid --->
<table border="1" cellpadding="10" cellspacing="0" style="border-collapse: collapse; width: 100%;">
<tr style="background-color: ##0066cc; color: white;">
<th>Product</th>
<th>Category</th>
<th style="text-align: right;">Price</th>
<th style="text-align: center;">Rating</th>
<th style="text-align: center;">Status</th>
</tr>
<cfif totalResults GT 0>
<cfloop array="#filteredProducts#" index="product">
<cfoutput>
<tr>
<td>
#product.name#
<cfif product.onSale><span style="background-color: ##ff5722; color: white; padding: 2px 6px; font-size: 10px; margin-left: 5px;">SALE</span></cfif>
</td>
<td>#product.category#</td>
<td style="text-align: right;">$#numberFormat(product.price, "0.00")#</td>
<td style="text-align: center;">#product.rating# ⭐</td>
<td style="text-align: center;">
<cfif product.inStock>
<span style="color: ##2e7d32;">✓ In Stock</span>
<cfelse>
<span style="color: ##c62828;">✗ Out of Stock</span>
</cfif>
</td>
</tr>
</cfoutput>
</cfloop>
<cfelse>
<tr>
<td colspan="5" style="text-align: center; padding: 30px; color: ##666;">
No products match your search criteria. Try adjusting your filters.
</td>
</tr>
</cfif>
</table>
<hr>
<h2>Quick Filter Examples:</h2>
<ul>
<li><a href="?category=Electronics">Electronics only</a></li>
<li><a href="?minPrice=100&maxPrice=500">Price range $100-$500</a></li>
<li><a href="?minRating=4">4+ star ratings</a></li>
<li><a href="?inStock=true">In stock products</a></li>
<li><a href="?onSale=true">On sale items</a></li>
<li><a href="?keyword=mouse&category=Electronics&inStock=true">Keyword + multiple filters</a></li>
</ul>
<hr>