How to delete multiple items in MVC with a single link? - c#

Consider following:
Partial View:
<%= Html.ListBox("BlackList", Model.Select(
x => new SelectListItem
{
Text = x.Word,
Value = x.ID.ToString(),
Selected = Model.Any(y=> y.ID == x.ID)
}))%>
Main View:
<td><% Html.RenderPartial("GetBlackList", ViewData["BlackList"]); %></td>
Controller:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult DeleteWord(int[] wordIdsToDelete)
{
if (!ModelState.IsValid)
return View();
try
{
_wordManager.DeleteWord(wordIdsToDelete);
return RedirectToAction("WordList");
}
catch
{
return View();
}
}
Model (WordManager)
public void DeleteWord(int[] idsToDelete)
{
var dataContext = GetLinqContext();
var currentList = GetTabooWordList();
foreach (var id in idsToDelete)
{
foreach (var item in currentList)
{
if (item.ID == id)
{
dataContext.BadWords.DeleteOnSubmit(item);
}
}
}
dataContext.SubmitChanges();
}
The question is how correctly pass the parameter - idsForDel ?
I.E I have to pass a client data to the server?
<%= Html.ActionLink("Delete Selected", "DeleteWord", "AdminWord", new { wordIds = idsForDel })%>
I think this can be made by jQuery. Any ideas?

You can bind to an array using the Model Binding to a List
(Haacked.com Model binding to a list, here you can see how to bind complex types as well).
Although I'm not happy with code where I create elements
so I can serialize it in order to bind it to the controllers action input parameter, this code works just what you want:
<script type="text/javascript">
function DeleteWords() {
var el = $("<form></form>");
//for every selected item create new input element and insert it
//inside of temporarty created form element
var selItems = $('#BlackList option:selected').each(function(intIndex) {
//is important how you name input elements (as you can read in link I referenced)
el.append($('<input/>')
.attr({ type: "hidden", name: "wordIdsToDelete", value: $(this).val() })
);
});
//make an ajax call with serialized temporary form
$.ajax({
type: "POST",
url: "/YourController/DeleteWord",
data: $(el).serialize(),
// error: HandleUnespectedError,
success: function(response) {
//handle response }
});}
Hope this helps...

How about this code?
<%= Html.ActionLink("Delete Selected", "DeleteWord",
"AdminWord", new { id="send" })%>
<script type="text/javascript">
$(function() {
$("#send").click(function() {
$.post(
$("form:first").attr("action"),
$("#GetBlackList").serialize()
);
});
});
</script>
And, If two or more records are deleted, DeleteAllOnSubmit is good.
dataContext.BadWords.DeleteAllOnSubmit(
currentList.Where(item=>currentList.Containts(item.id)).ToList()
);

Related

Update C# variable via Ajax?

I have got a page full of posts, I sort those posts before rendering it.
Now I have created a drop down so user's can sort the posts by newest or oldest.
The only problem is I don't know how to update the server-side variable through Ajax.
#{
var SortSelected = "";
var sortedArticles = ListOfPosts.OrderBy(x => x.GetPropertyValue<DateTime>("articleDate")).Reverse().ToList();
if (SortSelected == "Most recent")
{
sortedArticles = ListOfPosts.OrderBy(x => x.GetPropertyValue<DateTime>("articleDate")).Reverse().ToList();
}
else if (SortSelected == "Oldest")
{
sortedArticles = ListOfPosts.OrderBy(x => x.GetPropertyValue<DateTime>("articleDate")).ToList();
}
}
I have removed other code which is irrelevant to make it cleaner.
That's my code for the posts, this is the Razor(html)
<div class="AnimatedLabel">
<select name="contact" class="tm-md-12">
<option id="hide-selector-dropdown" value=""></option>
#foreach (var item in FilterTypes)
{
<option value="#item">#item</option>
}
</select>
<label for="contact">Sort by</label>
<span class="tm-icon-arrow--right" id="selector-dropdown-arrow"></span>
</div>
This is how I tried to do it -
<script>
$('select').on('change', function () {
SortSelected = this.value;
});
</script>
But it is not updating the value, I have been told because it is server-side.
I know people will probably roast me for this question but I do not know any other solution so any help would be great!
I do not have much experience with .net/c#
Thanks!
Okay, so I just wanted to show you how you can achieve something like this using AJAX. As far as I have understood, you want to sort your posts list based on the selection from the user in the dropdown list that you have. Please refer to the code snippet below and let me know if you were able to get what you wanted regarding your requirement:
<script>
$('select').on('change', function () {
//SortSelected = this.value;
//First get the text of the selected item
var selectedText=$('#hide-selector-dropdown :selected').text();
//Now generate your JSON data here to be sent to the server
var json = {
selectedText: selectedText
};
//Send the JSON data via AJAX to your Controller method
$.ajax({
url: '#Url.Action("ProcessMyValue", "Home")',
type: 'post',
dataType: "json",
data: { "json": JSON.stringify(json)},
success: function (result) {
//Show your list here
if (data.success) {
console.log(data.sortedArticles);
}
else {
console.log("List empty or not found");
}
},
error: function (error) {
console.log(error)
}
});
});
</script>
Your Controller would look like:
using System.Web.Script.Serialization;
[HttpPost]
public ActionResult ProcessMyValue(string json)
{
var serializer = new JavaScriptSerializer();
dynamic jsondata = serializer.Deserialize(json, typeof(object));
//Get your variables here from AJAX call
var SortSelected= jsondata["selectedText"];
//Do something with your variables here. I am assuming this:
var sortedArticles = ListOfPosts.OrderBy(x => x.GetPropertyValue<DateTime>("articleDate")).Reverse().ToList();
if (SortSelected == "Most recent")
{
sortedArticles = ListOfPosts.OrderBy(x => x.GetPropertyValue<DateTime>("articleDate")).Reverse().ToList();
}
else if (SortSelected == "Oldest")
{
sortedArticles = ListOfPosts.OrderBy(x => x.GetPropertyValue<DateTime>("articleDate")).ToList();
}
return Json(new { success = true, sortedArticles }, JsonRequestBehavior.AllowGet);
}
You can't change server variable value but you can use this for refresh your table.
<script>
$('select').on('change', function () {
$.get('/Url' , {sortBy:this.value}).done(function(result){
$('#yourTable').html(result);
}).fail(function(){
alert('Error !');
});
});
</script>
You can call web method in server side using ajax.
Use that method to update variable on server side

