vitalets / x-editable

In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
http://vitalets.github.io/x-editable
MIT License
6.51k stars 1.72k forks source link

data-type = file #50

Open kamov opened 11 years ago

kamov commented 11 years ago

Hi,

This is more a feature request that not a issue report.

There is a way for add input file for upload image?

If not, exist a solution?

Thanks and regards

vitalets commented 11 years ago

hi,

good idea, but need some investigation: afak, file upload is not possible via normal ajax in older browsetrs, and some fallback tricks a required to overcome that. have a look on this: http://malsup.com/jquery/form/#file-upload

tchapi commented 11 years ago

+1 that would be a great addition !

p0wl commented 11 years ago

+1, would love this.

vitalets commented 11 years ago

For file upload I found this: http://blueimp.github.com/jQuery-File-Upload/ Implementing file-upload in x-editable would be the same work at the end.. I think just using this plugin is the solution.

kamov commented 11 years ago

Hi

Yes, I know it and I integrate it on the form, but user should click Upload image and a popup is open for upload image using jquery file upload plugin.

Will be great implement this into x-editable...

jerrac commented 11 years ago

So, how did you integrate jQuery-File-Upload with x-editable?

Or are you saying to just use that plugin without using x-editable?

vitalets commented 11 years ago

I did not use it too much, but for me jQuery-File-Upload itself is nearly the same as it could be inside x-editable. I'm not sure what are advantages of adding wrapper around..

jerrac commented 11 years ago

Ok, so you didn't integrate it. That answers my question.

The reason I thought it might, emphasis on the 'might', be a good idea, is for easily making the UI consistent.

I haven't looked into how x-editable creates the popup and inline forms when you click, so it might be easy to emulate. I will check into that soon.

A use case would be a profile photo. Basically, just click the image, an x-editable form appears (inline or not), and you upload your replacement.

vitalets commented 11 years ago

Agree, it's usefull. I will investigate on it.. Thank you!

pixxelboy commented 11 years ago

As far as we're concerned here, we would love native support for file input.

stationkeeping commented 11 years ago

+1. This would be great.

jdespatis commented 10 years ago

Any news on this nice feature?

swdevbali commented 10 years ago

I have made some lite tutorial using this awesome x-editable plugin in my flask tutorial series. Well, uploading the file actually is not using x-editable, but it use the same level of user interactivity. So, I think it working just fine. Hope it help : http://bit.ly/1dcnJBz

marciocamello commented 10 years ago

Add this line in jqueryui-editable-file.js (function ($) { "use strict";

....Code script here

$.fn.editabletypes.file = File;

}(window.jQuery));

For me works fine, in php request print_r($_FILES) to return test, ok.

marciocamello commented 10 years ago

Script here

/**
 File editable input.

 @class file
 @extends abstractinput
 @experimental
 @example
 <a href="#" id="file" data-type="file" data-pk="1">awesome</a>

 *Note that on the server side the json return needs to be returned in a <textarea> element
 in order to handle HTML dataType, status and .statusText.
 See http://github.com/cmlenz/jquery-iframe-transport for details.

 <script>
 $(function(){
$('#file').editable({
url: '/post',
title: 'Enter file, caption and url #',
});
});
 </script>
 **/

