I am wondering how one would setup a multi-step form in CFWheels.
Clearly I would need to store form data in the session etc as I go, but I would like to know the best approach from a wheels perspective to do this the 'wheels way'.
Do I have just one action in my controller that handles this? Or would it be best to seperate each part of the form out into separate actions?
Advise on this and possible code examples would be much appreciated.
Thanks,
Michael
The way I've done it in past is use Ajax calls and a jquery modal.
though the jquery modal is not important, I just like the aesthetic. a simple div replacement will also work.
If you cannot be sure that the users can use AJAX then it won't work for you, but you might be able to use a popup window.
The advantage of using Ajax calls for multi-step forms is that you can adjust the form content from one step to another. Another advantage is that you don't have to store user data in the cache or session. Because each time you send a form, you can use the POST or GET.
For this to work, the quickest way of setting this up is to use the plugin called RemoteFormHelpers. Then each step of the form would be a different controller (or the same one with a switch statement based on the data passed)
I think this is a pretty versatile way of doing this, but you cannot do a form that uses file-uploads, well not easily as ajax won't let you do it without some serious pain.
Related
I'm working on a ruby on rails project, and I have a really simple doubt, in a view I have something like this Food.all, should I perform this query inside the controller and assign it to a instance variables or it is OK if I put this line inside the view.
What are the pros and cons?
I have to say I'm not doing anything else with that info.
The Food.all its actually a select in the view.
Thanks.
The default way is to define a variable in the controller:
#foods = Food.all
Though performing queries in views is sometimes acceptable (in my opinion). It has some benefits: caching would be easier and you write less code, especially if you have a partial with this code in many places in your project. But this code is less flexible, if you need something more complex you will need to move this query.
So think and choose wisely :)
View should only present data. Definitely better is to assign it to variable in controller and use from there.
See: How MVC works. In general view should communicate with controller, and controller with model.
I've a website implemented using emberJS, It has a "contact us" page, now when someone fills up the form & submit the data I need to do implement a POST request. Do I need to create a model for this ? right now I just did $.post(...).
I just wanted to know is there any much cleaner(or may I say emberish way) to implement this ?
IMHO, a ContactRequest model seems like the most idiomatic way to go about this. That way you can use the regular Ember facilities and later add features like a backend that shows pending contact requests and - depending on your use case - does things like sorting them by subject area etc.
Should I be writing application logic in my view code? For example, on submission of a form element, I need to create a user and send him an activation email. Is this something to do from a view function, or should I create a separate function to make it easier to test down the road? What does Django recommend here?
I found it very hard to figure out where everything goes when I started using django. It really depends on the type of logic you are writing.
First start with the models: model-methods and managers are a good place to perform row-level logic and table level logic i.e. a model manager would be a good place to write code to get a list of categories that are associated with all blogposts. A model method is a good place to count the characters in a particular blogpost.
View level logic should deal with bringing it all together - taking the request, performing the necessary steps to get to the result you need (maybe using the model managers) and then getting it ready for the template.
If there is code that doesn't fit in else where, but has a logical structure you can simply write a module to perform that. Similarly if there are scraps of code that you don't think belong, keep a utils.py to hold them.
You shouldn't perform any logic really in your templates - instead use template tags if you have to. These are good for using reusable pieces of code that you you neither want in every request cycle nor one single request cycle - you might want them in a subset (i.e. displaying a list of categories while in the blog section of your website)
If you do want some logic to be performed in every request cycle, use either context processors or middleware. If you want some logic to be performed only in one single request cycle, the view is probably the place.
TLDR: Writing logic in your view is fine, but there are plenty of places that might be more appropriate
Separating the registration code into it's own function to make testing easier is a good reason. If you allowed admins to register users in a separate, private view, then a registration function would be more DRY. Personally, I don't think a little application logic in the code will do to much harm.
You might find it instructive to have a look at the registration view in the django-registration app -- just to see how it's written, I'm not saying you should or have to use it. It has encapsulated the user registration into it's own function (there's a level of indirection as well, because the registration backends are pluggable).
I'm not really experienced with web development especially on views , I need a simple explanation (and pointers to a resource would be really nice as well) on how to deal with rendering a layout or a template partially without rendering whole page again...
What is the best practice?
Does Sitemesh layouts provide this? if so how ?
Shall I use JQuery pass the data as JSON from controller and update the corresponding div with ".html()" ? (which i did something like this a long time ago for some basic stuff, and think this is not really a grails way to do it)
or <g:include> does this for me?
Everything I read about this confused me even more :)
Actually the question is, what is the best practice in Grails to handle partial page updates (with Ajax or without ajax if there is any other ways these days)
Thanks in advance
EDIT:
this tutorial actually gives a really good idea of how to do it
What is the best practice?
The usual practice is to submit an AJAX request (i.e. a HTTP request triggered from JavaScript), and use a JavaScript callback function that updates a section of the page when a response is returned.
Does Sitemesh layouts provide this? if so how ?
When an AJAX request is received on the server-side, you could layout the response using Sitemesh in the same way that you can layout the response of a non-AJAX request. Sitemesh doesn't know or care what kind of request is being processed or whether it's laying out a whole page or just a fragment.
Shall I use JQuery pass the data as JSON from controller and update the corresponding div with ".html()"
Have a look at the tags provided by Grails that have the word "remote" somewhere in the tag name. They provide a very simple way to perform common AJAX tasks within a Grails application. For example, to submit an AJAX request to an action named bookByName and add the response to an element with id foo, simply add the following tag to your page.
<g:remoteFunction action='bookByName' update='foo'/>
Probably you need to use RemoteLink tag: http://grails.org/doc/latest/ref/Tags/remoteLink.html
You can configure it to update some fragment of your page, after calling an remote action.
BTW, it's grails way too, to use ajax and javascript, on client side :)
I am running ColdFusion MX, so I don't have the possibility of using the built-in cfimage Captcha functionality in my application, before form submitting.
But the problem is without captcha the bots submit the forms.
What will be best way to prevent automatic submitting?
Captchas don't have to be images!
Try one of the following solutions:
Most bots don't understand CSS. Create two submit buttons, the first with a value that will be rejected by the server, the second with a value that will be accepted by the server. Hide the first one using CSS.
Ask the user to answer a simple math problem. This will require you to create the math problem and store the expected solution somewhere (like the user's session), then compare the user's submitted answer with the stored answer. For extra protection, you can create simple addition, subtraction and multiplication questions. Avoid division, remainders are a pain for some users.
Bots read the names of form elements, and tend to ignore text labels. Try creating a checkbox named "optout" (like a newsletter), checked by default. Next to the checkbox, ask the user to uncheck the checkbox if they are a human. The opposite technique also works (unchecked checkbox that you ask the user to check).
All of these solutions can be done without third party code or API calls.
That being said, reCAPTCHA is pretty good and easy to integrate into almost any environment.
Take a look at cfformprotect - it will work with CFMX 6 and all later engines.
It aims to be fully accessible - and invisible to most users - with an assortment of methods to stop bots and spammers.
Also you might want to look at a CF wrapper for reCaptcha, which is compatible with CFMX 7.
A technique I used with a different technology was to use image buttons. Your POST handler gets the x,y co-ordinates where the images were clicked. I found the bots (which are just generating post requests) were passing 0,0 and by dropping those requests on the floor I brought the spam posts down to less than the real ones. Sorry that I don't know how to do that in CF but I hope the technique is useful to you.
Its always a good idea to do data validation on the server side before processing no matter which solution you use.
This post may help: http://www.bennadel.com/blog/405-Fully-Accessible-Spam-Form-Submission-Blocking-Using-ColdFusion-And-X-HTML-Version-III-.htm
How about using calculation method? Just like 8 + 5 = ?
OR
how about using ColdFusion.Ajax.submitForm?