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>
Related
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#">
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.
I'm developing an application in Coldfusion and AngularJS. I'm use AngularJS 1 and CF11.
A user has to be logged into the application. The user id is saved in the CF session.
In myAngularJS service I implemented Factories like that:
app.factory('ContactService', function($http){
var factory={};
factory.getContact=function(id){
return $http.post('http://myapp/contacts.cfc?method=getContacts&subsString=' + id);
};
return factory;
})
Here my component contacts.cfc
<cfcomponent displayname="Contacts" hint="Webservice for contacts app">
<cffunction name="getContacts" access="remote" returnformat="JSON" output="no">
<cfargument name="subsString" required="no" type="String" />
<cfset ret = arrayNew(1) />
<cftry>
<cfinclude template="cfc/person/qry/qry_Search.cfm" />
<cfloop from="1" to="#qryFastSearch.recordcount#" index="i">
<cfset searchVO = structNew() />
<cfset searchVO['ID']= #qryFastSearch.ID[i]# />
<cfset searchVO['PERSON']= #qryFastSearch.personName[i]# />
<cfset searchVO['COMPANY']= #qryFastSearch.COMPANY[i]# />
<cfset ret[i] = searchVO />
</cfloop>
<cfcatch type="any">
<cfset returnVO = structNew() />
<cfset returnVO.ERROR = true />
<cfset returnVO.MESSAGE = cfcatch.Message />
<cfset ret[1] = returnVO />
</cfcatch>
</cftry>
<cfreturn SerializeJSON(ret)>
</cffunction>
</cfcomponent>
When the system execute the controller, the factory is executed and the results appear. We can see in the console of the browser the url executed.
For example: http://myapp/contacts.cfc?method=getContacts&subsString=test
I would like to avoid a person to execute a query (thanks to this kind of url) if she is not connected into the application.
Is it equally possible to hide the url in the browser ?
What is the best way in order to do that ?
Many thanks in advance for your help.
To add to Dan's comment:
Ensure the user is logged in.
Check the value of CGI.REQUEST_METHOD. If it's not POST, then reject the request.
If you have roles & privileges, verify the user should access that URL.
Validate search parameters as best you can.
Since you're using $http.post(), you shouldn't be passing the subString in the query string. It should be part of the posted data to avoid browser caching and entries in the server logs that possibly shouldn't be there.
You state, "The user id is saved in the CF session". Pass it as an argument to your function.
<cffunction name="getContacts" access="remote" returnformat="JSON" output="no">
<cfargument name="subsString" required="no" type="String" />
<cfargument name="userId" required="yes" type="String" />
Then check for it.
<cfif StructKeyExists(session, "userId")
and session.userId is arguments.userId>
rest of function
<cfelse>
whatever you want goes here.
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#" />
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.