CFML form will not insert into SQL Server 2014 database - sql-server

Lucee 5.2, SQL Server 2014
I have a form that will not insert a new record into my SQL Server 2014 database.
I've studied this problem for a couple of days and nights and cannot figure out what is going on. I do not get an error message of any kind. I fill out the form, click the Submit button, and I am returned to a blank form. No record is inserted into the database table.
I have tested this abridged version of my code, below, but I still get the same result: no insert happens; and Lucee does not give me back any error message at all.
<!--- set a default value "" for RegisterID in scope URL --->
<cfparam name="url.RegisterID" default="">
<!--- define the RegisterID in scope FORM, then set form.RegisterID equal to the RegisterID passed in the URL --->
<cfparam name="form.RegisterID" default="#url.RegisterID#">
<!--- set default values for other user-editable fields --->
<cfparam name="form.Title" default="">
<cfparam name="form.x_first_name" default="">
<cfparam name="form.DateCreated" default="">
<cfparam name="form.DateModified" default="">
<!--- query editRegister tells Lucee which record to edit--->
<cfquery datasource="nnvawi" name="editRegister">
SELECT RegisterID
,Title
,x_first_name
,DateCreated
FROM NNVAWIRegister
WHERE RegisterID = <cfqueryparam cfsqltype="cf_sql_integer" value="#val(form.RegisterID)#">
</cfquery>
<cftry>
<cfset variables.error = "">
<cfif IsDefined("FORM.doSave")>
<!--- when a RegisterID Exists, the action is UPDATE --->
<cfif val(form.RegisterID)>
<!--- query UpdateUser updates a page record in content table --->
<cfquery name="UpdateUser" datasource="nnvawi">
UPDATE NNVAWIRegister
SET
Title = <cfqueryparam cfsqltype="cf_sql_varchar" value="#Trim(Left(form.Title,50))#">,
x_first_name = <cfqueryparam cfsqltype="cf_sql_varchar" value="#Trim(Left(form.x_first_name,255))#">,
DateModified = <cfqueryparam cfsqltype="cf_sql_timestamp" value="#now()#">
WHERE RegisterID = <cfqueryparam cfsqltype="cf_sql_integer" value="#val(form.RegisterID)#">
</cfquery>
<!--- CFELSE: if RegisterID does not exist, then create new Page --->
<cfelse>
<!--- query to insert new user record into content table --->
<cfquery name="InsertRecord" datasource="nnvawi" result="newRegistrant">
INSERT INTO NNVAWIRegister
(
,Title
,x_first_name
,DateCreated
)
VALUES(
<cfqueryparam cfsqltype="cf_sql_varchar" value="#Trim(Left(form.Title,50))#">,
<cfqueryparam cfsqltype="cf_sql_varchar" value="#Trim(Left(form.x_first_name,255))#">,
<cfqueryparam cfsqltype="cf_sql_timestamp" value="#now()#">
)
</cfquery>
<!--- use the result attribute value (newRegistrant) to set form field value --->
<cfset form.RegisterID = newRegistrant.IDENTITYCOL>
<!--- END cfif val(form.RegisterID) -- if a record needed to be updated or added, then it was done --->
</cfif>
</cfif>
<cfcatch type="Any">
<cfset variables.error = cfcatch.message>
</cfcatch>
</cftry>
<cfif len(variables.error) eq '0'>
<cfloop index="aCol" list="#editRegister.columnList#">
<cfset "form.#aCol#" = editRegister[aCol][editRegister.currentRow]>
</cfloop>
</cfif>
<cfinclude template="/admin/admin_header.cfm">
<!--- if there an error, display error in readable form --->
<cfif len(variables.error)>
<cfoutput>
<div class="errorbox">#variables.error#</div>
</cfoutput>
<br />
<div class="align-center">
<input type=button value="Go Back" onClick="history.go(-1)">
</div>
<cfabort>
</cfif>
<cfparam name="url.cftoken" default="">
<cfif len(url.cftoken)>
<div class="center"><button class="medium green"><i class="fa fa-check-square"></i> Update succeeded. Good work!</button></div>
</cfif>
<cfoutput>
<form method="post" name="ebwebworkForm" class="ebwebworkForm">
<ul>
<li>
<legend><h2>Registration Details</h2></legend>
</li>
<input type="hidden" name="RegisterID" value="#form.RegisterID#" /><!--- Embed RegisterID (PK) to assign a value to it --->
<li>
<label for="Title"><h3>Title (Ms., Mr., Dr. etc.):</h3></label>
<input type="text" name="Title" placeholder="Title" value="#Trim(Left(form.Title,255))#" maxlength="255" tabindex="1" size="70" autofocus="true" />
</li>
<li>
<label for="x_first_name"><h3>First Name:</h3></label>
<input type="text" name="x_first_name" placeholder="First Name" value="#Trim(Left(form.x_first_name,255))#" maxlength="255" tabindex="2" size="70" required="yes" />
<span class="form_hint">Enter First Name</span>
</li>
<li>
<div class="submitButton">
<button name="doSave" type="submit" class="green" tabindex="19">Save Record</button>
</div>
</li>
</ul>
</form>
</cfoutput>

