How to get checked value by cfloop in coldfusion - coldfusion-8

How can I get the checked values from some checkboxes using cfloop in coldfusion?
The checkboxes are created dynamically from a database query. ie:
<cfloop query="GetDataMaterial">
<input type="checkbox" name="MaterialID" value="#MaterialID#" />
</cfloop>

The form field will contain a comma-separated list of all values that are checked with the same form name.
For instance:
<input type="checkbox" name="MaterialID" value="1">
<input type="checkbox" name="MaterialID" value="2">
<input type="checkbox" name="MaterialID" value="4">
<input type="checkbox" name="MaterialID" value="8">
<input type="checkbox" name="MaterialID" value="16">
<input type="checkbox" name="MaterialID" value="32">
If the user Checks all of them, you'll get, assuming your form does a post:
form.MaterialID: "1,2,4,8,16,32"
If the user checks the first and last, you'll get
form.MaterialID: "1,32"
So, if you want to loop over them, you can
<cfloop list="#form.MaterialId#">
...
</cfloop>

Don't forget to have index="i" and use it to loop through the list of checkbox
<cfloop list="#form.MaterialId#" index="i">
<cfoutput>#i#</cfoutput>
</cfloop>

Related

Radio button not checked breaks page but works if checked

I have a simple form that I'm trying to pass data to which on the action page has an email that sends the data that I put into the form.
On my form page. I have a text field and two radio buttons.
My text field works if I don't put data into it. However, on my radio buttons the page works if I check it but doesnt work if I don't check it at all which results in my page breaking I'm not sure what I'm doing wrong? I want the page to process the default to "no" if I didn't check either radio buttons. Do I have to validate or something?
Here is my code.
<cfparam name="form.firstName" default="">
<cfparam name = "form.optradio1" default="no">
<form action="test.cfm" method="post">
<label for="firstName"></label>
<input type="text" name="firstName">
<input type="radio" name="optradio1" Value="Male" <cfif form.optradio1 eq "Yes">checked</cfif>>
</form>
That's how radio and checkbox inputs work in HTML. If they are not checked, they are not submitted on the form submit.
To determine if the radio input was checked, you can use
structKeyExists(form, <name of the input, as string>) as in
structKeyExists(form, "optradio1").
<cfparam name="form.firstName" default="">
<form action="test.cfm" method="post">
<label for="firstName"></label>
<input type="text" name="firstName">
<input type="radio" name="optradio1" Value="Male" <cfif structKeyExists(form, "optradio1")>checked</cfif>>
</form>
Assuming you have two radio inputs:
<cfparam name="form.firstName" default="">
<form action="test.cfm" method="post">
<label for="firstName"></label>
<input type="text" name="firstName">
<input type="radio" name="optradio1" Value="Male" <cfif structKeyExists(form, "optradio1") and form.optradio1 eq "Male">checked</cfif>>
<input type="radio" name="optradio1" Value="Female" <cfif structKeyExists(form, "optradio1") and form.optradio1 eq "Female">checked</cfif>>
</form>
Your initial code doesn't work because:
if checked, form.optradio1 was equal to Male
if not checked, form.optradio1 was defaulted to no because of
<cfparam name = "form.optradio1" default="no">

Form counting every record when clicking submit?

