1

I'm using Asp.net MVC 4 and Bootstrap 3 to upload a new image in a modal and show the image in the same modal after upload. So far uploading is working, but instead updating the modal, I'm redirected to the view. Here are my codes:

Controller

    [HttpPost]
    public ActionResult FlatImageOne(HttpPostedFileBase file, int getFlId)
    {
        if (file != null && file.ContentLength > 0)
        {
            string picName = getFlId.ToString() + "-0";
            WebImage img = new WebImage(file.InputStream);
            string picExt = Path.GetExtension(file.FileName);
            if (picExt == ".jpg" || picExt == ".gif" || picExt == ".jpeg" || picExt == ".png")
            {
                picExt = "PNG";
                string path = System.IO.Path.Combine(Server.MapPath("~/Images/Flats/"), picName);
                var img_cropped = img.Resize(1000, 667, false, true);
                img_cropped.Save(path, picExt);
                TempData["img1_update_success"] = "Image Updated Successfully!";
                return RedirectToAction("FlatImageOne", new { FlId = getFlId });
            }
            else
            {
                TempData["img1_update_fail"] = "Error! Wrong File Type(s)! Please Try Again.";
                return RedirectToAction("FlatImageOne", new { FlId = getFlId });
            }
        }
        else
        {
            TempData["img1_update_fail"] = "Error! Please provide an image file to update.";
            return RedirectToAction("FlatImageOne", new { FlId = getFlId });
        }
    }

View for Modal

