I have these codes in Application.cfm:
<CFSET Application.Payroll.Garnishment.PmtCodes = structNew()>
<CFSET Application.Payroll.Garnishment.PmtCodes[1] = "0 - Canceled check">
<CFSET Application.Payroll.Garnishment.PmtCodes[2] = "1 - Closed paymentadjustment">
<CFSET Application.Payroll.Garnishment.PmtCodes[3] = "2 - Multiple payments on one check">
<CFSET Application.Payroll.Garnishment.PmtCodes[4] = "3 - ACH/CTP Payments">
<CFSET Application.Payroll.Garnishment.PmtCodes[5] = "5 - Check Pick-up">
<CFSET Application.Payroll.Garnishment.PmtCodes[6] = "5A - Special Handling">
<CFSET Application.Payroll.Garnishment.PmtCodes[7] = "7 - One invoice paid on one check">
<CFSET Application.Payroll.Garnishment.PmtCodes[8] = "8 - Payroll - Garnishment (Payroll use only)">
<CFSET Application.Payroll.Garnishment.PmtCodes[9] = "9 - Manual check/wire transfer/bankdraft">
<CFSET Application.Payroll.Garnishment.PmtCodes[10] = "C - ACH Transfers (ap use only)">
<CFSET Application.Payroll.Garnishment.PmtCodes[11] = "D - Foreign bank drafts">
<CFSET Application.Payroll.Garnishment.PmtCodes[12] = "H - Hospital Managed Care">
<CFSET Application.Payroll.Garnishment.PmtCodes[13] = "M - Cash advances (AP use only)">
<CFSET Application.Payroll.Garnishment.PmtCodes[14] = "T - Wire US/ Foreign $ to Foreign bank (ap)">
<CFSET Application.Payroll.Garnishment.PmtCodes[15] = "V - Multiple Vendor Payments on credit card">
<CFSET Application.Payroll.Garnishment.PmtCodes[16] = "W - Wire US/Foreign $ US/Foreign bank (ap)">
<CFSET Application.Payroll.Garnishment.PmtCodes[16] = "Y - Payroll rush Checks (ap use only)">
<CFSET Application.Payroll.Garnishment.PmtCodes[16] = "Z - Student Aid check from Banner">
I am trying to utilize the struct to create a drop down list on update-employee.cfm like so:
<SELECT NAME="PmtCodes" SIZE="1">
<CFOUTPUT>
<CFLOOP collection="#Application.Payroll.Garnishment.PmtCodes#" item="key">
<OPTION VALUE="#Application.Payroll.Garnishment.PmtCodes[key]#"> </OPTION>
</CFLOOP>
</CFOUTPUT>
</SELECT>
However, there is no data populated in the drop down list. Any suggestions? Thanks.
You need to show something in the <option> tags
If you want to show the value and return the value
<OPTION VALUE="#Application.Payroll.Garnishment.PmtCodes[key]#">#xmlformat(Application.Payroll.Garnishment.PmtCodes[key])#</OPTION>
If you want to return the key
<OPTION VALUE="#key#">#xmlformat(Application.Payroll.Garnishment.PmtCodes[key])#</OPTION>
Include xmlformat() so that if your struct has special characters, it won't break the form
I think you need to include something within the OPTION tags too. So I would write that section as
<OPTION VALUE="#Application.Payroll.Garnishment.PmtCodes[key]#"> #Application.Payroll.Garnishment.PmtCodes[key]# </OPTION>
Related
I have a set of list values in ColdFusion variable, and I need to replace all the list values into desired text.
For Example:
<cfset headerColumnList = "FirstName,LastName,Email,FrequentGuestID,IP Address,Time Stamp Email Marketing">
<cfset a="test1">
<cfset b="test2">
<cfset c="test3">
<cfset d="test4">
<cfset e="test5">
<cfset f="test6">
<cfloop index = "ListElement" list= "#headerColumnList#" delimiters = ",">
<cfoutput>
#replaceList("#ListElement#","FirstName,LastName,Email,FrequentGuestID,IP Address,Time Stamp Email Marketing","#a#,#b#,#c#,#d#,#e#,#f#",",")#
</cfoutput>
</cfloop>
Output:
test1
test2
test3
test4
test5
Time Stamp test3 Marketing
In the above scenario. The value "Time Stamp Email Marketing" is supposed to be replaced with "test6" but I am getting in an alternative way where it is not replacing the phrase as a whole word. Can anyone tell me how do I replace the list phrases, any alternative for this?
Here you can use the ListQualify function to get exact result of an your scenario. So convert it in to qualify values and looping with that then you can replace it with your own list data. No need to change any order of a list values.
<cfset quoted = listQualify(headerColumnList,"''")>
<cfloop index = "ListElement" list= "#quoted#" delimiters = ",">
#replaceList(ListElement,quoted,"#a#,#b#,#c#,#d#,#e#,#f#")#
<br/>
</cfloop>
The code is working as written. You are seeing this because your check for "Email" in the replaceList() function is firing before the check for "Time Stamp Email Marketing". Notice the word "Email" in that string.
I don't know what your actual use case is but you can change the order of your code for this specific example to make it work like you want.
<cfset headerColumnList = "FirstName,LastName,Email,FrequentGuestID,IP Address,Time Stamp Email Marketing">
<cfset a="test1">
<cfset b="test2">
<cfset c="test3">
<cfset d="test4">
<cfset e="test5">
<cfset f="test6">
<cfloop index = "ListElement" list= "#headerColumnList#" delimiters = ",">
<cfoutput>
#replaceList("#ListElement#","FirstName,LastName,FrequentGuestID,IP Address,Time Stamp Email Marketing,Email","#a#,#b#,#d#,#e#,#f#,#c#",",")#
</cfoutput>
</cfloop>
This gives the desired output. Notice how I reordered the conditions within the replaceList() function.
I want to create database location records in mySQL. I have the following html string from a select box:
<cfset x='
<option value="1188">Aka Aka</option><option value="346">Ararimu</option><option value="293">Awhitu</option><option value="2851">Bombay</option><option value="865">Buckland</option>
'>
Rather than manually enter the records in the database, I'd like to strip out the html tags and end up with the following:
Aka Aka
Ararimu
Awhitu
Bombay
Buckland
Then I could do a simple loop based on line breaks and enter the data programatically. I can probably handle that part, but what I need to know is the simplest way to strip out the html to end up with the line break delimited list.
Here you go:
<cfset x='
<option value="1188">Aka Aka</option><option value="346">Ararimu</option><option value="293">Awhitu</option><option value="2851">Bombay</option><option value="865">Buckland</option>
'>
<cfset y = ListToArray(x, "</option>", "false", "true") />
<cfset z = ArrayNew(1) />
<cfloop array="#y#" index="name">
<cfif Trim(ListLast(name, ">")) is not "">
<cfset temp = ArrayAppend(z, ListLast(name, ">")) />
</cfif>
</cfloop>
<cfdump var="#z#" />
you have them in a 'z' array now, you can convert to list and add line break delimiters if you really want to.
I am just confusing myself with this one. I have a data log that is saved on the database as something like this:
Log-Date: 10/26/2012. Record created. Admission Date: 08/01/2012
Log-Date: 06/20/2013 Discharged. Discharge Date:10/15/2012
Reason for Discharge:01 - (routine discharge).
<!--- all other tracking info --->
I am trying to pull from this log only the discharges and sort/filter them by date. This log is saved in the database as one column varchar(MAX). I need to sort this data and only pull the discharge dates / reason using regex and then apply a filter. The end product should end up with me putting that array in a table with PATIENT | DISCHARGE DATE | DISCHARGE REASON My code right now is giving me some errors as it is leaving me with some empty array values. My question is that I need to remove those blank values and sort by the date, but I am unsure where to begin.
<cfquery name="getDischarge" datasource="#this.dsn#">
select PatientsName, LogData from Patient
</cfquery>
<cfoutput query="getDischarge" group="PatientsName">
<cfif LogData neq "">
<cfsavecontent variable="str">
#LogData#
</cfsavecontent>
<cfset possibilities = reMatch("Discharge Date?:(\d\d?/\d\d?/\d{4})\s*Reason for Discharge:\d* - ((?:(?!Log-Date:).)*)", str)>
<cfset dateArray = ArrayNew(2)>
<cfloop index="w"
array="#possibilities#">
<cfif w NEQ "">
<!--- create 1 dimensional temp array to hold DATE | REASON --->
<cfset tempArray = ArrayNew(1)>
<!--- trim our regex to have only the date & then DateFormat --->
<cfset theDate = #Mid(w, 16, 11)#>
<cfset formatDate = #dateformat('#thedate#','mm-dd-yyyy')#>
<!--- use our regex to find the reason for discharge --->
<cfset theReason = reMatch("Reason for Discharge:\d* - ((?:(?!Log-Date:).)*)", str)>
<!--- append our DATE | REASON to 1d temp array --->
<cfset ArrayAppend(tempArray, '#formatDate#')>
<cfset ArrayAppend(tempArray, '#theReason#')>
<!--- append our 1d array to our 2d array to output matching DATE | REASON --->
<cfset #ArrayAppend(dateArray, '#tempArray#')#>
</cfif>
</cfloop>
<cfdump var="#dateArray#">
</cfif> <!--- logdata neq "" --->
</cfoutput>
To me, logically, this should work and omit blank values, but this is what I get when I dump this data:
Looks like you are struggling with the Jakarta ORO regular expression engine that is used in ColdFusion. reMatch/reMatchNoCase are terrible when it comes to capturing. Java on the other hand offers the POSIX regular expression engine.
<cfset data = [
"Log-Date: 10/26/2012. Record created. Admission Date: 08/01/2012
Log-Date: 06/20/2013 Discharged. Discharge Date:10/15/2012
Reason for Discharge:01 - (routine discharge).
More stuff...",
"Log-Date: 10/26/2012. Record created. Admission Date: 08/01/2012
Log-Date: 06/20/2013 Discharged. Discharge Date:10/16/2012
Reason for Discharge:lorem ipsum."
]>
<cfset result = queryNew("DISCHARGE_DATE,DISCHARGE_REASON", "VARCHAR,VARCHAR")>
<cfloop array="#data#" index="line">
<cfset dischargeDate = reMatchGroupNoCase("Discharge Date:([0-9]{2}/[0-9]{2}/[0-9]{4})", line)>
<cfset dischargeReason = reMatchGroupNoCase("Reason for Discharge:([^\n]*)", line)>
<cfset hasDate = (arrayLen(dischargeDate) eq 1)>
<cfset hasReason = (arrayLen(dischargeReason) eq 1)>
<cfif hasDate or hasReason>
<cfset rowIndex = queryAddRow(result, 1)>
<cfif hasDate and isDate(dischargeDate[1])>
<cfset querySetCell(result, "DISCHARGE_DATE", dateFormat(dischargeDate[1], "yyyy-mm-dd"), rowIndex)>
</cfif>
<cfif hasReason>
<cfset querySetCell(result, "DISCHARGE_REASON", dischargeReason[1], rowIndex)>
</cfif>
</cfif>
</cfloop>
<cfquery name="orderedResult" dbType="query">
SELECT
*
FROM
[result]
ORDER BY
[DISCHARGE_DATE] ASC
</cfquery>
<cfdump var="#orderedResult#">
And here is the function you need:
<cffunction name="reMatchGroupNoCase" access="public" output="false" returnType="array">
<cfargument name="regex" type="string" required="true">
<cfargument name="value" type="string" required="true">
<cfset LOCAL.result = []>
<cfset LOCAL.Pattern = createObject("java", "java.util.regex.Pattern")>
<cfset ARGUMENTS.regex = LOCAL.Pattern.compile(ARGUMENTS.regex, bitOr(LOCAL.Pattern["CASE_INSENSITIVE"], LOCAL.Pattern["UNICODE_CASE"]))>
<cfset LOCAL.buffer = ARGUMENTS.regex.matcher(toString(ARGUMENTS.value))>
<cfset LOCAL.length = LOCAL.buffer.groupCount()>
<cfloop condition="LOCAL.buffer.find()">
<cfloop from="1" to="#LOCAL.length#" index="LOCAL.i">
<cfset LOCAL.value = LOCAL.buffer.group(
javaCast("int", LOCAL.i)
)>
<cfif isNull(LOCAL.value)>
<cfcontinue>
</cfif>
<cfset LOCAL.result.add(LOCAL.value)>
</cfloop>
</cfloop>
<cfreturn LOCAL.result>
</cffunction>
I recommend this approach:
with q1 as (select 'Log-Date: 10/26/2012. Record created. Admission Date: 08/01/2012
Log-Date: 06/20/2013 Discharged. Discharge Date:10/15/2012
Reason for Discharge:01 - (routine discharge). ' logData
)
select substring(logData, patindex('%Admission Date: %', logdata) + 16
, 10) admitDate
from q1
where logData like '%Discharge Date:%'
That returns 08/01/2012. You may have some complications for a variety of reasons, but the general idea should work.
I have a form with many values in it (around 25 fields). After the form is posted and inserted into the database, I have to take the form information and output it to a report. The report should only show fields with those that have values in it (so the report would only have 5 fields in it, if only 5 fields were filled in).
The easiest way would be to do something like this:
<cfif form.firstname neq "">
<li><First Name: #FORM.FIRSTNAME#</li>
</cfif>
<cfif form.lastname neq "">
<li><Last Name: #FORM.LASTNAME#</li>
</cfif>
Can anyone recommend a better way of doing this? I would like to keep it on the ColdFusion side, since the entire report is stripped of HTML to produce a plain text report as well.
You can loop through them like this
<cfloop list="#form.fieldNames#" index="i">
<li><cfoutput>#i# = #form[i]#</cfoutput></li>
</cfloop>
Not sure that is exactly what you want but it might get you on the right track
Based on your comment try this :
<cfloop list="#form.fieldNames#" index="i">
<li><cfoutput>
<cfswitch expression="#i#">
<cfcase value="firstName">
First Name
</cfcase>
<cfcase value="lastName">
Last Name
</cfcase>
<cfdefaultcase>
#i#
</cfdefaultcase>
</cfswitch>
: #form[i]#</cfoutput></li>
</cfloop>
Here's my attempt at this: Thanks to Lance for pointing me towards the right direction:
<ul>
<cfoutput>
<cfloop list="#form.fieldNames#" index="i">
<li>
<cfif len(trim(form[i])) neq 0>
<cfswitch expression="#i#">
<cfcase value="FIRST_NAME">First Name</cfcase>
<cfcase value="LAST_NAME">Last Name</cfcase>
<cfdefaultcase>#i#</cfdefaultcase>
</cfswitch>
: #FORM[i]#
</cfif>
</li>
</cfloop>
</cfoutput>
</ul>
Here's an alternative to using switch/case - put labels in a struct
<cfset FieldLabels =
{ 'first_name' : "First Name"
, 'last_name' : "Last Name"
, 'other stuff' : "Whatever you like"
}/>
<cfoutput>
<ul>
<cfloop index="CurField" list=#Form.FieldNames# >
<cfif len(trim( Form[CurField] )) >
<li>
#StructKeyExists( FieldLabels , lcase(CurField) )
? FieldLabels[ lcase(CurField) ]
: HtmlEditFormat( replace(CurField,'_',' ','all') )
#
: #HtmlEditFormat( Form[CurField] )#
</li>
</cfif>
</cfloop>
</ul>
</cfoutput>
Note that it does not do neq 0 on the len - this is entirely unnecessary.
The a ? b : c construct inside the first hashes is the ternary conditional operator - a compact way of doing if/else - supported in CF10 and Railo 3.3 onwards.
If a name doesn't have an explicit label, it replaces underscores with spaces, which is probably preferable if the report is for a non-technical audience.
If it's possible that you have code that adds (or removes) items in the form scope without modifying the FieldNames list, you can change the loop for this...
<cfloop item="CurField" collection=#Form# >
<cfif CurField EQ 'FieldNames'>
<cfcontinue />
</cfif>
...
Which looks at the actual keys in the Form scope - though the ordering of them is not guaranteed for this method.
How about you loop on the struct itself directly ?
<cfscript>
for(eachKey in FORM){
if(FORM[eachKey] neq ''){
writeOutput('<li>' &
FORM[eachKey] & ' = ' &
trim( FORM[eachKey] ) &
'</li>');
}
}
</cfscript>
You can have a space in the form variable name.
I trying to use a very simple CFGRID (with CFGRIDUPDATE) but not allow NULLS.
<cfset strWarning= "">
<cfif IsDefined("FORM.gridEntered")>
<cfif FORM.myName EQ '' OR FORM.myURL EQ ''>
<cfset strWarning= "Error: Form fields cannot be blank">
<cfelse>
<cfgridupdate grid="gridSomething"
dataSource="qryTSQL" tableName="tblName" keyOnly="Yes">
</cfif>
</cfif>
<cfoutput>#strWarning#</cfoutput><br />
<cfform>
<cfgrid name="gridSomething" query="qryTSQL"
selectMode="Edit" format="HTML">
<cfgridcolumn name = "myID" display="No">
<cfgridcolumn name = "myName">
<cfgridcolumn name = "myURL">
</cfgrid>
<cfinput type="submit" name="gridEntered">
The error I am getting is - Error Diagnostics: Complex object types cannot be converted to simple values. The expression has requested a variable or an intermediate expression result as a simple value. However, the result cannot be converted to a simple value. Simple values are strings, numbers, boolean values, and date/time values. Queries, arrays, and COM objects are examples of complex values.
The most likely cause of the error is that you tried to use a complex value as a simple one. For example, you tried to use a query variable in a cfif tag.
I think I am under thinking this desired solution.
Thanks.
EDIT: Updated Error Message
Error Diagnostics: Element MYURL is undefined in FROM.
Form scope - struct
FIELDNAMES GRIDENTERED,__CFGRID__CFFORM_1__GRIDSOMETHING
GRIDENTERED Submit Query
GRIDSOMETHING.MYID Form scope - array
1 1001
GRIDSOMETHING.MYURL Form scope - array
1 /test_d.cfm
GRIDSOMETHING.ORIGINAL.MYID Form scope - array
1 1001
GRIDSOMETHING.ORIGINAL.MYURL Form scope - array
1 /changed.cfm
GRIDSOMETHING.ROWSTATUS.ACTION Form scope - array
1 U
__CFGRID__CFFORM_1__GRIDSOMETHING __CFGRID__EDIT__=2 MYID Y MYURL Y 1 U 1001 1001 /test_d.cfm /changed.cfm
Grids work differently than standard FORM fields. Since grids contain multiples rows of data, CF creates arrays of the new/changed values. One for each grid column ie
FORM.gridname.columnName
To determine if any of the values for a specific column are empty, you need to loop through the array for that column and check each value:
<cfset updateCount = arrayLen(FORM.gridSomething.myName) />
<cfloop from="1" to="#updateCount#" index="x">
<cfset nameValue = trim( FORM.gridSomething.myName[x] ) />
<cfset urlValue = trim( FORM.gridSomething.myURL[x]) ) />
<!--- one or both of the values is empty --->
<cfif not len( nameValue ) OR not len( urlValue )>
... empty value found. do something here ....
</cfif>
</cfloop>
Add this function to you code and call it passing it the FORM scope as follows;
On page or CFC works the same!
Clears up errors with some versions of CF that choke on blank cols in a simple grid update
<cffunction name="cleanGridUpdate" >
<cfargument name="FORM" >
<cfloop collection="#FORM#" item="thisOne">
<cftry>
<cfset thisDeep = arrayLen(FORM[thisOne])>
<cfloop index="x" from="1" to="#thisDeep#">
<cfif len(FORM[thisOne][x])lt 1>
<cfset FORM[thisOne][x] = javaCast( "null", 0 )>
</cfif>
</cfloop>
<cfcatch>
<cfset cat=1>
</cfcatch>
</cftry>
</cfloop>
<cfreturn form>
</cffunction>
<cfif isDefined('URL.action') AND URL.action eq 'gridUpdate'>
<cfset cleanGridUpdate(FORM)>
<cfgridupdate grid="#URL.table#" table="#URL.table#" datasource="your_DS"
keyonly="yes" >
</cfif>
<cfform action="##?action=gridUpdate&table=cheesePuffs" method="post">
<cfgrid name='cheesePuffs' format='HTML'/>
<cfinput name="submit" type="submit" value>
</cfform>