I'm working on an MVC ASP.NET core project with EF 6 which stores product data in a database and creates a processing and shipping list. An important feature of the project is for certain users to be able to change the order of this list manually, which I'm implementing using drag&drop cards. Each card is created by looping through an IEnumerable of the model in the View, with each
I'm currently trying with var order = @Html.Raw(JsonConvert.SerializeObject(item.Order) as String);, but that doesn't seem to be exposing anything to JavaScript that I can work with. I have a second line exposing the entire object.
Controller Method:
public void ChangeOrder(Product p, int order) { //This creates a list of all of the jobs in the database sorted by descending Order var PList = from prod in _context.Products select prod; PList = PList.OrderByDescending(prod => prod.Order); int origin = p.Order; p.Order = order; if(origin > order) { int it = order; while (it < origin && it < PList.Count()) { PList.ElementAt(it++).Order--; } } else if(origin < order) { int it = origin; while (it < order && it < PList.Count()) { PList.ElementAt(it++).Order--; } } else { return; } }
Index View
@using Newtonsoft.Json; @model IEnumerable<Project.Models.Product> @{ ViewData["Title"] = "Index"; } <h2>Index</h2> @*The list container*@ <ul class="container" id="dragfield" style="width: 100%;"> @*The first card is a minicontainer for the create partial view*@ <li class="card popupsrc" onclick="callPopup">...</li> @foreach (var item in Model) { <li class="dragcard" draggable="true" style="float: left; padding: 8px">@item.Order @*For debugging purposes, this displays the order with the card*@ @*THE FOLLOWING LINEs ARE NOT SECURED AND SHOULD BE CHANGED BEFORE PUBLISHING - FOR TESTING PURPOSES ONLY*@ var order = @Html.Raw(JsonConvert.SerializeObject(item.Order) as String); var order = @Html.Raw(JsonConvert.SerializeObject(item) as String); <partial name="_ProductCard.cshtml" model="item" /> </li> } </ul>
site.js Drag & Drop Block
//D&D Functions Start { var dragSrcElem = null; function dragStartHandler(event) { // Target (this) element is card being dragged. dragSrcElem = this; event.dataTransfer.effectAllowed = 'move'; event.dataTransfer.setData('text/html', this.outerHTML); this.classList.add('dragElem'); } function dragOverHandler(event) { if (event.preventDefault) { event.preventDefault(); //Enables dropping } this.classList.add('over'); event.dataTransfer.dropEffect = 'move'; return false; } function dragEnterHandler(event) { // this|event.target is the card being hovered over. } function dragLeaveHandler(event) { this.classList.remove('over'); // this|e.target is card previously hovered over. } function handleDrop(event) { // this/e.target is card about to be usurped. if (event.stopPropagation) { event.stopPropagation(); // Prevents browsers from redirecting and cancelling the drag&drop } // If the card hasn't moved, do nothing if (dragSrcElem != this) { // Set the original card's HTML to the HTML of the card we dropped on this.parentNode.removeChild(dragSrcElem); var dropHTML = event.dataTransfer.getData('text/html'); this.insertAdjacentHTML('beforebegin', dropHTML); //refocuses to the original card var dropElem = this.previousSibling; //LOCATION OF ISSUE //call the Controller function to change the Order Attribute of the relocated card's item PFS.Controllers.ChangeOrder(dropElem, this.order); //LOCATION OF ISSUE addDnDHandlers(dropElem); } this.classList.remove('over'); return false; } function dragEndHandler(event) { // this|e.target is the original card. this.classList.remove('over'); } function addDnDHandlers(elem) { elem.addEventListener('dragstart', dragStartHandler, false); elem.addEventListener('dragenter', dragEnterHandler, false) elem.addEventListener('dragover', dragOverHandler, false); elem.addEventListener('dragleave', dragLeaveHandler, false); elem.addEventListener('drop', dropHandler, false); elem.addEventListener('dragend', dragEndHandler, false); } var jc = document.querySelectorAll('#dragcard .dragcard'); [].forEach.call(jc, addDnDHandlers); } //D&D Functions End
I expect the JavaScript handleDrop function to call a function in the controller using parameters from the view which originally called the JS function. Currently the code I have implemented in the view does not expose the necessary information to the Javascript code in a way I know how to access, nor does JS recognize the Controller function
From your JavaScript code, I'm not sure what exactly PFS
is in the context of PFS.Controllers.ChangeOrder...
so I'm not sure I could help there.
Personally, when I try to reach a controller action, I like to JavaScript's built-in fetch
function. Essentially, you pass in the url as a parameter and an object if you want to specify any other details (like a body or something). It looks something like this:
//Of course you should replace this with your actual url, this one is just for demo //purposes.
const changeOrderUrl = "order/ChangeOrder";
fetch(changeOrderUrl, {
method: "POST", //or GET or whatever your controller action is
body: JSON.stringify({
p: dropElem,
order: this.order
}),
headers: { "content-type": "application/json; charset=utf-8" }
})
.then(response => response.json())
.then((responseData) => {
//Do whatever you want with the response here. IF you don't want to do anything with
//the response, you can remove both of the .then()'s
});
Additionally, you'll most likely have to add a [FromBody]
attribute to the controller action's parameters like this: public void ChangeOrder([FromBody]Product p, int order)
Let me know if I can assist in any other way!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.