Execute cfquery after button press or behind the scenes action page? - coldfusion

My page creates a few random variables to pick prizes and winners for a drawing, and I want to write the prize winners and their prizes to a table after the winner clicks a button to claim the prize.
The problem is I want them to stay on the page so that a prize can be picked again if it isn't claimed.
The best solution I can come up with is an action page that the cfinput button references, but I don't want the action page to open up, I just want the cfquery on that page to run behind the scenes.
Here's an example of my query:
<cfquery name="updateQuantity" datasource="christmas">
UPDATE PRIZES
SET QUANTITY = QUANTITY - 1
WHERE prize_ID = #prizeID#
</cfquery>
I tried making my button a "submit" button and using cfif isDefined("form.Submit") to run the cfquery on the same page, but the submit button refreshes the page (which I don't want) and writes the next picked winner instead of the prizeID of the current session:
<cfform>
<cfinput name="submit" type="submit" value="Claim Your Prize!" onClick="">
</cfform>
<cfif isDefined("form.Submit")>
<cfquery name="updateQuantity" datasource="christmas">
UPDATE PRIZES
SET QUANTITY = QUANTITY - 1
WHERE prize_ID = #prizeID# </cfquery>
</cfif>
prizeID is determined by the randomly selected prize.

Adam is correct.
While AJAX is what you're after, ColdFusion's AJAX related tags are not the way to go.
Take the time to learn JQuery and AJAX (it isn't too hard, and the CF community has some great examples and guides) and do it properly; with your example requirements, you should be up and running in no time.
That way you can properly manage any logging and error handling that you may need to as well. Good luck!

It sounds like ColdFusion.Ajax.submitForm would work for you.
In general, I think an AJAX request is what you are looking for.

Related

Coldfusion - How to prevent multiple clicks?

I have a button (anchor tag) that send a confirm message if you press it.
The problem is that for example if you press it 5 times very quickly it will send 5 confirm messages, if you press it 2 times it will send 2 messages.
This can occur when the user has low connection speed and while the page is refreshing he presses again the button.
How can I manage this situation? I though of disabling the button but for other reasons this is not possible.
<a class="msg" href="/manage/conversations.cfm?destination=#destination#">
#ucase(request.l('Send'))#
</a>
Thank you for your time
Ultimately, you need to have code on your server to prevent processing the link multiple times from the same user.
However, to solve the UI issue, have you link call a function instead of the cf file directly.
<a class="msg" href="javascript: processLink(#destination#);">
#ucase(request.l('Send'))#
</a>
<script>
runCount = 0;
function processLink(destination){
runCount++;
if (runCount == 1){
window.location.href = "/manage/conversations.cfm?destination=" + destination;
}
}
</script>
As mentioned in the previous answer it's nice to have some client side javascript to stop duplicate submissions from trigger happy users however you should also do this checking server side.
One approach would be to create a hidden formfield with a GUID that coldfusion generates when coldfusion renders your form.
So something like:
<cfset GUID = createUUID()>
<cfoutput>
<form id="frm" action="/target.cfm" method="post">
<input type="hidden" name="guid" value="#GUID#">
<!-- all your formfields go here -->
<input type="submit">
</form>
</cfoutput>
On the server side the target page then checks if it has already previously received the GUID. There are lots of ways to do, here are two of many ways.
a) Use Session Scope.
This is probably the quickest way if you are not running in a clustered environment and just need something quick for a tiny application.
<cfif isDefined("session.MYPAGE_GUID") AND session.MYPAGE_GUID EQ form.guid>
<cfoutput>Duplicate Form Submission</cfoutput>
<cfabort>
<cfelse>
<cfset session.MYPAGE_GUID = form.guid>
<!-- Do Business Logic Here -->
</cfif>
b) Use a Database Table.
Create a database table with a column called GUID. Make sure that GUID is the primary key or has a unique constraint.
Before you run your business logic insert the form.GUID into the database table. If you can do the insert process your business logic, if not the database query will throw an error that the record exists. You can then catch this error and take the appropriate action for a duplicate submission.
I prefer the database option as it works across clustered environments and database server are solid protecting against race conditions to ensure that a GUID is only set once.
Please be aware that this is just demonstrating the basic concepts and is not a drop in solution. There is a bit of more work to get these concepts into an e-commerce solution.
The best way is to disable the link once it's selected. If you don't want to do that, an alternative is to structure conversations.cfm like this.
<div id="pageContent">
small amount of text
</div>
<cfflush>
</body>
</html>
<cfsavecontent variable = "actualPageContent">
code
</cfsavecontent>
<cfoutput>
<script>
var #toScript(actualPageContent, "newPageContent")#;
document.getElementById("pageContent").innerHTML = "newPageContent";
</script>
</cfoutput>

