|
Building an Email Application with Flash MX and ASP.NET -- by Brandon Ellis
**please note that this image is a code-continuation arrow... meaning the code on the line below is meant to reside on the same line when you type it in.** You can download the associated source files at the bottom of this page.
If anyone asked, 'What was the internet built for?' the obvious answer
is - communication. That said, one of the simplist applications to build using
asp.net and Flash is a mail client.
Now, let's will take a quick look at the code used in building the email application.
<%@ Import NameSpace="System.Web.Mail" %>
<script language="C#" runat="server">
public MailMessage oMail;
protected void page_load(Object Sender, EventArgs e){
if (Request.HttpMethod == "POST"){
Response.Write(sendMail());
}
}
protected string sendMail(){
strMsg = "You have received an email from " + Request.Form["name"];
strMsg += "\n\n" + Request["msg"];
oMail = new MailMessage();
oMail.To = "edeveloper@hotmail.com";
oMail.From = Request.Form["email"];
oMail.Subject = Request.Form["subject"];
oMail.Body = strMsg;
SmtpMail.Send(oMail);
return "sent=true";
}
</script>
That's pretty simple. Let's break the code up into a couple of smaller sections
and see what is going on:
<%@ Import NameSpace="System.Web.Mail" %>
<script language="C#" runat="server">
public MailMessage oMail;
protected void page_load(Object Sender, EventArgs e){
if (Request.HttpMethod == "POST"){
Response.Write(sendMail());
}
}
System.Web.Mail is the namespace that we are using.
Next is the opening script tag declaring the language we are using as C# and
telling the server to run this code - on the server. Underneath, this is where
we declare that we are going to be using an instance of the MailMessage class
to the send email.
"page_load" - This is the function that fires when the page
loads and calls any function nested inside of it to fire as well.
since the function inside of the page_load event will fire when the page
loads, we want to make sure that the user wants this function to run. Here,
we are telling the server to only run this function if the Request object
property "HttpMethod" is equal to "POST". This means that
unless the form is submitted from the Flash movie using "POST" as
the sending method from the LoadVars() class (we'll talk about that in a minute),
the event will not fire when the page loads.
Response.Write() is used to write out the returning value of the function.
If this looks unfamiliar to you, peak down to the end of the sendmail function
and look at the return value. Basically, what this is doing is telling the
function to return this string when the function has run.
Next is the function that creates the email (sendMail()):
First we build the message that will be the body of the email. It starts
out with "You have received and email from" and then adds the value
of the "name" field from the Flash form. Next we add a couple of
line breaks and the message from the Flash form. Next we create a new instance
of the MailMessage class that is being used to send the email. The To, From,
Subject and Body properties of "oMail", are then assigned the values
from the Flash form.
Last, we call the "smtpMail" class and use the "send" property to send
off the email and assign "sent=true" to be the returned value of
the sendMail() function.
protected string sendMail(){
strMsg = "You have received an email from " + Request.Form["name"];
strMsg += "\n\n" + Request.Form["msg"];
oMail = new MailMessage();
oMail.To = "edeveloper@hotmail.com";
oMail.From = Request.Form["email"];
oMail.Subject = Request.Form["subject"];
oMail.Body = strMsg;
SmtpMail.Send(oMail);
return "sent=true";
}
</script>
It's fairly simple how the email client is created by calling an instance
of the MailMessage class and assigning values to it's built in properties
and methods. Now let's take a look at the Flash section of this application.
After opening Flash MX, you will only need one frame to create the entire
Flash part of the is application. The textfield, text labels, buttons, backgrounds
- everything is created at runtime using actionscript. While creating the
Flash part in this manner is not necessary, I think it helps to build a deeper
understanding and appreciation of ActionScript and what can be accomplished.
I have also omitted the error checking functions since they are outside the
scope of this article and are fully commented in "send_mail.fla".
The application is made up of a background shape, five textfields (name, subject,
email address, the email message and the status), a smaller shape used as
a submit button, and four textfields that are the labels for the input fields.
Here is the ActionScript used to create the Flash part of this application:
/////////////////////////////////////////////////////////////////////////
// global styles
/////////////////////////////////////////////////////////////////////////
tStyle_fmt = new TextFormat();
tStyle_fmt.font = "verdana";
tStyle_fmt.size = 10;
tStyle_fmt.color = parseInt("ffffff",16);
/////////////////////////////////////////////////////////////////////////
// functions to create the movie elements
/////////////////////////////////////////////////////////////////////////
function make_bg(){
_root.createEmptyMovieClip("bg",-2);
with(_root.bg){
this.moveTo(0,0);
this.beginFill(0x336699,100);
this.lineTo(0,250);
this.lineTo(350,250);
this.lineTo(350,0);
this.endFill();
}
}
function makeTextBox(n,d,x,y,w,h,m,wr,s){
/*
n : name
d : depth
x : x pos
y : y pos
w : width
h : height
m : multiline
wr : wordwrap
s : scrollable
*/
_root.createTextField(n,d,x,y,w,h);
_root[n].border = true;
_root[n].borderColor = parseInt("333333",16);
_root[n].type = "input";
_root[n].background = true;
_root[n].backgroundColor = parseInt("284E75",16);
_root[n].multiline = m;
_root[n].wordWrap = wr;
_root[n].setNewTextFormat(tStyle_fmt);
}
function makeTextLabel(n,d,t,l){
/*
n : name
d : depth
t : name of the textfield that this is a label for
l: the text label
*/
_root.createTextField(n,d,_root[t]._x,_root[t]._y-15,10,14);
_root[n].border = false;
_root[n].variable = l;
_root[n].type = "dynamic";
_root[n].autoSize = "left";
_root[n].text = l;
_root[n].setTextFormat(tStyle_fmt);
}
function make_button(){
var lbl_x = 10;
var lbl_y = 210;
_root.createEmptyMovieClip("button_mc",-1);
with(_root["button_mc"]){
moveTo(10,210);
beginFill(0x284E75,100);
lineStyle(.5,333333,100)
lineTo(10,227);
lineTo(60,227);
lineTo(60,210);
endFill();
}
_root["button_mc"].onPress = function (){
this._x++;
this._y++;
}
_root["button_mc"].onRelease = function (){
this._x--;
this._y--;
if (!sent){
chkFrm();
} else {
getURL("javascript:document.location = this.location.href;","_self");
}
}
_root["button_mc"].onReleaseOutside = function (){
this._x--;
this._y--;
}
_root["button_mc"].createTextField
("button_lbl",-1,lbl_x,lbl_y,_root["button_mc"]._width,14);
_root["button_mc"]["button_lbl"].text = "Submit"
_root["button_mc"]["button_lbl"].autoSize = "center";
_root["button_mc"]["button_lbl"].setTextFormat(tStyle_fmt);
}
function make_TextFields(){
makeTextBox("name_txt",1,10,20,200,16);
makeTextLabel("name_lbl",2,"name_txt","Name:");
makeTextBox("subject_txt",3,10,60,200,16);
makeTextLabel("subject_lbl",4,"subject_txt","Subject:");
makeTextBox("email_txt",5,10,100,200,16);
makeTextLabel("email_lbl",6,"email_txt","Email:");
_root["email_txt"].restrict = "a-z,A-Z,0-9,@,\\-,.";
makeTextBox("msg_txt",7,10,140,300,60,true,true);
makeTextLabel("msg_lbl",8,"msg_txt","Message:");
makeTextBox("status_txt",9,110,210,200,16);
_root["status_txt"].text = "Status: Waiting to send mail...";
////////////////////////////////////////////////////////////
// thanks to Guy Watson - www.flashguru.co.uk //
// this code dynamically attachs a component to an object //
////////////////////////////////////////////////////////////
initialization={_targetInstanceName:"msg_txt",horizontal:false};
_root.attachMovie("FScrollBarSymbol","myScrollbar",10,initialization);
myScrollBar._x=msg_txt._width+11;
myScrollBar._y=msg_txt._y;
myScrollBar.setSize(msg_txt._height);
////////////////////////////////////////////////////////////
}
///////////////////////////////////////////////////////////////////////////
// error checking functions
///////////////////////////////////////////////////////////////////////////
**** this is where the error checking functions are
location in "send_mail.fla" ****
if (err == 0){
get_results();
}
}
function get_results(){
_root["status_txt"].text = "Status: Sending Mail...";
get_results_lv = new LoadVars();
get_results_lv.name = name_txt.text;
get_results_lv.subject = subject_txt.text;
get_results_lv.email = email_txt.text;
get_results_lv.msg = msg_txt.text;
get_results_lv.onLoad = function(success){
if (success){
_root["status_txt"].text = "Status: Mail Sent.";
} else {
_root["status_txt"].text = "Status: The mail could not be sent.";
}
}
get_results_lv.sendAndLoad("process.aspx",this.get_results_lv,"POST");
reset();
sent = true;
}
function reset(){
_root["name_txt"].text = "";
_root["subject_txt"].text = "";
_root["email_txt"].text = "";
_root["msg_txt"].text = "";
_root["button_mc"]["button_lbl"].text = "reset";
_root["button_mc"]["button_lbl"].setTextFormat(tStyle_fmt);
}
///////////////////////////////////////////////////////////////////////////
function init(){
make_bg();
make_TextFields();
make_button();
}
init();
Just as above, let's break this up into smaller sections to see what is going
on.
/////////////////////////////////////////////////////////////////////////
// global styles
/////////////////////////////////////////////////////////////////////////
tStyle_fmt = new TextFormat();
tStyle_fmt.font = "verdana";
tStyle_fmt.size = 10;
tStyle_fmt.color = parseInt("ffffff",16);
As the comment states, we are setting the base styles that will be used through
out this application. First things first, we create a new instance of the TextFormat()
class named tStyle_fmt. The font will be set to "Verdana", the initial
font size will be set to 10 and the font color is set to white.
/////////////////////////////////////////////////////////////////////////
// functions to create the movie elements
/////////////////////////////////////////////////////////////////////////
function make_bg(){
_root.createEmptyMovieClip("bg",-2);
with(_root.bg){
this.moveTo(0,0);
this.beginFill(0x336699,100);
this.lineTo(0,250);
this.lineTo(350,250);
this.lineTo(350,0);
this.endFill();
}
}
This is the function creating our background for the Flash email application.
We start by first creating an empty movieclip to hold the shape. we fill it
a blue (#336699). The lineTo() function is kinda like playing "connect
the dots" by establishing x,y coordinates and "drawing" a line
from one point to the next.
function makeTextBox(n,d,x,y,w,h,m,wr,s){
/*
n : name
d : depth
x : x pos
y : y pos
w : width
h : height
m : multiline
wr : wordwrap
s : scrollable
*/
_root.createTextField(n,d,x,y,w,h);
_root[n].border = true;
_root[n].borderColor = parseInt("333333",16);
_root[n].type = "input";
_root[n].background = true;
_root[n].backgroundColor = parseInt("284E75",16);
_root[n].multiline = m;
_root[n].wordWrap = wr;
_root[n].setNewTextFormat(tStyle_fmt);
}
This function creates the textboxes used to send the form variables that make
up the email. The variables that are passed into this function are: name -
the textfield instance name, depth - depth of this textfield instance, the
x position, the y position, the textfield's width, the height, whether or
not it is a multiline textfield and whether or not it has word wrapping .
These variable and their values are then assigned to the textfields properties.
Last, we apply the global styles to the textfields.
function makeTextLabel(n,d,t,l){
/*
n : name
d : depth
t : name of the textfield that this is a label for
l: the text label
*/
_root.createTextField(n,d,_root[t]._x,_root[t]._y-15,10,14);
_root[n].border = false;
_root[n].variable = l;
_root[n].type = "dynamic";
_root[n].autoSize = "left";
_root[n].text = l;
_root[n].setTextFormat(tStyle_fmt);
}
This function operates exactly as makeTextBox() except it's making the labels
that will identify each textfield for the user. The only other thing to note
is that we are using the variable "t" to specify each instance of
the textfield that the label is being used for. That way we can reference
the x and y properties of each textfield.
function make_button(){
var lbl_x = 10;
var lbl_y = 210;
_root.createEmptyMovieClip("button_mc",-1);
with(_root["button_mc"]){
moveTo(10,210);
beginFill(0x284E75,100);
lineStyle(.5,333333,100)
lineTo(10,227);
lineTo(60,227);
lineTo(60,210);
endFill();
}
_root["button_mc"].onPress = function (){
this._x++;
this._y++;
}
_root["button_mc"].onRelease = function (){
this._x--;
this._y--;
if (!sent){
chkFrm();
} else {
getURL("javascript:document.location = this.location.href;","_self");
}
}
_root["button_mc"].onReleaseOutside = function (){
this._x--;
this._y--;
}
_root["button_mc"].createTextField
("button_lbl",-1,lbl_x,lbl_y,_root["button_mc"]._width,14);
_root["button_mc"]["button_lbl"].text = "Submit"
_root["button_mc"]["button_lbl"].autoSize = "center";
_root["button_mc"]["button_lbl"].setTextFormat(tStyle_fmt);
}
It's pretty easy to tell what the make_button() function does and which button
it makes (since there is only one). We use the concept of making a shape and
filling it with color like we did with the background except this one uses
another function called lineStyle that will create a stroke around the shape.
The one we are using is a .5 pixel line that is a very dark grey. Now that
we have a shape with the instance name "button_mc", we need to assign
some events to it. first function (_root["button_mc"].onPress),
do nothing but simulate pressing a button down. This is accomplished by resetting
the x and y postions of the button clip down two pixels and over to pixels.
The next function (_root["button_mc"].onRelease), does a little
more. First it moves the button back to its original position - simulating
a button being depressed. Second, if the variable "sent" (which
we will get to in a moment) is not true then call the chkFrm() validation
function to make sure the form is filled with the information we want. But,
if sent is equal to true then call the javascript to refresh the form and
any cached variables. The last button event (_root["button_mc"].onReleaseOutside)
simulates the button being depressed if the user releases the button outside
of the button area.
Lastly, we create a textfield that serves as the submit button's label and
the style formatting is applied.
function make_TextFields(){
makeTextBox("name_txt",1,10,20,200,16);
makeTextLabel("name_lbl",2,"name_txt","Name:");
makeTextBox("subject_txt",3,10,60,200,16);
makeTextLabel("subject_lbl",4,"subject_txt","Subject:");
makeTextBox("email_txt",5,10,100,200,16);
makeTextLabel("email_lbl",6,"email_txt","Email:");
_root["email_txt"].restrict = "a-z,A-Z,0-9,@,\\-,.";
makeTextBox("msg_txt",7,10,140,300,60,true,true);
makeTextLabel("msg_lbl",8,"msg_txt","Message:");
makeTextBox("status_txt",9,110,210,200,16);
_root["status_txt"].text = "Status: Waiting to send mail...";
////////////////////////////////////////////////////////////
// thanks to Guy Watson - www.flashguru.co.uk //
// this code dynamically attachs a component to an object //
////////////////////////////////////////////////////////////
initialization={_targetInstanceName:"msg_txt",horizontal:false};
_root.attachMovie("FScrollBarSymbol","myScrollbar",10,initialization);
myScrollBar._x=msg_txt._width+11;
myScrollBar._y=msg_txt._y;
myScrollBar.setSize(msg_txt._height);
////////////////////////////////////////////////////////////
}
make_TextFields() serves as a wrapper for the individual makeTextfield() and
makeTextLabel() functions. The function's purpose is to create all the textfields
and text labels. Next there is a code snippet courtesy of Guy Watson that
dynamically attaches a scroll bar instance to a textfield.
///////////////////////////////////////////////////////////////////////////
// error checking functions
///////////////////////////////////////////////////////////////////////////
**** this is where the error checking functions are
location in "send_mail.fla" ****
if (err == 0){
get_results();
}
}
function get_results(){
_root["status_txt"].text = "Status: Sending Mail...";
get_results_lv = new LoadVars();
get_results_lv.name = name_txt.text;
get_results_lv.subject = subject_txt.text;
get_results_lv.email = email_txt.text;
get_results_lv.msg = msg_txt.text;
get_results_lv.onLoad = function(success){
if (success){
_root["status_txt"].text = "Status: Mail Sent.";
} else {
_root["status_txt"].text = "Status: The mail could not be sent.";
}
}
get_results_lv.sendAndLoad("process.aspx",this.get_results_lv,"POST");
reset();
sent = true;
}
The get_results() function is where we get all the form variables and
send them to process.aspx where they are used to create the email. First
thing is to change the status message to read "Sending Mail...".
Now we create a new instance of the LoadVars() class named get_results_lv
and assign the form variables to get_results_lv properties that will go
to the email. Next we assign a function to the "onLoad" event
when we receive a reply from the server. If the reply is success then change
the status message to read "Mail Sent.". Otherwise change the
status message to read "The mail could not be sent.". And now,
underneath the function is where we use the "sendAndLoad()" method
of the LoadVars() class to send the form variables and wait to receive a
reply from the server. After all that, we call the reset function that we
will talk about next and set the variable "sent" equal to true.
This will toggle the what the submit button is supposed to do (instead of
the submit button calling the chkFrm() validation function, the button will
call the javascript to reset the page).
Remember, the error checking functions are not covered in this article but
are fully documented in the send_mail.fla file and will not be covered here.
function reset(){
_root["name_txt"].text = "";
_root["subject_txt"].text = "";
_root["email_txt"].text = "";
_root["msg_txt"].text = "";
_root["button_mc"]["button_lbl"].text = "reset";
_root["button_mc"]["button_lbl"].setTextFormat(tStyle_fmt);
}
The reset() function is very simple. It sets the variable values back to empty
strings and changes the submit button text to read "reset" instead
of "submit".
function init(){
make_bg();
make_TextFields();
make_button();
}
init();
Lastly, the init() function is used to call all the other functions to create
the elements of our page. That's it. Happy Programming!
You can reach Brandon by email.
Download the source files here.
|