Dynamically add options to dropdown list using jQuery

This post is going to be a fun little exercise, and is a technique that used to carry some overhead (in terms of postbacks and viewstate) back in the day. The objective is to provide users with a dropdownlist containing pre-selected options – but allow them to add their own options, and persist those options back to the database.

Ingredients:
1 – dropdownlist
1 – textbox
2 – divs
3 – links
3 – jquery functions
1 – controller method

First we will create our html form. So far there is nothing controversial here, we are simply creating one div to hold the dropdownlist and the “add” link, and another div to hold the textbox and save/cancel links. To keep it simple, we are going to make this a color list:

<div id="FavoriteColorsList">
<select name="FavoriteColor" id="FavoriteColor" style="width:350px;">
<option value=""> Choose your favorite color</option>
<option value="Red">Red</option>
<option value="Blue">Blue</option>
<option value="Green">Green</option>
</select>
<a href="#" onclick="AddCustomFavoriteColor(); return false;">add my color</a>
</div>

<div id="CustomFavoriteColorform" style="display:none;">
<input type="text" id="CustomFavoriteColor" name="customFavoriteColor" style="width:250px;">&nbsp;&nbsp;
<a href="#" onclick="SaveCustomFavoriteColor(); return false;">save</a>&nbsp;&nbsp;
<a href="#" onclick="CancelCustomFavoriteColor(); return false;">cancel</a>
</div>

The expected behavior is to show the dropdown initially, and then once the user clicks the “add my color” link, to hide the dropdown div, and then display the textbox div. To make this happen, we have three jquery functions that are called from the links:


function AddCustomFavoriteColor() {
    $("#FavoriteColorsList").hide("fast");
    $("#CustomFavoriteColorform").show("fast");
    $("#CustomFavoriteColor").val("");
    $("#CustomFavoriteColor").focus();
}

function CancelCustomFavoriteColor() {
    $("#CustomFavoriteColor").val("");
    $("#FavoriteColorsList").show("fast");
    $("#CustomFavoriteColorform").hide("fast");
}

function SaveCustomFavoriteColor() {
    var opt = "<option value='" + $("#CustomFavoriteColor").val() + "'>" + $("#CustomFavoriteColor").val() + "</option>";

    $('#FavoriteColor').append(opt)
    $("#FavoriteColor").val($("#CustomFavoriteColor").val());

    $.post("/[YOUR-CONTROLLER]/[YOUR-METHOD]", { FavoriteColor: $("#CustomFavoriteColor").val() },
        function(data) {
            $("#CustomFavoriteColor").val("");
            $("#FavoriteColorsList").show("fast");
            $("#CustomFavoriteColorform").hide("fast");
        });
}

The last part is the server-side code to persist the saved value to the database. That is where you need to make sure you have some level of security, ideally something greater than what citibank rolled out.

Below is a video clip of the code in action:

July 23 / 2011
Author bill sternberger
Category Html, jquery
Comments 1 Comment

Store images on Flickr using Flickrnet.dll and ASP.NET MVC

For one of my recent projects I had to use Flickr as an image repository, so this code just shows how I was able to do that with the help of the fantastic Flickrnet.dll library. You can download the latest Flickrnet library here: http://flickrnet.codeplex.com/. You can also download the article’s full working Flickr demo code.

Getting Started

Before we dive into the MVC portion, you have to make sure you have installed the flickrnet.dll file, referenced it, and added the appropriate web.config elements.

configSections element

Append the following element after the default sectionGroup:
<section name="flickrNet" type="FlickrNet.FlickrConfigurationManager,FlickrNet"/>

And setup your database connection strings

Flickrnet element

Add the following element before the appSettings element:
<flickrNet apiKey="YOUR_API_KEY" secret="YOUR_SECRET" cacheDisabled="true"/>

appSettings element

Add the following keys to the appSettings element:

<add key="FlickrAuthtoken" value="YOUR_FROB/TOKEN" />
<add key="FlickrUserId" value="YOUR_USERID"/>


Click on the thumbnail for a larger view


