PDA

View Full Version : I need a complete CF8 crud-example (ExtJS 3.0, store.writer)



Mike Robinson
28 Aug 2009, 8:02 AM
I want to create a CF8 application using EXTJS 3.0's "store.writer" feature. I have already found and am using Cutter's "CFDataReader." Also, "ColdExt."

The back-end of my ColdFusion application obviously needs to have (I think) five functions: Get list-of-records; Read; Write; Create; Update. These would be four different functions I presume. I've got list-of-records working fine. I've already covered the issue (thanks, Cutter!) of Adobe's incompatible JSON implementation.

Okay, I can get tantalizingly-close by reading the juicy descriptions in the ExtJS docs about "HttpProxy," but none of them are complete and none of them are "very-plainly ColdFusion."

Mind you, I have been around web-programming (and programming) for a very long time, so "I'm no n00b," but I am wasting a tremendous amount of time searching through what invariably turn out to be incomplete, half-baked examples. This is causing me to thrash for days of wasted-effort that I simply do not have. (That's not intended as a "slam"... we've all been there, but "I have promises to keep," and my shirt-collar is now on fire.)

This should be "drop-dead simple crud." There ought to be an example that I can accurately copy. It ought to be able to fully-leverage the juicy capabilities of "data.store.writer" that I see in ExtJS 3.0, which is exactly what I need...

I'm not ready to dive into Direct on this, and my URL-format isn't "REST."

