I have a drop down list that is generated by two loops. The inner loop generates a series of numbers ie from 0 to 23. The outer loop, is a query loop that selects the correct value from the 23 numbers based on the values stored in my database.
My issue here is that those two loops conflict that results in displaying the numbers from 0 to 23 twice. How can keep both loops but avoiding this issue? This problem also cause issues when the form is submitted by trying to submit the form twice and deleting the user's input.
This is my code:
<select id="openHours#CountVar#" name="openHours#CountVar#">
<cfloop query="doctorHours" >
<cfloop from="0" to="23" index="OpenHours">
<option value="#openHours#"
<cfif TimeFormat(doctorHours.openTime,'HH') EQ OpenHours AND CountVar EQ doctorHours.day > selected="selected"</cfif>>#OpenHours#</option>
</cfloop>
</cfloop>
</select>
This is my CFDUMP for that query
query
RESULTSET
query
CLOSETIME DAY DOCTORID OPENTIME
1 1970-01-01 16:00:00.0 4 2011041516290025478779 1970-01-01 10:00:00.0
2 1970-01-01 16:00:00.0 1 2011041516290025478779 1970-01-01 13:00:00.0
3 1970-01-01 16:00:00.0 2 2011041516290025478779 1970-01-01 13:00:00.0
CACHED false
EXECUTIONTIME 0
SQL select doctorID, opentime, closetime, day from doctorBusinessHours where doctorID='2011041516290025478779'
You should return only the hours you need and then loop for the dropdownlist creation:
DATEPART(hh,yourdate) will return the hours for your datetime value:
<cfquery name="doctorHours" datasource="#ds#">
SELECT doctorID,DATEPART(hh,openTime) As OpenHours, DATEPART(hh,closetime) As CloseHours
FROM doctorHours
WHERE day = #CountVar#
AND doctorID='#docID#'
</cfquery>
ValueList will transform your query results into a list:
<cfset openTimesList = ValueList(doctorHours.OpenHours) />
<cfset closeTimesList = ValueList(doctorHours.CloseHours ) />
ListContains will return the index of the value within your list:
<select id="openHours#CountVar#" name="openHours#CountVar#">
<cfloop from="0" to="23" index="OpenHours">
<option value="#openHours#"
<cfif ListContains(openTimesList,OpenHours) NEQ 0 >
selected="selected"
</cfif>
>#OpenHours#</option>
</cfloop>
</select>
You can use the same strategy for the closeTimesList.
Hmmm....the number of values displayed in the code above will be equivelant to the number of records returned by the query X 23. If you're query returns 2 records you will see 46 options and so on. It seems like you believe the query has only 1 record. I would suggest perhaps it has more.
Try LIMIT 1 or TOP 1 in your query - or use Maxrows (as suggested in the comments)... but make sure you know what you are including and what you are excluding. You need to know why your query is not what you expect :)
Related
I have a self-submitting form, whose data gets used in a cfquery after it is submitted. I'm having a problem when the user submits a decimal rather than an integer.
This is for tires sizes
<select>
...
<option value="19.0">R19</option>
<option value="19.5">R19.5</option>
...
</select>
Then if the form is submitted, the results are passed on to a cfquery to show results only for that size.
<cfif form.size gt 0 >
AND ts.decDiameter = <cfqueryparam cfsqltype="cf_sql_decimal" value="#form.size#" />
</cfif>
This works perfectly for whole numbers, but when I select 19.5, it brings me back the results for 20. It is rounding up. Something weird with the cfqueryparam. It is transforming the result into a numeric value, but it is rounding it up to the next integer.
You need to add the scale parameter.
<cfqueryparam cfsqltype="cf_sql_decimal" scale="2" value="#form.size#">
You can use this reference...
http://help.adobe.com/livedocs/coldfusion/8/htmldocs/help.html?content=Tags_p-q_18.html
I am checking with some work where i am geting the query result as:
query
VALUE
1 #FF6600,#339933,#0033CC,#FF0000,#00CC66,#FF9900,#FFFF00,#00FFFF,#FF66FF
2 Open, Resolved, In-Progress, Escalated, Closed, Re-Opened,Rejected,On-Hold,Locked
Now i need to map the 1st row parrallel value to the 2row, I know that this can be done via cfloop or like should i convert it with Array..
Need nested loops, but not sure how it will work
please guide
Something like this should work for the data in your question.
<cfset NumberOfItems = ListLen(queryname.value[1])>
<cfoutput>
<cfloop from=1 to=NumberOfItems index=idx>
Row 1 item is #ListGetAt(queryname.value[1], idx)#<br>
Row 2 item is #ListGetAt(queryname.value[2], idx)#<br>
</cfloop>
</cfoutput>
OK. I've done a terrible job of explaining what I'm trying to do. I will try one more time to be more clear.
I have a list of variables that is submitted to a page with a cfquery insert. The variables come from dynamically named form fields, and are captured using a cfloop:
<cfloop list="#form.fieldnames#" index="item">
</cfloop>
What I have are form fields dynamically named, and a value added, as such:
<input type="hidden" name="ticketid_#some_number#" value="#some_quantity#">
For brevity, lets say the form field name is ticketid_6, and the value is 4. This could be a different name and value (for instance, ticketid_3 with a value of 1), or there might be several form fields of similar construct with different names and/or values.
So, on the insert page, I need to insert ticketid_6 4 times (creating 4 separate rows) into my table. So, a row in the database for each dynamically named form field, times the value of each.
I hope that explains it better.
Leigh,
I am still open to your suggestion on the previous post, but I fear I might not have explained my situation clearly enough for you to give your best recommendation. I will re-approach that question after I get this part figured out.
If you need to loop through all your field names and treat each one of those fields as a list you'd need to do two loops to insert each item.
<cfloop list="#form.fieldnames#" index="item"><!--- loop through all the form fields --->
<cfif find('ticketid_',item)><!--- if the form name contains 'ticketid_'. Use findNoCase if you want to ignore case sensitivity --->
<cfloop from="1" to="#form[item]#" index="counter"><!--- loop through the number in form.ticketid_ --->
<cfquery datasource="#dsn#">
INSERT INTO table (fieldname, fieldValue, TicketNum)
VALUES (
<cfqueryparam value="#item#" cfsqltype="cf_sql_varchar">,--fieldName from the form
<cfqueryparam value="#form[item]#" cfsqltype="cf_sql_varchar">--value of the fieldName in the form
<cfqueryparam value="#counter#" cfsqltype="cf_sql_integer">--ticket number being inserted
)
</cfquery>
</cfloop>
</cfif>
</cfloop>
You'll need to do server side validation to verify they haven't entered a non numeric number for the input box, but assuming you've done that this should achieve what you're looking for.
You need to use Evaluate function to get form dynamically input field value
Try this one
<input type="hidden" name="ticketid_#some_number#" value="#some_quantity#">
<cfloop list="#form.fieldnames#" index="item">
<cfoutpuy>Evaluate("ticketid_#item#")</cfoutpuy>
</cfloop>
You need to first bundle your data into an XML structure
<cfsavecontent variable="myFormData">
<cfoutput>
<ul class="xoxo">
<cfloop list="#form.fieldnames#" index="item">
<cfloop list="#form[item]#" index="eachItem">
<li><b>#xmlformat(item)#</b> <var>#xmlformat(eachItem)#</var>
</cfloop>
</cfloop>
</ul>
<cfoutput>
</cfsavecontent>
Then do a single insert
<cfquery>
INSERT INTO table (formData)
VALUES (<cfqueryparam value="#myFormData#" cfsqltype="cf_sql_varchar">)
</cfquery>
When you pull the data, you can
Show it as is, a bulleted list,
Promote to a bunch of rows in a table
Note that the data is inserted as both HTML and XML
I'm not sure my title explains this very well. Frankly, I'm not sure how to put it into words, but here goes:
I am capturing variables from dynamically created form fields on another page, that have been submitted to a page containing the code below. So far, everything works as I want it to. I'm getting the dynamically named form fields. Now I need to add the subtotal dollar amounts together to create a grand total. Unfortunately, I can't figure out how to get the individual totals out of the loop so I can do the math for the final number, due to their dynamic nature.
This part of the code below generates the subtotals, and I need to be able to add all of them together to get a grand total, but I can't figure out how:
#dollarformat(val(getticket[item].ticketprice * form[item]))#
Maybe I need to take a different approach...suggestions/help appreciated.
Here's the full code:
<CFLOOP LIST="#form.fieldnames#" INDEX="item">
<cfoutput>
<cfquery datasource="outertixdb" name="getticket[item]">
select * from tickets
where ticketid = '#item#'
</cfquery>
#getticket[item].ticketname#: #dollarformat(getticket[item].ticketprice)# x #form[item]# = #dollarformat(val(getticket[item].ticketprice * form[item]))#<br/>
</cfoutput>
You would need to set the name attribute of your cfquery using the following format:
<cfquery datasource="outertixdb" name="#getticket[item]#">
To handle the total, you would first need a variable before the cfloop
<cfset total = 0 />
Then, inside the loop, you simply add the price of the ticket to the total
<cfset total = total + getticket[item].ticketprice />
Also, you should be using cfqueryparam in your query. You can read more about it here
Lastly, if you do not need all the data in the tickets table, do not use 'select *..', only pull pack the data that you need.
Not sure I completely understand, but it sounds like you are simply trying to look up a bunch of ticket records, by "id". Then display the individual costs, plus a grand total. If that is all your doing, just give the fields the same name: ticketID. For example:
<input name="ticketID" value="1" ...>
<input name="ticketID" value="22" ...>
<input name="ticketID" value="45" ...>
<input name="ticketID" value="16" ...>
Then the values will be submitted as a list ie 1,22,45,16, which you can feed into your query using an IN clause. That lets you grab all of the data in a single query. (Generally you want to avoid running queries within a loop because performing a separate database query for each id generates a lot of unnecessary overhead and degrades performance).
* Change the cfsqltype as needed
SELECT TicketID, TicketPrice
FROM YourTable
WHERE TicketID IN ( <cfquerparam value="#FORM.ticketID#"
list="true"
cfsqltype="cf_sql_integer">
)
UPDATE:
form[item] is the value of the quantity select from the previous page.
That is a confusing naming convention. I would recommend using a slightly more intuitive name like "quantity". Something more descriptive of the contents. You can still use the ticket id to generate unique names, ie quantity_#ticketID#. For example, using the same ticket id's as above:
<input name="quantity_1" ...>
<input name="quantity_22" ...>
<input name="quantity_45" ...>
<input name="quantity_16" ...>
Once you have the results, there are several ways to generate a grand total. The simplest being to initialize a variable before your loop, then increment it as you iterate. Use the query ticket ID to grab the quantity value from the FORM scope:
<cfset grandTotal = 0>
<cfoutput query="yourQuery">
<!--- extract quantity value --->
<cfset currQuantity = FORM["quantity_"& yourQuery.ticketID ]>
... display price ...
<cfset grandTotal += val(yourQuery.ticketPrice * currQuantity )>
</cfoutput>
GrandTotal <cfoutput>#grandTotal#</cfoutput>
I would recommend throwing out the whole dynamically named query thing.
<cfset total = 0>
<CFLOOP LIST="#form.fieldnames#" INDEX="item">
<cfquery datasource="outertixdb" name="getticket">
select * from tickets
where ticketid = <cfqueryparam cfsqltype="cf_sql_varchar" value="#item#">
</cfquery>
<cfset total += getticket.ticketprice />
<cfoutput query="getTicket">
#ticketname#: #dollarformat(ticketprice)# × #form[item]#
= #dollarformat(val(ticketprice * form[item]))#<br/>
</cfoutput>
</cfloop>
Output your total as needed
So we have a news/announcement function that pulls info from a database and displays it
<cfquery name="announcement" datasource="#application.datasource#" dbtype="odbc">
SELECT top 2 * FROM NewsEvents
WHERE type = 2 AND active = 1 AND publish_datetime <= #now()# AND show_on_home = 1 AND item_datetime >= #createOdbcDate(now())#
ORDER BY item_datetime ASC
</cfquery>
What we're trying to do is display a piece of HTML within these announcement blocks, conditional on one of the two blocks NOT being the most recent of the two blocks.
The HTML is wrapped in this code:
<cfif announcement.recordCount gt 0>
<cfloop query="announcement">
<cfoutput>
html
</cfoutput>
</cfloop>
<cfelse>
<cfoutput><p>There are currently no announcements.</p></cfoutput>
</cfif>
I want one component of the HTML to only be displayed for the BOTTOM announcement, the one that is not the closest in item_datetime. Any thoughts on how to accomplish this?
You're ordering by date, so just do something like this:
<cfif CurrentRow EQ 1>
We're showing the first record, so show some stuff.
</cfif>
CurrentRow is always available in a loop to show you which record of the query you're currently on. So given your current query (and some made up data straight outta my head, you'll end up with this output:
Record 1: August 29, 2011
We're showing the first record, so show some stuff
Record 2: August 30, 2011
You're sorting by the date ASC, so the oldest record is first, while the newer record is last. I would recommend that you change your sorting to DESC, or you're never going to get newer records once you've added a third announcement after the first two. You could then resort them on the CF side to be in the display order you're after.
You can add a modifier to your CFQUERY statement like so. I would also modify your CFIF recordCount statement to look for more than 1 record at this point.
<cfif announcement.recordCount gt 1>
<cfoutput query="announcement" startRow="2">
<!--- Throw my output here --->
</cfoutput>
<cfelse>
<p>There are currently no announcements.</p>
</cfif>