当链接回页面时,重新显示数据库会导致输入
Reshowing database results in inputs when linked back to the page
我正在为我的项目使用 ColdFusion 16、HTML5、JavaScript 和 MSSQL。
我有一个表格,其中包含姓名、电子邮件、帐单和送货地址以及 Phone 号码,一旦提交表格,它就会将该信息插入数据库。在另一个页面上,我有一个 link 可以返回到同一页面,以防用户想要更改信息。
如何在这些字段中显示数据库中的内容?
另外,如何使页面看起来与离开时完全一样。
例如,选中带有箭头的方框,表示账单和运费是相同的。或者如果在提交页面时显示我的隐藏字段,则显示它们。
<div class="row">
<div class="col-lg-4">
<div class="form-group">
<label for="firstname">Name of owner:</label>
<cfoutput><input type="text" class="form-control input-sm" name="firstname" id="firstname" placeholder="First" maxlength="100" required="yes" value="" /></cfoutput>
</div>
</div>
<div class="col-lg-4">
<div class="form-group">
<label> </label>
<cfoutput><input type="text" class="form-control input-sm" name="middlename" id="middlename" placeholder="Middle" maxlength="100" value="" /></cfoutput>
</div>
</div>
<div class="col-lg-4">
<div class="form-group">
<label> </label>
<cfoutput><input type="text" class="form-control input-sm" name="lastname" id="lastname" placeholder="Last" maxlength="100" required="yes" value="" /></cfoutput>
</div>
</div>
</div>
当您在“地址”页面上时,可以使用查询来填充页面。
您需要某种 ID 来验证您要编辑的记录。我假设运输记录将根据某种会话标识符输入。
我的理论数据库设置:
账单地址
| ID | Address1 | etc... |
===============================
| 1 | 123 Sesame St | ...... |
送货地址
| ID | Address1 | etc... |
===============================
| 1 | 123 Sesame St | ...... |
在初始表单上,我们可以查询数据库,看看是否有用户的任何记录。
<cfquery name="getShippingAddress" datasource="myDSN">
SELECT TOP 1 ID, Address1, etc...
FROM ShippingAddress
WHERE ID = <cfqueryparam value="#session.ID#" cfsqltype="cf_sql_integer">
</cfquery>
<cfquery name="getBillingDetails" datasource="myDSN">
SELECT TOP 1 ID, Address1, etc...
FROM BillingAddress
WHERE ID = <cfqueryparam value="#session.ID#" cfsqltype="cf_sql_integer">
</cfquery>
注意:如果我们可以保证 ID
永远不会超过一行,那么我们可以跳过 TOP 1
.
当我们写出我们的表单时,我们可以将现有的值输出到表单中。
<cfoutput>
<input type="text" name="shippingAddress1"
value="#encodeForHTMLAttribute(getShippingAddress.Address1)#" />
</cfoutput>
在表单中,有一个复选框 (BillingShippingSame
) 用于确定账单地址是否与送货地址相同。
我们可以通过一些额外的检查来设置这个值。
<cfif BillingShippingSame = getShippingAddress.Address1 = getBillingAddress.Address1 AND .... >
这只是说,如果两个查询中的地址字段相同,则将 BillingShippingSame
设置为 true
,否则 false
。如果两个查询中的所有字段都相同,您还可以将两个查询转换为 JSON 并进行比较。 (serializeJSON(getShippingAddress) == serializeJSON(getBillinAddress)
)。如果您有多个需要检查的字段,这将节省一些输入,但如果两个查询中的字段相同,它们只会序列化相同的字段。然后只需在您的复选框输入中设置值。
<input type="text" name="BillingShippingSame" <cfif BillingShippingSame>checked="checked"</cfif> />
如果您愿意,您可以 javascript 页面,这样如果 BillingShippingSame
被选中,它要么禁用帐单表单字段,要么继续用返回的内容填充它们数据库。
回到我们的工作流程。由于 HTML 不会传递未选中的复选框,因此只需查看 form
范围以查看该框是否已选中。如果是,则将账单详细信息设置为送货详细信息。
Insert/Update 查询:
<cfset cleanShippingAddress1 = cleanString(form.ShippingAddress)>
<cfif structKeyExists(form,"BillingShippingSame")>
<cfset cleanBillingAddress1 = cleanString(form.ShippingAddress)>
<cfset cleanOtherBillingFields = .....>
<cfelse>
<cfset cleanBillingAddress1 = cleanString(form.BillingAddress)>
<cfset cleanOtherBillingFields = .....>
</cfif>
<cfset cleanOtherFields = cleanString(....)>
<cfquery name="UpsertShippingAddress" datasource="myDSN">
UPDATE ShippingAddress
SET ShippingAddress1 = <cfqueryparam value="#cleanShippingAddress1#" cfsqltype="cf_sql_varchar">
, OtherShippingFields =
<cfqueryparam value="#cleanOtherShippingFields#" cfsqltype="cf_sql_varchar">
, ...
WHERE ID = <cfqueryparam value="#session.ID#" cfsqltype="cf_sql_integer">
IF @@ROWCOUNT=0
INSERT INTO ShippingAddress ( ID, ShippingAddress1, OtherShippingFields, ....)
VALUES (
<cfqueryparam value="#session.ID#" cfsqltype="cf_sql_integer">
, <cfqueryparam value="#cleanShippingAddress1#" cfsqltype="cf_sql_varchar">
, <cfqueryparam value="#cleanOtherShippingFields#" cfsqltype="cf_sql_varchar">
, ...
) ;
</cfquery>
<cfquery name="UpsertBillingAddress" datasource="myDSN">
UPDATE BillingAddress
SET BillingAddress1 = <cfqueryparam value="#cleanBillingAddress1#" cfsqltype="cf_sql_varchar">
, OtherShippingFields =
<cfqueryparam value="#cleanOtherBillingFields#" cfsqltype="cf_sql_varchar">
, ...
WHERE ID = <cfqueryparam value="#session.ID#" cfsqltype="cf_sql_integer">
IF @@ROWCOUNT=0
INSERT INTO BillingAddress ( ID, BillingAddress1, OtherBillingFields, ....)
VALUES (
<cfqueryparam value="#session.ID#" cfsqltype="cf_sql_integer">
, <cfqueryparam value="#cleanBillingAddress1#" cfsqltype="cf_sql_varchar">
, cfqueryparam value="#cleanOtherBillingFields#" cfsqltype="cf_sql_varchar">
, ...
) ;
</cfquery>
当涉及到 form
或 url
或其他不可信的输入时,我倾向于偏执狂。我的 cleanString
函数会在字符串进入数据库之前对其进行各种清理。
我还使用了 UPDATE
数据库的 SQL 模式,如果没有插入任何行(@@ROWCOUNT=0
>> 未找到 ID),那么它将 INSERT
代替。
我正在为我的项目使用 ColdFusion 16、HTML5、JavaScript 和 MSSQL。
我有一个表格,其中包含姓名、电子邮件、帐单和送货地址以及 Phone 号码,一旦提交表格,它就会将该信息插入数据库。在另一个页面上,我有一个 link 可以返回到同一页面,以防用户想要更改信息。
如何在这些字段中显示数据库中的内容?
另外,如何使页面看起来与离开时完全一样。
例如,选中带有箭头的方框,表示账单和运费是相同的。或者如果在提交页面时显示我的隐藏字段,则显示它们。
<div class="row">
<div class="col-lg-4">
<div class="form-group">
<label for="firstname">Name of owner:</label>
<cfoutput><input type="text" class="form-control input-sm" name="firstname" id="firstname" placeholder="First" maxlength="100" required="yes" value="" /></cfoutput>
</div>
</div>
<div class="col-lg-4">
<div class="form-group">
<label> </label>
<cfoutput><input type="text" class="form-control input-sm" name="middlename" id="middlename" placeholder="Middle" maxlength="100" value="" /></cfoutput>
</div>
</div>
<div class="col-lg-4">
<div class="form-group">
<label> </label>
<cfoutput><input type="text" class="form-control input-sm" name="lastname" id="lastname" placeholder="Last" maxlength="100" required="yes" value="" /></cfoutput>
</div>
</div>
</div>
当您在“地址”页面上时,可以使用查询来填充页面。
您需要某种 ID 来验证您要编辑的记录。我假设运输记录将根据某种会话标识符输入。
我的理论数据库设置:
账单地址
| ID | Address1 | etc... |
===============================
| 1 | 123 Sesame St | ...... |
送货地址
| ID | Address1 | etc... |
===============================
| 1 | 123 Sesame St | ...... |
在初始表单上,我们可以查询数据库,看看是否有用户的任何记录。
<cfquery name="getShippingAddress" datasource="myDSN">
SELECT TOP 1 ID, Address1, etc...
FROM ShippingAddress
WHERE ID = <cfqueryparam value="#session.ID#" cfsqltype="cf_sql_integer">
</cfquery>
<cfquery name="getBillingDetails" datasource="myDSN">
SELECT TOP 1 ID, Address1, etc...
FROM BillingAddress
WHERE ID = <cfqueryparam value="#session.ID#" cfsqltype="cf_sql_integer">
</cfquery>
注意:如果我们可以保证 ID
永远不会超过一行,那么我们可以跳过 TOP 1
.
当我们写出我们的表单时,我们可以将现有的值输出到表单中。
<cfoutput>
<input type="text" name="shippingAddress1"
value="#encodeForHTMLAttribute(getShippingAddress.Address1)#" />
</cfoutput>
在表单中,有一个复选框 (BillingShippingSame
) 用于确定账单地址是否与送货地址相同。
我们可以通过一些额外的检查来设置这个值。
<cfif BillingShippingSame = getShippingAddress.Address1 = getBillingAddress.Address1 AND .... >
这只是说,如果两个查询中的地址字段相同,则将 BillingShippingSame
设置为 true
,否则 false
。如果两个查询中的所有字段都相同,您还可以将两个查询转换为 JSON 并进行比较。 (serializeJSON(getShippingAddress) == serializeJSON(getBillinAddress)
)。如果您有多个需要检查的字段,这将节省一些输入,但如果两个查询中的字段相同,它们只会序列化相同的字段。然后只需在您的复选框输入中设置值。
<input type="text" name="BillingShippingSame" <cfif BillingShippingSame>checked="checked"</cfif> />
如果您愿意,您可以 javascript 页面,这样如果 BillingShippingSame
被选中,它要么禁用帐单表单字段,要么继续用返回的内容填充它们数据库。
回到我们的工作流程。由于 HTML 不会传递未选中的复选框,因此只需查看 form
范围以查看该框是否已选中。如果是,则将账单详细信息设置为送货详细信息。
Insert/Update 查询:
<cfset cleanShippingAddress1 = cleanString(form.ShippingAddress)>
<cfif structKeyExists(form,"BillingShippingSame")>
<cfset cleanBillingAddress1 = cleanString(form.ShippingAddress)>
<cfset cleanOtherBillingFields = .....>
<cfelse>
<cfset cleanBillingAddress1 = cleanString(form.BillingAddress)>
<cfset cleanOtherBillingFields = .....>
</cfif>
<cfset cleanOtherFields = cleanString(....)>
<cfquery name="UpsertShippingAddress" datasource="myDSN">
UPDATE ShippingAddress
SET ShippingAddress1 = <cfqueryparam value="#cleanShippingAddress1#" cfsqltype="cf_sql_varchar">
, OtherShippingFields =
<cfqueryparam value="#cleanOtherShippingFields#" cfsqltype="cf_sql_varchar">
, ...
WHERE ID = <cfqueryparam value="#session.ID#" cfsqltype="cf_sql_integer">
IF @@ROWCOUNT=0
INSERT INTO ShippingAddress ( ID, ShippingAddress1, OtherShippingFields, ....)
VALUES (
<cfqueryparam value="#session.ID#" cfsqltype="cf_sql_integer">
, <cfqueryparam value="#cleanShippingAddress1#" cfsqltype="cf_sql_varchar">
, <cfqueryparam value="#cleanOtherShippingFields#" cfsqltype="cf_sql_varchar">
, ...
) ;
</cfquery>
<cfquery name="UpsertBillingAddress" datasource="myDSN">
UPDATE BillingAddress
SET BillingAddress1 = <cfqueryparam value="#cleanBillingAddress1#" cfsqltype="cf_sql_varchar">
, OtherShippingFields =
<cfqueryparam value="#cleanOtherBillingFields#" cfsqltype="cf_sql_varchar">
, ...
WHERE ID = <cfqueryparam value="#session.ID#" cfsqltype="cf_sql_integer">
IF @@ROWCOUNT=0
INSERT INTO BillingAddress ( ID, BillingAddress1, OtherBillingFields, ....)
VALUES (
<cfqueryparam value="#session.ID#" cfsqltype="cf_sql_integer">
, <cfqueryparam value="#cleanBillingAddress1#" cfsqltype="cf_sql_varchar">
, cfqueryparam value="#cleanOtherBillingFields#" cfsqltype="cf_sql_varchar">
, ...
) ;
</cfquery>
当涉及到 form
或 url
或其他不可信的输入时,我倾向于偏执狂。我的 cleanString
函数会在字符串进入数据库之前对其进行各种清理。
我还使用了 UPDATE
数据库的 SQL 模式,如果没有插入任何行(@@ROWCOUNT=0
>> 未找到 ID),那么它将 INSERT
代替。