Link to home
Start Free TrialLog in
Avatar of dan henderson
dan hendersonFlag for United States of America

asked on

ajax post without refreshing whole page

I have a javascript function to upload images to my application.  The upload part works perfectly.  The problem is that when it returns it wants to refresh the whole page.  Here is my code:
    function SavePhoto(pid) {
        var form = $('#frmPost');
        var file;
        var pid;

        // read the file inputs and stop at the first one found.
        var inputs = $("input:file");
        for (var i = 0; i < inputs.length; i++) {
            if (inputs[i].type.toLowerCase() == 'file') {
                if (inputs[i].files.length > 0) {
                    file = inputs[i].files[0];
                    break;
                }
            }
        }

        if (!file) {
            return;
        }

        // create the formdate object and append items to it.
        var fd = new FormData(form);
        fd.append("file", file);
        fd.append("pid", pid);

        $.ajax({
            type: "POST",
            url: '/Residents/UploadFile/' + pid,
            contentType: false,
            data: fd,
            processData: false,
            success: function (data) {
                //$('#divPets').load('/Residents/GetPets/' + RID);
                //alert(data);
            }
        });

    }

Open in new window


How do I keep the whole page from reloading?  I just want the div that holds the image to update.
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

AJAX calls don't refresh the page - that refresh is coming from somewhere else.

I suspect you have a button you are clicking that is triggering this.

The button is part of a form

The default action of the form is to submit - which is what is happening.

You need to cancel the default action on the button click.

How are you calling SavePhoto() (onclick? ) if so then simply do this

<input onclick="SavePhoto();return false;" ... />

Open in new window

The return false will cancel the default behaviour. IF that does not work post your form code here so we can see what is going on.
Avatar of dan henderson

ASKER

yes, it's from a button click.
already have "return false" as part of the "onclick" command.
the form is also part of a razor view.

here is my form code without the javascript since that's already posted above.
@model IEnumerable<Models.Pet>

<form id="frmPost">
    @foreach (var item in Model.Select((value, i) => new { i, value }))
    {
        <div class="col-md-5 no-padding lib-item" data-category="view" style="border: solid 1px black;margin-top: 15px;">
            <div class="lib-panel">
                <div class="row box-shadow" style="margin-top: 15px;">
                    <div class="col-md-6" style="vertical-align:middle;">
                        <img class="lib-img-show" src="@item.value.ImageURL" style="height:100px;width:100px;">
                        <br /><br />
                        <div id="@(string.Format("update{0}", @item.i))" style="display: none;">
                            <input type="file" id="petPhoto" /><br />
                            <button type="button" onclick="SavePhoto('@item.value.PetId', @item.i); return false;" class="btn-info">Save Photo</button>
                        </div>
                    </div>
                    <div class="col-md-6">
                        <div class="lib-row lib-header" style="font-weight:bold">
                            @item.value.Name
                            <br /><br />
                        </div>
                        <div class="lib-row">
                            @item.value.Breed
                            <br />
                            @item.value.Color
                            <br />
                            @item.value.Weight" pounds"
                            <br />
                            @item.value.Notes
                            <br /><br />

                            <button id="show" onclick="toggleDiv('@(string.Format("update{0}", @item.i))'); return false;">Update Photo</button>
                            <br /><br />
                            <button type="button" onclick="EditPet(@item.value.PetId); return false;">Edit</button>
                            <br />
                        </div>
                    </div>
                </div>
            </div>
        </div>

    }
</form>

Open in new window

Have you checked your console for errors - an error could cause the return not to work.

Do you have a test link?

