Multiple value input field with jQuery

Are you a Facebook or Hotmail user? You’ve probably seen those input boxes that let you input multiple email addresses or names, adding them to a list as you go along and giving you the ability to remove them later by clicking their close button… If you’re not sure what I’m talking about, they look a bit like this:

Multiple value input field with jQuery

So, having had a fairly extensive search on google for an out-of-the-box solution, it turns out there aren’t really any so I set about writing my own, using Hotmail’s for inspiration. It didn’t take many lines of code to get the job done… It’s implemented as a jQuery plugin with a little bit of CSS, which you can edit to your liking. Feel free to improve the plugin too – I haven’t checked to see if it works when applied to multiple inputs on the same page, but it works very nicely with just the one.

Here’s the code for the jQuery plugin:

(function( $ ){

     $.fn.multipleInput = function() {

          return this.each(function() {

               // create html elements

               // list of email addresses as unordered list
               $list = $('<ul />');

               // input
               var $input = $('<input type="text" />').keyup(function(event) {

                    if(event.which == 32 || event.which == 188) {
                         // key press is space or comma
                         var val = $(this).val().slice(0, -1); // remove space/comma from value

                         // append to list of emails with remove button
                         $list.append($('<li class="multipleInput-email"><span>' + val + '</span></li>')
                              .append($('<a href="#" class="multipleInput-close" title="Remove" />')
                                   .click(function(e) {
                                        $(this).parent().remove();
                                        e.preventDefault();
                                   })
                              )
                         );
                         $(this).attr('placeholder', '');
                         // empty input
                         $(this).val('');
                    }

               });

               // container div
               var $container = $('<div class="multipleInput-container" />').click(function() {
                    $input.focus();
               });

               // insert elements into DOM
               $container.append($list).append($input).insertAfter($(this));

               // add onsubmit handler to parent form to copy emails into original input as csv before submitting
               var $orig = $(this);
               $(this).closest('form').submit(function(e) {

                    var emails = new Array();
                    $('.multipleInput-email span').each(function() {
                         emails.push($(this).html());
                    });
                    emails.push($input.val());

                    $orig.val(emails.join());

               });

               return $(this).hide();

          });

     };
})( jQuery );

Here’s the CSS:

.multipleInput-container {
     border:1px #ccc solid;
     padding:1px;
     padding-bottom:0;
     cursor:text;
     font-size:13px;
     width:100%;
}

.multipleInput-container input {
     font-size:13px;
     clear:both;
     width:250px;
     height:24px;
     border:0;
     margin-bottom:1px;
}

.multipleInput-container ul {
     list-style-type:none;
}

li.multipleInput-email {
     float:left;
     margin-right:2px;
     margin-bottom:1px;
     border:1px #BBD8FB solid;
     padding:2px;
     background:#F3F7FD;
}

.multipleInput-close {
     width:16px;
     height:16px;
     background:url(close.png);
     display:block;
     float:right;
     margin:0 3px;
}

Turn a regular input into a super, jQuery-powered multiple value input like so… The names/emails entered will be submitted as a comma separated list from the original form input!

$('#my_input').multipleInput();

Any questions, feel free to comment!

Using an XML SOAP Web Service from Visual Studio 2005, 2008 and 2010

Introduction

Here we show how to use external SOAP web services from within Microsoft Visual Studio versions 2005, 2008 and 2010.

The scope of this article extends only to XML SOAP web services which may have been created in Visual Studio (and are usually identified by the asmx extension at the end of the URL).

In order to demonstrate the use of external web services, we will use T2A’s SOAP service, which was created using Visual Studio 2005.

All code examples here are in C#.

Making Life Easy

If you’ve never made use of an external web service from Visual Studio, you’re about to discover just how easy it is. In comparison, parsing XML yourself can be quite time consuming, even using a powerful XML reader or parser. A SOAP web service allows Visual Studio to discover how its methods operate (their inputs and return formats) and using this information, allows your IDE to create code within your project, to allow your code to seamlessly use the external service, just as if it was a class in your own code.