Cannot get Nested Content in SurfaceController and return as JSON in AJAX

I have run into this problem. I have a view which gets rendered like this:
#inherits Umbraco.Web.Mvc.UmbracoViewPage
#using MyProject.Web.Models;
#using ContentModels = Umbraco.Web.PublishedContentModels;
#{
Layout = "MasterPage.cshtml";
}
#Html.Partial("_HeroModule")
#foreach (var item in Model.GetPropertyValue<IEnumerable<IPublishedContent>>("generalContentCollection"))
{
var partialViewName = "_" + item.DocumentTypeAlias;
if (partialViewName == "_curtainsModule")
{
Html.RenderPartial("CurtainsModule", new CurtainsModuleModel(Model, item));
}
else
{
#Html.Partial(partialViewName, item);
}
The 'item' here is a nested content general collection. Inside of it there's another collection I need to reach called 'fabricsCollection' which is also Nested Content.
The problem with this is that when I go to a SurfaceController and do this the 'fabricsCollection' returns null probably because it's Nested Content:
[HttpPost]
public JsonResult GetFabrics(int data)
{
//gets the id of the actual page doctype
var page = Umbraco.TypedContent(data);
//fabricsCollection underneath returns null
var fabricsCollection = page.GetPropertyValue<IEnumerable<IPublishedContent>>("fabricsCollection");
return Json(fabricsCollection);
}
}
and the ajax call which works fine:
$(".clearAll-desktop").click(function () {
event.preventDefault;
var pageId = $(".curtains-module").attr('id');
var fabrics = "#Model.FabricsCollection.ToString()";
debugger;
console.log(pageId);
$.ajax({
url: '/umbraco/Surface/CurtainsModuleSurface/GetFabrics',
type: 'POST',
data: { data: pageId, collectionName: fabrics },
dataType: 'string',
success: function (data1) {
console.log('success');
}
});
return false;
})
I'm stuck here for a few days and I don't know what I'm doing wrong. Anyone with a clearer mind can pinpoint what I'm doing wrong?