(function ($) {

    "use strict";

    var File = function (options) {
        this.init('file', options, File.defaults);
    };

    //inherit from Abstract input
    $.fn.editableutils.inherit(File, $.fn.editabletypes.abstractinput);

    $.extend(File.prototype, {
        /**
         Renders input from tpl

         @method render()
         **/
        render: function() {
            this.$input = this.$tpl.find('input');

            this.$input.filter('[name="file"]').bind('change focus click', function() {
                var $this = $(this),
                    newVal = $this.val().split(/\s+/).pop(),
                    $button = $this.siblings('button');
                if(newVal !== '') {
                    $button.text(newVal);
                }
            });

        },

        /**
         Default method to show value in element. Can be overwritten by display option.

         @method value2html(value, element)
         **/
        value2html: function(value, element) {
            if(!value) {
                $(element).empty();
                return;
            }

            //@TODO Not sure what to return here since you can't set value of type=file
            //For images I would construct and image elemnt and link
            var html = '';
            $(element).html(html);
        },

        /**
         Gets value from element's html

         @method html2value(html)
         **/
        html2value: function(html) {
            /*
             you may write parsing method to get value by element's html
             */
            return null;
        },

        /**
         Converts value to string.
         It is used in internal comparing (not for sending to server).

         @method value2str(value)
         **/
        value2str: function(value) {
            var str = '';
            if(value) {
                for(var k in value) {
                    str = str + k + ':' + value[k] + ';';
                }
            }
            return str;
        },

        /*
         Converts string to value. Used for reading value from 'data-value' attribute.

         @method str2value(str)
         */
        str2value: function(str) {
            /*
             this is mainly for parsing value defined in data-value attribute.
             If you will always set value by javascript, no need to overwrite it
             */
            return str;
        },

        /**
         Sets value of input.

         @method value2input(value)
         @param {mixed} value
         **/
        value2input: function(value) {
            if(!value) {
                return;
            }
            this.$input.filter('[name="file"]').val(value.file);
            this.$input.filter('[name="caption"]').val(value.caption);
            this.$input.filter('[name="url"]').val(value.url);
        },

        /**
         Returns value of input.

         @method input2value()
         **/
        input2value: function() {
            return {
                file: this.$input.filter('[name="file"]').val(),
            };
        },

        /**
         Activates input: sets focus on the first field.

         @method activate()
         **/
        activate: function() {

            //Set file specific option and success callback to load new file reference
            //Hard to know if the file is remote so just force the send
            $(this.options.scope).editable('option', 'savenochange', true );
            //iframe transport specific ajaxOptions.
            $(this.options.scope).editable('option', 'ajaxOptions', {
                dataType: 'json',
                iframe: true,
                files: this.$input.filter('[name="file"]')
            });

            this.$input.filter('[name="file"]').focus();
        },

        /**
         Attaches handler to submit form in case of 'showbuttons=false' mode

         @method autosubmit()
         **/
        autosubmit: function() {
            this.$input.keydown(function (e) {
                if (e.which === 13) {
                    $(this).closest('form').submit();
                }
            });
        }
    });

    File.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
        tpl: '<div class="editable-file">' +
            '<span style="position:relative; display: inline-block; overflow: hidden; cursor: pointer;">' +
            '<input type="file" name="file" class="input-small" size="1" style="opacity: 0;filter: alpha(opacity=0); cursor: pointer; font-size: 400%; height: 600%; position: absolute; top: 0; right: 0; width: 240%" />' +
            '<button type="button" style="cursor: pointer; display: inline-block; margin-right: 5px;  ">Chose file</button>' +
            '</span></div>',

        inputclass: '',

    });

    $.fn.editabletypes.file = File;

}(window.jQuery));
lloydzhou commented 10 years ago

update this script do not using iframe to upload file:

/** Activates input: sets focus on the first field.

     @method activate()
     **/
    activate: function() {

        //Set file specific option and success callback to load new file reference
        //Hard to know if the file is remote so just force the send
        $(this.options.scope).editable('option', 'savenochange', true );
        $(this.options.scope).editable('option', 'ajaxOptions', {
            dataType: 'json',
            contentType: false, 
            processData: false,
            type: 'POST'  // can using POST or PUT method.
        });
        var self = this
        $(this.options.scope).editable('option', 'params', function(p){
            var d = new FormData()
            d.append('file', self.$input.filter('[name="file"]')[0].files[0]);
            return d
        })

        this.$input.filter('[name="file"]').focus();
    },
disq commented 10 years ago

add

                d.append("pk", $(self.options.scope).data("pk"));
                d.append("name", $(self.options.scope).data("name"));

right before return d to include pk and name as well.

rohitsakala commented 9 years ago

this.$input.filter('[name="file"]').val(value.file); this line should be removed if not security error is thrown !

sburkett commented 7 years ago

+1 for this feature

redefinered commented 7 years ago

Any news on this feature?