follow me
Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Drag and Drop in javascript, and Save persisting position using ASP.net

Drag and Drop are one of the few jQuery's UI Library. jQuery UI provides abstractions for low-level interaction and animation, advanced effects and high-level, themeable widgets, built on top of the jQuery JavaScript Library, that you can use to build highly interactive web applications.

To make use of Draggables, you need to download the UI library and then use the ui.core and ui.draggable files along with jquery:


<script src="script/jquery-1.3.1.min.js" type="text/javascript"></script>
<script src="script/ui.core.min.js" type="text/javascript"></script>
<script src="script/ui.draggable.min.js" type="text/javascript"></script>

There are lots of demos you can see in some site about this drag and drop interactions of the elements but i think only few can give on how to save the persisting position of the dragged item across Postbacks, or even sessions.

So we need to have a simple example of asp.net form.


<form id="form1" runat="server">
<div id="div1" style="border: 1px solid blue; text-align: center; width: 100px; height: 20px;">
Move this text
</div>
</form>


Basically it looks like this:



The Javascript that makes the div draggable:


<script type="text/javascript">
$(function() {
$("#div1").draggable({
drag: function(event, ui) {
$("#div1").css("opacity", "0.6"); // Additional css. Transparency when drag.
},
stop: function(event, ui) {
saveCoords(ui.absolutePosition.left, ui.absolutePosition.top, ui.helper.attr('id'));
$("#div1").css("opacity", "1.0"); // Additional css. Full opacity when stopped
},
cursor: "move"
});
});
</script>


Take a look on the stop callback event a saveCoords() function will be called with 3 arguments are supplied: the x coordinate, y coordinate and the id of the current draggable - ui.helper.attr('id'). And here what that function does:


function saveCoords(x, y, el, id) {

$.ajax({
type: "POST",
url: "Coordinates.asmx/SaveCoords", // the function inside the handler
data: "{x: '" + x + "', y: '" + y + "', element: '" + el + "', userid: '1'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(response) {
if (response.d != '1') {
alert('Not Saved!');
}
},
error: function(response) {
alert(response.responseText);
}
});
}


This function makes a call to a Web Service called Coordinates, invoking its method, [url:]SaveCoords(). It passes [data:] in the x and y coordinates, the id of the element and a user ID (hardcoded for thos example, bit could be provided by a session variable, for instance). Here's the Web Service:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Script.Services;
using System.Data.SqlClient;
using System.Data;

///
/// Summary description for Coordinates
///
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

//[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]

