I have been working with knockout.js and knockout-sortable.js. In order to create a sortable table. One of the columns of this table should upload images, and still be able to sort the table. The upload works fine, but then when I sort the table the button of the fine uploader is missed, and all the attributes.
Fiddle: http://jsfiddle.net/XdevK/6/
Steps to reproduce:
- Click Add Asset
- Click again Add Asset.
- Move the second asset to the first position. The fineuploader button is missed.
What is actually happening is that the div content is removed once the sort is done.
Js Code:
var CommunityAsset = function(value, description, name) {
this.Value = value;
this.Description = ko.observable(description);
this.Name = "fineUploader" + name;
}
var viewOverview = function()
{
var self = this;
self.communityAssets = ko.observableArray();
self.clearAsset = function(data, event) {
self.communityAssets.remove(data);
};
self.Uploaders = {};
self.addAsset = function() {
var name = self.communityAssets().length;
var asset = new CommunityAsset("http://placehold.it/240x160", "", name);
self.communityAssets.push(asset);
createFineUploader(name);
};
self.addAssetWithParams = function(value, description, name) {
var asset = new CommunityAsset(value, description, name);
self.communityAssets.push(asset);
createFineUploader(name);
};
}
var vc = new viewOverview();
vc.addAssetWithParams("http://placehold.it/240x160", "Hola",0);
ko.applyBindings(vc, $("#communityOverview")[0]);
function createFineUploader(intIndex)
{
vc.Uploaders[intIndex] = new qq.FineUploader({
element: $('#fineUploader'+intIndex)[0],
request: {
endpoint: '/Communities/FileUpload'
},
autoUpload: true,
sizeLimit: 4000000, // max size
validation: {
allowedExtensions: ['jpeg', 'jpg', 'gif']
},
text: {
uploadButton: '<i class="icon-upload icon-white"></i> Upload a file'
},
multiple: false,
template: '<div class="qq-uploader ">' +
'<pre class="qq-upload-drop-area "><span>{dragZoneText}</span></pre>' +
'<div class="qq-upload-button btn btn-success" style="width: auto;">{uploadButtonText}</div>' +
'<ul class="qq-upload-list" style="margin-top: 10px; text-align: center;"></ul>' +
'</div>',
classes: {
success: 'alert alert-success',
fail: 'alert alert-error'
},
callbacks: {
onComplete: function(id, name, response) {
if (response.success)
{
var asset = ko.utils.arrayFirst(vc.communityAssets(), function(currentAsset) {
return currentAsset.Name == "fineUploader"+intIndex; // <-- is this the desired seat?
});
// asset found?
if (asset) {
asset.Value = response.path;
}
}
}
},
debug: true
});
}
Html
<div class="tab-pane" id="communityOverview">
<table class="table" >
<thead>
<tr>
<th>Sort Order</th>
<th>Community Overview Image</th>
<th>Community Overview Image Description</th>
</tr>
</thead>
<tbody data-bind="sortable: communityAssets">
<tr>
<td class="item"><span data-bind="text: $index" ></span>
</td>
<td class="item">
<div class="image-options">
<div class="control-group">
<div class="controls">
<img style="width:240px; height:160px;" data-bind="attr:{src: Value}" />
</div>
<br />
<div data-bind="attr: {id:Name}"></div>
</div>
</div><!-- .image-options -->
<a href="Javascript:void(0);" data-bind="click: $root.clearAsset ">Delete Asset</a>
</td>
<td class="item">
<textarea class="input-block-level" rows="11" cols="3" data-bind="value: Description"></textarea>
</td>
</tr>
</tbody>
</table>
<a href="#" data-bind="click: addAsset">Add Task</a>
</div>
What I think is actually happening is that the sortable recreates the table. This means i should run the recreation of the fineuploader library on the callback of the sort.
How can I mantain the button to stay as it is once the sort is done?
I decided to recreate the fileUploader (this could happen with any other pluggin inserted into the sortable table).
It was kind of easy.
Here's the code (not in jsfiddle because I would lose time making the scenario).
HTML
Javascript:
The magic is done with
ko.bindingHandlers.sortable.afterMove = vc.recreateUploaders;
So after a row is moved we recreate the the pluggin creation. There's a portion I added of the FileName, this was done because if you uploaded a file correctly the label of the file name will be also removed if the row is moved, so this will add the FileName label back again.Hope it helps someone!