-1

Convoluted question, I know. I'm working on a small MVC application for the purposes of my own learning and I'm stuck at this point after much SO scouring. My View is such (note that ItemList is a List):

@model PackItOut.ViewModels.IndexViewModel
<ol id="item-list-20">
                @foreach (var i in Model.ItemList)
                {
                    <li class="ui-widget-content">
                        @switch (i.Category)
                        {
                            case "Food":
                                <i class="fa fa-cutlery" aria-hidden="true"></i>
                                break;
                            case "Shelter":
                                <i class="fa fa-tree" aria-hidden="true"></i>
                                break;
                            case "First Aid":
                                <i class="fa fa-medkit" aria-hidden="true"></i>
                                break;
                            case "Clothing":
                                <i class="fa fa-child" aria-hidden="true"></i>
                                break;
                            case "Fluid":
                                <i class="fa fa-tint" aria-hidden="true"></i>
                                break;
                            case "Weather":
                                <i class="fa fa-bolt" aria-hidden="true"></i>
                                break;
                            default:
                                break;
                        }
                        @i.Name
                    </li>
                }
            </ol>
<button class="btn btn-danger change-item" id="remove-item-btn"><i class="fa fa-trash" aria-hidden="true"></i> Remove Item</button>

The Javascript is such:

$(document).ready(function() {
var theItemList = $("ol[id*='item-list-']");
$(theItemList).selectable({
    selected: function(event, ui) {
        $(ui.selected).addClass("ui-selected").siblings().removeClass("ui-selected");
    },
    stop: function () {
        var hasSelection = $(".ui-selected");
        if (hasSelection != null)
            $(".change-item").css('visibility', 'visible');
        else
            $(".change-item").css('visibility', 'hidden');
    }
});
$("#remove-item-btn").on("click", function (event) {
    var targetItem = document.getElementsByClassName("ui-selected");
    if (targetItem == null)
        alert('Please select an item to remove.');
});
});

Ideally, in the .on("click") I'd like to pass in the object represented by the targeted item so I can remove the item from the ViewModel collection but I'm having trouble getting the actual object and not just the HTML. Any suggestions on not only this issue but any other issues you see in this snippet are always welcome. Thanks in advance.

  • What do you mean _remove the item from the collection_? Are you wanting to call a controller method to remove the an object from the database? –  May 10 '16 at 01:39
  • Yes - This would remove the item from the database (possibly asynchronously?) and would refresh the collection so the item did not appear in the view. (I haven't investigated the answer provided below yet) – Chris Cioli May 11 '16 at 21:58
  • Then you need to give the item something to identify it - e.g. using a `data-id="@i.ID"` so that you can access it in your script, then make an ajax call to remove the item from the database based on its `ID`, and in the success callback, remove it from the DOM. –  May 12 '16 at 00:34
  • Thank you... I was missing the connection from the ajax call and removing the item from the DOM in the success callback. – Chris Cioli Jun 01 '16 at 17:09

1 Answers1

0

I'm going to look into my crystal ball and predict the future. Once you complete the removal functionality, you're going to want to be able to add to the list as well, right? Good thing there's a NuGet package called BeginCollectionItem and related blog post by Steve Sanderson dedicated to this exact scenario - adding and removing items from a list in MVC.

I'm not going to write out a full solution because that's been done, but I recently implemented this myself using this package. There are several answers on SO involving this package that should help to get you started. This one is especially good.

In response to your specific question, however, you could do something like is mentioned in the linked answer to simply remove a div associated with a list item:

HTML/Razor:

@model PackItOut.ViewModels.IndexViewModel
<div id="editorRows">
    <ol id="item-list-20">
        @foreach (var i in Model.ItemList)
        {
            <div class="editorRow">
                <li class="ui-widget-content">
                    @switch (i.Category)
                    {
                        case "Food":
                            <i class="fa fa-cutlery" aria-hidden="true"></i>
                            break;
                        case "Shelter":
                            <i class="fa fa-tree" aria-hidden="true"></i>
                            break;
                        case "First Aid":
                            <i class="fa fa-medkit" aria-hidden="true"></i>
                            break;
                        case "Clothing":
                            <i class="fa fa-child" aria-hidden="true"></i>
                            break;
                        case "Fluid":
                            <i class="fa fa-tint" aria-hidden="true"></i>
                            break;
                        case "Weather":
                            <i class="fa fa-bolt" aria-hidden="true"></i>
                            break;
                        default:
                            break;
                    }
                    @i.Name
                </li>
                <button class="btn btn-danger deleteRow"><i class="fa fa-trash" aria-hidden="true"></i> Remove Item</button>
            </div>
        }
    </ol>
</div>

JavaScript:

$('#editorRows').on('click', '.deleteRow', function () {
    $(this).closest('.editorRow').remove();
});

Although you will have to play with your HTML elements because you can't nest a <div> within an <ol>.

Community
  • 1
  • 1
unaligned
  • 160
  • 1
  • 9