A reader asked:
I'm a coldfusion newbie, trying to figure out how to properly use the cfslider tag and update a database value when the slider is moved. I really need a good example of this functionality, can't find anything on the web.I had not touched cfslider since the beta of ColdFusion 9, but I spent a few minutes with it today and came up with a simple demo. First though - I must point out two disappointing issues with cfslider. First, it doesn't support the range attribute. Apparently that only works with the Flash Form or Applet versions. You must use min and max instead. No big deal of course, just a bit silly. (I filed a bug report for this. "Bug" because the docs do not make it clear it isn't supported, so I assume this is a real bug and not just a documentation issue.) Secondly, there is no way to provide a label with the HTML slider. The docs say you can use a label which will automatically update as you slide, but it too must be Flash/Applet only. This one is actually a bit more sucky since you get no visual cue at all what the value is. Before I even attempted to do a database call, I "fixed" that issue. Here is my example:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<cfparam name="session.slider" default="50">
<script>
function sliderChange(ob, value) {
//console.dir(arguments)
$("#sliderValue").html(value)
}
</script>
<b>Your Coolness:</b>
<cfslider format="html" min="1" max="100" value="#session.slider#" name="coolness" onchange="sliderChange" tip="false">
<cfoutput><b id="sliderValue">#session.slider#</b></cfoutput>
I've got a few things going on here, so let me address them one by one. I decided I was going to use a session value to persist my slider. The original user wanted to save it to a database but I wanted something folks could try quickly at home. This template doesn't persist the change - that comes next. I used the onChange attribute to specify a JavaScript function to run when the slider changes. Unfortunately, the documentation tells you nothing about the method signature of that call. I used the (commented out now) console.dir command you see above to inspect it and discovered that the function is passed the slider object and the value. I also added a comment to the online CFML Reference for cfslider. Hopefully it will be incorporated in a future version of the docs. So the final step was to just get the label working. I used jQuery for it which may be overkill for this example, but you could translate that to a document.getElementById call. You can see a demo of this here.
Once I had that working I then worked up a quick example of performing an update on change. As I said, I used session variables instead of database updates, but the way I do it would work with either. I modified my sliderChange function like so:
function sliderChange(ob, value) {
$.get("updateslider.cfm",{newvalue:value})
$("#sliderValue").html(value)
}
As you can see, I added a get request. I have no need to wait for the response so there isn't a callback handler. All updateslider.cfm does is:
<cfparam name="url.newvalue" default="">
<cfif isNumeric(url.newvalue) and round(url.newvalue) is url.newvalue and url.newvalue gte 1 and url.newvalue lte 100>
<cfset session.slider = url.newvalue>
</cfif>
Notice all the validation? Repeat after me - AJAX calls are not magically "safe" from URL hacking. Anyway, you can see that it just validates the value sent and stores it in the session. You can test this here. Change the value and then reload the page. Notice the slider is at the last position you set it.
Archived Comments
That's cool Ray. I was looking into the slider the other week but didn't really get anywhere with it, this should help. Only problem I see with your example is that I can't set my actual coolness high enough :)
Yeah, okay, I'll leave now...
I can always add a second slider for PHP devs with max=5. ;)
Brutal.
I had a look at the source code of the example and "oooh myyy gooodness" - Ext + YUI + jQuery for such a simple widget. ColdFusion should get on diet for its UI elements implementation. It works, which is enough in some cases, but ~1Mb of external libraries is way too much IMHO for such stuff
@Jura: Yep, it does a lot - but of course, all of that will be cached on the client after the first hit.
I would rather create a custom tag or helper that would just do the slider for me that uses the jquery-ui library, but I like jQuery more then ext. Too many files get included with ext, and they will only cache on the client if you tell the client to cache them, with apache or iis. Well sometimes the browser will cache files that it wants to, but it can be unexpected to what files it does cache.
@Ray - first off thanks for showing the slider. On the db update end of things I would've probably handled it with something like...
function sliderChange(ob, value) {
var myCFCmethodToUpdate = new myCFC();
myCFCmethodToUpdate.setCallbackHandler(sliderChangeCallback);
myCFCmethodToUpdate.setErrorHandler(errorHandler);
myCFCmethodToUpdate.updaterMethodName(ob, value);
}
Were you just trying to show a jQuery only solution? I think that the cfajaxproxy stuff is by far the most useful enhancement since cfSlicedBread!
No particular reason - just figured a simple CFM to process the save would be enough, but your solution makes sense as well.
Ray, if you changed the onChange to onDrag, would your slider change its label more "real time", instead of just at the end when you release the slider? That'd be a bit cooler... ;)
I disagree - you wouldn't want a buttload of XHR requests being fired as you drag back and forth.
Ahh- very true, and a "duh" moment on my part! That'll teach me to reply late in the AM. ;)
However, if you wanted the same effect as I'm describing without all the requests, couldn't you setup a separate onDrag event handler to do just the local updating? Something like:
function sliderDrag(ob, value) {
$("#sliderValue").html(value)
}
That should give it that real time "application-like" feel, right? ;)
Good point - ondrag would be better for the label doohicky, and onchange for the update portion.
Ugh - the method signature is different. :( Testing now.
Ok, I'll post a comment to LiveDocs. The signature is: object,event.
See here: http://www.coldfusionjedi.c...
My code now does:
<script type="text/javascript" src="http://ajax.googleapis.com/..."></script>
<cfparam name="session.slider" default="50">
<script>
function sliderDrag(ob, event) {
console.dir(arguments)
$("#sliderValue").html(ob.value)
}
function sliderChange(ob, value) {
$.get("updateslider.cfm",{newvalue:value})
}
</script>
<b>Your Coolness:</b>
<cfslider format="html" min="1" max="100" value="#session.slider#" name="coolness" ondrag="sliderDrag" onchange="sliderChange" tip="false">
<cfoutput><b id="sliderValue">#session.slider#</b></cfoutput>
Ahh, better! ;)