EasyUI Forum

General Category => EasyUI for jQuery => Topic started by: chkaufmann on February 24, 2014, 02:00:52 AM



Title: Propertygrid with file upload
Post by: chkaufmann on February 24, 2014, 02:00:52 AM
I would like to create my own inline editor for a file upload
- show a link to the current file
- choose a new file on double click
- upload the file with AJAX in onAfterEdit event

Did already somebody build an editor for this?

cu Christian


Title: Re: Propertygrid with file upload
Post by: stworthy on February 24, 2014, 06:26:28 PM
The file editor must display many informations, the current file name, the upload input, etc. So an extended combo component may be suitable. Please refer to the following test code.
Code:
$.extend($.fn.datagrid.defaults.editors, {
file: {
init: function(container, options){
var input = $('<input>').appendTo(container);
input.combo(options);
var p = input.combo('panel');
$('<div class="file-name"></div>').appendTo(p);
var f = $('<form></form>').appendTo(p);
f.append('<input type="file">');
return input;
},
destroy: function(target){
$(target).combo('destroy');
},
getValue: function(target){
var p = $(target).combo('panel');
var v = p.find('input[type=file]').val();
console.log(v);
v = v || p.find('div.file-name').text();
$(target).combo('setValue', v);
return $(target).combo('getValue');
},
setValue: function(target, value){
$(target).combo('setValue', value).combo('setText', value);
var p = $(target).combo('panel');
p.find('div.file-name').text(value);
},
resize: function(target, width){
$(target).combo('resize', width);
}
}
});


Title: Re: Propertygrid with file upload
Post by: chkaufmann on February 25, 2014, 12:10:42 AM
I tried myself and it seems much complicater. Here are the pieces of code I already have. I still try to get used to Javascript/jQuery in general and to the notation you use in your library:

Code:
var
  _fileUploadData;

$.extend($.fn.datagrid.defaults.editors, {
    fileUpload: {
        init: function(container, options){
            var input = $('<input type="file" class="datagrid-editable-input">').appendTo(container);
            input.on('change', function (event) {
              _fileUploadData = event.target.files;  // >> I didn't find the way to "bind" it to the row/editor
              var pg = input.parents('table.propertygrid');
              pg.propertygrid('endEdit', input.parents('.datagrid-row').attr('datagrid-row-index'));  // doesn't work like this :-(
            });

            return input;
        },
        destroy: function(target){
            $(target).remove();
        },
        getValue: function(target){
          return _fileUploadData[0].name;
        },
        setValue: function(target, value){
          $(target).trigger('click');  // open the file dialog immediately
        },
        resize: function(target, width){
            $(target)._outerWidth(width);
        }
    }
}

Once this is working, my idea is to do something like described here in the onAfterEdit event:
http://abandon.ie/notebook/simple-file-uploads-using-jquery-ajax

I already post each changed (simple) value there and the server sends back an updated property grid which I apply with .propertygrid('loadData'). This works fine for strings, combos and memos and allows me to update dependent fields on the server:
Code:
// an object to handle interaction of a treegrid and a propertygrid
function BSTreeEditor(treeid, propertygridid, source) {
  var that = this;
  this.tree  = $('#' + treeid);
  this.pgrid = $('#' + propertygridid);
  this.resturl    = 'rest/' + source;

  this.tree.treegrid({
    idField: 'id',
    treeField: 'column0',
    sortName: 'column0',
    remoteSort: false,

    onSelect: function(node) {
      var url = that.resturl + '/detail?id=' + node.id;
      bsSendRestRequest(url, null, null, function(data, statusCode) {
        that.tree.treegrid('update', data.node);
        that.pgrid.propertygrid('loadData', data.propertygrid);
      });
    }

  });

  this.pgrid.propertygrid({
    showGroup: true,
    columns:[[
      { field:'name', title:'Name', width:100, resizable:true },
      { field:'value', title:'Value', width:100, resizable:false,
        formatter: function(value, row){
          if ( row.valuedisplay )
            return row.valuedisplay
          else if ( row.editor.type == 'text' )
            return bsHtmlEncode(value);
          else if ( row.editor.type == 'textarea' )
            return value.replace(/\n/g, '<br>');
          else
            return value;
        },
        styler: function(value, rowData, index) {
          if ( rowData.editor.type == 'textarea' )
            return 'white-space: normal;';
          else
            return '';
        }
      }
    ]],

    onBeforeEdit: function(rowIndex, rowData) {
      if ( rowData.editor.type == 'combobox' )
        rowData.editor.showPanel; // << This should open the dropdown on click but it doesn't work like this :-(
    },

    onAfterEdit: function(rowIndex, rowData, changes) {
      if ( changes.value ) {
        var tmp  = { 'valuename' : rowData.valuename,  'value' : changes.value };
        var tmp2 = that.pgrid.propertygrid('getData');
        var url  = that.resturl + '/detail?id=' + tmp2.id;
        bsSendRestRequest(url, JSON.stringify(tmp), "application/json; charset=utf-8", function(data, statusCode) {
          that.tree.treegrid('update', data.node);
          if ( that.tree.treegrid('bsRefresh') == data.node.id )
            that.pgrid.propertygrid('loadData', data.propertygrid);
        });
      }
    }
  });



cu Christian