I have the following cfdocument code:
<cfdocument format="pdf" orientation = "landscape" bookmark="Yes" marginleft=".25" marginright=".25" marginTop = ".75" marginbottom=".75" scale="90" localUrl="yes">
<cfoutput>
<cfdocumentsection name="Summary Page" marginleft=".25" marginright=".25" marginTop = "1.65" marginbottom="1" >
<cfdocumentitem type="header">
<center>
<table width="1000" height="200" cellpadding="3" cellspacing="0">
<tr><td>Header Page</td></tr>
</table>
</center>
</cfdocumentitem>
<cfloop query="first_query">
<cfquery name="getDetails" dbtype="query">
select * from first_query
where type= <cfqueryparam cfsqltype="cf_sql_varchar" value="#Type#">
</cfquery>
<cfsavecontent variable="trhead">
<tr class="bigbluecolor" style="text-align:center;">
<td width="6%">Term</td<
</tr>
</cfsavecontent>
#trhead#
<cfloop query="getDetails">
<tr align="center">
<td width="6%">#Listfirst(TermYears,'.')# Years</td>
</tr>
<cfif getDetails.recordcount GT 6 AND getDetails.currentRow EQ 6>
<cfdocumentitem type="pagebreak"/>
#trhead#
</cfif>
</cfloop>
</table>
</td></tr></table>
</cfloop>
</cfoutput>
</cfdocumentsection>
</cfdocument>
However, it does not do the page break. It shows empty pages at the top and then it starts breaking anywhere it wants. I want my inner loop to break after 4 records and the <TH> header to repeat itself again on the start of the second page.
The trhead variable contains the code which I have wrapped with the savecontent to show it.
Can anyone explain what I am missing?
The unpredictability of the page breaks is because of this:
<cfif getDetails.recordcount GT 6 AND getDetails.currentRow EQ 6>
If getDetails has less than 6 records, that condition will never return true. Plus, if you have 12 or more records, it won't return true. I suggest this approach. First, add this to first_query:
order by type
Then build your content like this:
<cfsavecontent variable="trhead">
<tr class="bigbluecolor" style="text-align:center;">
<td width="6%">Term</td>
</tr>
</cfsavecontent>
<cfoutput query="first_query">
other content goes here
<cfif currentRow mod 6 is 0>
<cfdocumentitem type="pagebreak"/>
#trhead#
</cfif>
</cfoutput>
I am building a report that outputs the information into a word document using Coldfusion. Some of the information is output into tables and occasionally the table is occurring at the bottom of a page and the table ends up breaking apart to two pages. How do I keep the table from breaking apart?
The format is .doc.
<cfsavecontent variable="myDocument">
<html xmlns:w="urn:schemas-microsoft-com:office:word">
<head>
<xml>
<w:WordDocument>
<w:View>Print</w:View>
<w:Zoom>100</w:Zoom>
<w:DoNotOptimizeForBrowser/>
</w:WordDocument>
</xml>
</head>
<body>
<!--- run some queries to get information --->
<!--- Display some information via normal <cfoutput> --->
<!--- Then display information in table like this --->
<cfset xtest_count = 0>
<cfloop query="test">
<cfif xtest_count eq 0>
<cfset xtest_count = xtest_count + 1>
<b><u>Speaker<cfif test.recordcount gt 1>s</cfif></u></b><br><br>
<table width="100%" cellpadding=3 cellspacing=2 border=1>
<tr>
<td><b>Title</b></td>
<td><b>Name</b></td>
<td><b>Credentials</b></td>
<td><b>Organization</b></td>
</tr>
</cfif>
<tr>
<td>#test.title#</td>
<td nowrap>#test.first_name# #test.last_name#</td>
<td>#test.credentials#</td>
<td>#test.company_name#</td>
</tr>
</cfloop>
</table>
<!--- Display More information--->
</body>
</html>
</cfsavecontent>
I did SEARCHing code, something like this.
--pageone.cfm--
<cfparam name="Form.studNo" default="" />
<form action="pagetwo.cfm" method="POST">
<label> Please insert ID:
<input name="studNo" value="<cfoutput>#Form.studNo#</cfoutput>" />
</label>
<input type="submit" value="Search" />
</form>
--pagetwo--
SELECT * FROM students
WHERE students_ID IN (#Form.studNo#)
On page two, I will display the details of student's info and user can edit a new information if the data is not right.
I'm thinking of, displaying data of one student per page and user can click Next for the next students (ID that has been inserted) on pageone.cfm
Can anyone help me with these?
#henry.
I did try something like this.
--example.cfm--
<CFPARAM NAME="StartRow" DEFAULT="1">
<CFPARAM NAME="DisplayRows" DEFAULT="1">
<CFQUERY NAME="getStudent" DATASOURCE="#dsn#"
CACHEDWITHIN="#CreateTimeSpan(0,0,15,0)#">
SELECT *
FROM students
</CFQUERY>
<CFSET ToRow = StartRow + (DisplayRows - 1)>
<CFIF ToRow GT getStudent.RecordCount>
<CFSET ToRow = getStudent.RecordCount>
</CFIF>
<HTML>
<HEAD>
<TITLE>Next/Previous Record Browsing</TITLE>
</HEAD>
<BODY>
<CFOUTPUT>
<H4>Displaying records #StartRow# - #ToRow# from the
#getStudent.RecordCount# data inserted.</H4>
</CFOUTPUT>
<!--- create the header for the table --->
<TABLE CELLPADDING="3" CELLSPACING="0">
<TR BGCOLOR="#888888">
<TH>Name</TH>
<TH>ID</TH>
<TH>Gender</TH>
<TH>E-mail</TH>
</TR>
<CFOUTPUT QUERY="getStudent" STARTROW="#StartRow#"
MAXROWS="#DisplayRows#">
<TR BGCOLOR="##C0C0C0">
<TD>#Name#</TD>
<TD>#ID#</TD>
<TD>#Gender#</TD>
<TD>#Email#</TD>
</TR>
</CFOUTPUT>
</TABLE>
<CFSET Next = StartRow + DisplayRows>
<CFSET Previous = StartRow - DisplayRows>
<!--- Create a previous records link if the records being displayed aren't the
first set --->
<CFOUTPUT>
<CFIF Previous GTE 1>
<A HREF="example.cfm?StartRow=#Previous#"><B>Previous #DisplayRows#
Records</B></A>
<CFELSE>
Previous Records
</CFIF>
<CFIF Next LTE getStudent.RecordCount>
<A HREF="example.cfm?StartRow=#Next#"><B>Next
<CFIF (getStudent.RecordCount - Next) LT DisplayRows>
#Evaluate((getStudent.RecordCount - Next)+1)#
<CFELSE>
#DisplayRows#
</CFIF> Records</B></A>
<CFELSE>
Next Records
</CFIF>
</CFOUTPUT>
</BODY>
</HTML>
You may use session to store the specified IDs in pageone.cfm, then go through the array of IDs and use array index as the current page number, and array length as the total page count.
However in this day and age, using JS to display a record at a time makes more sense.
Your approach is ok, but I'd recommend using existing libaries that do the trick of paginating and even constructing HTML for displaying page number buttons, next-previous links and what not.
Please revise http://paginationcfc.riaforge.org/ - a ColdFusion project that deals with pagination quite well and is very easy to implement, saving you tons of work. You could even set it do display one record per page, and the rest (next-previous buttons and maybe "page numbers") would be automagically done by the pagination component.
Ah, doing so (one big query and subsequent sub-queries) I strongly suggest caching.
HTH.
When a user deselects an item (by unchecking the checkbox) from the form, I want the corresponding data to be deleted from the database.
Here is what my form looks like:
Category
Item 80 626
1.Item # 1 (87) chk chk
2.Item # 2 (59) chk chk
So basically, the list looks like this:
DB_list = (80|87, 626|87, 80|59, 626|59)
Now if a user deselects one of these items 80|87, I want it to be deleted from the database like so:
DELETE FROM TBL
WHERE Item = 87
AND Category = 80
So on form submit, the list becomes
New_List = (626|87, 80|59, 626|59)
How do we delete 80|87?
This is one way to do it:
<cfoutput>
<cfset DB_list = "80|87,626|87,80|59,626|59" />
<cfset New_List = DB_list />
<cfset myitems="80,626">
<cfset mycategories = "87,59"/>
<cfif structKeyExists(form,"fieldnames")>
<!-- on submit -->
<cfif structKeyExists(form,"listitem")>
<cfset New_List = form.listitem>
</cfif>
<br />RESULT:<br />
DB_list:#DB_list#<br />
New_List:#New_List# <br /><br />
<cfloop from="1" to="#ListLen(DB_list)#" index="ix">
<cfset listitem = ListGetAt(DB_list,ix)>
<cfif ListFindNoCase(New_List,listitem) eq 0>
<!-- hence: split in javascript -->
<cfset listitemarray=ListToArray(listitem,"|")/>
<cfset itemid=listitemarray[1] />
<cfset categoryid=listitemarray[2] />
<cfquery>
DELETE FROM TBL
WHERE Item = <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#itemid#">
AND Category = <cfqueryparam cfsqltype="CF_SQL_INTEGER" value="#categoryid#">
</cfquery>
</cfif>
</cfloop>
</cfif>
<form name="tstForm" id="tstForm" method="post" action="">
<table>
<tr>
<td> </td>
<cfloop from="1" to="#ListLen(mycategories)#" index="lstindex1">
<td>Category #ListGetAt(mycategories,lstindex1)#</td>
</cfloop>
</tr>
<cfloop from="1" to="#ListLen(myitems)#" index="lstindex2">
<tr>
<cfset itemid=#ListGetAt(myitems,lstindex2)# />
<td>item #itemid#</td>
<cfloop from="1" to="#ListLen(mycategories)#" index="lstindex3">
<cfset catid=#ListGetAt(mycategories,lstindex3)# />
<td>
<input type="checkbox" id="listitem_#itemid#_#catid#" name="listitem" value="#itemid#|#catid#" <cfif ListFindNoCase(New_List,"#itemid#|#catid#",",") gt 0>checked</cfif>/>
</td>
</cfloop>
</tr>
</cfloop>
</table>
<button type="submit">Submit</button>
</form>
</cfoutput>
Run this code here
My approach would be to have a hidden field in the form that has all the available values for the checkboxes. Then when the form is submitted, compare what's in the hidden form field with what's in the checkbox field. Whatever the hidden field has that the check box field does not can be deleted.
Without the use of JavaScript, Dan Bracuk's solution would work the best for your stated requirements. However, another simpler approach to this problem is to just delete all previous choices then re-insert whatever items are still checked. Then there is no need to compare old and new values to determine what has changed.
How about
DELETE
FROM tbl
WHERE NOT CONVERT(varchar(20), Item) + '|' + CONVERT(varchar(20), Category)
IN <cfqueryparam cfsqltype="CF_SQL_varchar" value="#form.new_list#" list="yes">
My approach using sql server is to delete all the list items from the db, and then add only the ones that have been submitted by the form. All delete and add queries should be put into a single transaction, so if anything fails you can make o rollback.
I have a report which is doing a page-break on a tfoot tag.
<style type="text/css">
#media print
{
tfoot{page-break-after:always}
}
</style>
The output comes from a query (here called "test"), ordered by state. The report is in a table and I want to break after each state. It's PAGING correctly. But the problem is that the first header (for the first state) precedes and the first footer (for the first state) follows each subsequent header and footer. In my test program I worked around it by inventing a blank state and setting its header and footer to blank. However, in my real program things are too complicated to do that; and I don't like kluges anyway. Can anyone tell me how to get that first header and footer to appear just once where they are supposed to be? Here is the test program:
<cfset statels = (" ,DE,NC,MD")> <!--- the blank state is the kluge --->
<cfset i = 0>
<table style = "margin-left: 50px">
<cfloop list = #statels# index = "state">
<cfset i = i + 1>
<cfoutput>
<thead>
<cfif i EQ 1>
<tr><td>  </td></tr>
<cfelse>
<tr>
<td style = "border:1px solid green">This is a Header #state#</td>
<td> <img src="http://localhost/reports/XYZinc.jpg" alt="picture"> </td>
</tr>
<!--- column headings to be on each page --->
<tr>
<cfloop array = #test.GetColumnList()# index = "col">
<td class = "repsort">#col# </td>
</cfloop>
</tr>
</cfif>
</thead>
</cfoutput>
<cfoutput query = "test">
<cfif test["PersonState"][currentrow] EQ state>
<tr>
<cfloop array = #test.GetColumnList()# index = "col">
<td>#test[col]currentrow]# </td>
</cfloop>
</tr>
</cfif><!--- personstate is state --->
</cfoutput>
<cfoutput>
<tfoot>
<cfif i EQ 1>
<tr><td>  </td></tr>
<cfelse>
<tr>
<td>This is a footer<br> i is #i# state is #state#
</td>
</tr>
</cfif>
</tfoot>
</cfoutput> <!---query = test --->
</cfloop> <!--- i loop --->
</table>