If not can you post the rendered HTML
here is the rendered html for div holding the form that has the post call:
<div id="divPets" aria-labelledby="ui-id-2" role="tabpanel" class="ui-tabs-panel ui-corner-bottom ui-widget-content" aria-hidden="false" style=""><form id="frmPost">
        <div class="col-md-5 no-padding lib-item" data-category="view" style="border: solid 1px black;margin-top: 15px;">
            <div class="lib-panel">
                <div class="row box-shadow" style="margin-top: 15px;">
                    <div class="col-md-6" style="vertical-align:middle;">
                        <img class="lib-img-show" src="Gallery/PID1_Petey_T.png" style="height:100px;width:100px;">
                        <br><br>
                        <div id="update0" style="display: none;">
                            <input type="file" id="petPhoto"><br>
                            <button type="button" onclick="SavePhoto('1', 0); return false;" class="btn-info">Save Photo</button>
                        </div>
                    </div>
                    <div class="col-md-6">
                        <div class="lib-row lib-header" style="font-weight:bold">
                            Pete
                            <br><br>
                        </div>
                        <div class="lib-row">
                            chihuahua
                            <br>
                            tan
                            <br>
                            12" pounds"
                            <br>
                            
                            <br><br>

                            <button id="show" onclick="toggleDiv('update0'); return false;">Update Photo</button>
                            <br><br>
                            <button type="button" onclick="EditPet(1); return false;">Edit</button>
                            <br>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <div class="col-md-5 no-padding lib-item" data-category="view" style="border: solid 1px black;margin-top: 15px;">
            <div class="lib-panel">
                <div class="row box-shadow" style="margin-top: 15px;">
                    <div class="col-md-6" style="vertical-align:middle;">
                        <img class="lib-img-show" src="Gallery/PID2_April_T.png" style="height:100px;width:100px;">
                        <br><br>
                        <div id="update1" style="display: none;">
                            <input type="file" id="petPhoto"><br>
                            <button type="button" onclick="SavePhoto('2', 1); return false;" class="btn-info">Save Photo</button>
                        </div>
                    </div>
                    <div class="col-md-6">
                        <div class="lib-row lib-header" style="font-weight:bold">
                            Fred
                            <br><br>
                        </div>
                        <div class="lib-row">
                            german shepard
                            <br>
                            black
                            <br>
                            35" pounds"
                            <br>
                            
                            <br><br>

                            <button id="show" onclick="toggleDiv('update1'); return false;">Update Photo</button>
                            <br><br>
                            <button type="button" onclick="EditPet(2); return false;">Edit</button>
                            <br>
                        </div>
                    </div>
                </div>
            </div>
        </div>
</form>

Open in new window

Here is the page that holds the div above.  I has a jqgrid control that loads everything when a row is selected.  Don't know if this is causing the issue, but the ajax call is done on the pet page within the div.
@model IEnumerable<Models.Resident>

@{
    ViewBag.Title = "Index";
}




<div class="container" style="margin-top: 15px;">
    <div style="float:left;">
        <table id="grid-table"></table>
        <div id="pager"></div>
    </div>
    

    <div class="row">
        <div class="col-lg-4 col-md-4 col-sm-4">
            <div class="panel panel-success">
                <div class="panel-heading">Notes</div>
                <div class="panel-body" id="divNotes" style="max-height: 250px;overflow-y: scroll;"></div>
            </div>
        </div>
        <div class="col-lg-4 col-md-4 col-sm-4">
            <div class="panel panel-danger">
                <div class="panel-heading">Emergency Contact</div>
                <div class="panel-body" id="divEMC" style="max-height: 75px;overflow-y: scroll;"></div>
            </div>
        </div>
        <div class="col-lg-4 col-md-4 col-sm-4">
            <div class="panel panel-warning">
                <div class="panel-heading">Out of Town</div>
                <div class="panel-body" id="divOOT" style="overflow-y: scroll;"></div>
            </div>
        </div>
    </div>
</div>

<br />
<div class="container">

        <div class="row">
            @* NEW PANELS *@

            <div class="col-lg-12 col-md-12 col-sm-12">
                <div id="tabs">
                    <ul class="nav nav-tabs tabs-up">
                        <li><a href="#divResident" data-toggle="tab" data-target="divResident" data-url="/Residents/Details1/">Resident</a></li>
                        <li><a href="#divPets" data-toggle="tab" data-target="divPets" data-url="/Residents/GetPets/">Pets</a></li>
                        <li><a href="#divCalls" data-toggle="tab" data-target="divCalls" data-url="/Dispatches/FetchSummary/">Calls</a></li>
                    </ul>
                    <div id="divResident" class="active"></div>
                    <div id="divPets"></div>
                    <div id="divCalls"></div>
                </div>

            </div>


        </div>

    </div>