Your INSERT SQL is invalid. The list of values starts with a comma, that means Title must not be preceded by a comma.
The reason you don't see an error message is that the queries are wrapped into a <cftry>/<cfcatch> block. Within the <cfcatch> there is a <cfset variables.error = cfcatch.message>, though the actual error message is stored in cfcatch.detail. So it is not output.

Related

ColdFusion checkbox processing

I have a question about processing data for lines where checkbox is checked.
When I hit "Submit", I need to end up with as many lines in a table as checked on the form.
Here is code that populates the form data. Checkbox''s value is unique.
<CFLOOP query = "ship_details">
<tr bgcolor="#IIf(CurrentRow Mod 2, DE('ffffff'), DE('f8f8f8'))#">
<TD class="TDC" align="right"><INPUT TYPE="CHECKBOX" name="MYCHECKBOX" value="#ship_details.cust_po_nbr#" ID="chkPo" checked></TD>
<TD class="TDC">#ship_details.cust_po_nbr#</TD>
<TD class="TDC">#ship_details.store_id#</TD>
<TD class="TDC">#ship_details.numb_of_cart#</TD>
<TD class="TDC">#ship_details.total_qty#</TD>
<TD class="TDC">#ship_details.weight#</TD>
<TD class="TDC">#ship_details.volume#</TD>
<cfif form.soldto EQ "AMAZON">
<TD class="TDC"><cfinput name="pallets" type="text" size="10"></TD>
</cfif>
</TR>
</CFLOOP>
When I hit "Submit", following query fails.
<cfquery name="abc" datasource="#REQUEST.T#">
insert into T
values (
#ship_details.cust_po_nbr#
,#pallets#
)
</cfquery>
It''s because values entered into fields coming over as list:
<cfloop list="#MYCHECKBOX#" index="i">
<cfoutput>#i# - #pallets#<br /></cfoutput>
</cfloop>
<cfabort>
I see this:
152N0000 - 1,2,5
152N5IKV - 1,2,5
6N8SCRIY - 1,2,5
A simple approach is appending or prepending an identifier or index to all of your input names. This way you can connect fields with each other in the controller.
Simplified example (ugly iteration)
<cfloop query="ship_details">
<input type="checkbox" name="MYCHECKBOX_#ship_details.currentRow#" value="#ship_details.cust_po_nbr#">
<input type="text" name="pallets_#ship_details.currentRow#">
</cfloop>
yields a form submit like
{
"MYCHECKBOX_1": "12345",
"MYCHECKBOX_3": "12347",
"pallets_1": "5",
"pallets_2": "",
"pallets_3": "7"
}
(row 1 and 3 have been checked - unchecked inputs are not part of a submit)
which you can connect doing
<cfset inputData = []>
<cfset MAX_ROWS = 99>
<cfloop from="1" to="#MAX_ROWS#" index="row">
<!--- has this row been checked? --->
<cfif not structKeyExists(FORM, "MYCHECKBOX_#row#")>
<cfcontinue>
</cfif>
<cfset inputData.add({
"cust_po_nbr": FORM["MYCHECKBOX_#row#"],
"pallets": FORM["pallets_#row#"]
})>
</cfloop>
<cfdump var="#inputData#">
and ending up with
[
{
"cust_po_nbr": "12345",
"pallets": "5"
},
{
"cust_po_nbr": "12347",
"pallets": "7"
}
]
Proper example
Since iterating over an artificial limit is pretty ugly, you can also just extract the checkboxes beforehand by matching against fieldnames
<cfset inputData = []>
<cfset checkedRows = reMatchNoCase("\bMYCHECKBOX_[0-9]+\b", FORM.FIELDNAMES)>
<cfloop array="#checkedRows#" index="cbKey">
<cfset row = listLast(cbKey, "_")>
<cfset inputData.add({
"cust_po_nbr": FORM[cbKey],
"pallets": FORM["pallets_#row#"]
})>
</cfloop>
<cfdump var="#inputData#">

