Django – Implement textbox with autocomplete feature to enter multiple emails separated by comma

The JavaScript portion to implement an autocomplete was pretty straightforward. JQuery site for more the sample. The challenge was to get this implementation into Django and specially because the source data was dynamically being passed from the view. But once I figured out how to convert the python list to a javascript array, things were pretty straightforward.

View

def sendFulfillmentEmail(request, tenant_id):
    # Eliminating code before
    email_contacts = [str(u.email) for u in User.objects.all().filter(is_active=True)]
    email_contacts = simplejson.dumps(email_contacts)
    # Eliminating code after
    template = 'app/fulfillment_email_form.html'
    return render_to_response(template, locals(), context_instance=RequestContext(request))

Template
Now, the email_contacts need to be converted to a JavaScript array and used as a source.

{% extends "../../opportunities/templates/opportunities/base.html" %}
{% block extrahead %}
< link rel="stylesheet" href="/site-media/js/jquery-ui-themes-1.11.4/themes/smoothness/jquery-ui.css">
< script src="/site-media/js/jquery-ui-1.11.4/jquery-ui.js"></script>
<!-- Also requires the jquery.js file but that's already imported in base.html so not importing again -->


$(function() {
	//alert('{{email_contacts|safe}}');
	var email_contacts = {{email_contacts|safe}};   //-- The safe filter converts the JSON content to JavaScript array
	function split( val ) {
	  return val.split( /,\s*/ );
	}
	function extractLast( term ) {
	  return split( term ).pop();
	}
 
        $( "#id_email_cc" )
		// don't navigate away from the field on tab when selecting an item
		.bind( "keydown", function( event ) {
			if ( event.keyCode === $.ui.keyCode.TAB &&
			  $( this ).autocomplete( "instance" ).menu.active ) {
				event.preventDefault();
			}
		})
		.autocomplete({
			minLength: 0,
			autoFocus: true,     //- This will automatically select the first item from the menu. On hitting tab, selected item will be populated.
			source: function( request, response ) {
			        // delegate back to autocomplete, but extract the last term
			        response( $.ui.autocomplete.filter(
				    email_contacts, extractLast( request.term ) ) );
        	        },
			focus: function() {
				// prevent value inserted on focus
				return false;
			},
			select: function( event, ui ) {
				var terms = split( this.value );
				// remove the current input
				terms.pop();
				// add the selected item
				terms.push( ui.item.value );
				// add placeholder to get the comma-and-space at the end
				terms.push( "" );
				this.value = terms.join( ", " );
				return false;
			}
		});
});

<meta name="robots" content="NONE,NOARCHIVE" />
{% endblock %}
</pre>
{% block content %}

<!-- Eliminating other parts of form -->

			{{fulfillment_email_form.email_cc}}
			
		        <!-- View the source of HTML file and the id of the field is set to id_email_cc and that's what is used in the JQuery function -->
<!-- Eliminating other parts of form -->
{% endblock %}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s