Mike Howe
Mike Howe

Reputation: 263

MVC Ajax jQuery Check box

------------ Updated code ---------------------

@for (int i = 0; i < Model.PeopleCheckBoxes.Count(); i++)
{

  <div class="person">
  <span>@Model.PeopleCheckBoxes.ToArray()[i].Username</span>

  @Html.CheckBoxFor(m => @Model.PeopleCheckBoxes.ToArray()[i].IsTaxExempt,
                    new { data_eventID = Model.catID, 
                          data_peopleID = Model.PeopleCheckBoxes.ToArray()[i].Id, 
                          @class = "PeopleCheckBox" }) 

   </div>

<script type="text/javascript">
    $(document).ready(function () {

        $('.PeopleCheckBox').change(function () {
            if (!$(this).is(':checked')) { // ignore checked items
                var url = '@Url.Action("RemoveMemberFromEvent2", "GiftList")';
                var eID = $(this).data('eventID');
                var pID = $(this).data('peopleID');

                $.post(url, { eventid: eID, peopleID: pid }, function (data) {
                    if (data) {
                        self.closest('.person').remove(); // remove the elements from the DOM
                    } else {
                        alert('Oops'); // the person was not removed
                    }
                });

            }
        });

  [HttpPost]
        public JsonResult RemoveMemberFromEvent2(int eventID, int peopleID) 
        {
             // database updated ..................
             return Json(true);
        }

------------ End Updated code ---------------------

-------- Not using this partial view now; added it just to see if it could be used -----

[HttpPost]
    public PartialViewResult RemoveMemberFromEvent(int eventID, int peopleID)
           {
              // removes checkbox from database :
              var aEvent = (from p in _EventMemberRepository.Table . . .
                _giftListService.DeletePersonOnGiftPage(aEvent);

                // queries database for new updated data : 
                var members2 = from c in _custRepository.Table  ....

                return PartialView("_RemoveMemberFromEvent", vModel);
            }

I want to have a Method run when a Check box is un-checked, and pass in 2 values to it. What is a good way to do it? I would like to use Ajax with jQuery but have no idea how to code it :

@foreach (var item2 in Model.PeopleCheckBoxes)    
{
 @item2.Username 

 @Html.CheckBox("chkPeople", true, new {eventID = Model.catID, peopleID =item2.Id})
 ...

     public class GiftListController : Controller
        { 

     [HttpPost] 
            public ActionResult RemoveMemberFromEvent(int eventID, int peopleID) 
            {
                var aEvent = (from p in _EventMemberRepository.Table
                ............  
                return RedirectToAction("Index");
            }        

Any ideas appreciated. Thanks

Upvotes: 0

Views: 4640

Answers (2)

user3559349
user3559349

Reputation:

You are creating invalid html including checkboxes with duplicate ID's and you should store the values as custom data attributes. Rather that using foreach, use a for loop

@for (int i = 0; i < Model.PeopleCheckBoxes.Count; i++)
{
  <span>@Model.PeopleCheckBoxes[i].Username</span>
  @Html.CheckBoxFor(m => m.PeopleCheckBoxes[i].SomeProperty, true, new { data_eventID = Model.catID, data_peopleID = Model.PeopleCheckBoxes[i].ID, @class = "PeopleCheckBox")
}

or if its IEnumerable

@{ var i = 0; }
@foreach (var item2 in Model.PeopleCheckBoxes)
{
  var id = "mycheckbox" + i;
  <span>@item2.Username</span>
  @Html.CheckBoxFor(m => item2.SomeProperty, true, new { data_eventID = Model.catID, data_peopleID = item2.ID, @class = "PeopleCheckBox", id = @id)
  i++;
}

Note the class name is added for use as a jQuery selector

Script

$('.PeopleCheckBox').change(function () {
    if (!$(this).is(':checked')) { // ignore checked items
        var url = '@Url.Action("RemoveMemberFromEvent", "GiftList")';
        var eID = $(this).data('eventID');
        var pID = $(this).data('peopleID');
        $.post(url, { eventid: eID, peopleID: pid }, function (data) {
            // do something with the returned data if you want
        });
    }
});

However you doing a redirect in the action method (its not actually going to return anything in the success function of the post method) so its unclear why you are taking this approach as opposed to say creating a form element for each person with a Delete (submit) button.

Edit

As an alternative you could change you controller action method to return a JSON result indicating if the delete was successful, and if so remove the item. This would allow the user to stay on the page and continue deleting additional items without the redirects. For example

[HttpPost]
public JsonResult RemoveMemberFromEvent(int eventID, int peopleID) 
{
  // delete member and return value indicating if successful
  if (isDeleted)
  {
    return Json(true);
  }
  else
  {
    return null;
  }
}

and in view, wrap all he controls relating to a person in a container so it can be selected

@for (int i = 0; i < Model.PeopleCheckBoxes.Count; i++)
{
  <div class="person">
    <span>@Model.PeopleCheckBoxes[i].Username</span>
    @Html.CheckBoxFor(m => m.PeopleCheckBoxes[i].SomeProperty, true, ...
  </div>
}

then in script

if (!$(this).is(':checked')) {
  var self = $(this); // save scope
  ...
  $.post(url, { eventid: eID, peopleID: pid }, function (data) {
    if(data) {
     self.closest('.person').remove(); // remove the elements from the DOM
    } else {
      alert('Oops'); // the person was not removed
    }
  });

Upvotes: 2

Tech Hands
Tech Hands

Reputation: 53

Your View will look somewhat like this:

@Html.CheckBox("mycheckbox", new { onclick="customMethod()"})

Your JavaScript method which helps make the Ajax call can go thus:

function customMethod(){
$.ajax({
        url: "@Url.Action("ActionMethod", "Controller")",
        type: "POST",
        async: true,
        dataType: "json",

        data: {
            variable1: '@Model.catID',
            variable2: '@item2.id'
        },

        success: function(data) {
            //If you have a response, it will be in the 'data' object
        }
    });
}

And then your Controller would take the form below:

public string ActionMethod (int variable1, int variable2)
    {
        //Use your variables here and return your response, if any.
    }

Upvotes: 1

Related Questions