HTML inside foreach statement not rendering even though data is being passed back to view

I went through the debug and found that the values are being passed but for some reason the property values are not being added to page. I can't figure out why. On submit, data chosen from the form is sent to DisplayProviders.
DisplayProviders then compares the string values to the property names in the list of provider agencies then stores the data found inside TempData. A RedirectToAction occurs and sends the TempData to Index().
The View, after the second request of Index(), then recieves the list of providers. However, even though ViewBag is not null (I went though it in debug) it doesn't add the agency names when I go through it with foreach. Using debug, I found that the names ARE being passed but the HTML is not being added to the page.
Please help!
In Controller:
public ActionResult Index()
{
ViewBag.ListOfProviders = TempData["ProvidersFound"];
return View();
}
[HttpGet]
public ActionResult DisplayProviders(string[] area, string[] mode, string[] eligibility)
{
var allProviders = repo.GetProviders();
//Code to narrow down list of providers using the options passed
//through ajax (area, mode, and eligibility) this part works and
//provider agencies were found and stored in TempData
TempData["ProvidersFound"] = providersFound;
return RedirectToAction("Index");
}
Code in View:
#model TransportationProvidersDemo.Models.Provider
#{
var providersFound = ViewBag.ListOfProviders;
}
<--HTML form here (omitted)-->
<input type="submit" />
<div>
#if (providersFound != null)
{
foreach (var item in providersFound)
{
<div>
<h3>#item.AgencyName</h3>
</div>
}
}
</div>
And I'm using ajax to send data to DisplayProviders
$.ajax({
type: "GET",
url: "/Home/DisplayProviders",
contentType: "application/json; charset=utf-8",
data: { area: areaSelected, mode: modeSelected, eligibility: eligibilitySelected },
datatype: "json",
traditional: true,
success: function (response) {
if (response != null) {
alert("SUCCESS! Good job!");
} else {
alert("Something went wrong");
}
},
failure: function (response) {
alert("Failure");
},
error: function (response) {
alert("Error");
}
});
can you try passing your found providers list from Tempdata as model in the view object ? like below:
Controller:
public ActionResult Index()
{
var ListOfProviders = TempData["ProvidersFound"] as (your strongly type list);
return View(ListOfProviders);
}
View:
#model List<TransportationProvidersDemo.Models.Provider>
#if (Model != null)
{
foreach (var item in Model)
{
<div>
<h3>#item.AgencyName</h3>
</div>
}
}
</div>
The problem is that RedirectToAction is a client side redirect that stores data in session state. You won't get the correct data from the ajax response. You should just return the view directly from DisplayProviders instead.
If you want to use the ViewBag you must be aware that the elements you read from it are of type object so you need to cast them.
View :
#model List<TransportationProvidersDemo.Models.Provider>
#{
var providersFound = ViewBag.ListOfProviders != null ?
ViewBag.ListOfProviders as List<Providers> :
null;
}
<ommited form here>
#if (providersFound!= null)
{
foreach (var item in Model)
{
<div>
<h3>#item.AgencyName</h3>
</div>
}
}
</div>

Problems Cascading dropdownlist, generated dropdown isn't posting selected value to server