coldfusion mobile app - connection to remote database server under cfclient tag

I am writing a CF mobile app and am using the cfclient tag. I am encountering issues with remote datasource connections and can’t get it resolved.
From cfclient, I am using “rooms” as my datasource string which is defined in the CF Administrator as a data source. It is connecting to a remote SQL Server. “Tblblogs” exists in the "rooms" database, but under cfclient I get an error that: > No such table exists
However, if I take same query [blgQ] that selects “tblblogs” outside cfclient, it works fine and without issue. I am not sure why it is not making right datasource connection under cfclient (as defined in the administrator) .
<!DOCTYPE html>
<html >
<body>
<h2>Add Expense</h2>
<form >
<table >
<tr>
<td>Date:</td> <td><input type="date" id="dateTxt"></td>
</tr>
<tr>
<td>Amount:</td> <td><input type="number" id="amtTxt"></td>
</tr>
<tr>
<td>Description</td>
<td><input type="text" id="descTxt"></td>
</tr>
<tr>
<td colspan="2">
<button type="button" id="addBtn">Add</button>
</td>
</tr>
</table>
</form>
<h2>Expenses:</h2>
<table id="expList">
<tr>
<th>Date</th>
<th>Amount</th>
<th>Description</th>
</tr>
</table>
</body>
</html>
<script >
document.getElementById("addBtn").onclick = function(){
addExpense();
}
</script>
<!--- cfclient code starts here --->
<cfclient>
<cfset document.getElementById("expList").innerHTML =''>
<!--- on client side you do not need to pre-configure datasource --->
<cfset dsn = "rooms">
<cftry>
<!--- create database if not already created --->
<cfquery datasource="rooms">
create table if not exists expenses (
id integer primary key,
expense_date integer,
amount real,
desc text
)
</cfquery>
<!--- Get expense records from the table --->
<cfquery datasource="rooms" name="expenses">
select * from expense order by expense_date desc
</cfquery>
<cfset alert(expenses.amount)>
<!--- Loop over expenses query object and display --->
<cfloop query="expenses">
<cfset var tmpDate = new Date(expense_date)>
<cfset addExpenseRow(expense_date,amount,desc)>
</cfloop>
<cfcatch type="any" name="e">
<cfset alert(e.message)>
</cfcatch>
</cftry>
<!--- Helper function to add epxpense row to HTML table --->
<cffunction name="addExpenseRow" >
<cfargument name="expense_date" >
<cfargument name="amt" >
<cfargument name="desc" >
<cfoutput >
<cfsavecontent variable="rowHtml" >
<tr>
<td>#dateFormat(expense_date,"mm/dd/yyyy")#</td>
<td>#amt#</td>
<td>#desc#</td>
</tr>
</cfsavecontent>
</cfoutput>
<cfset document.getElementById("expList").innerHTML += rowHtml>
</cffunction>
<!--- Called from JS script block in response to click event for addBtn --->
<cffunction name="addExpense" >
<cfset var tmpDate = new Date(document.getElementById("dateTxt").value)>
<cfset var amt = Number(document.getElementById("amtTxt").value)>
<cfset var desc = document.getElementById("descTxt").value>
<!--- TODO: Do data validation --->
<cftry>
<!--- Insert expense row into database table --->
<cfquery datasource="rooms" result="result">
insert into expense (expense_date,amount,desc) values(
<cfqueryparam cfsqltype="cf_sql_date" value="#tmpDate.getTime()#">,
<cfqueryparam cfsqltype="cf_sql_numeric" value="#amt#">,
<cfqueryparam cfsqltype="cf_sql_varchar" value="#desc#">
)
</cfquery>
<cfcatch type="any" name="e">
<cfset alert(e.message)>
</cfcatch>
</cftry>
<!--- add the new expense row to HTML table --->
<cfset addExpenseRow(tmpDate,amt,desc)>
</cffunction>
</cfclient>
<cfquery datasource="rooms" name="blgQ">
select * from tblblogs
</cfquery>
<cfdump var="#blgQ#"
> Blockquote
<cfquery> on <cfclient> is not really the same thing as the regular <cfclient>.
It is intended to do light weight interactions with Web SQL. Web SQL is not universally supported, and it is not likely to. <cfclient> will also suffer from all the issues that plagued <cfform>. Namely javascript will move forward, but the code generated by this tag may not.
See Client side CFML For Mobile Development.
I suspect you are trying to do something that might be more appropriate with AJAX or REST

