0

I am doing something like 'To do' list, where user can take text and drag into two tables "to do" and "done". First he can create a note. All data is in DB.

model IEnumerable<ToDoList.Models.KtoCo>

@{    ViewBag.Title = "Index"}
<h2>Index</h2>

<p>
@Html.ActionLink("Create New", "Create")
</p>

<!DOCTYPE HTML>
<html><head><style>#div1, #div2 {
        float: left;
        width: 500px;
        height: 500px;
        margin: 10px;
        padding: 10px;
        border: 1px solid black;
    }
</style>
<script>
    function allowDrop(ev) {
        ev.preventDefault();
    }

    function drag(ev) {
        ev.dataTransfer.setData("text", ev.target.id);
    }

    function drop(ev) {
        ev.preventDefault();
        var data = ev.dataTransfer.getData("text");
        ev.target.appendChild(document.getElementById(data));
    }
</script>

@foreach (var item in Model)
{
    <div draggable="true" ondragstart="drag(event)" id=@item.Id width="88" height="31">

        @Html.DisplayFor(modelItem => item.Kto)
        @Html.DisplayFor(modelItem => item.Co)

        @Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
        @Html.ActionLink("Delete", "Delete", new { id = item.Id })
    </div>

}


<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"> </div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)"></div>

`

This is my View. And here is a model:

namespace ToDoList.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;

[Table("KtoCo")]
public partial class KtoCo
{
    public int Id { get; set; }

    [StringLength(50)]
    public string Kto { get; set; }

    public string Co { get; set; }
}
}

The question is: Is there possible way to keep the notes in tables, even after refreshing site?

P.S. I know that the view is not very pretty, i will be working on it later.

1 Answers1

0

I'm sure there would be a couple of ways to do this.

Conceptually, what you need to do is store on the server which items have been dragged onto which list. Then when you load the page you will need to check these server-side lists to determine which items to render in which lists.

The below is just pseudo-code - it is unlikely to compile and is non-complete but hopefully is enough to get you started and get the idea.

To store the 'drops': Within the Javascript drop(ev) method make an asynchronous post request to a Controller Action sending the ID of the item dropped and the ID of the list it was dropped onto. You'll then need to store that information somewhere so that when you render the page next time, you can retrieve it. Perhaps in a Session variable.

Your action method might look something like this:

    public ActionResult PutItemInList(int listId, int itemId)
    {
        if (listId == ToDoList)
        {
            var toDoIds = (List<int>)Session["ToDoIds"];
            toDoIds.Add(itemId);
            Session["ToDoIds"] = toDoIds;
        }
        if (listId == DoneList)
        {
            var doneIds = (List<int>)Session["ToDoIds"];
            doneIds.Add(itemId);
            Session["DoneIds"] = doneIds;
        }
    }

To render the page: You will need to use the information from the Session variable to render the view.

Add a new ViewModel class which will store:

  1. the list of KtoCo (your current ViewModel)
  2. the list of IDs in the ToDo list
  3. the list of IDs in the Done list

Something like this:

public class ToDoViewModel
{
    public List<KtoCos> KtoCos { get; set; }
    public List<int> ToDoList { get; set; }
    public List<int> DoneList { get; set; }
}

In your action method which renders the View, get the information from Session and create a new ViewModel class. Something like this:

    public ActionResult ActionMethod()
    {
        var toDoIds = (List<int>)Session["ToDoIds"];
        var doneIds = (List<int>)Session["DoneIds"];

        var viewModel = new ToDoViewModel();
        viewModel.DoneList.AddRange(doneIds);
        viewModel.ToDoList.AddRange(toDoIds);
        viewModel.Ktos = GetFromDbSomehow();
        return View(viewModel);
    }

Then in your Razor view, whose model is now the new ViewModel class, inspect those list properties to render out the items in the correct location.

Something like this:

@foreach (var item in Model.KtoCos)
{
    <div draggable="true" ondragstart="drag(event)" id=@item.Id width="88" height="31">

        @Html.DisplayFor(modelItem => item.Kto)
        @Html.DisplayFor(modelItem => item.Co)

        @Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
        @Html.ActionLink("Delete", "Delete", new { id = item.Id })
    </div>

}

<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
    @foreach (var item in Model.ToDoList)
    {
        <div>@item.SomeInfo</div>
    }
</div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)">
    @foreach (var item in Model.DoneList)
    {   
        <div>@item.SomeInfo</div>
    }
</div>
JTech
  • 3,420
  • 7
  • 44
  • 51
  • If I would like have the same position to others session (this application is for multiple users/employees), is it a good idea to have this drop area as list, and add this content after drop to DataBase? Is it possible? – Patrycja Nov 01 '18 at 12:00
  • To have the same position for all users, then sounds like ApplicationState would be appropriate. See this answer for more info: https://stackoverflow.com/questions/5096544/application-vs-session-vs-cache – JTech Nov 01 '18 at 22:29
  • I don't understand this question: "is it a good idea to have this drop area as list, and add this content after drop to DataBase" - can you ask it in another way? – JTech Nov 01 '18 at 22:30
  • I meant create two lists, drag and drop items between them and saving changes in DB (for example 'Save button'). – Patrycja Nov 02 '18 at 10:05
  • Perhaps its best if you update your question to reflect what you still need to know. Or ask a new question and mark this one as answered if you have the info you need now. – JTech Nov 06 '18 at 04:52