tony09uk
tony09uk

Reputation: 2991

asp mvc display not updating when using ajax

I have been following the example of some ajax functionality I got working earlier in my project, but I have come to a sticking point where my current functionality doesn't seem to work, the only difference that I can see that I am naming the partialView that I am returning and that I am trying to update images being displayed (although i'm guessing that wont make a difference).

Aim Allow user to select and upload images, and display newly uploaded images using ajax

Problem Images from both the temporary and final destination folders are displayed on initial page load, but partial page refresh does not appear to happen after upload is complete

controller

[HttpPost]
public ActionResult _Image(TakeOn to, IEnumerable<HttpPostedFileBase> FileUpload)
{
    to.ImageUpload(FileUpload);//takes all files in FileUpload and places them in a temporary folder
    return PartialView("_Rooms", to);
}

js (ajax)

$(".row").on("change", ".imgInput", function (e) {
    var roomID = $(this).siblings("input:hidden").val();
    $("#roomIdentifier").val(roomID);
    var formData = new FormData(jQuery('#takeOn').get(0)) // store form data to pass on to the controller
    $.ajax({
        type: "POST",
        url: "/Property/_Image",
        contentType: false,
        data: formData,
        dataType: 'json',
        encode: true,
        async: false,
        processData: false,
        cache: false,
        success: function (data) {
            //$(".imgUploader").html(data);//first attempt, both tried by targetting .imgUploader and #accordion
            $("#accordion").replaceWith(("#accordion", html));
        },
        error: function (request, status, error) {
        }
    });

    //clear input value
    var input = $(this);
    input.replaceWith(input.val('').clone(true));
    //clear identifier
    $("#roomIdentifier").val('');
});

view (_Rooms.cshtml) - (this is a partial view which is held in #accordion div )

@model TjsPropertyPeople.Web.Admin.ViewModels.Property.TakeOn

@for (int i = 0; i < Model.Rooms.Count; i++)
{
<div class="panel panel-default room">
    <div class="panel-heading">
        <h4 class="panel-title">
            @{ ViewBag.Title = Model.Rooms[i].Title == null ? "New Room" : Model.Rooms[i].Title; }
            @{ ViewBag.titleID = "title" + i; }
            <a [email protected] data-toggle="collapse" data-parent="#accordion" href="#collapseOne" class="collapsed">@ViewBag.Title</a>
        </h4>
    </div>
    <div class="panel-collapse collapse in" style="height: auto;">
        <div class="panel-body">
            <row class="col-lg-4">
                @{ViewBag.roomID = "roomtitle" + i;}
                @Html.TextBoxFor(m => m.Rooms[i].Title, null, new { @id = ViewBag.roomID, @class = "form-control roomTitle", @placeholder = "Title" })
            </row>
            <row class="col-lg-4">
                @Html.TextBoxFor(m => m.Rooms[i].Width, null, new { @class = "form-control", @placeholder = "Width" })
            </row>
            <row class="col-lg-4">
                @Html.TextBoxFor(m => m.Rooms[i].Length, null, new { @class = "form-control", @placeholder = "Length" })
                <label class="checkbox-inline">
                    @Html.CheckBoxFor(m => Model.Rooms[i].Overall) Overall
                </label>
            </row>
            <row class="col-lg-6">
                @Html.TextAreaFor(m => m.Rooms[i].Description, new { @class = "form-control", @placeholder = "Description" })
            </row>
            <row class="col-lg-6">
                <div class="imgUploader">
                    <div>
                        <div style="height: auto; width: auto; position: relative;">
                            @{ ViewBag.TempPath = Server.MapPath("~/App_Uploads/Images/Temp/" + Model.PropertyID + "/" + Model.Rooms[i].RoomID + "/"); }
                            @{ ViewBag.UploadedPath = Server.MapPath("~/App_Uploads/Images/Property/" + Model.PropertyID + "/" + Model.Rooms[i].RoomID + "/"); }
                            @{ ViewBag.TempExists = Directory.Exists(ViewBag.TempPath); }
                            @{ ViewBag.UploadedExists = Directory.Exists(ViewBag.UploadedPath); }
                            @{ List<string> files = new List<string>(); }

                            @if (ViewBag.TempExists)
                            {
                                string[] f = Directory.GetFiles(ViewBag.TempPath);
                                files.AddRange(f);
                            }
                            @if (ViewBag.UploadedExists)
                            {
                                string[] f = Directory.GetFiles(ViewBag.UploadedPath);
                                files.AddRange(f);
                            }
                            @foreach (var file in files)
                            {
                                string name = file.Substring(file.LastIndexOf("App_Uploads"));
                                name = @"~\" + name;
                                <img class="pull-left panel" src="@Url.Content(name)" height="50" />
                                @*<div class="delete">X</div>*@
                            }
                        </div>
                    </div>
                </div>
                <input class="imgInput" type="file" name="FileUpload" multiple accept="image/jpeg">
                @Html.HiddenFor(m => m.Rooms[i].RoomID)
            </row>
        </div>
    </div>
</div>
}

Note I realise that the view could be written MUCH better, I just don't know how to abstract all that unnecessary code from the view at this time and feel I should get the functionality working before "playing" with yet another area I don't fully understand (although I'm against any advice that can be offered in this area)

EDIT

in the error part of the script I added alert("Error: " + error) and it returned this

javascript error syntax: unexpected token <

I have googled it and found this answer, there seem to be a lot of places in my code that could be causing this (if this answer is applicable to me). So how would I start tracking down the root of the problem?

Upvotes: 1

Views: 513

Answers (2)

tony09uk
tony09uk

Reputation: 2991

Thanks to Brian Ogden I was able to resolve this issue.

As mentioned I needed to change

$("#accordion").replaceWith(("#accordion", html));

To:

$("#accordion").html(data);

But this brought another problem syntax error: unexpected token <

It was caused by not closing a html tag so changing:

<input class="imgInput" type="file" name="FileUpload" multiple accept="image/jpeg">

to

<input class="imgInput" type="file" name="FileUpload" multiple accept="image/jpeg" />

resolved it completely. I would be interested to know why a badly formatted tag stop ajax calls from working

Upvotes: 0

Brian Ogden
Brian Ogden

Reputation: 19212

Try changing this line in your $ajax.success function from:

$("#accordion").replaceWith(("#accordion", html));

To:

 $("#accordion").html(data);

The ("#accordion", html) looks like invalid jQuery to me, and I don't see a var called html in your code either. Your partial HTML response var is named data not html.

If that doesn't work, add the following line to your $ajax.success function:

console.log(data);

And see that the response is your Partial HTML in your browser F12 developer tools Console

Upvotes: 1

Related Questions