CouchApp uploading attachments (part 2)


In my previous post I presented how to upload attachments to a document using HTML (there were few lines of JavaScript for retrieving the last revision of the document).

In this post I will shift to almost doing everything in JavaScript in order to have more control.

Uploading an attachment into CouchDB using JavaScript

Simplest case: validation

The very first step is introduce a validation for checking that we have chosen a file to upload. I want to get something like:

Error on CouchApp attachment upload
Error on CouchApp attachment upload

So I start with the following HTML:

<form id="upload" method="post" enctype="multipart/form-data">
    <label style="display:none; visibility: hidden;">
        Revision :
        <input id="revision" type="text" name="_rev"/>
    </label>
    <input id="attachment" type="file" name="_attachments"/>
    <br/>
    <input type="button" value="Submit"/>
</form>

Basically it’s a form with three input: one for the revision (that is hidden and filled from JavaScript); while the second is for the attachment (the file); the last one is just a button that I will use for invoking the validation procedure.

This is the piece of code for getting document revision.

// Get the document revision
var db = $.couch.db("hermesapp");
var id = "doc_with_attachment";
db.openDoc(id, {
    success:function (result) {
        // Update revision input field
        $("#revision").val(result._rev);
    },
    error:function (a, b, c) {
        alert("Error: " + c);
        console.log("Error on openDoc:", a, b, c);
    }
});

Now, the validation code that has to run when the button is clicked:

$("input[type='button']", "#upload").click(function (ev) {
    var empty = false;
    var form = $("#upload");
    $.each($("input[type='file'][name='_attachments']", form), function (idx, input) {
        if (input.value === "") {
            empty = true;
        }
    });
    if (empty) {
        alert("No attachment file defined!");
        return;
    }
    // Submit the form with the attachment.
    ...
})

I get a reference to the form and inside the form to any input which type is file and which name is _attachments and check that all of them are not an empty string (the loop is because we can send multiple attachments by repeating this input).

Submitting the validated form might be as simple as:

// Submit the form with the attachment
form.attr("action", "/hermesapp/" + $.couch.encodeDocId(id));
form.submit();

or if I want to use ajaxSubmit from jquery.form.js:

// Submit the form with the attachment
form.ajaxSubmit({
    url:"/hermesapp/" + $.couch.encodeDocId(id),
    success:function (response) {
        alert("saved");
        console.log("response", response);
    },
    error:function (a, b, c) {
        alert("error");
        console.log("errors", a, b, c);
    }
});

Avoiding the fact of showing the message received from the server:

CouchDB message on successful upload
CouchDB message on successful upload

and getting instead:

Message on successful attachment upload in CouchDB
Message on successful attachment upload in CouchDB

NOTE: this solution requires that you use jquery.forms.js that you can already find it in your CouchDB server (since futon uses it). In order to download it in your couchapp as we did with jquery.couch.js you should access http://localhost:5984/_utils/script/jquery.form.js (replacing localhost by the IP address of your CouchDB server and saving it with the other JavaScript files (see here for more details on setting up a CouchApp).

Stay tuned!

Next post convers Uploading attachments from JavaScript in CouchDB using PUT instead of POST: why and how. Subscribe to this blog to receive notice.

Leave a comment