Skip to content

Commit

Permalink
Simplified form handling (removed Ajax forms)
Browse files Browse the repository at this point in the history
  • Loading branch information
dezoito committed Feb 26, 2015
1 parent a35177e commit 8d5dc35
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 188 deletions.
52 changes: 43 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,62 @@
ColdFusion + FW/1 App to store news articles
---------------------------------------------------

I created this app as an exercise to learn the [FW/1 Framework](https://github.com/framework-one/fw1).
This application was created as an exercise to learn the awesome [FW/1 Framework](https://github.com/framework-one/fw1).

Here's some of the topics I tried to cover:

#### Project Structure
### 1- Project Structure
I decided to use subsystems, so the main app's logic is inside the **/home** folder (which is the default subsystem).

Notice that I added these folders to the project's root:

**/customtags** - Well, stores the few custom tags used in this project (I made one to handle pagination)

**/lib** - Stores User Defined Functions and UDF libraries

**/setup** - Contains the SQL script for database creation
**/setup** - Contains the SQL script for database creation (I used mySQL, but it's simple enough to run on other DBs)

**/static** - This is where I keep JS, CSS and images
**/static** - This is where I keep JS, CSS and Image files

**/tests** - Self explanatory

#### Forms and Validation

#### Use of UDF Libraries
### 2- Forms and Validation
The app uses the same view to display Create or Update forms,
the same methods to validade and save objects and performs CSRF verification with _CSRFVerifyToken()_ to stop Cross Site Request Forgery.

Validation errors and messages are displayed next to their respect form fields.



### 3- Use of UDF Libraries
The _/lib_ folder contains _functions.cfc_, a library of commonly used functions
that is saved in the **application** scope so they can be easily accessed anywhere.


### 4- Accessing an External Service
The app can display a summary of articles in a modal window (using the [flask-Summarizer App](https://github.com/dezoito/flask-Summarizer).
I used this as a way to see how to make Ajax calls and also access an external service.



### 5- BDD Testing
The folder _/tests_ contains the spects for tests that run using [testBox](http://wiki.coldbox.org/wiki/TestBox.cfm) and [CFSelenium](http://cfselenium.riaforge.org/).

I start with some very simple tests that escalate to CRUD tests that save data to a testing database.
**_/tests/specs/Test_6_Integration_Selenium.cfc_** contains full integration tests using Selenium.

To run these tests, you must have CFSelenium and testBox installed on your server.

###

### References
Aside from the Official Documentation, I learned a lot studying these resources:

[**Raymond Camdem's QBall Sample Application**](http://www.raymondcamden.com/2010/02/27/Framework-One-Sample-Application-QBall)

[**Simon Bingham's Xindi CMS**](https://github.com/simonbingham/xindi)

#### Use of static assets
[**Joe Steinbring's Pagination Gist**](https://gist.github.com/steinbring/4315198)

#### Accessing an External Service

#### BDD Testing
16 changes: 0 additions & 16 deletions home/controllers/clipping.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,6 @@ component accessors="true" {
// will render clipping.form view from here...
}

/**
* Generates clipping form
* either for a new one, or for an update
* to be displayed in a modal window
*/
function ajaxForm (struct rc){
// disable trace and debug info
variables.fw.disableFrameworkTrace();
setting showdebugoutput="false";

// builds the form just like the non-ajax version
return form( rc );

// will render clipping.ajaxform view from here...
}

/**
* saves an article
*/
Expand Down
130 changes: 0 additions & 130 deletions home/views/clipping/_inc_form.cfm

This file was deleted.

23 changes: 0 additions & 23 deletions home/views/clipping/ajaxform.cfm

This file was deleted.

131 changes: 126 additions & 5 deletions home/views/clipping/form.cfm
Original file line number Diff line number Diff line change
@@ -1,7 +1,91 @@
<!-------------------------------------------------------------
Include with common form definitions and fields.
Menus are defined at the parent .cfm
--------------------------------------------------------------->

<!--- display alert if there were errors --->
<cfif structKeyExists(rc, "stErrors") and (structCount(rc.stErrors) gt 0)>
<div class="alert alert-danger">
<a href="#" class="close" data-dismiss="alert">&times;</a>
<b>Your article could not be posted!</b><br/>
Please fix the errors below:

<!-------------------------------------------------------------
<ul>
<cfloop index="e" struct="#rc.stErrors#">
<cfoutput><li>#rc.stErrors[e]#</li></cfoutput>
</cfloop>
</ul>
--------------------------------------------------------------->
</div>
</cfif>

<!-------------------------------------------------------------
for styling info see:
http://www.tutorialrepublic.com/twitter-bootstrap-tutorial/bootstrap-forms.php
--------------------------------------------------------------->

<cfoutput>
<form action="#buildURL('clipping.save')#" method="post" role="form" class="form-horizontal" id="f_clipping">

<input name="csrftoken" type="hidden" value="#session.csrfToken#">

<input type="hidden" name="clipping_id" id="clipping_id"
value="#HtmlEditFormat(rc.Clipping.getClipping_id())#">

<!--- define how the buttom menu will be displayed in the forms --->
<cfsavecontent
variable = "button_menu">
<div class="form-group">
<label for="clipping_titulo" class="control-label col-sm-2">Title <span class="required">*</span></label>
<div class="col-sm-9">
<input type="text" name="clipping_titulo" id="clipping_titulo"
value="#HTMLEditFormat(rc.Clipping.getClipping_titulo())#" size="100" class="form-control">
<!--- display errors? --->
#view("helpers/_field_error", {field="clipping_titulo"})#
</div>
</div>

<div class="form-group">
<label for="clipping_texto" class="control-label col-sm-2">Text <span class="required">*</span></label>
<div class="col-sm-9">
<textarea name="clipping_texto" id="clipping_texto" cols="50" rows="10"
class="form-control">#HTMLEditFormat(rc.Clipping.getClipping_texto())#</textarea>
<!--- display errors? --->
#view("helpers/_field_error", {field="clipping_texto"})#
</div>
</div>

<div class="form-group">
<label for="clipping_link" class="control-label col-sm-2">Link</label>
<div class="col-sm-9">
<input type="url" name="clipping_link"
value="#HTMLEditFormat(rc.Clipping.getClipping_link())#" size="100" class="form-control">
<!--- display errors? --->
#view("helpers/_field_error", {field="clipping_link"})#
</div>
</div>

<div class="form-group">
<label for="clipping_fonte" class="control-label col-sm-2">Source</label>
<div class="col-sm-9">
<input type="text" name="clipping_fonte"
value="#HTMLEditFormat(rc.Clipping.getClipping_fonte())#" size="100" class="form-control">
<!--- display errors? --->
#view("helpers/_field_error", {field="clipping_fonte"})#
</div>
</div>

<div class="form-group">
<label for="published" class="control-label col-sm-2">Published: <span class="required">*</span></label>
<div class="col-sm-3">
<input type="text" name="published"
value="#dateFormat(rc.Clipping.getPublished(), "dd/mm/yyyy")#" size="10"
class="form-control datepicker">
<!--- display errors? --->
#view("helpers/_field_error", {field="published"})#
</div>
</div>

<!--- display menu (defined in the view that included this file) --->
<div class="form-group">
<div class="col-xs-offset-2 col-xs-10">
<button type="submit" class="btn btn-primary" id="btn_save">Save</button>
Expand All @@ -12,7 +96,44 @@
</cfif>
</div>
</div>
</cfsavecontent>


<cfinclude template="_inc_form.cfm">
</form>
</cfoutput>

<!--- form to delete clipping articles --->
<cfoutput>
<form action="#buildURL('clipping.delete')#" method="post" id="form-delete">
<input name="csrftoken" type="hidden" value="#session.csrfToken#">
<input type="hidden" name="clipping_id" id="clipping_id" value="#HtmlEditFormat(rc.Clipping.getClipping_id())#">
</form>
</cfoutput>

<!--- use WYSIWYG editor instead of textarea --->
<script>
// Replace the <textarea id="clipping_texto"> with a CKEditor
// instance, using default configuration.
// examples in: http://ckeditor.com/latest/samples/plugins/toolbar/toolbar.html
CKEDITOR.replace( 'clipping_texto', {
width: 600,
height: 300,
resize_dir: 'both',
resize_minWidth: 200,
resize_minHeight: 300,
resize_maxWidth: 800,
toolbar: [
{ name: 'document', items: [ 'Source', '-', 'Templates' ] }, // Defines toolbar group with name (used to create voice label) and items in 3 subgroups.
[ 'Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo' ], // Defines toolbar group without name. // Line break - next group will be placed in new line.
{ name: 'basicstyles', items: [ 'Bold', 'Italic'] },
{ name: 'links', items: [ 'Link', 'Unlink', 'Anchor' ] },
{ name: 'insert', items: [ 'Image', 'Table', 'HorizontalRule', 'PageBreak'] },
]
});
// if we have date inputs, make them a datepicker
// $(document).ready(function(){
// $(".datepicker").datepicker({ dateFormat: 'dd/mm/yy' });
// });
</script>
Loading

0 comments on commit 8d5dc35

Please sign in to comment.