locked
JQuery Sortable - Images sorting and save the new sorted list to the database RRS feed

  • Question

  • User-1053389048 posted

    Hi,

    I was following this post (https://forums.asp.net/t/1650158.aspx?Sorting+rearranging+order+of+a+photo+album+using+jQuery+Sortable) to sort the images listing priority and save the new sorted list to the database using .Net Core 2.2 MVC.

    Error:

    I'm not able to save the list to the database. Error code is HTTP500: SERVER ERROR.  Below are my codes:

    HTML:

    <ul id="sortable">
    @if (Model.Images.Count() > 0)
    {
    @foreach (var item in Model.Images)
    {

    <li class="ui-state-default"><img id="@item.Id" src="@Url.Content("~/upload/images/" + @item.FileURL)" width="296" alt="" /></li>
    }
    }
    </ul>
    <input type="button" id="orderPhoto" value="Save change" />

    JavaScript:

    <script src="~/lib/jquery-ui-1.12.1/jquery-ui.js"></script>

    <script src="https://code.jquery.com/jquery-1.12.4.js"></script>

    <script type="text/javascript">
    $(function () {
    $("#sortable").sortable({
    placeholder: "ui-state-highlight"
    });
    $("#sortable").disableSelection();

    $("#orderPhoto").click(function () {
    var photos = $.map($("li.ui-state-default"), function (item, index) {
    var imgDetail = new Object();
    imgDetail.Id = parseInt($(item).find("img").attr("id"));
    imgDetail.Priority = index + 1;
    return imgDetail;
    });
    var jsonPhotos = JSON.stringify(photos);
    $.ajax({
    type: "POST",
    contentType: 'application/json',
    data: '{"photos":' + jsonPhotos + '}',
    url: '/Property/SortImg',
    dataType: "json",
    traditional: true,
    success: function (data) {
    alert(data.d);
    },
    error: function(XMLHttpRequest, textStatus, errorThrown) {
    debugger;
    }
    });
    });
    });

    </script>

    </script>

    Json Result from above:

    {"photos":[{"Id":14,"Priority":1},{"Id":15,"Priority":2},{"Id":16,"Priority":3},{"Id":17,"Priority":4},{"Id":18,"Priority":5},{"Id":19,"Priority":6},{"Id":20,"Priority":7},{"Id":21,"Priority":8},{"Id":22,"Priority":9},{"Id":23,"Priority":10},{"Id":24,"Priority":11},{"Id":25,"Priority":12},{"Id":6,"Priority":13},{"Id":7,"Priority":14},{"Id":8,"Priority":15},{"Id":9,"Priority":16},{"Id":10,"Priority":17},{"Id":11,"Priority":18},{"Id":12,"Priority":19}]}

    View Model:

    public class SortImageViewModel
    {
    public int Id { get; set; }
    public int Priority { get; set; }
    }

    Post the above Json result to the controller below. What it should do is finding the matching Id in the Json list with the Images Id from the database table, then update the Priority number.

    [HttpPost]
    public IActionResult SortImg(List<SortImageViewModel> photos)
    {

    foreach (SortImageViewModel item in photos)
    {
    var imgDB = _db.Images.FirstOrDefault(x => x.Id == item.Id);
    imgDB.Priority = item.Priority;
    _db.Update(imgDB);
    _db.SaveChanges();

    }

    return View(RedirectToAction(nameof(Index)));

    }

    I think it is something wrong with the above controller. I tried many methods but failed. Any help is appreciated.

    Thank you.

    Thursday, August 1, 2019 12:00 PM

Answers

  • User-1053389048 posted

    Hi,

    For days I researched and tried so many methods. Remove the dataType:"json", or change dataType to "text" didn't work. The controller received null or 0 value.

    Today I just manage to make it work by adding [FromBody]  to the controller. Codes as below:

    [HttpPost]
    public string SortImg([FromBody]List<SortImageViewModel> photos)  // Add [FromBody] and it works!
    {

    foreach (SortImageViewModel item in photos)
    {
    var imgDB = _db.Images.FirstOrDefault(x => x.Id == item.Id);
    imgDB.Priority = item.Priority;
    _db.Update(imgDB);
    _db.SaveChanges();

    }

    return "true";

    }

    Now, problem solved. I guess [FromBody] is needed to instruct the controller to read from the string passed!?...

    Thanks for your help YongQing :)

    Sam

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, August 6, 2019 10:56 AM

