2

I'm new to wheels and still learning. It seems to me that every post of a form needs to call an action that maps to a method in the particular model. However, is it possible for a form to post to itself?

What I want to avoid is people navigating to an action view directly - which seems to throw an error. I'd also like to do a lot of self-posting because it might mean I won't have to have a lot of empty files laying around in my views folder.

Another advantage I was thinking about was the fact that if a form is self posting, I'd have the benefit of having it used globally. For example, I might have a form in my header that I want my user to fill out anywhere in the website. Or is there a way to detect where the user came from and do a dynamic redirectTo?

Many thanks, Michael.

Michael Giovanni Pumo
  • 14,338
  • 18
  • 91
  • 140

3 Answers3

2

Michael, you may want to consider making a form like that Ajaxy. In other words, you can have it submit the form data, using jQuery or similar, to a remote CFC method (i.e., a method whose access attribute is set to "remote"). That CFC could work its magic per usual and return the appropriate response that you act on in your view.

Here is a link to the Wheels docs "Wheels, Ajax and You". There's some nice stuff in that section and it might be what you're looking for here!

craig.kaminsky
  • 5,588
  • 28
  • 31
2

To avoid errors due to users browsing to post actions, look at Verification: http://cfwheels.org/docs/chapter/verification

So your create and update actions would be configured like this in the controller's init:

<cffunction name="init">
    <cfset verifies(only="create,update", post=true, params="comment", paramsTypes="struct")>
</cffunction>

It is not unreasonable to redirect the user back to the previous page after the form has posted. Look at redirectTo(back=true) for your success action. http://cfwheels.org/docs/1-1/function/redirectto

<cffunction name="init">
    <cfscript>
        verifies(only="create,update", params="comment", paramsTypes="struct");
        provides("html,json");
    </cfscript>
</cffunction>

<cffunction name="create">
    <cfscript>
        comment = model("comment").new(params.comment);
        comment.save();

        if (isAjax())
        {
            renderWith(comment);
        }
        else
        {
            if (comment.hasErrors())
                redirectTo(back=true, error="There was an error saving the comment.");
            else
                redirectTo(back=true, success="The comment was posted successfully.");
        }
    </cfscript>
</cffunction>

Yes, I like Craig's answer that AJAX is a good solution, but you also need to consider what happens if the AJAX fails and the form is ultimately posted to the URL through a non-AJAX request. Best to provide a fully accessible experience.

Chris Peters
  • 17,918
  • 6
  • 49
  • 65
  • That's an excellent point, Chris. Thank you for adding it to the thread! – craig.kaminsky Apr 18 '12 at 20:59
  • No prob. Adding some more edits. Could have been less lazy on the examples the first time through. – Chris Peters Apr 18 '12 at 21:04
  • Ok, that works a treat, and as a bonus, I now do not need my empty view templates either...which solves another main problem I was having - it just seems superfluous to me. Yourself and Craig have helped a great deal...Craig did have the answer granted but I've changed it to you since it seems to answer my initial problems more directly. Thanks to you both though! The verifies() method was just the feature I was looking for and you've both shown me an AJAX route which is brilliant. – Michael Giovanni Pumo Apr 24 '12 at 14:13
1

What little I know about Wheels is that it's an opinionated MVC framework inspired by Ruby on Rails. You are requesting help on avoiding the the Model-View-Controller pattern by having the form post to itself and bypass the controller. This should not be possible or at least discouraged in such a framework.

A good MVC framework should allow you to reuse your model, views and in some cases even controllers - globally.

BKK
  • 2,073
  • 14
  • 17