Utility Function: PatternFind()

Another pattern based function.


<cffunction name="PatternFind" output="false" returntype="boolean">
    <cfargument name="pattern" type="string" required="true" />
    <cfargument name="string" type="string" required="true" />
    
    <cfset var local = StructNew() />
    
    <cfif IsSimpleValue(arguments.pattern)>
        <cfset arguments.pattern = CreateObject("java", "java.util.regex.Pattern").compile(arguments.pattern) />
    </cfif>
    
    <cfset local.matcher = arguments.pattern.matcher(arguments.string) >
    
    <cfreturn local.matcher.find() />
</cffunction>

 

BlogCFC Tweaks: Bug Fix for viewByCategory.cfm

I recently posted a blog entry with some code and instructions to allow drilling down into categories to view the posts in that category. Unfortunately, it had a bug. The meat of the viewByTemplate.cfm file should look like this:


<cfmodule template="../tags/datatable.cfm" data="#entries#" editlink="entry.cfm" label="Entries"
         linkcol="title" defaultsort="posted" defaultdir="desc">

    <cfmodule template="../tags/datacol.cfm" colname="title" label="Title" />
    <cfmodule template="../tags/datacol.cfm" colname="released" label="Released" format="yesno"/>
    <cfmodule template="../tags/datacol.cfm" colname="posted" label="Posted" format="datetime" />
    <cfmodule template="../tags/datacol.cfm" colname="views" label="Views" format="number" />
    <cfmodule template="../tags/datacol.cfm" label="View" data="<a href=""#application.rooturl#/index.cfm?mode=entry&entry=$id$"">View</a>" sort="false"/>
</cfmodule>

Notice the missing "querystring" attribute on the datatable module. If you don't remove that bit, clicking on a blog post link from the category view wont take you to that blog post at all. I've updated the code in the relevant zip.

 

Utility Functions: Java Regex Pattern Matching

Ok, so this time I have a trio of functions all to get at a key piece of Java regular expression matching: groups. Groups allow you to extract small snippets of a regular expression, and let you do a lot more with them then ColdFusion alone. Check out the whole bunch.

 

Utility Function: ListRemove() and ListRemoveNoCase()

I ran into a problem earlier where I needed to remove the elements of one list from another list I could have worked around it in a couple of ways, but I thought that I'd rather have a function to do this for me.

<cffunction name="ListRemove" output="false" returntype="string">
    <cfargument name="string1" type="string" required="true" />
    <cfargument name="string2" type="string" required="true" />
    <cfargument name="scope" type="string" required="false" default="all" />
    <cfargument name="delimiters" type="string" required="false" default="," />

    <cfset var returnValue = "" />
    <cfset var position = 0 />

    <cfif NOT ListFindNoCase("one,all", arguments.scope)>
        <cfthrow errorcode="ListRemove" message="Invalid argument SCOPE. Valid values are ONE and ALL." />
    </cfif>

    <cfloop list="#arguments.string1#" index="value" delimiters="#arguments.delimiters#">
        <cfset position = ListFind(arguments.string2, value, arguments.delimiters) />
        
        <cfif position gt 0 AND arguments.scope eq "one">
            <cfset arguments.string2 = ListDeleteAt(arguments.string2, position) />
        <cfelseif position eq 0>
            <cfset returnValue = ListAppend(returnValue, value, arguments.delimiters) />
        </cfif>
    </cfloop>

    <cfreturn returnValue />
</cffunction>

And that meant that I needed to make the case insensitive version as well.

<cffunction name="ListRemoveNoCase" output="false" returntype="string">
    <cfargument name="string1" type="string" required="true" />
    <cfargument name="string2" type="string" required="true" />
    <cfargument name="scope" type="string" required="false" default="all" />
    <cfargument name="delimiters" type="string" required="false" default="," />

    <cfset var returnValue = "" />
    <cfset var position = 0 />

    <cfif NOT ListFindNoCase("one,all", arguments.scope)>
        <cfthrow errorcode="ListRemove" message="Invalid argument SCOPE. Valid values are ONE and ALL." />
    </cfif>

    <cfloop list="#arguments.string1#" index="value" delimiters="#arguments.delimiters#">
        <cfset position = ListFindNoCase(arguments.string2, value, arguments.delimiters) />
        
        <cfif position gt 0 AND arguments.scope eq "one">
            <cfset arguments.string2 = ListDeleteAt(arguments.string2, position) />
        <cfelseif position eq 0>
            <cfset returnValue = ListAppend(returnValue, value, arguments.delimiters) />
        </cfif>
    </cfloop>

    <cfreturn returnValue />
</cffunction>

Click more for a view of example results against some test data.

 

More Fun with ArgumentCollection

So, I went back and visited the thread on AttributeCollection and ArgumentCollection I talked about back on Wednesday, and I came up with another test I wanted to look at with ArgumentCollection:


<cfset request.test = {
    value1 = "One",
    value2 = "Two"
} /
>

<cfset request.test2 = {
    value3 = "Three",
    value4 = "Four"
} /
>



<cffunction
    name="OutputArguments"
    returntype="void"
    output="true"
>

    <cfargument name="argumentCollection" type="struct" requred="false" default="#request.test2#"/>

    <cfdump var="#ARGUMENTS#" label="From OutputArguments()" />
</cffunction>

I'm not sure what I expect the result to be, but the result I got isn't it:

 

Javascript Abstraction in ColdFusion: Pro or Con?

There is an interesting article up on Ajaxian.com today discussing the pros and cons of Javascript abstractions. It's aimed squarely at the root of an issue that I have with ColdFusion 8's Ajax and Javascript integration: abstractions are easier and save time, but do you loose something by giving away that control? I heard Andy Powell give a talk at CFUnited in 2007 about the (then) upcoming release of ColdFusion 8 and its Ajax and JS support, where he asked the room to raise their hands if they liked Javascript. Those few of us that did got some weird looks from the crowd... how weird: people that use a technology might actually like it?

I like Javascript, and I don't think that thats weird. If I need FCKEditor in ColdFusion, I still use FCKEditor, rather then the new tags. If I need ExtJS, I still use ExtJS rather then the new tags. Why? Because I know that I can program better for my situation then Adobe. Its not that Adobe's code isn't good, its just that they have to program in such a way that it works for everyone, and that always creates bloat. Always.

Using <cfwindow> will save you some time, I'm not saying that it wont, but its going to add overhead that might not intend. You might not ever notice that overhead, and thats fine, but what happens if its a problem? Ultimately you'll have to go find someone that actually knows (and probably likes) Javascript to fix the problem for you. Why not get that person to write it in the first place?

Where would you draw the line? The purist in me says "Code it straight in JS and don't mess around." while the realist in me says "If most people don't need to rework the tags, then its working fine." Do you think abstraction can come back to bite you, or is it just a time saver?

 

More Entries

Jon Hartmann, July 2011

I'm Jon Hartmann and I'm a Javascript fanatic, UX/UI evangelist and former ColdFusion master. I blog about mysterious error messages, user interface design questions, and all things baffling and irksome about programming for the web.

Learn more about me on LinkedIn.