All replies

  • User665608656 posted

    Hi samsooi,

    According to your code, the reason for this issue is that when you use ajax to call the SortImg method, the SortImg method return IActionResult type.

    If you only want to redirect to another view after you update data ,you could better do it in the success method in ajax instead of controller.

    You need to change your code like below :

     [HttpPost] 
            public string SortImg(List<SortImageViewModel> photos)
            {
                foreach (SortImageViewModel item in photos)
                {
                    var imgDB = _db.Images.FirstOrDefault(x => x.Id == item.Id);
                    imgDB.Priority = item.Priority;
                    _db.Update(imgDB);
                    _db.SaveChanges();
    
                }
                return "";
            }

    Change code in your ajax like this:

    <script type="text/javascript">
    $(function () {
    $("#sortable").sortable({
    placeholder: "ui-state-highlight"
    });
    $("#sortable").disableSelection();
    
    $("#orderPhoto").click(function () {
    var photos = $.map($("li.ui-state-default"), function (item, index) {
    var imgDetail = new Object();
    imgDetail.Id = parseInt($(item).find("img").attr("id"));
    imgDetail.Priority = index + 1;
    return imgDetail;
    });
    var jsonPhotos = JSON.stringify(photos);
    $.ajax({
    type: "POST",
    contentType: 'application/json',
    data: '{"photos":' + jsonPhotos + '}',
    url: '/Property/SortImg',
    dataType: "json",
    traditional: true,
    success: function (data) {
    alert(data.d);
    window.location.href ='/Property/View';//you can change it to what you want to redirect
    },
    error: function(XMLHttpRequest, textStatus, errorThrown) {
    debugger;
    }
    });
    });
    });
    
    </script>


    Hope this will help you.

    Best Regards,

    YongQing. 

    Friday, August 2, 2019 7:22 AM
  • User-1053389048 posted

    Thanks for your feedback.

    I tried the code. But still not able to save to the database. 

    Error messages:

    textStatus parsererror

    errorThrown JSON.parse Error: Unexpected input at

    stack SyntaxError: JSON.parse Error: Unexpected input at at jQuery.parseJSON (https://code.jquery.com/jquery-1.12.4.js:9011:3) at ajaxConvert (https://code.jquery.com/jquery-1.12.4.js:9335:8) at done (https://code.jquery.com/jquery-1.12.4.js:9789:4) at callback (https://code.jquery.com/jquery-1.12.4.js:10311:8)

    I checked my data posted and it should be correct.

    {"photos":[{"Id":14,"Priority":1},{"Id":15,"Priority":2},{"Id":16,"Priority":3},{"Id":17,"Priority":4},{"Id":18,"Priority":5},{"Id":19,"Priority":6},{"Id":20,"Priority":7},{"Id":21,"Priority":8},{"Id":22,"Priority":9},{"Id":23,"Priority":10},{"Id":24,"Priority":11},{"Id":25,"Priority":12},{"Id":6,"Priority":13},{"Id":7,"Priority":14},{"Id":8,"Priority":15},{"Id":9,"Priority":16},{"Id":10,"Priority":17},{"Id":11,"Priority":18},{"Id":12,"Priority":19}]}

    I googled the above error messages, still no luck. Any idea?

    Thank you.

    Friday, August 2, 2019 11:49 AM
  • User665608656 posted

    Hi samsooi,

    samsooi

    Error messages:

    textStatus parsererror

    errorThrown JSON.parse Error: Unexpected input at

    stack SyntaxError: JSON.parse Error: Unexpected input at at jQuery.parseJSON (https://code.jquery.com/jquery-1.12.4.js:9011:3) at ajaxConvert (https://code.jquery.com/jquery-1.12.4.js:9335:8) at done (https://code.jquery.com/jquery-1.12.4.js:9789:4) at callback (https://code.jquery.com/jquery-1.12.4.js:10311:8)

    The error message shows that the data type returned by the method in the controller  is not consistent with the datatype in the ajax.

    To solve this question, you can try to delete this sentence from Ajax:

    dataType: "json", // remove this sentence
    

    You can also refer to this link : jQuery returning “parsererror” for ajax request

    Best Regards,

    YongQing.

    Monday, August 5, 2019 1:32 AM
  • User-1053389048 posted

    Hi,

    For days I researched and tried so many methods. Remove the dataType:"json", or change dataType to "text" didn't work. The controller received null or 0 value.

    Today I just manage to make it work by adding [FromBody]  to the controller. Codes as below:

    [HttpPost]
    public string SortImg([FromBody]List<SortImageViewModel> photos)  // Add [FromBody] and it works!
    {

    foreach (SortImageViewModel item in photos)
    {
    var imgDB = _db.Images.FirstOrDefault(x => x.Id == item.Id);
    imgDB.Priority = item.Priority;
    _db.Update(imgDB);
    _db.SaveChanges();

    }

    return "true";

    }

    Now, problem solved. I guess [FromBody] is needed to instruct the controller to read from the string passed!?...

    Thanks for your help YongQing :)

    Sam

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, August 6, 2019 10:56 AM