Here is my view in image
The code is working fine, but...
When i submit the form, it only sends the value of first dropdownlist (I checked on browser network received arguments), also when i view the page source it doesn't show the generated options that I generated using ajax function.
Here is my Code
Action that generate my first dropdownList
public ActionResult TwoDropDownList()
{
HotelContext H = new HotelContext();
ViewBag.DropDownListOne = new SelectList(H.Continent.ToList(), "Id", "Name");
return View();
}
Action that return json of second dropdownlist data
[HttpPost]
public JsonResult UpdateCountryDropDownList(int ContinentId)
{
HotelContext H = new HotelContext();
List<SelectListItem> CountryNames = new List<SelectListItem>();
List<Country> Co = H.Country.Where(x => x.ContinentId == ContinentId).ToList();
Co.ForEach(x =>
{
CountryNames.Add(new SelectListItem { Text = x.Name, Value = x.Id.ToString() });
});
return Json(CountryNames , JsonRequestBehavior.AllowGet);
}
My Ajax call
#model Hotel.Models.Continent
<script>
$(document).ready(function () {
$("#Name").change(function () {
var ContinentoId = $(this).val();
$.ajax({
type: "POST",
dataType: "json",
data: { ContinentId: ContinentoId },
url: '#Url.Action("UpdateCountryDropDownList","Home")',
success: function (result) {
var Country = "<select id='ddlCountry'>";
Country = Country + '<option value="">--Select--</option>';
for (var i = 0; i < result.length; i++) {
Country = Country + '<option value=' + result[i].Value + '>' + result[i].Text + '</option>';
}
Country = Country + '</select>';
$('#Countries').html(Country);
},
error: function (xhr, ajaxOptions, thrownError) {
console.log(arguments)
}
});
});
})
</script>
My View
#using(Html.BeginForm()){
SelectList se = ViewBag.DropDownListOne;
#Html.DropDownListFor(x=>x.Name,se,"--Select--")
<div id ="Countries">
#Html.DropDownList("ddlCountry",new List<SelectListItem>(),"--Select--")
</div>
<input type="submit" value="submit" style="margin-top:100px;" />
}
HTTPPost Action
[HttpPost]
public string TwoDropDownList(string Name, string ddlCountry)
{
if (string.IsNullOrEmpty(Name) || string.IsNullOrEmpty(ddlCountry))
{
return ("you must select Both");
}
else
return ("everything is working fine");
}
You already have a <select> element with name="ddlCountry" (generated by #Html.DropDownList("ddlCountry", new List<SelectListItem>(), "--Select--") but in the ajax call, you overwrite it and create a new <select> element without a name attribute (so its value is not posted back.
In the success callback, you should be creating <option> elements and appending them to the existing <select>
success: function (result) {
var country = $('#ddlCountry); // get the existing element
country.empty().append($('<option></option>').val('').text('--Select--'));
$.each(result, function(index, item) {
country.append($('<option></option>').val(item.Value).text(item.Text));
});
}
Side note: Your methods should be returning a collection of anonymous objects, not SelectListItem There is no point sending extra data (the other properties of SelectListItem) across the wire when you don't use them.
I think you are missing the end tag </div> for the <div id ="Countries">.
Try this:
<div id ="Countries">
#Html.DropDownList("ddlCountry",new List<SelectListItem>(),"--Select--")
</div>

Loading MVC webgrid content second time not working

We have a webgrid there i am trying to bind IDictionary. I dont have any issue in binding first time. I am facing difficulty in the second time. I am getting the result in the model and it not refreshing the grid content second time. Trying to populate the grid data by dropdown value change. First time i am loading on menu click.
Here is my controller code. In the result i have the list of values. I am facing issue in binding it in webgrid after ajax call second time.
public List<IDictionary> GetHotelingList(int floorId)
{
var model = new List<IDictionary>();
using (var context = new FloorContext())
{
try
{
model = ListHotelingByFloorId(context, floorId);
}
catch (Exception ex)
{
}
}
return model;
}
This is my ajax call
$("#floor").bind("change", function () {
var facilityId = parseInt($("#FacilityDropDown option:selected").val());
var floorId = parseInt($("#floor option:selected").val());
$.ajax({
type: 'POST',
url: '/Floor/GetHotelingList',
cache: false,
data: { floorId: floorId },
success: function (data) {
},
complete: function () {
},
error: function () {
if (facilityName.indexOf('-') != -1) {
$('#floor').empty();
return;
}
else
alert("error in generating floor");
}
});
});
Code for binding in the grid.
#using System.Dynamic
#model List<System.Collections.IDictionary>
#{
var result = new List<dynamic>();
foreach (var emprow in Model)
{
var row = (IDictionary<string, object>)new ExpandoObject();
var eachEmpRow = (Dictionary<string, object>)emprow;
foreach (KeyValuePair<string, object> keyValuePair in eachEmpRow)
{
row.Add(keyValuePair);
}
result.Add(row);
}
var grid = new WebGrid(result, rowsPerPage: 50, ajaxUpdateContainerId: "grdHoteling");
}
Any help please?
Thanks in advance
you have to make a container div in main view from where you call ajax and load result in that div:
<div id="GridContainer">
// load you view first time here
</div>
and on ajax call update content of this div in success call back of ajax:
success: function (data) {
$("#GridContainer").html(data);
}

Categories