Yesterday I failed to get images to upload as CouchDB document attachments using couchapp. This should be do-able given that the Futon administration interface can do it. Just how easy it is remains to be seen...
...which turns out to be fairly easy!
I borrow code from two of CouchDB's javascript libraries:
futon.browse.js
—defines how the Futon interface submits its file upload formjquery.dialog.js
—attaches actions to futon dialogs like the one that uploads files
upload.html
template:<script src="/_utils/script/json2.js"></script>Piece by piece, this function disables normal form submission so that
<script src="/_utils/script/jquery.js?1.2.6"></script>
<script src="/_utils/script/jquery.couch.js?0.8.0"></script>
<script src="/_utils/script/jquery.form.js?0.9.0"></script>
<script src="<%= asset_path %>/vendor/couchapp/jquery.couchapp.js"></script>
<script type="text/javascript" charset="utf-8">
$("#recipe-upload").submit(function(e) { // invoke callback on submit
e.preventDefault();
var data = {};
$.each($("form :input").serializeArray(), function(i, field) {
data[field.name] = field.value;
});
$("form :file").each(function() {
data[this.name] = this.value; // file inputs need special handling
});
if (!data._attachments || data._attachments.length == 0) {
alert("Please select a file to upload.");
return;
}
$(this).ajaxSubmit({
url: "/<%= dbname %>/<%= docid %>",
success: function(resp) {
$('#saved').fadeIn().animate({ opacity: 1.0 },3000).fadeOut();
}
});
});
</script>
ajaxSubmit()
can be used instead:e.preventDefault();Next it assembles all of the data in the form into a Javascript object:
var data = {};After checking to see if the data has an empty file upload field, it performs an
$.each($("form :input").serializeArray(), function(i, field) {
data[field.name] = field.value;
});
$("form :file").each(function() {
data[this.name] = this.value; // file inputs need special handling
});
ajaxSubmit
using the current DB and document ID (as supplied by the show function) and defines a simple on-success callback function:$(this).ajaxSubmit({To test this out, I create an empty "test" document (more precisely I use this document from yesterday):
url: "/<%= dbname %>/<%= docid %>",
success: function(resp) {
$('#saved').fadeIn().animate({ opacity: 1.0 },3000).fadeOut();
}
});
Then, I access the upload show function for the test document (http://localhost:5984/eee/_design/relax/_show/upload/test) and upload my favorite avatar image:
The "Saved" animation shows, which leads me to believe that the image has been successfully uploaded. To make sure, I check the document again:
Sure enough, the image is now attached to the CouchDB test document. Yay!
There is still some more that I would do if I wanted this to be ready for every day use—links back to the main edit page, an automatic redirect after upload, etc.—but that is good enough for today. I am just happy to know that it is possible with relatively little effort.
Day #25
Small addition to a truly purposefull and informative blog entry. This tells the user that the update has failed- firebug console message of success and fail
ReplyDelete(these messages are within pre tags which are not allowed in your blog comments)
{"ok":true,"id":"test","rev":"25-1223e10f2bd556a67665bc9a0ebae738"}
{"error":"conflict","reason":"Document update conflict."}
$(this).ajaxSubmit({
url: "/<%= dbname %>/<%= docid %>",
success: function(resp) {
if(resp.match("ok")){ $('#saved').fadeIn().animate({ opacity: 1.0 },3000).fadeOut();}
else if(resp.match("error")){ $('#failed').fadeIn().animate({ opacity: 1.0 },3000).fadeOut();}
}
This is not working for me. I get the error: '{"error":"method_not_allowed","reason":"Only DELETE,GET,HEAD,PUT allowed"}'. Here is my entire html document which I put on couchdb.
ReplyDeleteI was however forced to remove the usual HTML brackets because HTML is not allowed in comments for some reason.
html
head
script src="http://code.jquery.com/jquery-1.8.2.min.js"/script
script src="http://localhost:5984/_utils/script/jquery.js?1.2.6"/script
script src="http://localhost:5984/_utils/script/jquery.couch.js?0.8.0"/script
script src="http://localhost:5984/_utils/script/jquery.form.js?0.9.0"/script
/head
body
form method="post"
input type="file" id="recipe-upload"
input type="submit"
/form
script type="text/javascript" charset="utf-8"
$("#recipe-upload").submit(function(e) { // invoke callback on submit
e.preventDefault();
var data = {};
$.each($("form :input").serializeArray(), function(i, field) {
data[field.name] = field.value;
});
$("form :file").each(function() {
data[this.name] = this.value; // file inputs need special handling
});
if (!data._attachments || data._attachments.length == 0) {
alert("Please select a file to upload.");
return;
}
$(this).ajaxSubmit({
url: "/%= dbname %/%= docid %",
success: function(resp) {
$('#saved').fadeIn().animate({ opacity: 1.0 },3000).fadeOut();
alert("success");
}
});
});
/script
/body
/html
'
Here is a very simple example with good comments that you can load into your CouchDB. https://gist.github.com/4074427
ReplyDelete