It's been almost a month since I last made a post. Sorry but I've been busy, mainly with work. I can only spend a few hours a week working on this. I'll make up for it with two posts in one day. The first post is to talk a little more about the asynchronous library I originally created for this blog. It's called SimpleAsynch. I't's been enhanced a bit and I'm now using it on a new application that I'll talk about a later. (Sorry Patrick, I haven't been writing games where things blow up. I promise to do that next.)




The world doesn't really need another asynchronous library, but this one is different. I created it. That doesn't make it better just different. Something else that might make this different is how the requests and responses are constructed and used.

1.Construct a request and submit it to the application server through a post action using XMLHttpRequest.
2.On the application server treat the request as any standard post request, parse the parameter list and perform an action, database update, reach out to a web service, etc.
3.When we're ready to return a response, use the asynchronous library to construct a XML document. In the document is a list of action node. Each action node is made up of an action (duh), the action recipient which could be an element id or JavaScript function, and finally a value to either store in the element or pass to a callback.
4.The response is then returned to the browser where the asynchronous library loops through and executes all of the actions.




There are several actions available:

input - populate an input field, if it doesn't exist create a hidden input field and store the value
div - replace the innerHTML of the div with the value supplied
options - replace all options in a select with the comma delimented option list stored in the value
select - set the selected option in a select to the value supplied
tab - if we use the tabber.js library, we can use this action to activate the tab named in the value parameter
delayCallback - we can use this to execute a callback function on the client, I can't remember why I needed this, I had a reason
callback - use the callback to execute yes a callback, the callback function could build another asynchronous request, we actually do this on the admin piece for the blog and on the project application that I'll talk about later
alert - the alert action will display an alert with the name and value concatenated, useful for reporting errors or for debugging

Now the first version of SimpleAsynch did not construct a XML response, but returned a pipe delimented set of actions, ids, and values. While the delimented response was initially easier to construct and prove out, it was a pain to manage and debug once more complex actions were performed. The project application uses the XML version, while the blog and Salesforce applications use the old delimited version.

The current library accommodates the most important of all browsers, IE6. There are no other browsers. That's wrong. It actually supports all browsers that I have access to IE6, IE7, Firefox 3 on Windows and Linux, Safari 3 on Mac and iPod. I've not downloaded Safari 4 yet nor I have I tried it on Chrome.

Now for some sample code...
The event handler on the browser constructs the request using SimpleAsynch.


function updateProject(){
var request = ""
request = addRequestFunction(request,"updateProject",false);
request = addRequestParameter(request,"projectId",false);
request = addRequestParameter(request,"projectName",false)
request = addRequestParameter(request,"projectStatus",false)
request = addRequestParameter(request,"projectDescription",false)
request = addRequestParameter(request,"projectScheduledStart",false)
request = addRequestParameter(request,"projectScheduledStop",false)
request = addRequestParameter(request,"projectActualStart",false)
request = addRequestParameter(request,"projectActualStop",false)
request = addRequestParameterAndValue(request,"projectAccessList",getAccessList(),false)
request = addCallback(request,"clearProjectForm",true);
postRequest("/updateProject",request);
}

There are a few functions that can be used to add parameters, addRequestFunction, addRequestParameter, addRequestParameterAndValue, and addCallback. The addRequestParameter function will locate the element by the id passed and will populate the value of that element in the parameter list. The addRequestParameterAndValue will let you add parameters to the request for elements that may not exist on the page. The addCallback function will be returned back to the client by the application server in the action list. Finally, postRequest will send the request off to the server.

I won't pull up all of the SimpleAsynch.js code here. You can get it from the site.

On the server you would process the request and build a response. Here's an example where we're trying to populate the screen with the details of a requirement. This example shows the construction of the xml using the SimpleAsynch ResponseXml class. ResponseXml uses a django template to construct the XML for the response.


class LoadRequirement(webapp.RequestHandler):
def post(self):
requirementId = self.request.get('requirementId')
requirements_query = db.GqlQuery("SELECT * FROM Requirement where requirementId = :1",
int(requirementId))
requirements = requirements_query.fetch(1)

rx = ResponseXml()

for requirement in requirements:
rx.addAction("input","requirementIdHidden",str(requirement.requirementId))
rx.addAction("input","requirementNumber",str(requirement.requirementNumber))
rx.addAction("input","listRequirementNumber",str(requirement.requirementNumber))
rx.addAction("input","requirementSubNumber",str(requirement.subNumber))
rx.addAction("input","requirementVersion",str(requirement.version))
rx.addAction("input","requirementMaxVersionHidden",str(requirement.maxVersion))
rx.addAction("input","requirementSummary",requirement.summary)
rx.addAction("input","requirementDescription",requirement.description)
rx.addAction("input","requirementComments",requirement.comments)
rx.addAction("input","requirementStatus",requirement.status)
labelString = ""
for label in requirement.labels:
labelString = label " "
rx.addAction("input","requirementLabels",labelString)
rx.addAction("input","requirementAuthor",str(requirement.requirementAuthor))
rx.addAction("input","requirementEntered",requirement.entered.strftime("%m/%d/%y %H:%M"))
rx.addAction("callback",self.request.get("callback"),"")
if rx.getLength()==0:
rx.addAction("alert","Requirement was not found.","")
self.response.out.write(rx.getXml())

Here's an application that might actually be useful. It's called mamoo project - http://mamooproject.appspot.com/. I've got more work to do on it, but there's enough here to look at. Here's how this all came about. At work, we've been going through a review process of requirements gathering tools. I'm not sure if we'll purchase one, but the vendors are sure nice to talk to. All of the presentations we've seen start off with something like, "Imagine the hell of having to capture requirements in a ginormous Word document. How stupid is that? (giggle...giggle)" However correct they may be, this is not a good way to win over a group of people, especially when everyone in the room has a "ginormous" requirements document back at their desk waiting for them.

So the outcome of all of this? We're still living with our big Word requirements document and we're dragging our feet with the vendors. The fact is, all of the tools we've looked at are good and have pretty much the same functionality and integration points with other applications, our test suite, etc. There are some big differences in cost, but that isn't the issue. I think the biggest barrier for us is maybe a little bit of fear. These are big applications. These things will collect requirements, create use cases, build activity diagrams, create test scenarios and scripts, integrate with development tools, build mockups. It's a bit much for an organization that doesn't have a standard template for the ginormous requirements document. We should probably start smaller. So I began working on mamoo project.


First off, I do not expect mamoo project to be used at work. I'm working on google app engine and work would not buy in to using something on gae. I could port it to .Net if they wanted to use it, but I don't really have the time. I just took advantage of this problem so that I could work on google. This looked like a good problem to solve and if I use it for future projects so much the better.

I started off with just the requirements piece. Here's what we have.



- You can look at the requirements for mamoo project to see what's complete "accepted" and what is left "review".
- On the requirements screen use the bottom left control to display all versions and all minor requirements.
- When you first go to requirements you only see the minor ones.
- All changes to requirements are saved as new versions of the same requirement.
- Requirements are color coded based on status.
- The layouts were a little tricky, but they do work under IE, FF, and Safari, even on the iPod if you squint real hard.
- All of the asynchronous calls are taken care of with SimpleAsynch.

There is a large list of fixes and features to be added. I'm working now on a site landing page. This will include security and access lists for all projects. I'm also working on the export of the requirements to google docs. It's a little tricky. You can't just create a new spreadsheet in docs, you have to use an existing one or upload a new one. The problem is that google app engine won't let you just load up a new sheet from the file system. I'll figure it out. The risks and tasks and reports are all just an idea. Along with the challenge of capturing requirements, projects need a good way to manage risk. In the past I've used several tools for this, none have been ideal though one came close, Mercury Test Director - Quality Center - HP QC. The defect section had a nice layout and the defects themselves were customizable. It gave us a good place to store risks, issues, action items, requirements defects, test defects, lessons learned, anything you can thing of. You had good traceability and an okay reporting tool. I'll model the mamoo project tasks and risks section off of Quality Center. It will have much less functionality, but it will still be useful and it won't require a massive applet download to run. Risks and Tasks will also be exportable to docs.

 
 User
top comments
 
top views
 
top tags
 
favorite sites