<link href="~/Content/themes/cupertino/jquery-ui.cupertino.css" rel="stylesheet" />
<link href="~/Content/ui.jqgrid.css" rel="stylesheet" />
<link href="~/Content/font-awesome.css" rel="stylesheet" />
<link href="~/Content/Site.css" rel="stylesheet" />

<script src="~/Scripts/jquery-3.1.1.js"></script>
<script src="~/Scripts/jquery-ui-1.12.1.js"></script>
<script src="~/Scripts/free-jqGrid/jquery.jqgrid.src.js"></script>



<style type="text/css">
    .rowClass {
        background-color: orange;
        background-image: none;
    }

    .body {
        font-size: 12px;
    }

    tabs-smaller .ui-tabs-nav li {
        margin-top: 0.6em;
        font-size: 80%;
    }
</style>

<script language="javascript">
    var RID = 0;


    $(document).ready(function () {
        var grid_selector = "#grid-table";
        var pager_selector = "#pager";

        $(grid_selector).jqGrid({
            url: '/Residents/GetResidents',
            async: true,
            datatype: "json",
            contentType: "application/json; charset-utf-8",
            mtype: 'GET',
            loadonce: true,
            width: 600,
            colNames: ['ID', 'First Name', 'Last Name',
                'Street Address', 'Home Phone', ''],
            colModel: [
                { name: 'id', width: 20, search: false, sortable: false, search: false },
                { name: 'firstName', width: 90, sortable: false, search: false },
                { name: 'lastName', width: 90 },
                { name: 'streetAddress', width: 200 },
                { name: 'homePhone', width: 75 },
                { name: 'officerWarning', width: 50, search: false, formatter: 'checkbox', align: 'center' }
            ],
            iconSet: "fontAwesome",
            ignoreCase: true,
            rowNum: 20,
            pager: pager_selector,
            pgbuttons: true,
            sortable: false,
            viewrecords: false,
            caption: "Residents",
            emptyrecords: 'No data for the applied filter',
            height: 450,
            gridview: true,
            rowattr: function (rd) {
                if (rd.officerWarning) {
                    return { "class": "rowClass" };
                }
            },
            onSelectRow: function (id) {
                if (id > 0 && id != null) {
                    RID = id;
                    var target = '/Residents/Details1/' + id;

                    $('#divResident').load(target, function (response, status, xhr) {
                        var notes = $(response).find('#notes');
                        $('#divNotes').html(notes.html());
                        $("#tabs").tabs({ active: 0 });

                        var emcName = $(response).find('#emcName');
                        var emcPhone = $(response).find('#emcPhone');
                        var emcRelation = $(response).find('#emcRelation');

                        $('#divEMC').html(emcName.html() + '<br />' + emcPhone.html() + '<br />' + emcRelation.html());
                        $('#divOOT').load('/ResidentOots/Details/' + id);
                    });
                }
            }
        });

        $("#grid-table").jqGrid('filterToolbar', { stringResult: true, searchOnEnter: false, ignoreCase: true });
        $("#pager_left, #pager_center", "#pager").width(50);
        $("#tabs").tabs({ active: 0 });

    });


    // tab click operations
    $('#tabs a').on('click', function (e) {
        e.preventDefault();

        $("#tabs").tabs({ active: e.id });
        var url = $(this).attr("data-url") + RID;
        var target = $(this).attr("data-target");
        //alert(url);
        switch (target) {
            case 'divResident':
                //this has already been loaded.
                break;
            case 'divPets':
                $('#divPets').load(url);
                break;
            case 'divCalls':
                $('#divCalls').load(url);
                break;
        }

        $(this).show();
    });

    // Edit / Save OOT
    function EditResident(rid) {
        var url = '/Residents/Edit/' + rid;
        $('#divResident').load(url);
    }

    function SaveResident(form) {
        var formId = '#' + form.id;
        url = 'Residents/Edit';
        var frmData = $(formId).serialize();

        $.ajax({
            type: "POST",
            url: url,
            data: frmData,
            success: function (data) {
                fetchUrl = '/Residents/Details1/' + data[0];
                $('#divResident').load(fetchUrl);
            }
        });
    }

    // Edit / Save Pet
    function EditPet(pid) {
        var url = '/Residents/EditPet/' + pid;
        $('#divPets').load(url);
    }

    function SavePet(form) {
        var formId = '#' + form.id;
        url = 'Residents/EditPet';
        var frmData = $(formId).serialize();

        $.ajax({
            type: "POST",
            url: url,
            data: frmData,
            success: function (data) {
                fetchUrl = '/Residents/GetPets/' + data[0];
                $('#divPets').load(fetchUrl);
            }
        });
    }
    
    function Cancel(name, id){
        switch (name) {
            case 'Resident':
                fetchUrl = '/Residents/Details1/' + id;
                $('#divResident').load(fetchUrl);
                break;
            case 'Pet':
                fetchUrl = '/Residents/GetPets/' + id;
                $('#divPets').load(fetchUrl);
        }
    }



    
    function LoadCallDetail(target) {
        alert(target);
        $('#divCalls').load(target);
    }
