3

I have two inputs of type file, one in a partial view, and another in main page

In partial view

<input type="file" name="image" id="image" onchange="readURL(this)"/>

In main page

<input type="file" name="userProfilePic" id="userProfilePic" style="display:none" />

What I want is that when a user changes image/file on the visible file upload, the image/file should be updated on main/other input too. Here's my code.

function readURL(input) {
    if (input.files && input.files[0]) {
        var reader = new FileReader();

        reader.onload = function (e) {
            $('#imagePreview').attr('src', e.target.result);
        }
        reader.readAsDataURL(input.files[0]);
        // window['profilePic'] = input.files[0];
        $('#userProfilePic').get(0).files[0] = input.files[0];
        return false;
    }

The Error

The error is quite weird, when I open my console, and check for files, it shows up sometime, and a moment later it don't.

In my console window

$('#userProfilePic').get(0).files[0]
File (file object details)

....

(after a second)
$('#userProfilePic').get(0).files[0]
undefined

And it isn't happening the first time only. Say sometimes, it shows the values for 5-6 times, then 7th time it won't...

$('#userProfilePic').get(0).files[0]
File (file object details)

....

(after a second)
$('#userProfilePic').get(0).files[0]
File (file object details)

....

(after a second)
$('#userProfilePic').get(0).files[0]
File (file object details)

....

(after a second)
$('#userProfilePic').get(0).files[0]
undefined

That's all the code I have, there is no other code. Now, as you can see in the code, I also set window[profilePic] to the file object. But if I check that in console window, it always shows no matter what? How is this happening?

The problem

I need to submit the form, but when I do, the image (the input file) is being sent as null, but sometimes as a valid file. As I explained earlier, when I check the value in console, it shows for first time, or some random number of times, then all of a sudden it is gone, while the variable that I set on window (window[profilePic]) always have that file object.
In case someone is wondering, the original/visible file input where user actually selects the file always has the value.

Amirhossein Mehrvarzi
  • 18,024
  • 7
  • 45
  • 70
Razort4x
  • 3,296
  • 10
  • 50
  • 88

3 Answers3

2

You cant do this for security reasons , all files uploaded via input type="file" have to be done manually by the user.

However as long as the user will upload an image anyway , you should do all the process you want in your server side script.

for further info , please refer to this post here :

How to set a value to a file input in HTML?

Community
  • 1
  • 1
ProllyGeek
  • 15,517
  • 9
  • 53
  • 72
  • Is there any other work around? If you have fully read my question, I hope you understand my requirement. Can I send any other way? – Razort4x Nov 02 '14 at 19:08
  • Also, one question, it might sound stupid but how does browser knows that weather it is done by code or the user has manually selelcted a file? – Razort4x Nov 02 '14 at 19:08
  • @Razort4x answering your first question yes there is a work around , i can help if i know what would you do afterwards , assuming hidden input file is set , to give you exact details , for second question , you may refer to W3 Post : http://www.w3.org/TR/html-markup/input.file.html , not attributes with readonly value , this is how the function was built , so the browser doesnt know if it is set programatically or not , the thing is you cant do it , so the browser doesnt have to check. – ProllyGeek Nov 02 '14 at 19:15
  • Thanks for that w3 link, but it got me thinking again, how does it works internally. I mean if a user selects a file, how is the files value set if the control is only read only? Anyway, it's of no concern. About my first question, it's a image that user uploads, so I process it and the set it as the user's profile pic. I was posting it in HttpPostedFileBase in the action. What do you think can be done? – Razort4x Nov 02 '14 at 19:24
  • @Razort4x well what makes sense in this case , will never be uploading same pic twice !! the solution is simply that you upload the pic once to your server and point both user's profile pic and whatever will have the same pic to the same file , in case you want to crop image , resize it , or any other process all this can be done via scripts , but never upload same file twice. – ProllyGeek Nov 02 '14 at 19:29
0

Why you try to use two inputfile for the same file?

if you try to make a form in a PartialView with a inputfile and extra data? I answered a very similar question here:

File upload in MVC when used in bootstrap modal returns null

1) make a model for used in the form with all elements for the form,

2) declare the model in the first line in the partial view

3) pass as parameter the model to the post function.

4) you use a Partial view, well is possible use this view in differents pages, you need specify the control to treatement the form.

An Example in code:

Model:

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

    public class PartialFormModel
    {
        [Required]
        [StringLength(200)]
        public string FileName { get; set; }

        [StringLength(200)]
        public string Title { get; set; }

        [StringLength(1000)]
        public string Description { get; set; }

        public int? Order { get; set; }

        [NotMapped]
        public HttpPostedFileBase ImageFile { get; set; }
    }

PartialVIEW:

@model YOURSPACENAME.Models.PartialFormModel    

@using (Html.BeginForm("YourActionName", "YourControllerName", FormMethod.Post, new { @class = "form-horizontal", @role = "form", @enctype="multipart/form-data" })) 
    {
        @Html.AntiForgeryToken()

        <div class="form-group">
                @Html.LabelFor(model => model.FileName, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.FileName, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.FileName, "", new { @class = "text-danger" })
                </div>
            </div>

    <div class="form-group">
                @Html.LabelFor(model => model.ImageFile, new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.TextBoxFor(m => m.ImageFile, new { @class = "form-control", type = "file" })
                </div>
            </div>

            <div class="form-group">
                <div class="col-md-offset-2 col-md-10">
                    <input type="submit" value="Create" class="btn btn-default" />
                </div>
            </div>
    }

CONTROLLER

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult YourActionName(PartialFormModel obj)
{
    if (ModelState.IsValid)
    {
        //your options
    }
    return PartialView("_EditSlider");
}
Community
  • 1
  • 1
chefjuanpi
  • 1,570
  • 15
  • 27
0

Considering that:

  1. For security reasons you can't set value of input type="file" programmatically.
  2. Changing the type of an <input> throws a security error in some browsers (old IE and Firefox versions).

I don't know actually what you want. But I exhort you to create a new input element, set its type to the one you want, say file, and set its properties according to your need. like this:

<script>
function createInputType(_type, _value, _name, _id, _class) {
    var newObject = document.createElement('input');
    newObject.type = _type;
    newObject.value = _value;
    newObject.name = _name;
    newObject.id = _id;
    newObject.className = _class;
    return newObject;
}
</script>
Amirhossein Mehrvarzi
  • 18,024
  • 7
  • 45
  • 70