:(( ... Yesterday!! :((

Mike Robinson
30 Aug 2009, 4:07 AM
Having now had some ~o) (and a good look at the ExtJS source-code), I'm going to try to turn this thread into a "how to do it" thread ... or, at least, a "how I did it" thread. This will include source-code postings as I complete them. Contributions welcome.

Setting the Stage:


I'm talking about ColdFusion 8, from Adobe. Which is what we use, here, now. You should be aware that ColdFusion 9 will incorporate ExtJS 3.x, or so I am told, whereas CF8 used ExtJS 1.1. So you might want to just wait a bit and do nothing at all 'cept pony up some cash to Adobe when the time comes... Otherwise AFAIK you can't mix the versions successfully. Earlier versions of CF (ColdFusion MX and so forth) do not have the built-in support for Ajax that CF8 and later versions do.
You will need Firebug, the indispensible Ajax plug-in for FireFox. Don't leave home without it.
CF8 made a bit of a mistake in its implementation of the JSON protocol. Plus, there are a couple of different ways that the data could be encoded. Fortunately, "Cutter" created a "ColdFusion Query Data Reader" (discussed in this forum and here (http://blog.cutterscrossing.com/index.cfm/2009/2/13/Ext-Custom-Data-Reader-for-ColdFusion-More-Info)) which you can "drop in" as a reader to your Ext.data.Store objects and "it just works."
You will need ExtJS 3.0 or later, because this version implements the concept of a writer, which allows a Store to be a full read/write mechanism. You manipulate the rows in the Store, and the Store fires off the necessary calls to the host. Very nice.
You ought to have the ColdExt ColdFusion extension library (discussed here (http://coldext.riaforge.org/) and here (http://www.madfellas.com/docs)) which will generate much of the JavaScript code that you need. You need to take the time to read the source-code to all of the examples shown at the second link. Documentation is sketchy. Although the tags are not (yet) fully up-to-date with ExtJS 3.0, there are "catch-all" tag parameters that allow you to specify the additional parameters (such as writer specifications) using JavaScript notation.
When you use ColdExt, the <cfimport> tag needs to be repeated at the top of each source-file; it doesn't seem to work when <cfinclude>d. Otherwise, include files work great for the "obligatory preamble boilerplate" and "obligatory post-amble" of your pages. (By that I mean, "the header, the script tags, the body-tag and so forth" in one file, and the "</body>" tag in the other.) Put the <script> and stylesheet tags in the <header> but the ColdExt stuff all needs to be in the <body>. Originally I thought I'd need two preamble include-files but that did not turn out to be the case.
Okay, I've found that I do like Eclipse (http://www.eclipse.org/) better than DreamWeaver. Your mileage may vary. You'll need the CFEclipse (http://www.eclipse.org/) plug-in too. The ColdExt tags can be added to Eclipse's documentation too... the first hotlink above shows how.
You will need to manage to "wrap your mind around" just how the various parts of ExtJS actually work together...

Mike Robinson
30 Aug 2009, 4:33 AM
"How ExtJS works":

Okay, okay, that's obviously a much too-big topic title. ("Explain World War Two. Use both sides of paper if necessary...") But maybe you get the idea of what I'm driving at here. If you are coming from the padded-cell world of ColdFusion and are trying to grok (http://en.wikipedia.org/wiki/Grok) how this world works, if you're like me you feel like a stranger in a strange land (http://en.wikipedia.org/wiki/Stranger_in_a_Strange_Land) even if you know a good bit about JavaScript.



"Use the Source, Luke!" If you go to the ExtJS 3.x API documentation page (http://www.extjs.com/deploy/dev/docs/), you can read the documentation (such as it is...) on every page and feature. What is slightly less obvious is that all of the method, property and file names are hot-links to the actual JavaScript source-code that implements that feature. I don't know about you, but I didn't "get" how, say, Ext.data.Store was supposed to work until I found the source-file and read the thing stem-to-sterrn. (And I still don't know much about it.)
Mind the (Ext.data.)Store: This is where all of the data used by, say, a grid, actually gets kept on the client-side. The data is obtained by a reader, and with ExtJS 3.0, it is updated to the host by a writer. You don't want to be wiring things up to "buttons" and other events. You want these interactions to be managed by the Store.
Follow the examples: Read 'em all. Look at the source-code to every ExtJS example and every ColdExt example too. Follow 'em scrupulously... it seems to work. Also look at the ExtJS source-code itself.
How ExtJS does CRUD: "Create, Read, Update, Destroy." These are the four things that you can do to a record in a database. These are, therefore, the four things that your back-end software (in ColdFusion) is going to have to be able to do. These are going to be straight AJAX calls, which can be directed to distinct URLs in your ColdFusion .CFC library or to just one. If more than one of the CRUD requests are handled by the same URL, an "xaction" parameter will be present in the AJAX request. The parameter will be one of: "create, read, update, destroy."
CF8 does Ajax (for you): If you've got Cutter's reader, ExtJS will be able to understand the (incorrect) data format used by CF8. Beyond that, CF8 implements AJAX quite well indeed if you remember to use the "remote" clause when defining your <cffunction>s. You'll be receiving a struct and returning a struct.It needs to conform to what the reader expects.
ExtJS does primary-keys (for you): You probably use auto-increment primary keys, assigned by the host side. When you create a new record, you do so by creating the record in the Store. The Store knows that the record is "a phantom." It assigns a dummy ID-value to the record for its own purposes, but knows that the value is, indeed, a dummy. It will send a create AJAX-call for those records, either one-at-a-time or in bulk (your choice). The host-side response should include the ID field (containing the actual ID-number assigned by the host), as well as any other field-values that may have been generated or computed by the host. If several records were submitted at once, you must return an array of structs in the same order. The Store will automagically replace the "phantom" IDs with the real ones.
Time-savers in BasicForm: Objects like "FormPanels" have a getForm() function which leads to the underlying BasicForm object in which you will find many useful things ... like a way to move values en masse to-and-from a record in the Store. While it's right there in the first paragraphs of the documentation-page for FormPanel, etc, I have a bad habit of overlooking things like that. Maybe you do, too. I hate to find that something "has already been done for me" 8-| and that it had literally not occurred to me to look for it.
Content is rendered into DOM objects: In the standard ColdFusion world, content is specified in the CFM files and it's basically set-up and spit-out for you by the host. Although the ColdExt libraries allow you to more-or-less keep that "tag-based declarative" mindset, you do need to be aware of just how ExtJS finally comes up with the content that you see: that it "renders it" to create a DOM (http://en.wikipedia.org/wiki/Document_Object_Model) structure which is then inserted at some location (usually marked in the HTML by a <div>). This can happen "automagically" or you can control the rendering yourself. What's important here is to understand that the ExtJS code for various visual controls and widgets (whether you use ColdExt to do it all or not) is defining the renderer. The web-browser decides that the page has been loaded, so it calls an event routine which causes all those ExtJS calls to occur, and they (or you) do the "rendering," and voila... a DOM structure now exists for your ever-loyal web browser to display. Those rendered structures include references to event-handling subroutines (in the ExtJS code, and in yours).

Mike Robinson
30 Aug 2009, 5:20 AM
That's enough for now. More code and comments will follow in the next several days as I bring-up an actual working CRUD application in CF8. Please chime in and add your own! Discoveries, war-stories, you name it. For suggestions or questions, please private-message me.

My goal for this thread is simply to consolidate into one resource the results of my very painful "sip from the firehose." I thought that I was stepping into shallow waters and found myself grasping for a life-boat. This is, of course, "how it often works in real-life" and therefore I do not mean it as any sort of a "slam" to anyone or anything. But you (yes, you, Gentle Reader...) ought to follow in these footsteps knowing where the rocks are.

Reading Assignment: Read the entire source code to: Ext.data.Store, DataReader, DataWriter, DataProxy, HttpProxy, Record, API and Ajax. Yes, I do mean "read the entire source file, using the hotlink in the title of each documentation-page, stem-to-stern. Many of these are descendent-classes with very little code in them. Several of them have Mystical Magick JavaScript Mojo beyond the Ken of Mere Mortal Beings, but most of them actually do not. (And even with "Mystical Magicks," you can often guess what the spell is doing even if you cannot cast it yourself.)

HTH! Bye bye for now...

Mike Robinson
4 Sep 2009, 11:10 AM
Let no one in the ColdFusion (CF8) community have to go through what I just went through. I give you... herewith attached, "Instant CRUD." (For ExtJS 3.x... requires the Writer support introduced in that version.)

Here's what you'll find inside, mostly but not-quite debugged:

On the client side: (all of these are ".CFM" files containing JavaScript, and they use the "ColdExt 1.2" tag-extension library):


cr_PrototypeManager.cfm is the user-side page... a basic CRUD page, very battle-scarred by now and not yet cleaned-up from the long fight.
header_js.cfm and footer_js.cfm are the standard header/footer includes we use.
Cutter's CFQueryReader.js file is included for your interest and edification ... it is not modified, and of course is readily available elsewhere. This is the code that knows how to interpret the responses that CF8 uses when the reply consists either of a query or a cfgrid-type slice of one. It's used only for "read" requests.

On the host side:


The ColdExt tag-extension library is not included but is heavily referenced in the code.
crv2_js.cfc is the tag-library that drives the client-side requests.
InstantCRUD.cfc is the hard-won module... the code that can be called as a subroutine by another CFC to process a request. All that "crv2_js.cfc" has to do in each case is to call the subroutine.

Are there bugs? Undoubtedly. But I wanted you to see it.

There is a couple weeks' worth of head-banging in this ... and I know that CF9 is going to cover a lot of the same material probably much better than I did. I do not claim to say that I "did it right or did it well." But I do not want anyone out there to have to repeat what I did.

A lot of my "most painful discoveries" are in the source-code comments, which are extemporaneous. I'll write more later.

Comments, fixes, and so-on are welcome.

EDIT: THIS ATTACHED-FILE HAS ERRORS, AND WAS REMOVED. AN UPDATED FILE HAS BEEN POSTED LATER.

Mike Robinson
11 Sep 2009, 9:17 AM
The "InstantCRUD" zip-file herewith attached contains numerous corrections to the material previously posted.


The paging logic was totally wrong, and it turns out that the CF8 function to prepare grid-output was unsuitable. (It produces rows of NULLs to fill-out the last page.) This is replaced by logic that builds the output manually. (Did you know that a query could be accessed with rows and columns? Neither did I...)

ColdExt as a library leaves a few things to be desired especially with reference to ExtJS 3.x, most especially its lack of documentation. But by a great deal of poring through the source code of that library I continue to use it.

The sample page in the original file ("prototype manager") is still there, and it's basic-crud. There is a realistic AJAX RPC example-page as well.

taguchi
14 Jul 2010, 3:30 AM
Mike,

Thanks so much for your introductory post on your journery into mastering ColdExt and ExtJs 3.0. A couple of days ago I started researching ExtJS for coldfusion and found your posts today.

In your your final post on this thread you mentioned something about a zip file with some succesful implementation examples.

email me the latest working version? I just sent you a PM with my email address.

Thanks in advance,

Taguchi

budhines
5 Mar 2011, 11:49 AM
Mike,
Thanks for the write-up. You mentioned that you included some zip files but I do not see them. I am hoping you will share and include them!
thanks,
Bud

smanke
22 Apr 2011, 6:39 AM
I'm really interested in the files too. I know we're onto CF9 now, but I'm stuck with an issue updating a CRUD test I am doing and its kicking my butt. I know the issue I'm hitting has to do with the phantom keys that Mike mentions, but I can't figure out how to make the phantom record in the store update with the mySQL primary key once the database has created the record. its making me crazy... I'm hoping the sample files will have the solution I am looking for.

Its amazing how little info there is out there for CF developers.

westercamp
22 Mar 2012, 5:28 AM
I am in the same boat trying to pull all of this together. Could you send me what you have for your CF CRUD?

My email is jaywestercamp@yahoo.com

Much Appreciated!

Thanks,

Jay