The selected text is not staying selected in a drop down menu on my order page.
I've added a drop down menu to our order page to select the words "UPS Account Number, or "FedEx Account Number". Then an input box gets displayed for the user to type in their account number. I am using the onChange event with this drop down menu. This works fine on a page by itself, but when I try to use it on our order page, the selected text in the drop down menu does not stay selected. If I change the cfset to page.ShipAcctMethod, it errors out.
<cfif isDefined('form.ShipAcctMethod')
AND form.ShipAcctMethod NEQ "">
<cfset form.ShipAcctMethod = form.ShipAcctMethod>
</cfif>
<select name="ShipAcctMethod" required="yes" onChange="this.form.submit()">
<option value="" selected>Shipping Account</option>
<option value="UPSNumber" <cfif isDefined('page.ShipAcctMethod')
and form.ShipAcctMethod eq 'UPSNumber'>selected</cfif>>
UPS Account Number
</option>
<option value="FedExNumber" <cfif isDefined('page.ShipAcctMethod')
and form.ShipAcctMethod eq 'FedExNumber'>selected</cfif>>
FedEx Account Number
</option>
</select>
<br><br>
<!--- Choose a selection --->
<cfif isDefined('form.ShipAcctMethod') and
form.ShipAcctMethod eq 'UPSNumber'>
<input type="text" maxlength="100"
size="30"name="UPSNumber"
placeholder="UPS Account Number" required>
</td>
</tr>
<cfelseif isDefined('form.ShipAcctMethod')
and form.ShipAcctMethod eq 'FedExNumber'>
<input type="text" maxlength="100"
size="30"name="FedExNumber"
placeholder="FedEx Account Number" required>
</td>
</tr>
I need the selected text to stay selected because this is a requirement the user has to choose. How do I get the selected text to stay selected?
Sorry, I don't have the ability to comment since I don't have a 50 reputation, so I'm providing this as an answer. As Ageax said, the problem is because isDefined('page.ShipAcctMethod') should be isDefined('form.ShipAcctMethod'). Because of this, the condition will always evaluate to false and the "selected" attribute never gets set for those options.
Related
I have a form that has 3 rows. A checkbox and two input field per row.
The field names are paid, amount and tranid.
If I tick the checkbox on the second row, and enter data into the other two fields and click submit I have the following;
Listlen is 1.
listgetat(form.paid,1) contains the value assigned to the check box.
the list for amount are 0.00,16.00,0.00
The list for tranid id are "",Test123,"" (nul, value, nul)
Therein is my problem. I can't loop through the list because listlen = 1 and listgetat(form.amount,1) returns 0.00 because the data is in the second list item.
I can't get the value from listgetat(form.paid,2) because I only selected one checkbox, so listgetat(form.paid,1) contains that value.
Clearly my understanding of working with lists is lacking.
This is a payment processing page, where the user selects which outstanding payments have been paid. They enter a bank transaction ID and how much was paid. The number of rows depends on how many payments are outstanding, in this test case there are three.
Can someone please explain how to process the list.
thank you.
The input page; Select only unpaid transactions:
<cfquery name="unpaid" datasource="#Application.datasource#">
select * from payments where pflag=0
</cfquery>
The input page; The three relevant fields;
<cfif #unpaid.recordcount# gt 0>
<cfoutput query="unpaid">
<tr>
<td><span class="pagetext">
<input type="checkbox" name="paid" id="paid" value="#idpayments#" />
</span></td>
<td class="pagetext">#idpayments#</td>
<input name="tranid" type="text" id="tranid" size="15" maxlength="40" /></td>
<td align="right">
<span class="pagetext">$<input name="amount" type="text" id="amount" size="7" maxlength="7" value="#ap#" />
</span></td>
</tr>
<cfset total=#total#+#ep#>
</cfoutput>
</cfif>
The processing code..
<cfloop from="1" to="#Listlen(FORM.amount)#" index="i">
<cfif #ListGetAt(FORM.amount,i)# gt 0>
<!--- update the payment --->
<cfquery name="updtrec" datasource="#Application.datasource#">
update payments set pflag=1,
ap=#ListGetAt(FORM.amount,i)#,
datepaid='#newdate#',
<cfif #len(ListGetAt(FORM.tranid,i))# gt 0>, ptranid=#ListGetAt(FORM.tranid,i)#</cfif>
where idpayments=#ListGetAt(FORM.paid,i)#
</cfquery>
</cfif>
</cfloop>
A description of the issue is helpful, but you should also include some code along with it. The absolute smallest amount of code needed to illustrate the issue, omitting any irrelevant stuff like css. Here's a good example for this question:
<form ...>
Row #1
<input type="checkbox" name="paid" value="111">
Amount <input type="text" name="amount">
TransId <input type="text" name="transid">
<br>
Row #2
<input type="checkbox" name="paid" value="222">
Amount <input type="text" name="amount">
TransId <input type="text" name="transid">
<br>
Row #3
<input type="checkbox" name="paid" value="333">
Amount <input type="text" name="amount">
TransId <input type="text" name="transid">
</form>
Clearly my understanding of working with lists is lacking.
The problem isn't your understanding of lists, but of how form fields are handled. The code mistakenly assumes all three form variables will always contain a list of three values. They won't. While same name'd fields get converted into a comma separated list when submitted, not all form fields submit a value and some values are effectively discarded:
A checkbox only submits a value IF it's checked
An enabled text field always submits a value, but that value may be an empty string. Historically, most list functionality in CF ignores empty strings
So the form variables aren't guaranteed to always contain a list of three values. It may be less if some of the text fields are empty or boxes aren't checked (form.paid won't even exist at all if none of the boxes are checked). That's why the list functions aren't working as you expected.
Assuming you have a unique numeric value like an "id" for each row, give all checkboxes the same name and use the numeric id as the checkbox value. Then use the numeric "id" as part of the associated text field names, in order to group each row of fields together
<input type="checkbox" name="paid" value="111">
<input type="text" name="amount_111">
<input type="text" name="transid_111">
...
<input type="checkbox" name="paid" value="222">
<input type="text" name="amount_222">
<input type="text" name="transid_222">
...
When submitted, form.paid will contain a list of the selected id's. Loop through the list of id's and use the current "id" to extract the amount and transid values:
for (....) {
amount = form["amount_"& currentId];
transid = form["transid_"& currentId];
}
For the life of me I can't get CFIF to give me a true result when using the EQ operator with 2 equal fields . Below is the CF code:
<select class="form-control" name="sales_contact_id">
<cfoutput query="rc.getPartnerContacts">
<cfif rc.getPartnerContacts.id EQ rc.getPartner.sales_contact_id>
<cfoutput><option value="#rc.getPartnerContacts.id#" selected="selected">#fname# #lname#</option>
</cfoutput>
<cfelse>
<cfoutput><option value="#rc.getPartnerContacts.id#">#fname# #lname# #rc.getPartner.sales_contact_id#</option>
</cfoutput>
</cfif>
</cfoutput>
</select>
I put the #rc.getPartner.sales_contact_id# into the option text to show the value of the variable.
And this is the HTML output:
<select name="sales_contact_id" class="form-control">
<option value="1">David Elliott 2</option>
<option value="2">James Knight 2</option>
<option value="3">Fred Bloggs 2</option>
<option value="4">John Doe 2</option>
<option value="5">Jane Smith 2</option>
</select>
The value of the rc.getPartner.sales_contact_id field is 2 which the same as the id field for the 'James Knight' record in the rc.getPartnerContacts recordset. The CFIF statement should be true for the James Knight record so that this option is the default within the drop down list. I've tried using val(), I've tried subtracting one from the other and then using a CFIF EQ 0 and still won't work!
I'm sure that this is a really simple mistake but I can't see it!!!
This is a formatted comment. When in doubt, look at your data.
<cfdump var="#rc.getPartnerContacts#">
<cfoutput query="rc.getPartnerContacts">
<cfif rc.getPartnerContacts.id EQ rc.getPartner.sales_contact_id>
yes
<cfelse>
no ID is #id# and sales contact id is #rc.getPartner.sales_contact_id#
</cfif>
<br>
A facepalm moment - The <cfoutput> within a <cfoutput> caused the problem.
I am trying to get a better understanding of server side validation. I have been writing a lot of client side validation using JavaScript but did not realize if the user just turns JavaScript off the whole app does not validate any field. This is what I am looking into doing for ColdFusion Server side validation.
What I am wondering is how would you toggle on and off making a field required or not based on lets say a radio buttons yes or no. Say you have a radio button the if yes is chosen it makes another input required but if no is chosen it makes another field required. I was just wondering how you would do something like that with the _cf format of toggling on and off. Would you just create if statements on hidden fields to do so or something?
I have been researching it a lot and just was looking for some input on how people are achieving things like this because it just seems like you can do so much through client side but then its all pointless because they can just turn it off.
<table>
<tr>
<td>Date:</td>
<td><input type="text" name="date" size="20"></td>
<strong class="delete me and add my line number to the highlight in my pre tag">
<input type="hidden" name="date_cfformrequired" value="You must enter a date.">
<input type="hidden" name="date_cfformdate" value="The date you entered is not a valid date."></strong>
</tr>
<tr>
<td>Distance:</td>
<td><input type="text" name="distance" size="20"></td>
<strong class="delete me and add my line number to the highlight in my pre tag">
<input type="hidden" name="distance_cfformrequired" value="You must enter a distance.">
<input type="hidden" name="distance_cfformfloat" value="The distance you entered is not a valid number."></strong>
</tr>
<tr>
<td>Time:</td>
<td><input type="text" name="time" size="20"></td>
<strong class="delete me and add my line number to the highlight in my pre tag">
<input type="hidden" name="time_cfformrequired" value="You must enter a time.">
<input type="hidden" name="time_cfformregex" value="^\d{1,3}:\d{0,2}$"></strong>
</tr>
<tr>
<td>Comments:</td>
<td><input type="text" name="comments" size="50"></td>
<strong class="delete me and add my line number to the highlight in my pre tag">
<input type="hidden" name="comments_cfformrequired" value="You must enter a comment.">
<input type="hidden" name="comments_cfformmaxlength" value="50"></strong>
</tr>
<tr>
<td colspan="2" align="right">
<input type="submit" name="Add Entry">
</td>
</tr>
</table>
Your understanding of the difference between client and server side validation is correct. Consider that client side validation can be chalked up to a feature. Rather than the user entering information, submitting the form, and then being told something was incorrect, Javascript validation can guide them, but because it can be disabled, it's not good to rely on.
Server side validation always happens as dictated.
The code is pretty easy
As an example - HTML
Name:
<input type="text" name="myname">
Were you referred by a current user?
<input type="radio" name="Referred" value="0" checked> No
<input type="radio" name="Referred" value="1"> Yes
Who referred you?
<input type="text" name="ref_user">
Form processing
<cfset Err = {Messages = []}> // creates a struct named Err with an array names Messages.
<cfif len(trim(form.myname)) eq 0>
<cfset ArrayAppend(Err.Messages,"Please enter your name!">
</cfif>
<cfif form.Referred eq 1 and len(trim(form.ref_user)) eq 0>
<cfset ArrayAppend(Err.Messages,"You said someone referred you, who was it?">
</cfif>
<cfif ArrayLen(err.messages) eq 0>
...no errors, we can do form processing...
</cfif>
And then, when outputting your errors, if they exist
<cfif ArrayLen(err.messages) gt 0>
Sorry, an error occurred.<br>
<cfoutput>
<cfloop array="#err.messages#" index="cError">
- #cError#.<br>
</cfloop>
</cfoutput>
</cfif>
On the first line of the last code snippet, you'll see gt 0 at the end of the line. This is not necessary and most people will leave it off. You seem familiar with javascript, cf works the same way in that in that you might say
if (Err.Messages.length) {
... show
}
In cf, you can do similar, <cfif ArrayLen(Err.Messages)>.
Remember to either cfparam your variables or check for their existence in your form processing, like this..
<cfif not StructKeyExists(form, "Referred") or (form.Referred eq 1 and len(trim(form.ref_user)) eq 0)>
<cfset ArrayAppend(Err.Messages,"You said someone referred you, who was it?">
</cfif>
Is it possible to populate a dropdown list with query results? For example with this output: Peps Company - AL ie (Company and State) separated with a hyphen.
Edit: Sorry for leaving out code. There is only one datasource.
<cfquery name="CompanyInfo" datasource=>
SELECT company, state
FROM clients
WHERE serv_billing = 1
AND status = 'Active'
ORDER BY Company
</cfquery>
<FORM METHOD="POST" ACTION="nextpage.cfm">
<SELECT name="company">
<CFOUTPUT QUERY="CompanyInfo">
<OPTION value="#CompanyInfo.company#">#CompanyInfo.company# - #CompanyInfo.state#</OPTION>
</CFOUTPUT>
</SELECT>
<INPUT TYPE="submit" VALUE="Submit Company">
</FORM>
Would this code give me the desired format for the dropdown list items ie Peps - AL?
?
The answer is yes. This code will do precisely that.
Does it not work? Do you have a problem with it, or..? I find it strange that you didn't simply try it out because you already seem to have the code to do what you want to do.
Seybsen's answer is technically correct, however, I would compel you to follow best practices and perform a single loop, rather than iterative returns to the database on each row result of the main query:
<CFQUERY name="qCompanies" datasource="yourdsn">
SELECT companies.id, companies.company, states.state_code
FROM companies
INNER JOIN states ON (companies.state_id = states.state_id)
</CFQUERY>
<SELECT name="company">
<CFOUTPUT QUERY="qCompanies">
<OPTION value="#qCompanies.id#">#qCompanies.company# - #qCompanies.state_code#</OPTION>
</CFOUTPUT>
</SELECT>
You can do it with cfloop like this:
<cfquery name="CompanyInfo" datasource="yourdsn">
SELECT company, state
FROM clients
WHERE serv_billing = 1 AND status = 'Active'
Order by Company
</cfquery>
<FORM METHOD="POST" ACTION="nextpage.cfm">
<SELECT name="company">
<CFLOOP QUERY="CompanyInfo">
<OPTION value="#CompanyInfo.company#">#CompanyInfo.company# - #CompanyInfo.state#</OPTION>
</CFLOOP>
</SELECT>
<INPUT TYPE="submit" VALUE="Submit Company">
</FORM>
I have a form where a user rates a poem from 1 to 3. My code is as follows:
<select name="rating">
<cfif len(duplicateCheck.score)><option value="#duplicateCheck.score#">You scored: #duplicateCheck.score#</option>
<cfelse><option value="">– Rate This Poem –</option>
</cfif>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
If the user has already rated the poem, I am trying to make their previous score be selected. If not, the user can select 1-3. How should I do this?
Depends on how you're storing the fact that the user has already rated the poem. But from a high level:
<option value="1"<cfif userHasSelected eq 1> selected="selected"</cfif>>1</option>
<option value="2"<cfif userHasSelected eq 2> selected="selected"</cfif>>2</option>
<option value="3"<cfif userHasSelected eq 3> selected="selected"</cfif>>3</option>
So, do you already have a handle on whether or not the user has rated the poem? Or is that the actual question?
If you loop through your list of options you could do this dynamically.
<cfloop from="1" to="3" index="thisOption">
<option value="#thisOption#" <cfif userHasSelected eq thisOption> selected="selected"
</cfif>>#thisOption#</option>
</cfloop>
Or you can move the code to select the drop down out of the option html, which i prefer.
<cfloop from="1" to="3" index="thisOption">
<cfset variables.selected = userHasSelected eq thisOption? 'selected' : '' />
<option value="#thisOption#" #selected#>#thisOption#</option>
</cfloop>