Gotta Getta gifStream
Author: Daniel
W. Short
Author's Site: Web-Shorts.com
Reference ID: 15635
Introduction
What's a gifStream? gifStream is a method of performing an action
on a database without refreshing the current page. It's accomplished
by changing the SRC attribute of an image to the URL of a dynamic
page which handles the database work. We can pass multiple querystring
values to the processing page, which allows us to affect multiple
records, one at a time, from one page, without refreshing or submitting
forms.
What are the ingredients?
We need just a few things to make this work:
- A transparent GIF, that we're going to call "gifStream".
- Two images for our toggle buttons, we're using "on.gif"
and "off.gif". The script could also be reworked to
use checkboxes.
- Some snazzy JavaScript to swap a URL in place of our gifStream,
depending on the state of our toggle.
- A database with a Boolean (yes/no) type field. That's what we're
going to use for this example, but the technique could certainly
be expanded to work with different field types. I'll leave that
for homework.
- A separate page to do all the database processing. We're going
to use "streamer.asp".
Baking a cake
Now we've got to put all of our ingredients together. The flow
of user actions once all is complete goes like this:
- User clicks image to call toggle JavaScript.
- JavaScript determines current state of toggle, swaps the toggle
image accordingly and determines the new value for our field.
- JavaScript builds a new URL to perform our update.
- JavaScript swaps SRC attribute of gifStream to our new URL.
- "Streamer.asp" takes the querystrings passed by the
JavaScript and does all the work.
The transparent GIF: gifStream
In the example below, you'll see a small table with a colored background.
That table contains a 10x10 transparent GIF called "gifStream".
The user won't interact with this element at all. When the ON/OFF
toggle in the "Toggle Stuff" table below is clicked, we
perform something similar to a swap image, except instead of swapping
in a new image, we're swapping in the URL to "streamer.asp",
which updates our database. In this way, we can toggle records on
and off without having to refresh the page.
<img src="transparent.gif" name="gifStream" id="gifStream" /> Building
our toggles and tables
On the left hand side, in the Front End table, we're dynamically
writing out our images in a repeat region, so that each ON/OFF graphic
has a unique id, containing our record's ID. In this manner, we
can ensure that when the toggle for record 2 is clicked, that we
swap the right images, and send the right ID to "streamer.asp".
Each time you click the ON/OFF toggle in the Front End table you're
changing the database content. You won't see this change in the
right hand table, because the page has to be refreshed in order
for the database results to be updated. Turn the toggles on and
off a few times for several records, and then refresh the page to
see the result.
Each time you click a toggle, you'll receive a JavaScript alert
showing the URL that's swapped into our gifStream gif floating on
this page. Now, if there are two people on this page, you can both
be affecting the data at the same time, so if you refresh, you're
going to see the last thing submitted to the database, not necessarily
the last thing you submitted to the database.
Both sections are dynamic
| Front End |
Database content (refresh to update) |
|
|
| ID |
bitCheck |
| 1 |
0 |
| 2 |
0 |
| 3 |
0 |
| 4 |
0 |
|
|
|
Here's what the code looks like to create the Front End table.
<table border="1" cellpadding="3" cellspacing="0">
<tr>
<td>ID</td>
<td>Switch</td>
</tr> <% While ((Repeat1__numRows <> 0) AND (NOT rsValues.EOF)) %>
<tr>
<td><%=(rsValues.Fields.Item("ID").Value)%></td>
<td><a href="#" onClick="toggle(<%= rsValues("id") %>);return false">
<% If CInt(rsValues("bitCheck") = 0) Then %>
<img src="on.gif" name="i<%= rsValues("id") %>"
border="0" id="i<%= rsValues("id") %>" />
<% Else %>
<img src="off.gif" name="i<%= rsValues("id") %>"
border="0" id="i<%= rsValues("id") %>" />
<% End If%></a></td>
</tr>
<%
Repeat1__index=Repeat1__index+1
Repeat1__numRows=Repeat1__numRows-1
rsValues.MoveNext()
Wend
%>
</table>
Notice the If statement inside the table cell. If the bitCheck
value is 0, then we write out the "on.gif" image. If it's
1, then we write out the "off.gif" image. Each image is
given an id of "i<%= rsValues("id") %>"
so we can ensure that each image has a unique id to reference in
our JavaScript.
What's our JavaScript doing?
I've heavily commented the following JavaScript file, so that you
can see what's going on as you step through the function. We've
named our toggle images "on.gif" and "off.gif".
The JavaScript searches the SRC attribute of the image for the string
"on" to determine it's status. So far that reason, make
sure that you don't have the string "on" in both image
paths. "passion_on.gif" and "passion_off.gif"
are bad names, as both contain the "on" string.
When the ON/OFF images are clicked, they call the toggle function,
and pass the ID for the record we want to change. That's named myid
in the JavaScript.
<script language="JavaScript" type="text/JavaScript">
<!--
function toggle(myid){
/* The myid value is the ID we're going to pass to streamer.asp
Our on and off images have a unique name based on our record id.
Get it's src attribute */
//("i'+myid+'") = i plus the ID (we wrote that dynamically in our repeat
var imgRef = MM_findObj('i'+myid)
//This is the folder all of our images and our streamer.asp are located in
//Just makes the javascript easier to read and modify.
var RootURL = "http://www.domain.com/"
/* If the image is *currently* on, we need to swap it to off, and set our
database value to 0, if it's off, we switch it to on and set our database
value to 1 */
if(imgRef.src.indexOf("on")>=0){ //If the image is on, do stuff
//Swap out our image
imgRef.src=RootURL+'off.gif';
//Set our new value
var newval = 0;
}else{ //The image wasn't on, so it must be off, do more stuff
//Swap out our image
imgRef.src=RootURL+'on.gif';
//Set our new value
var newval = 1;
}
/*Create a unique seed for our url. This prevents the browser
from caching our URL. Each time the image is clicked a new
url is processed.*/
var TimeSeed = new Date();
//Create our new URL
var myURL = RootURL+"streamer.asp?id="+myid+"&value="+newval+
"×eed="+escape(TimeSeed);
//Swap our new URL into the gifStream's src attribute
MM_findObj("gifStream").src = myURL
//Output an alert for debugging
alert("gifStream.src = " + myURL);
return false;
}
function MM_findObj(n, d) { //v4.01
var p,i,x; if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
if(!x && d.getElementById) x=d.getElementById(n); return x;
}
//-->
</script>
Compressed toggle function without comments:
<script language="JavaScript" type="text/JavaScript">
<!--
function toggle(myid){
var imgRef = MM_findObj('i'+myid)
var RootURL = "http://www.domain.com/"
if(imgRef.src.indexOf("on")>=0){
imgRef.src=RootURL+'off.gif';
var newval = 0;
}else{
imgRef.src=RootURL+'on.gif';
var newval = 1;
}
var TimeSeed = new Date();
var myURL = RootURL+"streamer.asp?id="+myid+"&value="+newval+
"×eed="+escape(TimeSeed);
MM_findObj("gifStream").src = myURL
return false;
}
function MM_findObj(n, d) { //v4.01
var p,i,x; if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
if(!x && d.getElementById) x=d.getElementById(n); return x;
}
//-->
</script>
What's in Streamer.asp?
Now that we've created our URL and passed it to "Streamer.asp",
how do we use it? Just like you would any other querystring variables.
You can build recordset, send an email, update a record, delete
a record or perform any number of server side actions. All you have
to do is pull your values out of the querystring you passed through
the JavaScript. So in our example we're pulling out the value and
the id and using those to update our records.
In our JavaScript, we pass a URL like this:
http://www.domain.com/streamer.asp?id=1&value=0×eed=Fri%20Jul%11 We can then use Request.Querystring("id")
and Request.Querystring("value") to grab the variables
and do an update with them.
<%@LANGUAGE="VBSCRIPT" CODEPAGE="1252"%>
<% Option Explicit %> <!--#include file="Connections/connFile.asp" --> <% Dim rsValues, strSQL
Set rsValues = Server.CreateObject("ADODB.Connection")
rsValues.ConnectionString = MM_conn_STRING
rsValues.Open()
'Build our SQL String for the update
strSQL = "UPDATE tblTesting SET bitCheck = " & CInt(Request.QueryString("value")) &_
" WHERE ID = " & CInt(Request.QueryString("id")) & ";"
'Execute the Update
rsValues.execute strSQL
%>
Customizing the Script
One of the best things about this, is you can customize the javascript
to send just about any value you want, or to use any type of element
for a toggle. In the script below, we've customized it to use checkboxes
instead of images. Not only is it easily understood by clients and
designers alike, but the script is actually quite smaller.
<script language="JavaScript" type="text/JavaScript">
<!--
function toggleCbox(fieldname,myid){
var TimeSeed = new Date();
var RootURL = "http://www.domain.com/"
var myURL = RootURL+"streamer.asp?id="+myid+"&value="+
MM_findObj(fieldname).checked+"×eed="+escape(TimeSeed);
MM_findObj("gifStream").src = myURL;
}
function MM_findObj(n, d) { //v4.01
var p,i,x; if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
if(!x && d.getElementById) x=d.getElementById(n); return x;
}
//-->
</script>
Then to build our checkboxes, we just do something like this:
<input
<% If rsValues("bitCheck") = 0 Then Response.Write("checked") : Response.Write("")%>
type="checkbox"
name="i<%= rsValues("ID") %>"
value="1"
onclick="toggleCbox(this.name,'<%=rsValues("ID")%>');" />
Both sections are dynamic
| Front End |
Database content (refresh to update) |
|
|
| ID |
bitCheck |
| 1 |
0 |
| 2 |
0 |
| 3 |
0 |
| 4 |
0 |
|
|
|
Each time the checkbox is clicked, it passes the checkbox name
(this.name) as well as the id of the record we want to change. Then
our function simply checks for the current value of the checkbox
(1 if it's checked, 0 if it's not) and sends the appropriate URL.
|