Пропала кнопка Fineuploader после перемещения сортируемой таблицы. Элементы плагина пропущены в сортируемой таблице при перемещении строки

Я работал с knockout.js и knockout-sortable.js. Чтобы создать сортируемую таблицу. Один из столбцов этой таблицы должен загружать изображения и по-прежнему иметь возможность сортировать таблицу. Загрузка работает нормально, но затем, когда я сортирую таблицу, не хватает кнопки точного загрузчика и всех атрибутов.

Скрипка: http://jsfiddle.net/XdevK/6/

Действия по воспроизведению:

  1. Нажмите "Добавить актив".
  2. Снова нажмите «Добавить актив».
  3. Переместите второй актив на первую позицию. Не хватает кнопки финишера.

На самом деле происходит то, что содержимое div удаляется после завершения сортировки.

Код Js:

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>

Я думаю, что на самом деле происходит то, что sortable воссоздает таблицу. Это означает, что я должен запустить воссоздание библиотеки fineuploader при обратном вызове сортировки.

Как я могу сделать так, чтобы кнопка оставалась такой, как есть после завершения сортировки?


person Sanchitos    schedule 17.07.2013    source источник
comment
Вам нужно создать собственный обработчик привязки и переместить создание загрузчика в его функцию инициализации ...   -  person nemesv    schedule 18.07.2013
comment
Какой у Вас вопрос?   -  person Ray Nicholus    schedule 18.07.2013
comment
Почему бы просто не создать один экземпляр загрузчика и отсортировать ‹li› элементы, которые он помещает на страницу для каждого загруженного файла?   -  person Mark Feltner    schedule 18.07.2013
comment
@nemesv Как мне создать этот обработчик привязки?   -  person Sanchitos    schedule 18.07.2013


Ответы (1)


Я решил воссоздать fileUploader (это могло произойти с любым другим плагином, вставленным в сортируемую таблицу).

Это было довольно легко.

Вот код (не в jsfiddle, потому что я потеряю время на создание сценария).

HTML

<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: URL}"/>
                </div>
                <br/>
                <div data-bind="attr: {id: 'fineUploader' + 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>

Javascript:

 var CommunityAsset = function(value, description, name, url) {
        this.URL = url;
        this.Value = value;  
        this.Description = ko.observable(description);
        this.Name = name;  
        this.FileName  = "";
        this.FileSize = "";          
    }
    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("", "", name, "http://placehold.it/240x160");                    
            self.communityAssets.push(asset);
            createFineUploader(name);
        };


    self.addAssetWithParams = function(value, description, name, url) {            
        var asset = new CommunityAsset(value, description, name, url);        
        self.communityAssets.push(asset);

    };       
    self.recreateUploaders = function(arg) {   
        createFineUploader(arg.item.Name);
        if (arg.item.FileName != "")
        {
            $("#fineUploader"+arg.item.Name+" .qq-upload-list").append('<li class=" alert alert-success"><span class="qq-upload-file">'+arg.item.FileName+
            '</span><span class="qq-upload-size" style="display: inline;">'+arg.item.FileSize+'</span></li>');
        }            

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 == intIndex; // <-- is this the desired seat?
                                    });

                                    if (asset) {
                                        var number = response.size;
                                        var size = "";
                                        if (number >= 1048576)
                                        {   
                                            number = number / 1048576;
                                            size = "MB";
                                        }
                                        else
                                        {
                                            number = number / 1024;
                                            size = "kB";

                                        }
                                        asset.FileSize = number.toFixed(1) + "" + size;
                                        asset.FileName = response.fileName;
                                        asset.Value = response.path;
                                    }                                     
                                }
                            }
                        },
                        debug: true
                    });

}              
     }; 
}
var vc = new viewOverview();  
ko.bindingHandlers.sortable.afterMove  = vc.recreateUploaders;
ko.applyBindings(vc, $("#communityOverview")[0]);

Магия совершается с помощью ko.bindingHandlers.sortable.afterMove = vc.recreateUploaders;. Итак, после перемещения строки мы воссоздаем создание плагина. Я добавил часть FileName, это было сделано потому, что если вы правильно загрузили файл, метка имени файла также будет удалена, если строка будет перемещена, так что это снова добавит метку FileName.

Надеюсь, это кому-то поможет!

person Sanchitos    schedule 18.07.2013
comment
Если вы уже используете jQuery, почему бы не использовать оболочку подключаемого модуля jQuery Fine Uploader? - person Ray Nicholus; 19.07.2013