How to add and save entry in dropdown listbox using coldfusion

Id like to make a drop down list box where in at the end of the list, an option "Enter New housing", that if selected there will be a message box then it will automatically saves on the database and refreshes the object.
Im a beginner and this is what ive started:
<cfquery name="housingsel" datasource=" " dbtype=" ">
select rtrim(housing_name) as housing, housingid as housingid from housing order by housing
</cfquery>
<!---<cfquery name="housingins" datasource=" " dbtype=" ">
insert into housing (housingid,housing_name) values (1,'Tierra Pura Housing')
</cfquery>--->
<body>
<div class="container">
<div class="content">
<h1>Housing</h1>
<table width="300" bgcolor="#FFFFFF" cellpadding="2" cellspacing="0" border="0">
<cfform action="de_housing.cfm" method="POST">
<tr><td height="20" class="lbl" align="right">Housing</td><td>
<select name="housingcat">
<CFOUTPUT QUERY="housingsel">
<OPTION VALUE="#housingid#">#housing#</OPTION>
</CFOUTPUT>
<option value="new">Enter New Housing</option>
</select>
</td></tr>
<tr><td height="20" class="lbl"></td><td align="left">
</td></tr>
</cfform>
</table>
Please help!
Thanks!
First off, avoid cfform at all costs. It will not help you. See https://github.com/cfjedimaster/ColdFusion-UI-the-Right-Way for reasons why and examples of how to do stuff the right way.
That being said, what you want to do isn't difficult. Let's break it down.
> "Id like to make a drop down list box where in at the end of the list, an option "Enter New housing", that if selected "
Using jQuery, you would add a change handler to your dropdown. In that change handler, you can get the selected index of the drop down. If that index is equal to the length of the options, then the user has picked the last one.
> "there will be a message box"
You have a few choices here. One simple, but not pretty way, is to use the built in confirm option. It has a simple modal box API that the user can type in. There are pretty options, like jQuery UI dialogs, but the confirm option is super simple. I'd recommend starting there.
> "automatically saves on the database"
So, you will know when a user enters a value into the confirm. Take that and use jQuery to do an XHR (Ajax) hit to your code. You will need to write CF code to respond to this request and insert it into the db. Not too difficult and it has been shown many places elsewhere. I'd also add logic to check for dupes.
> "refreshes the object"
When you do a XHR in jQuery, you know when the server is done doing crap, so in the response handler, you can add a new option to the drop down. This too has been done many times before, just Google for adding an option to a drop down. (You will probably end up back here.)

Getting dropdown value from template django

I am facing an issue working with django ( using shopcart ). I want to add a select options field to change dynamically an item suscription in the cart, but I am not getting the value selected from the template.
In my template where I display the cart I have :
<form action="" method="GET">{%csrf_token%}
<select name="suscr" title="suscr">
<option value="" selected>Suscribe</option>
<option value="1" name="suscr" >Weekly</option>
<option value="2" name="suscr">Monthly</option>
</select>
</form>
I want to select an option and then, if I press 'Checkout' to have the cart updated.
Appart from that, I believe its missing a method modifying the item in cart.py.
Any ideas would help.
Thanks
The above form is inside a loop
{% for item in cart %}
What i propose you to do is not python-oriented but all javascript for the most part as, from the description, we assume that what you are dealing with is going all at the client-side.
As you are dealing with a shopping cart, what i'd do is storing what the user is checking in a sessionStorage so that the information would persist while the user navigates through your website even with multiple tabs. As the user might just be "walking around" you shopping website, there's no need to push things to the database without even knowing if the user wants that. Just remove the form and keep with the select, then you get what the user selected appending an attribute to select: <select onchange=my_function(this.value)>...</select> and then, inside my_functionin a script change whatever you want to the page.
When the user enters the shopping cart page you show him what he selected so far getting the items from the sessionStorageand then, if he/she confirms that wants to buy, then submit a form to the server-side, update the database and proccess that as your workflow states.
tl;dr: store the options in sessionStorage, just post to the server at the end.
For help on the server-side update your question with more info about the cart.py

Field giving error after CF9 to CF10 Upgrade

