Home > Back-end >  How can I re-order divs using 2 buttons and save the order?
How can I re-order divs using 2 buttons and save the order?

Time:12-02

I have mulitple divs that are dipslayed using a foreach loop and i want to be able re-order using 2 buttons and i also want be able to save this order so when i come back on after refreshing the page the new order is still present.

**What I have done so far **

I have managed to use JavaScript to move the html elements up and down using 2 buttons. I have also added public int OrderNum to the public class Lesson and I have made the divs order by increasing OrderNum. However i'm struggling to be able to change the orderNumm when the button is of each div when the buttons are pressed.

C#

public class Lesson : IModel
    {
        
        public override String partitionKey { get => CourseId; }

        [Required]
        public string CourseId { get; set; }

        [Required]
        [StringLength(256, ErrorMessage = "Maximum {1} characters")]
        public string Title { get; set; }
        [Required]
        public string Content { get; set; }

        public string ImageID { get; set; }
        public string ImageURL { get => (ImageID != null) ? Storage.Image.Path(ImageID) : null; }

        public int OrderNum { get; set; } 
    }

HTML

@foreach (var Lesson in Model.Lessons.OrderBy(x => x.OrderNum))
                {
                <li >
                    <a href="@Url.Action("Index","Lesson", new { CourseCategory = Model.Course.Category, CourseID = Model.Course.id, Lesson.id })">@Lesson.OrderNum</a>               
                            @if (AppUser.CurrentUser.Areas.Admin)
                            {
                                <a class='up' href='#'><i ></i></a> <a class='down' href='#'><i ></i></a>
                                <div >
                                    <div>
                                        <a href="@Url.Action("EditLesson", "Lesson", new { CourseCategory = Model.Course.Category, CourseID = Model.Course.id, Lesson.id })">
                                            <i ></i>
                                        </a>
                                    </div>
                                    <div>
                                        <form action="@Url.Action("DeleteLesson","Lesson", new{CourseCategory = Model.Course.Category, CourseID = Model.Course.id, Lesson.id})" method="post">
                                            <button type="submit"  value="Delete"></button>
                                        </form>
                                    </div>                           
                                </div>
                            }
                    </li>
                }

JavaScript

window.onload = function () {
    var upLink = document.querySelectorAll(".up");

    for (var i = 0; i < upLink.length; i  ) {
        upLink[i].addEventListener('click', function () {
            var wrapper = this.parentElement;
            

            if (wrapper.previousElementSibling)
                wrapper.parentNode.insertBefore(wrapper, wrapper.previousElementSibling);
        });
    }

    var downLink = document.querySelectorAll(".down");

    for (var i = 0; i < downLink.length; i  ) {
        downLink[i].addEventListener('click', function () {
            var wrapper = this.parentElement;

            if (wrapper.nextElementSibling)
                wrapper.parentNode.insertBefore(wrapper.nextElementSibling, wrapper);
        });
    }

CodePudding user response:

I have not tested the upcoming codes, just to create an insight: First: Add an attribute to each "list-group-item" element to you can relate them to the server object in future.

 <li  data-elementid="@Lesson.id">

Then at click event handlers post new orders to the server to be set to the objects:

 upLink[i].addEventListener('click', function () {
        var wrapper = this.parentElement;           

        if (wrapper.previousElementSibling)
            wrapper.parentNode.insertBefore(wrapper, wrapper.previousElementSibling);
        var elements= document.querySelectorAll(".list-group-item");
        var stringToBeSend='';
        for (var j = 0; j < elements.length; j  ) {
               stringToBeSend =elements[j].getAttribute("data-elementid") ":" j ",";
        }
        fetch('[Address to a new controller to save new positions. e.g. /api/lessons/UpdatePositions]', {
        method: 'POST',
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        },
        body: stringToBeSend})
       
        .catch(error => console.error('Unable to post positions.', error));
    });

Now you need a controller to get the comma separated string and update new lesson positions. For example:

        [HttpPost("UpdatePositions")]
        public IActionResult UpdatePositions(string commaSepPositions)
        {
            var valueLists = commaSepPositions.Split(',');
            foreach(var value in valueLists)
            {
                if (!string.IsNullOrWhiteSpace(value))
                {
                    var positions = value.Split(':');
                    if (positions.Length > 1)
                    {
                        var lessonIDStr = positions[0];
                        var newPositionStr = positions[1];
                    }

                    //Now update entity in db
                }
            }
            
            return Ok();
        }
  • Related