<div>
    @using (Html.BeginForm("FlatImageOne", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
    {
        @Html.ValidationSummary(true, "Error! Please provide valid information!")

        <input type="file" name="file" style="width: 100%;" /><br />
        <input type="hidden" name="getFlId" value="@ViewBag.ImgName" />
        <input type="submit" class="btn btn-info" value="Upload" />
    }
</div><br />
<div>
    <img src="~/Images/Flats/@(ViewBag.ImgName)-0.png" alt="your image" class="img-responsive" />
</div>

View (This page opens the modal if link is clicked!)

<script>
    $('.btnInfo').click(function (e) {
        var id = $(this).attr('href');
        e.preventDefault();
        $('#modal-content').load("FlatImageOne?FlId=" + id);
    });
</script>

<a href="@Model.serial" class="btnInfo" data-target="#myModal" data-toggle="modal">Change Featured Image</a>

<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                <h4 class="modal-title" id="myModalLabel">Change Image</h4>
            </div>
            <div class="modal-body">
                <div id="modal-content"></div>
            </div>
        </div>
    </div>
</div>

How can I reload the modal after upload instead redirecting to the page?

Update

As to @Stephen Muecke's suggestion, I've added ajax on the modal's view. But I'm getting error alert every time I try to upload. Here are the codes,

        $('#btnUpload').click(function (e) {
            e.preventDefault();
            var formdata = new FormData($('form').get(0));
            $.ajax({
                url: '@Url.Action("FlatImageOne", "Home")',
                type: 'POST',
                data: formdata,
                processData: false,
                contentType: false,
                success: function (data) {
                    alert("Upload successful!");
                },
                error: function () {
                    alert("Error");
                }
            });
        });
halfer
  • 19,824
  • 17
  • 99
  • 186
Shihan Khan
  • 2,180
  • 4
  • 34
  • 67
  • 1
    You might want to read about the [Post/Redirect/Get pattern](https://en.wikipedia.org/wiki/Post/Redirect/Get), to understand why what you're trying to do is a bad idea. – Tieson T. Jan 13 '16 at 06:37
  • Your form is inside the modal and inside that form you are uploading a image and want to show that image in the same modal after it upload without closing or refreshing the modal is it Right? – Anil Panwar Jan 13 '16 at 06:38
  • @AnilPanwar, yes you're absolutely correct. – Shihan Khan Jan 13 '16 at 06:39
  • 2
    If you want to post data and stay on the same page, you need to use ajax. Since you have a file input, you will need to use `FormData` (refer [this answer](http://stackoverflow.com/questions/29293637/how-to-append-whole-set-of-model-to-formdata-and-obtain-it-in-mvc/29293681#29293681) for an example –  Jan 13 '16 at 06:39
  • @TiesonT., thanks for the heads up. I already know about it, but since it's just an image, I'm willing to take the risk. Besides, all ids will be encoded, I haven't given the codes here because it'll be difficult to understand the problem then. – Shihan Khan Jan 13 '16 at 06:42
  • Let me check with that, if I stuck I'll let you know. – Shihan Khan Jan 13 '16 at 06:44
  • @StephenMuecke, Hi, please check my latest update. I'm only getting error alert everytime I try to upload. – Shihan Khan Jan 13 '16 at 07:11
  • Probably your throwing an exception on the server (you have not shown the revised controller POST method so can't know for sure). Use you browser tools (NetWork tab) to inspect the response - it will give you the details of the error. –  Jan 13 '16 at 07:14
  • You cannot upload file with ajax so easy – Gene R Jan 13 '16 at 07:18
  • @SinOscuras where you use ajax call. In external Js or on cshtml? – Umer Waheed Jan 13 '16 at 07:21
  • @StephenMuecke, I checked the error and it seems like it's not getting `getFlId` value which is needed to rename the image. Any idea what's wrong? – Shihan Khan Jan 13 '16 at 07:21
  • @Umer, on cshtml. Is it safe? – Shihan Khan Jan 13 '16 at 07:22
  • You have an input with `name="getFlId"` so its value should bind to the `int getFlId` parameter. Are you sure `@ViewBag.ImgName` actualyy has a valid value when you generate the view (inspect the page source and check the `value` attribute) –  Jan 13 '16 at 07:24
  • @SinOscuras yes it's ok but it is recommended to use in external js. Have you changed return RedirectToActionto return json? – Umer Waheed Jan 13 '16 at 07:25
  • @StephenMuecke, yes I've checked at console and I'm getting the accurate id in the viewbag. No problem with that. – Shihan Khan Jan 13 '16 at 07:26
  • @Umer, There is no reason to use an external js file (and if OP did, then `url: '@Url.Action("FlatImageOne", "Home")',` would not even work –  Jan 13 '16 at 07:26
  • @Umer, thanks. No, it's RedirectToAction. – Shihan Khan Jan 13 '16 at 07:26
  • So is the value of `int getFlId` equal to `0` when you hit the POST method? –  Jan 13 '16 at 07:28
  • @StephenMuecke i said it's ok but it is recommended to use in external file. I know helper is not working in external file '@Url.Action("FlatImageOne", "Home")'. But /Home/FlatImageOne will work – Umer Waheed Jan 13 '16 at 07:28
  • No, not at all. It's 32 at this moment. – Shihan Khan Jan 13 '16 at 07:28
  • Which means its binding correctly. So what are you expecting it to be? –  Jan 13 '16 at 07:29
  • @SinOscuras if you are getting all parameters then the error is 100% redirectToAction. You should return json. – Umer Waheed Jan 13 '16 at 07:29
  • @SinOscuras Debug it and see what happen. Is complete function run or getting some exception? – Umer Waheed Jan 13 '16 at 07:30
  • @StephenMuecke, this Viewbag value will pass on the controller as a parameter and will rename the image with the value. Please check my post for Controller part. – Shihan Khan Jan 13 '16 at 07:32
  • So what is the problem? Your stated previously that you _not getting getFlId value_ but you are - its `32`. Note you also need to remove all the `TempData` and `return RedirectToAction()` code - your now using ajax which stays on the same page - it will never redirect. I suggest you test that you ajax is working by commenting out all the code inside the controller method and replace it with `return Json(true);` –  Jan 13 '16 at 07:37
  • 1
    @SinOscuras i add the answer.Please see it – Umer Waheed Jan 13 '16 at 07:39

2 Answers2

0

This to get you an idea how you can perform it.

Change anchor to button like this

<button data-serial="@Model.serial" class="btnInfo" data-target="#myModal" data-toggle="modal">Change Featured Image</<button >

Modify your modal as:

<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                <h4 class="modal-title" id="myModalLabel">Change Image</h4>
            </div>
            <div class="modal-body">
               <div> 
                  <input type="file" name="file" id="Upload" />    
                 <input type="hidden"  id="SerailID" />   //Filled on showm.bs.modal event fires on modal opening          
                 <input type="button" id="UploadButton" class="btn btn-info" value="Upload" />
        </div>
        <div id="setImage">
          //Append here image on success
        </div>
            </div>
        </div>
    </div>
</div>

show.bs.modal called when modal opens

$('#myModal').on('show.bs.modal', function (event) {
  var button = $(event.relatedTarget) // Button that triggered the modal
  var serialID= button.data('serial') // Extract info from data-* attributes
  // If necessary, you could initiate an AJAX request here (and then do the updating in a callback).
  // Update the modal's content. We'll use jQuery here, but you could use a data binding library or other methods instead.

  $("#SerailID").val(serialID); //Put value to hidden input


  });




$("#UploadButton").on("click",function(){
     e.preventDefault();
    var file = document.getElementById('Upload').files[0];
    var fileName = file.name;
    var SerialID = $("#SerailID").val(); //get serial id from hidden button
    var fd = new FormData();
    fd.append("file", file);
    fd.append("getFlId", SerialID );

    $.ajax({
        url: "Set YOUR URL",
        type:"POST",
        processData: false,
        contentType: false,
        data: fd ,
        success: function (response) {
           //append image after sccess upload.
           $("#setImage").html(" <img src="~/Images/Flats/'+SerialID +'" alt="your image" class="img-responsive" />");
        },
        error: function (er) {
            alert(er);
        }

});
Anil Panwar
  • 2,592
  • 1
  • 11
  • 24
  • Thanks, I checked your code and realized that I wasn't appending anything in my `Formdata()`. But I've still one question, what is the use of `show.bs.modal` you mentioned here? – Shihan Khan Jan 13 '16 at 07:40
  • Its bootstrap event just like event(click, keyup etc) in jquery...this fires when modal opens using clicked button that has data target attribute as id of the modal. I suggest you to go through bootstrap events once because it makes life easir when you use bootstrap. Check Javascript menu item for more kind of event in getbootsrap.com – Anil Panwar Jan 13 '16 at 08:04
  • @SinOscuras, `FormData($('form').get(0));` automatically adds the form inputs (including the file input). You don't need to append anything –  Jan 13 '16 at 08:05
  • Okie that's good I just wrote this code without checking it, i wrote in notepad and posted for reference. – Anil Panwar Jan 13 '16 at 08:10
  • @AnilPanwar, thanks, but now a new problem is causing. Image is not updating in modal. It's always showing the cached image. Any idea why it's happening? – Shihan Khan Jan 13 '16 at 08:14
  • Cache false in ajax as $.ajax({ cache: false }); Are you appending image as in success i have mentioned? if so then put debugger to see the id / name of the image is correct you passing when appending – Anil Panwar Jan 13 '16 at 09:24
-1

Try this

[HttpPost]
    public ActionResult FlatImageOne(HttpPostedFileBase file, int getFlId)
    {
        var status = false;
        if (file != null && file.ContentLength > 0)
        {
            string picName = getFlId.ToString() + "-0";
            WebImage img = new WebImage(file.InputStream);
            string picExt = Path.GetExtension(file.FileName);
            if (picExt == ".jpg" || picExt == ".gif" || picExt == ".jpeg" || picExt == ".png")
            {
                picExt = "PNG";
                string path = System.IO.Path.Combine(Server.MapPath("~/Images/Flats/"), picName);
                var img_cropped = img.Resize(1000, 667, false, true);
                img_cropped.Save(path, picExt);
                TempData["img1_update_success"] = "Image Updated Successfully!";
                return RedirectToAction("FlatImageOne", new { FlId = getFlId });
            }
            else
            {
                TempData["img1_update_fail"] = "Error! Wrong File Type(s)! Please Try Again.";

             status =true;
            }
        }
        else
        {
            TempData["img1_update_fail"] = "Error! Please provide an image file to update.";
            status =true;
        }

return Json(status );
    }
Umer Waheed
  • 4,044
  • 7
  • 41
  • 62