We have a form which has some mandatory fields and 2 buttons(One is Submit, second is Search).
Search buttton code is like :
<input name="btnSearch" type="submit" id="Search" value="Search">
This code redirects to action form and then further to a new screen. Finally it reverts back to the main form and has code to restore the selected values.
One of the mandatory fields has the following code:
<td align="right">Class Id:<font color="red">*</font></td>
<td><cfselect name="YY_CLASS_ID" size="1" query="XX_Class_List"
value="XX_CLASS_ID" display="XX_DESCRIPTION"
required="yes"selected="#variables.XX_CLASS_ID#">
<cfif variables.XX_CLASS_ID eq "">
<option value="" selected></option>
</cfif>
</cfselect></td>
When user clicks on the search button and this Class ID dropdown is blank, they get an error that "Error in YY_CLASS_ID text".
yy_class_id field has required attribute as ‘yes’ and message attribute is not set. As per our understanding, this means error should always come if the user tries to navigate away from the screen without populating the CLASS ID.
However, as per our user ,they were not getting this error in CF9 and started coming after the CF10 upgrade. They are frequent users of the screen and could have not missed this in past if this was happening during CF9 days.
Can anyone please confirm if something has changed in CF10 which was not earlier in CF9 and causing this issue. Or we missing something here.
Let me know if any more information is needed.

sqllite read/write queue concern with django

I'm building a website where college students can order delivery food. One special attribute about our site is that customers have to choose a preset delivery time. For example we have a drop at 7pm, 10pm, and at midnight.
All the information about the food is static (ie price, description, name), except the quantity remaining for that specific drop time.
Obviously i didn't want to hardcode the HTML for all the food items on my menu page, so i wrote a forloop in the html template. So i need to store the quantity remaining for the specific time somewhere in my model. the only problem is that I'm scared that if i use the same variable to transport the quantity remaining number to my template, i'll give out wrong information if alot of people are accessing the menu page at the same time.
For example, lets say the 7pm drop has 10 burritos remaining. And the 10pm drop has 40 burritos. Is there a chance that if someone has faster internet than the other customer, the wrong quantity remaining will display?
how would you guys go around to solve this problem?
i basically need a way to tell my template the quantity remaining for that specific time. and using the solution i have now, doesn't make me feel at ease. Esp if many people are going to be accessing the site at the same time.
view.py
orders = OrderItem.objects.filter(date__range=[now - timedelta(hours=20), now]).filter(time=hour)
steak_and_egg = 0
queso = 0
for food in orders:
if food.product.name == "Steak and Egg Burrito":
steak_and_egg = steak_and_egg + food.quantity
elif food.product.name == "Queso Burrito":
queso = queso + food.quantity
#if burritos are sold out, then tell template not to display "buy" link
quantity_steak_and_egg = max_cotixan_steak_and_egg - steak_and_egg
quantity_queso = max_cotixan_queso - queso
#psuedocode
steakandegg.quantity_remaining = quantity_steak_and_egg
queso.quantity_remaining = quantity_queso
HTML:
{% for item in food %}
<div id="food_set">
<img src="{{item.photo_menu.url}}" alt="" id="thumbnail photo" />
<div style='overflow:hidden'>
<p id="food_name">{{item.name}}</p>
<p id="price">${{item.price}}</p>
</div>
<p id="food_restaurant">By {{item.restaurant}}</p>
<div id="food_footer">
<img src="{{MEDIA_URL}}/images/order_dots.png" alt="" id="order_dots" />
<a id ="order_button" href="{{item.slug}}"></a>
<p id="quantity_remaining">{{item.quantity_remaining}} left</p>
</div><!-- end food_footer-->
</div><!-- end food_set-->
I don't understand what "faster Internet" or "using the same variable" have to do with anything here (or, indeed, what it has to do with sqlite particularly).
This question is about a fundamental property of web apps: that they are request/response based. That is, the client makes a request, and the server replies with a response, which represents the status of the data at that time. There's simply no getting around that: you can make it more dynamic, by using Ajax to update the page after the initial load, which is what StackOverflow does to show update messages while you're on the page. But even then, there's still a delay.
(I should note that there are ways of doing real-time updates, but they're complicated, and almost certainly overkill for a college food-ordering website.)
Now the issue is, why does this matter? It shouldn't. The user sees a page saying there is 1 burrito left - perhaps with a red warning saying "order quickly! almost gone!" - and they press the order button. On submission of that order, your code presumably checks for the actual status at that time. And, guess what, in the meantime you've processed another order and the burrito has already gone. So what? You simply show a message to the user, "sorry, it's gone, try something else". Anyone with any experience ordering things on the web - say, concert tickets - will understand what's happened.