</script>

Open in new window

Here is the get and post calls in the controller.  It's only returning a string after post:
        [HttpGet]
        public ActionResult UploadFile()
        {
            return PartialView();
        }
        [HttpPost]
        public ActionResult UploadFile(HttpPostedFileBase file, int pid)
        {
            string path = "";
            string fileName = "";
            string imageUrl = "";
            string baseFileName = "";
            string thumbnail;
            string ext = "";

            try
            {
                if (file.ContentLength > 0)
                {
                    fileName = "PID" + pid.ToString() + "_" + Path.GetFileName(file.FileName);
                    baseFileName = Path.GetFileNameWithoutExtension(fileName);
                    ext = Path.GetExtension(fileName);

                    string folder = Server.MapPath("~/Gallery");

                    // save the image
                    path = Path.Combine(folder, fileName);
                    file.SaveAs(path);

                    //Read image back from file and create thumbnail from it
                    thumbnail = baseFileName + "_T" + ext; 
                    var path2 = Path.Combine(folder, thumbnail);

                    /* Creates Image from specified data stream */
                    using (var image = Image.FromStream(file.InputStream, true, true)) 
                    {
                        using (var thumb = image.GetThumbnailImage(
                             100, /* width*/
                             100, /* height*/
                             () => false,
                             IntPtr.Zero))
                        {
                            var jpgInfo = ImageCodecInfo.GetImageEncoders().Where(codecInfo => codecInfo.MimeType == "image/png").First(); /* Returns array of image encoder objects built into GDI+ */
                            using (var encParams = new EncoderParameters(1))
                            {
                                string outputPath = path2;
                                long quality = 100;
                                encParams.Param[0] = new EncoderParameter(Encoder.Quality, quality);
                                thumb.Save(outputPath, jpgInfo, encParams);
                            }
                        }
                    }

                    imageUrl = "Gallery/" + thumbnail;

                    ResidentPet pet = db.ResidentPets.Find(pid);
                    if (pet != null)
                    {
                        pet.ImageURL = imageUrl;
                        db.SaveChanges();
                        return Content("OK");
                    }
                    else
                    {
                        return Content("No pet found");
                    }
                }

                ViewBag.Message = "File Uploaded Successfully!!";
                return Content("OK");
            }
            catch
            {
                ViewBag.Message = "File upload failed!!";
                return Content("Failed");
            }
        }

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks for pointing that out.  I have made the correction.  The whole page still gets reloaded.
I figured it out.  Moved the js code to the parent page, return the id.toString from the controller, then reload the div.
Thanks for you help.
You are welcome.