Coldfusion finding date in an array

Need help finding a specific date in an array.
I have an Array Populated from a JSON file. Would like a form to enter in a date then return the data if it's in the Array.
This is what I've tried so far.
<!---Form and submit button to enter date--->
<p>
<cfform name="pickdate" id="pickdate" >
<cfinput required="yes" name="datepicker" type="datefield" id="datepicker" validate="USDATE">
<cfinput type="submit" name="insertpbnum" value="Enter" id="submit">
</cfform>
</p>
<br>
<br>
<!---Get lotto numbers from JSON file--->
<cfhttp url="https://data.ny.gov/api/views/d6yy-54nr/rows.json?accessType=DOWNLOAD" method="get" result="httpResp" timeout="120">
<cfhttpparam type="header" name="Content-Type" value="application/json" />
</cfhttp>
<cfset pbdata=deserializeJSON(httpResp.filecontent)>
<cfoutput>
<!---loop thru JSON file to grab lotto numbers and dates--->
<cfloop from="1" to="#arrayLen(pbdata.data)#" index="i">
<!---change xml date-time format to Coldfusion formate--->
#arrayFind(datetimeformat(Parsedatetime(pbdata.data[i][9]),"MM-DD-YYYY","datepicker"))#
<!---#i#: #Parsedatetime(pbdata.data[i][9])# : #pbdata.data[i][10]#---><br />
</cfloop>
</cfoutput>
I'm I going about this the correct way. Or is it better to put the array into a database?
Thanks
This is a different approach, but will hopefully accomplish what your trying to do. This solution throws the data into a query and then performs a query of query (QOQ) to check for the date.
<cfhttp url="https://data.ny.gov/api/views/d6yy-54nr/rows.json?accessType=DOWNLOAD" method="get" result="httpResp" timeout="120">
<cfhttpparam type="header" name="Content-Type" value="application/json" />
</cfhttp>
<cfset pbdata=deserializeJSON(httpResp.filecontent)>
<!--- Get list of column names --->
<cfset columnList = "" />
<cfloop from="1" to="11" index="i">
<cfset columnList = listAppend(columnList, replace(pbdata.meta.view.columns[i].name, " ", "", "All")) />
</cfloop>
<!--- Populate data into query --->
<cfset qryData = queryNew(columnList) />
<cfset dataRowCount = arrayLen(pbdata.data) />
<cfset queryAddRow(qryData, dataRowCount) />
<cfloop from="1" to="#dataRowCount#" index="i">
<cfloop from="1" to="#arrayLen(pbdata.data[i])#" index="j">
<cfif j EQ 11 AND pbdata.data[i][j] EQ "null">
<!--- default multiplier field to 0 if null --->
<cfset querySetCell(qryData, listGetAt(columnList, j), 0, i) />
<cfelse>
<cfset querySetCell(qryData, listGetAt(columnList, j), pbdata.data[i][j], i) />
</cfif>
</cfloop>
</cfloop>
<!--- Query the recordset --->
<cfquery name="rs" dbtype="query">
SELECT *
FROM qryData
WHERE DrawDate = '#dateFormat("5/26/2010", "YYYY-MM-DD")#T00:00:00'
</cfquery>
<cfdump var="#rs#" />

