2

I currently have a Django form that has N rows by 12 columns textboxes in the shape of a table. Users are able to populate this form one text box at a time:

[________][________][________][________][________][________][________][________][________][________][________][________][________][________][________][________][________][________][________][________][________][________][________][________][________][________][________]

Note: this table only shows 9 columns, but the actual form I am using is 12.

I would like to add the ability for users to copy a range of cells in Excel and paste into the form filling up the appropriate cells.

I tried to mimic the syntax for a method that I have successfully created which is able to clear all data fields after clicking the clear button on the form:

$(document).on("click", "#clear_button", function() {
    $("input[type=text]").val("");
});

The data coming from Excel for a single row is tabbed delimited and this is about as far as I've gotten:

$(document).on("paste", "input[type=text]", function(){
    var input_id = $(this).attr("id");
    var value = $(this).val();
    var value_split_array = value.split("\t");
    var row_selected = input_id.match(/([-\w]+)_\d+/)[1];
    var num = parseInt(input_id.match(/[-\w]+_(\d+)/)[1], 10);
    for (i=num; i < value_split_array.length-1 || i < 12; i++) {
        $("[id="+row_selected+"_"+i+"]").val(value_split_array[i-num]);
    }
});

I thought this would work, but unfortunately it did not. Wondering if anyone has any suggestions.

Kevin Brown-Silva
  • 40,873
  • 40
  • 203
  • 237
pj2452
  • 905
  • 3
  • 10
  • 22

1 Answers1

4

The paste event fires before the data is pasted into the input field, so you can't get the pasted text using $(this).val(). You need to access the clipboardData property of the event object.

Since jQuery doesn't include clipboardData in its event object, you need to get it from the originalEvent field.

Your event handler would look like this.

function (event) {
    var input_id = $(this).attr("id");
    var value;
    if (event.originalEvent.clipboardData) { // Firefox, Chrome, etc.
        value = event.originalEvent.clipboardData.getData('text/plain');
    } else if (window.clipboardData) { // IE
        value = window.clipboardData.getData("Text")
    } else {
        // clipboard is not available in this browser
        return;
    }
    /* ... */
    event.preventDefault(); // prevent the original paste
}

To be more robust, you should query clipboardData to ensure it has a text/plain representation before proceeding.

In IE, it looks like this is how you read the clipboard.

var value = window.clipboardData.getData("Text");
Tmdean
  • 9,108
  • 43
  • 51
  • Hi again. I am now noticing that this works flawlessly on Chrome, but IE10/IE11 both fail at the "var value = event.originalEvent.clipboardData.getData('text/plain');" line with the following error. "Unable to get property 'getData' of undefined or null reference." – pj2452 Jan 02 '15 at 06:06