I have a form that im outputting results of comments, it can more than one.
I can aprrove these comments all at once, but what I'm trying to do is make it
with the option to submit 1 comment at a time or all comments at a time.
The form at first I wrote it to work on 'submit all', so now with adding a submit
per comment also, I get some errors.
I get because every time I submit a comment (1 comment) its still looking for all the other comments
which I did not submit.
What I think is doing since txtTotalRecords= Mush2.Recordcount, it trying to find the
other records which weren't submitted.
I just can't figure out how I can change this to make it work.
Doing a cfdump on the form i get, meaning there are 11 comments to submit.
How would I be able to change RecordCount to take in every record by itself?
<cfparam name="FormSubmit" type="string" default="FormNotSubmitted">
<cfif isDefined("form.submit")><cfset FormSubmit = "FormSubmitted"></cfif>
<cfif isDefined("form.submit1")><cfset FormSubmit = "FormSubmitted1"></cfif>
<!--- Begin Content ================================================== --->
<cfif FormSubmit eq "FormNotSubmitted" || FormSubmit eq "FormNotSubmitted1" >
<form method="post" action="cse_execoffice_pending.cfm" name="review_comments">
<cfoutput>
<input type="hidden" name="txtApprovedBy" value="#GetCurrentUser.emp_id#">
<!-- count the records that come in from the pending -->
</cfoutput>
<cfoutput query="Mush3">
<form method="post" action="cse_execoffice_pending.cfm" name="review_onecomment">
<input type="hidden" name="txtTotalRecords" value="#Mush2.Recordcount#">
<hr>
<div class="comments_approvaldecision">
<p>
<CFDUMP VAR=#response_id#>
<input type="hidden" name="txtResponseID#mush2.CurrentRow#" value="#response_id#">
<input type="radio" name="execoffice_status#mush2.CurrentRow#" id="approve#CurrentRow#" value="1" checked="checked"> <label for="approve#CurrentRow#">Approve</label><br>
<input type="radio" name="execoffice_status#mush2.CurrentRow#" id="deny#CurrentRow#" value="2"> <label for="deny#CurrentRow#">Deny</label>
</p>
<p> </p>
<p>
<input type="radio" name="star#mush2.CurrentRow#" id="givestar#mush2.CurrentRow#" value="0" checked="checked"> <label for="givestar#CurrentRow#"></i> Give Star!</label><br>
<input type="radio" name="star#mush2.CurrentRow#" id="denystar#mush2.CurrentRow#" value="1"> <label for="denystar#CurrentRow#"></i> No Star</label>
</p>
</div>
</div>
<input type="submit" name="Submit1" value="Submit">
</form>
</cfoutput>
<p><input type="submit" name="Submit" value="Submit"></p>
</form>
</cfif>
<cfdump var="#form#">
<cfif FormSubmit eq "FormSubmitted" || FormSubmit eq "FormSubmitted1">
<!--- Get Form Values --->
<cfloop from="1" to="#txtTotalRecords#" index="j">
<h2>test</h2>
<cfset response_id[j] = #Trim(form["txtResponseID" & j])#>
<cfset execoffice_status[j] = #Trim(form["execoffice_status" & j])#>
<cfset star[j] = #Trim(form["star" & j])#>
<cfset commentpositive[j] = #Trim(form["txtCommentPositive" & j])#>
<cfset commentnegative[j] = #Trim(form["txtCommentNegative" & j])#>
<cfset commentpositivereReplace[j] = reReplace(commentpositive[j], '\n', '<br>', 'ALL')>
<cfset commentnegativereReplace[j] = reReplace(commentnegative[j], '\n', '<br>', 'ALL')>
</cfloop>
......... more code...
I believe the code you are getting errors on is not in your sample code listed on this page.
I'm assuming you are doing a to/from loop based upon form.txtTotalRecords.
What you'll want to do is loop over your form items looking for a specific partial form name.
something like this:
<cfloop list="form.fieldnames" index="i">
<cfif left(i,13) IS "txtResponseID">
<cfset thisID = replaceNoCase(i,"txtResponseID","")>
<cfquery>
UPDATE myTable
SET approve = <cfqueryparam value="#form["execoffice_status" & thisID]#">
WHERE ID = <cfqueryparam value="#thisID">
</cfquery>
</cfif>
</cfloop>

How can I keep form values without using session?