[ScriptService]
public class Coordinates : WebService
{
private String conString = System.Configuration.ConfigurationManager.ConnectionStrings["dragCon"].ConnectionString;

[WebMethod]
public int SaveCoords(int x, int y, string element, int userid)
{
int result = 0;
using (SqlConnection conn = new SqlConnection(conString))
{
string query = "UPDATE Coords SET xPos = @xPos, yPos = @yPos WHERE Element = @Element AND UserID = @UserID";
using (SqlCommand cmd = new SqlCommand(query, conn))
{
cmd.Parameters.AddWithValue("xPos", x);
cmd.Parameters.AddWithValue("yPos", y);
cmd.Parameters.AddWithValue("Element", element);
cmd.Parameters.AddWithValue("UserID", userid);
conn.Open();
result = (int)cmd.ExecuteNonQuery();
}
}
return result;
}


Note: in this sample i already had a database Drag in my server and a table name Coords with four fields xPos, yPos, Element and a UserID.

The WebMethod simply takes the arguments passed to it and saves them to the database. It returns the number of rows affected for error checking. Great. So the position of the element is saved. How does that get translated to a draggable being positioned where it was left when the page is next requested by the user with the ID of 1? We need another Web Method:


[WebMethod]
public DataSet GetSavedCoords(int userid)
{
DataSet dt = new DataSet();

string query = "SELECT xPos, yPos, Element FROM Coords WHERE UserID = '" + userid + "'";
SqlConnection con = new SqlConnection(conString);
SqlCommand cmd = new SqlCommand(query, con);
con.Open();

SqlDataAdapter sda = new SqlDataAdapter(cmd);
sda.Fill(dt);

return dt;
}


Taking the User ID as an argument, this method returns a DataSet filled with the positions of all elements saved against the user, and it is invoked in the Page_Load() event in the Code Behind:


protected void Page_Load(object sender, EventArgs e)
{
Coordinates coords = new Coordinates();
DataSet dt = coords.GetSavedCoords(1);
using(DataTableReader reader = dt.CreateDataReader())
{
while (reader.Read())
{
HtmlGenericControl ctl = (HtmlGenericControl)this.FindControl(reader["element"].ToString());
if (ctl != null)
{
ctl.Style.Add("left", reader["xPos"].ToString() + "px");
ctl.Style.Add("top", reader["yPos"].ToString() + "px");

}
}
}
}



The Web Service class is instantiated and its GetSavedCoords() method is called. For each row in the returned DataSet, an element on the page is sought with the same id as one saved in the database. If it is found, it has a dash of CSS applied to it through Attributes.Add(). These set the CSS top and left values. When the page is rendered again, the text is exactly where it was left last time.

-
Read More...

Creating a Captcha image

This time I will talk about a simple captcha image. This will prevent some automated scripts that will spam your registration area in you website, or if you have some comments area in the page.

An overview of the output will be, you will see an image in some part of the page and you will type the text you see in the image in order for you too complete what you are doing.

You need to use the Drawing Assemblies.


using System.Drawing;
using System.Drawing.Text; //for styling fonts
using System.Drawing.Imaging; // for rendering the background


The drawing assemblies are very important because we will draw some random images programmatically.

Now you will need to have a separate page or save it to an image file for the captcha. We will talk about this later.

On the page load event handler of the page, you will have to define the captcha image. The safest way I know is to have a Web user control and place the code inside the page load of the user control and place the user control in any part of the main page. The user control that you place your code shall not have any other controls to prevent disfiguration of the main page.

Ok, on the Page_Load event handler on your user control, you have to initialize the Bitmap.

 
protected void Page_Load(object sender, EventArgs e)
{
// define the Bitmap image with its size.
Bitmap b = new Bitmap(60, 20);
// create a graphics from the initialized bitmap.
Graphics g = Graphics.FromImage(b);
//creates a background color of the image.
g.Clear(Color.Blue);
g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;

// ~following codes will be here.
}


You already have initiallize your image. Next is to generate a random alphanumeric characters on the image you just created.



Font f = new Font("Verdana", 8, FontStyle.Bold); // creates an instance of font you will be using.
string randomStr = "";

// initialize all the alphanumeric characters that can be generated on the fly.
string[] str = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q",
"R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h",
"i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y",
"z", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" };

//generate 5 random alphanumeric characters or depends on how many character you want
Random ar = new Random();

for(int i=0;i$lt;5;i++)
{
string rn = str[ar.Next(0, 62)];
// (0, 62) this means that it will get a random character from str from first character
// to the last and there are 62 characters in all

randomStr += rn; // stack up to randomStr the random characters choosen.
}

g.DrawString(randomStr, f, Brushes.White, 3, 3); // Draw the text to the image.
Response.ContentType = "image/GIF"; // set the image type to GIF.

// save the image into your server path with the filename.
b.Save(Server.MapPath("captcha.gif"), ImageFormat.Gif);



This time you have your alphanumeric characters generated and drawn into the image for later comparison. How can I compare an imge from a text?

Here's how. Remember we stack up the generated random characters into the variable randomStr right? You'll just need to add that string to a session or a cookie. I use session for this example.


// add the randomStr value to a session named "randomStr".
Session.Add("randomStr", randomStr);


Now we're done.

In order to compare the captcha image versus the text the user enters is you have to get the Session value of randomStr.


if(Session["randomStr"].ToString() == txtCaptcha.Text)
{
// your code goes here
}


And here's the complete code.



using System.Drawing;
using System.Drawing.Text; // you need this so you can style your fonts
using System.Drawing.Imaging; // you need this so you can do rendering the background

...

protected void Page_Load(object sender, EventArgs e)
{
Bitmap b = new Bitmap(60, 20); // define the Bitmap image with its size.
Graphics g = Graphics.FromImage(b); // create a graphics from the initialized bitmap.
g.Clear(Color.Blue); // creates a background color of the image.
g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;

Font f = new Font("Verdana", 8, FontStyle.Bold); // creates an instance of font you will be using.
string randomStr = "";

// initialize all the alphanumeric characters that can be generated on the fly.
string[] str = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q",
"R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h",
"i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y",
"z", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" };

// generate 5 random alphanumeric characters
Random ar = new Random();
for(int i=0;i$lt;5;i++)
{
string rn = str[ar.Next(0, 62)];
// (0, 62) this means that it will get a random character from str from first character
// to the last and there are 62 characters in all

randomStr += rn; // stack up to randomStr the random characters choosen.
}

g.DrawString(randomStr, f, Brushes.White, 3, 3); // Draw the text to the image.
Response.ContentType = "image/GIF"; // set the image type to GIF.
b.Save(Server.MapPath("captcha.gif"), ImageFormat.Gif); // save the image into your server path with the filename.
Session.Add("randomStr", randomStr); // add the randomStr value to a session named "randomStr".

// destroys the objects created
f.Dispose();
g.Dispose();
b.Dispose();
}





ciao

Read More...