That is all you need to do in web.config. You get your apikey and secret through flickr. An awesome article off the flickrnet.codeplex site covers how to get your FROB/Token: http://blogs.msdn.com/coding4fun/archive/2006/11/22/1126978.aspx.

Database Setup

The images are going to be uploaded to Flickr, but we are going to keep references to the images in the database for later retrieval. Here is the table script if you are using MySQL:

CREATE TABLE  `sampledb`.`Image` (
  `ImageID` int(11) NOT NULL AUTO_INCREMENT,
  `ImageURL` varchar(250) DEFAULT NULL,
  `Tags` varchar(150) DEFAULT NULL,
  `FlickrID` varchar(50) DEFAULT NULL,
  `ImageURLThumbnail` varchar(250) DEFAULT NULL,
  PRIMARY KEY (`ImageID`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;

or if you are using SQL Server:

CREATE TABLE  [SampleDB].[dbo].[Image] (
  ImageID int NOT NULL IDENTITY,
  ImageURL varchar(250) DEFAULT NULL,
  Tags varchar(150) DEFAULT NULL,
  FlickrID varchar(50) DEFAULT NULL,
  ImageURLThumbnail varchar(250) DEFAULT NULL,
  PRIMARY KEY (ImageID)
);

Once the database is setup, all we have left is the code for uploading, storing, and retrieving the images.

Uploading Images into Flickr

This part is easier than you think. We start out with a typical upload form. For this sample we are going to only have a file input control and a textbox to store our tags:

<form method="post" enctype="multipart/form-data" id="form1" action="/Home/Index">  
        <b>Image</b><br />        
        <input type="file" name="NewImageName" id="NewImageName" />
        <br /><br />        
        <b>Tags</b><br />
        <input type="text" name="NewImgTags" id="NewImgTags" />
        <br />                
        <input type="submit" value="Upload" />
    </form>

Nothing controversial there, moving on to the controller is where we find the meat. The first thing the controller needs is a reference to the Flirckrnet.dll and to System.Configuration, so you add your using statements:

using FlickrNet;
using System.Configuration;

Next up is creating the Index post method. Here, we reference the Flickrnet object and upload the photo. At this point, Flickr takes the image, and depending upon the size and dimensions, will resize it into any of five different sizes: square, thumbnail, small, medium, and large.

We then loop through the different sizes Flickr sends back, and store the thumbnail and large image urls into our table. Below is part of the controller method that uploads the image, and then loops through the sizes. You can download a full working sample here.

var flickr = new Flickr
{
    AuthToken = ConfigurationManager.AppSettings["FlickrAuthtoken"]
};

//
//  Upload the image, title, tags, security settings
//
var flickr_id = flickr.UploadPicture(file.InputStream, ImageTitle, ImageDescription, ImageTags, IsPublic,IsFamily,IsFriends);

//
//  Loop through links to resized images up on flickr
//  and store in the database
//
var flickrPhotos = flickr.PhotosGetSizes(flickr_id);

Image newImage = new Image();
newImage.FlickrID = flickr_id.ToString();

//
//  I only care about the thumbnail and the large image, but
//  you can store all of them (when applicable)
//
for (int i = 0; i < flickrPhotos.SizeCollection.Length; i++)
{
    switch (flickrPhotos.SizeCollection[i].Label)
    {
        case "Square":
            break;
        case "Thumbnail":
            newImage.ImageURLThumbnail = flickrPhotos.SizeCollection[i].Source;
             break;
        case "Small":
             break;
        case "Medium":
             break;
        case "Large":
             newImage.ImageURL = flickrPhotos.SizeCollection[i].Source;  
             ViewData["NewUrl"] = flickrPhotos.SizeCollection[i].Source;
             break;
    }
}

newImage.Tags = ImageTags;
newImage.CreateAndFlush();  

The code sample then sends the large image url from Flickr back down to the browser to preview. Below is a video of the code in action:

March 30 / 2010
Author bill sternberger
Category ASP.NET MVC, C#
Comments 5 Comments

Update textbox with ASP.NET, MVC, jQuery

This post arrives to you today from the awesome Hotel Dunn Inn in beautiful San Jose, Costa Rica! Best. Beds. Ever. It was time to clear the brain and work on some pet projects, and of course code.

In this sample we will look at updating values in textboxes, and then notifying the user of the results. The scenario would be having an Excel-style grid where the user can tab from field to field saving cell values with the onchange event.

Adding References

For this exercise, you just need a reference to the jquery library:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>   
1

<h2>Setting up the Html Form</h2>
We are going to add three textboxes--each with an onchange event--along with a div to hold the result. In real life, the 1, 2, and 3 values would be the item IDs.

1
    <div id="resultmessage" style="width:550px;"></div>    
    Textbox 1<br />
    <input type="text" name="textbox1" id="textbox1" onchange="Update('1',this.value);" />
    <br /><br />    
    Textbox 2<br />
    <input type="text" name="textbox2" id="textbox2" onchange="Update('2',this.value);" />
    <br /><br />    
    Textbox 3<br />
    <input type="text" name="textbox3" id="textbox3" onchange="Update('3',this.value);" />
    <br /><br />

Whenever a user tabs off each box, it will trigger and update to the database. To do that, we add a jQuery function. The function is simple:

  • Use jQuery $.post to send the text change to your controller method
  • Check the result from the controller
  • Display the success or error message

Below is the entire function:

function Update(id, val) {
            $.post("/ControllerName/UpdateTextbox",
            {
                ID: id,
                Value: val
            },
            function(data) {
                <div style='color:blue;'>var myObject = eval('(' + data + ')');
                var saveresult = myObject;</div>
                if (saveresult != "") {
                    $("#resultmessage").html("<div style='display:block; background-color: Red; color: White; font-size: 18px; font-weight: bold; padding: 10px 10px 10px 10px;'>Oops! " + saveresult)
                    $("#resultmessage").show('slow');
                    setTimeout("$('#resultmessage').hide('slow');", 2500);
                }
                else {
                    $("#resultmessage").html("<div style='display:block; background-color: Green; color: White; font-size: 18px; font-weight: bold; padding: 10px 10px 10px 10px;'>Saved!")
                    $("#resultmessage").show('slow');
                    setTimeout("$('#resultmessage').hide('slow');", 2500);
                }
            });
        }

The final piece is a method in a controller–which is pretty vanilla–with one minor twist: instead of an ActionResult, we are going to use a JsonResult:

    public JsonResult UpdateTextbox(string ID, string Value)
    {
        //This is where you would update the database
        string result = (Value.ToLower().StartsWith("r")) ? "ID doesn't exist" : "";
        return Json(result);
    }

Below is a little video clip of the sample in action.

March 05 / 2010
Author bill sternberger
Category ASP.NET MVC, jquery
Comments No Comments

Check username availability with jQuery, ASP.NET MVC, C#

This post shows how to add dynamic username availability lookup to an ASP.NET MVC view, using jQuery and C#. There are three parts to the solution: the html form, jQuery function, and the controller.

Html form

This part is pretty simple: a textbox for the username field with an onchange event, a div to hold the lookup results, and a lookup button.

    <h3>Username</h3>
    <%= Html.TextBox("Username", "", new { @onchange = "CheckAvailability()" })%>
    <div style="display:inline;" id="usernamelookupresult"></div><br/>
    <input type="button" value="Check Availability" onclick="CheckAvailability()" />
</code>

jQuery Username Lookup

This is where the magic happens. Well, nothing really magical, just a jQuery call to a controller, passing in the username value. In the example below, the function processing the result looks for a 0 to indicate the username is available. You can modify that to be whatever you want.


    function CheckAvailability() {
        $.post("/Home/CheckAvailability",
        { Username: $("#Username").val()},
            function(data) {
                var myObject = eval('(' + data + ')');
                var newid = myObject;
                if (newid == 0) {
                    $("#usernamelookupresult").html("<font color='green'>Available :-D</font>")
                }
                else {
                    $("#usernamelookupresult").html("<font color='red'>Taken :-(</font>")
                }
        });
    }

Controller

This is where your business logic lives, and is where the lookup occurs. For this exercise, we are keeping it simple, but you can see where to add your database lookup.


    public ActionResult CheckAvailability(string Username)
    {
            int Taken = 0;
            //  This is where you add your database lookup
            if (Username == "username")
            {
                Taken = 1;
            }
            return Json(Taken);
    }

Download Sample Application

Below is a quick clip to show the code from the downloadable sample in action:

February 22 / 2010

Latitude and Longitude Lookup with jQuery, C#, ASP.NET MVC

I recently had a requirement for a mapping application that required me to pass in longitude and latitude coordinates. It wasn’t realistic to have the user look those values up, so I had to figure out a way to automatically lookup the coordinates given a zip code.

There are tons of pay services (some of which I use), but for this project needed something free. I stumbled on http://www.geonames.org/ which has a great service. You can see their webservice documentation here: http://www.geonames.org/export/web-services.html.

Ok, let’s get started:

Web form

These are the input fields we will use to perform the lookup. We are going to have three textboxes, one which has an onchange event.

    Zip Code<br/>
    <%= Html.TextBox("Zip", "", new { @onchange = "LookupCoordinates(this.value)" })%>
    <br/><br/>
    Latitude: <%= Html.TextBox("Lat") %>,
    Longitude:<%= Html.TextBox("Lon") %>

jQuery Function

This function is responsible for looking up the latitude and longitude coordinates, and populating the results into the textboxes. Note that I’m wiring in US as the country below. The country is an optional parameter, when entered gives you more relevant results. Otherwise you are going to have to write some kind of loop.

    function LookupCoordinates(zip) {
            $.post("/Home/LookupCoordinates",
            { Zip: zip, Country: "US" },
            function(data) {
                var result = eval('(' + data + ')');
                var coordinates = result.split(",");
                $("#Lat").val(coordinates[0]);
                $("#Lon").val(coordinates[1]);
            });
        }

Call Geonames.org

In this sample, the call to geonames.org is wired into the controller. In real life, you probably want to wrap it in some kind of helper or service class. There are a few using statements you will need:

using System.IO;
using System.Net;
using System.Xml;

The above namespaces are important because we are going to make a WebRequest, and then parse the Xml results. The webservice method we are going to call is:

http://ws.geonames.org/postalCodeSearch?postalcode=78702&amp;maxRows=10&amp;country=US

Since we know the Zip and the Country, we should in theory only get 1 result. Below is a screenshot of the elements returned for our 78702 search (Austin):

Onto the method:

    public ActionResult LookupCoordinates(string Zip, string Country)
    {
        string Lat = "";
        string Lon = "";
        string PostUrl = "http://ws.geonames.org/postalCodeSearch?postalcode=" + Zip + "&maxRows=10&country=" + Country;
        WebResponse webResponse = webRequest.GetResponse();
        if (webResponse == null)
        { }
        else
        {
            StreamReader sr = new StreamReader(webResponse.GetResponseStream());
            string Result = sr.ReadToEnd().Trim();
            if (Result != "")
            {
                // Load the response into an XML doc
                XmlDocument xdoc = new XmlDocument();
                xdoc.LoadXml(Result);
                //  Navigate to latitude node
                XmlNodeList name = xdoc.GetElementsByTagName("lat");
                if (name.Count > 0)
                {
                    Lat = name[0].InnerText;
                }
                //  Navigate to longitude node
                name = xdoc.GetElementsByTagName("lng");
                if (name.Count > 0)
                {
                     Lon = name[0].InnerText;
                }
            }
        }
        return Json(Lat + "," + Lon);
    }

From there, the method returns the latitude and longitude in a comma separated string, the javascript call splits the results and populates each respective text box. Below is a video preview – really short, really lame, but you get to see the code in action:

February 18 / 2010
Author bill sternberger
Category ASP.NET MVC, C#, jquery
Comments 13 Comments