Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delete By Id MVC 5

I'm using BeginCollectionItem with MVC 5 for adding and removing rows whenever.

One issue I'm having is with the delete function, I followed an online tutorial which specified using #divId:first which seems to indicate deleting the first row whenever. This is no good for me, and wouldn't make sense to an end user.

As I'm using BCI I want to delete these from the html DOM so they won't have database Ids.

How do I delete by the Id of the model, this apparently (I think I read somewhere) is automatically generated by BCI?

Delete Function in the main view

$('#deleterow').live('click', function () {
            $(this).parents('#newRow:first').remove();
            return false;
        });

Partial View with rows I want to delete by Id

@model  Mvc.Models.Project
@using (Html.BeginCollectionItem("something"))
{
    <div id="newRow">
        @Html.LabelFor(m => m.Name)
        @Html.EditorFor(m => m.Name)

        <a href="#" id="deleterow">Delete</a>
    </div>
}

Update 2

When viewing the rendered html the data-action attribute renders as 0 for all objects so the JQuery can't and won't delete a row/object from the view.

Update

Instead of the check box I want to use the Delete link button, I assume this is possible? Not very familiar with jQuery but it is something I intend to look at, fairly new to MVC too but this is what I have so far:

Main View

<h3>Students</h3>
<div id="newStudent">
    @foreach(var Student in Model.students)
    {
        Html.RenderPartial("_Student");
    }
</div>
<input type="button" id="addStudent" name="addStudent" value="Add Student"/>

<input type="submit" value="Submit"/>
@section Scripts
{
    <script type="text/javascript">
        $('#addStudent').on('click', function () {
        $.ajax({
            async: false,
            url: 'School/AddNewStudent'
        }).success(function (partialView) {
            $('#newStudent').append(partialView);
        });
    });

    $('#newStudent').on('click', '.deleteStudent', function () {
        var id = $(this).data('id');
        if (id === 0) { // assumes Id is integer
            $(this).closest('.studentRow').remove();
        }
        else { // existing item - controller to delete from Db
            var url = '@Url.Action("action", "controller")';
            $.post(url, { ID: id }, function (response) {
                if (response) {
                    $(this).closest('.studentRow').remove();
                }
            }).fail(function (response) {
                // display error message
            });
        }
    });
    </script>
}

Partial View

@using (Html.BeginCollectionItem("students"))
{
    <div id="studentRow">
        @Html.HiddenFor(m => m.Id)
        @Html.LabelFor(m => m.Name)
        @Html.EditorFor(m => m.Name)

        <a href="#" class="deleteStudent" data-action="@Model.Id">Delete</a>
    </div>

}

Controller

public class SchoolController : Controller
{
    // GET: School
    public ActionResult Index()
    {
        var newSchool = new School();

        return View(newSchool);
    }

    public ActionResult AddNewStudent()
    {
        var student = new Student();
        return PartialView("_Student", student);
    }
    [HttpPost, ActionName("DeleteStudent")]
    public ActionResult DeleteStudent(School school)
    {
        foreach(var student in school.students.Where(s => !s.isDeleted))
        {
            return View(school.students);
        }

        return View();
    }
}
like image 818
JammAndTea Avatar asked Mar 17 '23 06:03

JammAndTea


1 Answers

What I have done is created a IsDeleted Property in Model/ViewModel, Put it in the Row as a Hidden Field, And also have a delete button against each Row

 using (Html.BeginCollectionItem("Contacts"))
    {
        <div class="row mt-10">
            @Html.HiddenFor(m => m.Id)
            @Html.HiddenFor(m => m.isDeleted, new { data_is_deleted = "false" })

.......Removed HTML

        <div class="col-md-1">
            <span class="glyphicon glyphicon-trash" data-action="removeItem" title="remove" style="cursor:pointer"></span>
        </div>

Then add this jQuery a JavaScript file. (Note: Don't add this to the Row Partial View, I add it in the View that calls the Row Partial View)

You might have to edit this jQuery to match your HTML structure, The goal in this jQuery is to update the IsDeleted field to either true or false and then Disable the other Input fields

$(document).on('click', '*[data-action="removeItem"]', function(e){
    e.stopPropagation();
    var btn = $(this);
    var row = btn.closest('.row');
    var parent = btn.parent();
    var checkBox = parent.siblings('*[data-is-deleted]');

    var checkBoxVal = checkBox.val();
    if(checkBoxVal == 'False' || checkBox.val() == 'false'){
        checkBox.val('true');
        row.find('input, textarea, select').attr('readonly', 'readonly');
    } else {
        checkBox.val('false');
        row.find('input, textarea, select').attr("readonly", false);
    }
    checkBoxVal = checkBox.val();
});

This is what your view will look like:

enter image description here

When post Back to Controller:

foreach (var contact in contacts.Where(s => !s.isDeleted))
{
   // New and Updated Items
}

foreach (var contact in myModel.Where(s => s.isDeleted && s.Id!= 0))
 {              
    // Deleted Items
// You don't have to delete Items where Id == 0, Bcz they are not in the DB.
// Just some Item added to the View and then deleted without Save
  }

Deleted Items will be disabled: Note: You can Hide them by editing the above jQuery

enter image description here

EDIT A: Actual controller code is something like this:

[HttpPost]
public ActionResult SaveStudent(Student model){


// Save model items

// Then Save the List of Items like this:

    foreach (var contact in model.myListItems.Where(s => !s.isDeleted))
    {
       // New and Updated Items
    }

    foreach (var contact in model.myListItems.Where(s => s.isDeleted && s.Id!= 0))
     {              
        // Deleted Items
    // You don't have to delete Items where Id == 0, Bcz they are not in the DB.
    // Just some Item added to the View and then deleted without Save
      }


}
like image 185
Dawood Awan Avatar answered Mar 24 '23 19:03

Dawood Awan