I have one form page with pagination. I want to keep the form values as the user goes to the previous or next page, using pagination. I know that it can be done using the session scope. However, here I don't want to use session scope. Does anyone have any ideas on how to do this without using session? Please let me know.
Here is my form page:
<cfoutput>
<form action="#buildUrl(action='survey.save_surveyresults',querystring='surveyId=#rc.surveyid#')#" method="post">
<input type="hidden" name="id" value="0">
<input type="hidden" name="surveyid" value="#rc.surveyId#">
<div class="container-fluid">
<div class="row">
<div class="control-group">
<label class="label-control" for="name">Name</label>
<div class="controls">
<input type="text" name="name" id="name" required="true" placeholder="enter your name" value="#rc.name#">
</div>
</div>
<div class="control-group">
<label class="label-control" for="email">Email</label>
<div class="controls">
<input type="text" name="email" id="email" required="true" placeholder="enter your Email" value="#rc.email#">
</div>
</div>
<cfloop query="rc.questions" startrow="#startrow#" maxrows="#perpage#">
<!--- because we have all questions and answers in query we can use switch instead calling template or view
for each question, so its simplify directory structures, questions directory is not necessary now --->
<h3>#CurrentRow#<cfif rc.questions.isrequired><strong>*</strong></cfif>. #rc.questions.question#<h3>
<cfswitch expression="#rc.questions.template#">
<fieldset>
<cfcase value="textbox">
<input type="text" class="input-xlarge" name="#template#_#questionid#" id="question_#questionid#">
</cfcase>
<cfcase value="multiplechoice">
<cfloop list="#answer#" delimiters="," index="i">
<div class="controls">
<label>
<input type="radio" name="#template#_#questionid#" id="question_#questionid#" value="#answerID#" >
<span class="lbl">#i#</span>
</label>
</div>
</cfloop>
</cfcase>
<cfcase value="multiplechoiceother">
<cfloop list="#answer#" delimiters="," index="i">
<div class="controls">
<label>
<input type="radio" name="#template#_#questionid#" id="question_#questionid#" value="#answerID#" >
<span class="lbl">#i#</span>
</label>
</div>
</cfloop>
<div class="control-group">
<label class="label-control" for="other">Other</label>
<div class="controls">
<input type="text" class="input-xlarge" name="#template#_#questionid#" id="question_#questionid#">
</div>
</div>
</cfcase>
</fieldset>
</cfswitch>
</cfloop>
<p></p><br />
<cfif startrow GT 1>
Previous
</cfif>
<cfif (startrow + perpage - 1) lt rc.questions.recordcount>
Next
<cfelse>
<button type="submit" name="submit" class="btn btn-success">Finish</button>
</cfif>
</div>
</div>
</div>
</form>
</cfoutput>
You could break the form up into different sections and have it all in one page. You can hide/show parts of the form using JavaScript based on which 'page' of the form they are one.
This makes going forward or backward in the form a snap since it is not submitted until they are done with the whole form and the values they entered will still be there.. and is pretty easy to handle with jQuery or other JavaScript libraries.
As Dan said - save submitted values in hidden fields.
One issue I see with your HTML is that Previous/Next pages are just links - not submit buttons. So make sure that when clicking those links users are submitting the form - not just going to a different url.
Here's a simple snippet of code that will embed all your form variables into hidden fields. You would place this code inside the form handler on the page you are submitting to. Note Lucas' answer as well. Your form may not be submitting correctly for reasons of badly formed..er...form.
<Cfloop collection="#form#" item="fItem">
<cfoutput>
<input type="hidden" name="#fItem#" value="#form[fItem]#"/>
</cfoutput>
</cfloop>
Again .. this would go _inside" of the form on the subsequent page. This is fairly common in multipart forms (shopping carts with multiple steps, profile entries etc).
Bear in mind that with the approaches above, you need to re-validate your form values on the server side every time you submit them (or at the very least before your final processing).
What you make up for in server memory, you may lose in terms of traffic and load times, depending on scale so I would advise that you proceed with caution. Increasing production traffic unnecessarily can result in financial impacts, and often server memory can be cheaper than extended increased traffic outlay; it comes down to your requirements and scale at the end of the day.
Shipping form variables around also increases your attack surface for malicious injection of form data, so while you may be concerned with session variables being altered on you (curious to hear more on this), you are already opening yourself up by shipping this data around as plain text. Do not rely on client-side validation for this (or any) data.

Accessing variables of a dynamic form

I am creating a form with cfloop and need to access each variable individually when submitting the form. I need to use the selected entries of the form in a loop that will add my selections to a database.
This is my form:
<form method="post">
<input type="hidden" name="isPost" value="1">
...
<cfoutput>
<cfloop query="client_admin_surveys">
<input type="text" size="35" name="surveyID" id="surveyID" value="#id#">
<input type="text" size="35" name="surveyName" id="surveyName" value="#name#">
<input type="checkbox" name="amplify" id="amplify">
<input type="checkbox" name="enchance" id="enchance">
<input type="checkbox" name="pacify" id="pacify">
<input type="checkbox" name="pacifyUrgent" id="pacifyUrgent">
</cfloop>
</cfoutput>
...
<input type="submit" name="submit" value="Submit">
</form>
After posting the form, the results group all of my selections because I have the same "name" for my form elements. I tried adding an i count next to each name to make it different but then I got a bit confused about how to process the fields.
You started down the correct path when you added the counter - go back and add that, something like:
<input type="checkbox" name="amplify#client_admin_surveys.currentRow#" id="amplify">
Would work.
I also sometimes like to add a form field for the 'counter' on the processing page
<input type="hidden" name="counter" value="#client_admin_surveys.recordCount#" />
Then on the processing page, you can loop over the counter and access the form fields using bracket notation
<cfloop from="1" to="#form.counter#" indexd="i">
<cfset thisAmplify = form["amplify" & i] />
<cfset thisEnhance = form["enhance" & i] />
<!---- more logic here --->
</cfloop>

Coldfusion: how get value of the radio button to do the loop?

For example:
How many item you want to select? 1 2 3 4
If 3 is selected then
loop from 1 to 3
do something
end loop
I want everything process in the same page. Can someone let me know what I need to do? I tried cfselect and radio buttons but no luck. Thank you.
I think you're over thinking the problem. The form will return the value of the selected radio button.
HTML:
<form method="post" action="">
<p>HOW MANY YOU WANT?!? YOU CHOOSE NOW!</p>
<input type="radio" name="varname" value="1" onclick="this.form.submit();">1
<input type="radio" name="varname" value="2" onclick="this.form.submit();">2
<input type="radio" name="varname" value="3" onclick="this.form.submit();">3
<input type="submit">
</form>
ColdFusion:
<cfif isDefined("form.varname") AND form.varname GT 0>
<cfloop index="i" from="1" to="#form.varname#" step="1">
<!--- Do Stuff --->
</cfloop>
</cfif>