Coldfusion Arrays and Session shopping cart

I'm a noob with Coldfusion and I've been trying to figure out this simple issue for weeks now. I have a shopping cart i've created using coldfusion and dreamweaver. I'm trying to figure out what I've got wrong in my Application.CFC that's not deleting the session on browser close or reload.. Any guidence would be greatly appreciated. TIA
APPLICATION.CFC Code: Edited 4/19/2016 # 10:55pm
<cfcomponent>
<cfset this.name = "cart">
<cfset application.datasource.name = "mmd24_shoppingcart">
<cfset application.directory.root.path = "productlist.cfm" >
<cfset This.Sessionmanagement=True>
<cfset This.Sessiontimeout="#createtimespan(0,5,0,0)#">
<cfset This.applicationtimeout="#createtimespan(5,0,0,0)#">
<cfif isdefined("cookie.CFID") and isdefined("cookie.CFTOKEN")>
<cfset tempCFID = cookie.CFID >
<cfset tempCFTOKEN = cookie.cftoken >
<cfcookie name="CFID" value="#tempCFID#" >
<cfcookie name="CFTOKEN" value="#tempCFTOKEN#" >
</cfif>
</cfcomponent>
shoppingcart.cfm EDITED 4/19/2016 # 10:55pm CST
<link href="css/bootstrap.min.css" rel="stylesheet">
<html>
<html lang="en">
<meta name="viewport" content="width=device-width. initial-scale=1
charset=utf-8>
<cfparam name = "url.productid" default = "">
<cfparam name = "url.qty" default = "">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap
/3.3.6/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap
/3.3.6/css/bootstrap-theme.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3
/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6
/js/bootstrap.min.js"></script>
<style>
p.solid{border-style: solid;}
text.solid{border-style: solid;}
text.inset {border-style: inset;}
text.double {border-style: double;}
</style>
</head>
<body>
<br />
<center><h1><p> ShoppingCart</p></h1></center>
<cfquery name = "getlist" datasource="mmd24_shoppingcart">
SELECT *
FROM Products
Where Products.productID = <cfqueryparam
cfsqltype="cf_sql_integer" value="#url.productid#">
</cfquery>
<cflock scope="session" timeout="10">
<cfset addNew = true>
<cfif not isDefined("session.cart")>
<cfset session.cart = arrayNew(1)>
<cfelse>
<cfloop index="i" from="1" to="#arrayLen(session.cart)#">
<cfif URL.productid is session.cart[i].productId>
<cfset session.cart[i].productQty =
session.cart[i].productQty + 1>
<cfset addNew = false>
</cfif>
</cfloop>
</cfif>
<cfif addNew is true>
<cfset newItem=StructNew()>
<cfset newItem.productId = URL.productid>
<cfset newItem.productName = getlist.ProductName>
<cfset newItem.productPrice = getlist.ProductPrice>
<cfset newItem.productDescription =
getlist.ProductDescription>
<cfset newItem.productQty = URL.qty>
<cfset newItem.productPhoto = getlist.ProductPhoto>
<cfset ArrayAppend(session.cart, newItem)>
</cfif>
<cfset TotalOrderAmount = 0>
<cfset TotalItemAmount = 0>
<cfset TotalTax = 0>
<cfset counterhi = 0>
</cflock>
<cfoutput query ="getlist">
<cflock scope="session" type="readonly" timeout="10">
<cfloop index="i" from="1" to="#arrayLen(session.cart)#">
<table class = "table table-bordered">
<thead>
<tr>
<th>Product Photo</th>
<th>Product Name</th>
<th>Product Description</th>
<th>Quantity Ordered</th>
<th>Product Price</th>
</th>
</thead>
<tr>
<td><img src="#session.cart[i].ProductPhoto#"></td>
<td>#session.cart[i].ProductName#</td>
<td>#session.cart[i].ProductDescription#</td>
<td>#session.cart[i].ProductQty#</td>
<td>#DollarFormat(session.cart[i].ProductPrice)#</td>
<cfset Itemtotal = #getlist.productprice# *
#session.cart[i].ProductQty#>
<cfset OrderTotal = #Itemtotal#>
<cfset Tax = #OrderTotal# * "0.07">
<cfset TotalOrderAmount = #OrderTotal# + #Tax# + #TotalOrderAmount#>
<cfset TotalItemAmount = #Itemtotal# + #TotalItemAmount#>
<cfset TotalTax = #Tax# + #TotalTax#>
<tr>
<td> <b><text class=double>Item Total:</text></b><text
class=double>#DollarFormat(Itemtotal)# </text><br />
<b><text class=double>Sales Tax:</text></b><text
class=double>#DollarFormat(Tax)# </text><br />
</td>
</table>
</cfloop>
</cflock>
</cfoutput>
<cfoutput query ="getlist">
<br /> <br /> <br />
<b><text class=double>Total Item Amount:</text></b><text
class=double> #DollarFormat(TotalItemAmount)# </text><br/>
<b><text class=double>Total Tax Amount:</text></b><text
class=double> #DollarFormat(TotalTax)# </text><br/>
<b><text class=double>Total Order Amount:</text></b><text
class=double> #DollarFormat(TotalOrderAmount)# </text><br/>
<br /><br />
<form action="customerform.cfm" method="post">
<a input type="submit" name="submit" href="customerform.cfm"
class="btn btn-primary" role="button">Proceed to Checkout</a>
<br>
</br>
<a input type="submit" name="submit" href="productlist.cfm"
class="btn btn-primary" role="button">Continue Shopping</a>
<br />
</cfoutput>
</body>
</html>
FWIW, you should NEVER be referring to user input (the URL or FORM scope) for price and other information. You should take the ID of the product and look up the info from your database in order to store it in session. At best, the product ID and quantity are all you want to pull from user input, making sure that you have set a correctly typed cfparam for each.
Specifically to the error, that is probably coming from this line:
<cfset sItem.price = url.ProductPrice>
Since you do not set a default value for url.ProductPrice using a cfparam, if you don't pass ProductPrice in to via URL each time, then it won't find it. Perhaps you need to use a cfparam for each possible url var.

Incrementing values in form field names

I need to validate X number of fields. Each field is named "testFieldX", where X is any real number greater that 1.
So basically what I have in a form are fields with names:
testField1
testField2
testField3
etc.
I need to iterate over all of them and validate.
Let's assume I have 5 fields.
Then
<cfloop index="i" from="1" to="5">
<cfif form.testField & i EQ "">
Show error
</cfif>
</cfloop>
However it does not work. I get an error that the field name "testField" does not exists, which is true (only testField1+) exist. It seems like the things are not concatenating. Does it work only with strings?
How can I solve this problem?
The syntax you're after is:
<cfif form["testfield" & i] EQ "">
That will concatenate the strings as you're expecting.
<cfif structKeyExists(form,"test1")>
<cfloop from="1" to="3" index="i">
<cfif form["test" & i] eq ''>
Error : <cfoutput>#i#</cfoutput><br />
</cfif>
</cfloop>
</cfif>
<form name="sub" method="post">
Test1: <input type="text" name="test1" id="test1" /><br />
Test2: <input type="text" name="test2" id="test2" /><br />
Test3: <input type="text" name="test3" id="test3" /><br />
<input type="submit" value="Submit" />
</form>

Resources