Using a Web Service from Visual Studio 2005

In order to simply demonstrate the use of T2A’s SOAP service, we created a C# console application. The IDE created an empty project.

We then “told” our project about the web service. We right clicked on the project in the solution explorer, and clicked on Add Web Reference. This can be viewed below, for our project ws_test_2005:-

A new window opened, in which we specified the location of the web service, in this case, http://t2a.co/soap. We clicked the go button:-

The IDE was able to identify the web service. We named the web service t2a. We then clicked on add reference as seen below.

The IDE then created the necessary code to allow our simple project to use the external web service. You can see the information about the added web reference in the right hand pane below:-

We then created a simple console application which uses the T2A soap service, specifically the geo_code method, which as its name suggests, returns geographical co-ordinates for a given postcode, street or place.

The example code shown below uses T2A’s free test mode, during which it returns dummy data at no charge, for the benefit of developers in their initial integration stages.


using System;
using System.Collections.Generic;
using System.Text;

namespace ws_test_2005
{
    class Program
    {
        static void Main(string[] args)
        {
            string api_key = "test";

            t2a.T2A ws = new t2a.T2A();
            t2a.geo_code_res ws_res = ws.geo_code(api_key, null,"york");
            if (ws_res.status.CompareTo("ok") == 0)
            {
                 //print geo code data
                int i = 0;
                while (i < ws_res.geo_data_list.Length)
                {
                    Console.WriteLine(ws_res.geo_data_list[i].description +
                        " at (" +
                        ws_res.geo_data_list[i].latitude + "," +
                        ws_res.geo_data_list[i].longitude+")"
                        );

                    i++;
                }

            }

        }
    }
}

When the console application is executed in the debugger, we can see the class instance that the IDE has created; in this case an array of geo_data instances, this being a member of the result class geo_code_res. Note in the bottom pane the contents of the class instances, in this case, the dummy data returned by T2A in free test mode:-

Detailed Explanation of the Code Example

Normally you would use the API key associated with your T2A account; for this example we are using T2A’s free test mode; this is activated by an API key “test”:-

string api_key = "test";

Remember that we named the external web service t2a? The code created by the IDE is in a namespace t2a. The namespace includes the main class that contains the T2A methods; this is named T2A, or more correctly, t2a.T2A.

We now create an instance of that class.

t2a.T2A ws = new t2a.T2A();

The geo_code method returns an instance of the class t2a.geo_code_res. We now invoke the method; the third parameter is the place, street or postcode for which we want the geo co-ordinates.

t2a.geo_code_res ws_res = ws.geo_code(api_key, null,"york");

If the method has succeeded, the status is ok. If not, we normally would then read the error code.

We then display the contents of the t2a.geo_data instances held in the array t2a.geo_code_res.geo_data_list.

if (ws_res.status.CompareTo("ok") == 0)
{
   //print geo code data

   int i = 0;
   while (i < ws_res.geo_data_list.Length)
   {
      Console.WriteLine(ws_res.geo_data_list[i].description +
      " at (" +
      ws_res.geo_data_list[i].latitude + "," +
      ws_res.geo_data_list[i].longitude+")"
      );

Using a Web Service from Visual Studio 2008

We created a C# console application; it actually uses the same code as shown above. When adding the web reference, the first thing one notices is that whereas formerly beneath Add Reference there was an item Add Web Reference, this seems to be missing from Visual Studio 2008. In its place is Add Service Reference.

We clicked that instead (see below).

A new window opened, named Add Service Reference. In order to add a “legacy” web reference, we clicked the advanced button at the bottom.

Yet another new window opened, named Service Reference Settings. We hit the Add Web Reference button at the bottom.

From that point, adding the web reference is the same as above, for Visual Studio 2005. We created the reference by informing the dialog box that we wished to use http://t2a.co/soap as we had with Visual Studio 2005.

Using a Web Service from Visual Studio 2010

The procedure for adding the web reference is the virtually the same for the 2010 version as for 2008; the image below shows the default Solution Explorer pane for our console application.