I have list page to show all images with its name from database in asp.net mvc list action (PhotoList - get).. in that view page (PhotoList.aspx), I have created checkbox to delete multiple rows. I want scenario like following
First page shows the list with in first column checkbox and in second column PhotoName and on the down page one button for delete selected rows .
when selects checkboxes and clicks the delete button, according to selection the rows will be deleted from database and return the same list page..
I don't understand where to write code for delete and how?
<% foreach (var item in Model) { %>
<tr>
<td>
<input type="checkbox" name="deleteImage" value="<%= item.PhotoId %>"/>
</td>
<td>
<%= Html.ActionLink("Edit", "Edit", new { id=item.PhotoId }) %>
</td>
<td>
<%= Html.Encode(item.PhotoName) %>
</td>
</tr>
<% } %>
<input type="button" name="Delete" value="Delete Selected items"/>
The Code for delete will be written in the HttpPost action for delete. Something like below should work if you are using myModel
[HttpPost]
public ActionResult Delete(myModel deleteEntries) //This is the post-version of your Action that rendered the view..If it's Edit, then change the name to Edit
{
var deleteList = db.deleteEntries.where(d => d.checkBox == true).ToList();
foreach (myList my in deleteList)
{
db.myList.Remove(my); // remember db should be your DbContext instace
}
db.SaveChanges();
}
UPDATE
You will first need to make a ViewModel because otherwise you cannot recognize which entries are checked for deletion with the help of checkbox.
Make a ViewMode class like following
using pratice3.Models;
public class MyPhotoViewModel
{
public UserManagementDbEntities.tblPhoto TablePhoto { get; set; }
public bool checkBox { get; set; }
}
Return this to your view
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult PhotosList()
{
var viewModel = _datamodel.tblPhoto.Select(g => new MyPhotoViewModel
{
TablePhoto = g;
checkBox = false;
}).ToList();
return View(viewModel);
}
In View, change the using statement to reflect IEnumerable<MyPhotoViewModel> and make appropriate changes accordingly.
Then, define your Post Action like following
[HttpPost]
public ActionResult PhotosList(IEnumerable<MyPhotoViewModel> myPhotoList)
{
var deleteList = myPhotoList.where(d => d.checkBox == true).ToList();
foreach (var deletePhoto in deleteList)
{
_datamodel.tblPhoto.DeleteObject(deletePhoto.TablePhoto);
}
db.SaveChanges();
}
Using jQuery you can do this.
On button click get all the Ids of photos, something like this
var selected = new Array();
$('name="deleteImage" input:checked').each(function () {
selected.push($(this).attr('id')));
});
var selectedIds = selected.join(',');
Now on button click, make ajax call to some function on server side which will accept these ids and will delete from DB or so.
$.ajax({
url: '#Url.Action("DeleteRecord", "UserManage")',
data: 'ids=' + selectedIds + '&time=' + new Date(), //Date makes each call unique
success: function (data) {
//You can reload page
},
error: function (data) {
//You can show error
}
});
Hope this helps.
Related
I have a partial view on a View of MVC so after Submit the form that is submitting within jquery that you can see below in the code. I have to refresh the Partial view to show some changes that made in partial view after clicking on save button. What should I do in the section of script on click of save?
#using(Html.BeginForm(FormMethod.Post, new{id="form"}))
{
<div>
#Html.Partial("_VehicleCard", Model)
</div>
<div>
<div id="submitBtn" class="row>
#(Model.VehicleCards.Count>0?"":"hidden")">
<div>
<button type="button" id="btnSubmit">Save</button>
</div>
</div>
</div>
}
#section scripts{
<script>
$('#btnSubmit').click(function (event) {
event.preventDefault();
event.stopImmediatePropagation();
$('#form').submit();
//here i wants to refresh Patrial View.
});
</script>
}
Here is my Controller code:
public PartialViewResult GetVehicleForEndMileage(string date, int? Id)
{
try
{
var model = new VehicleEndMilageVM();
DateTime selectedDate;
DateTime.TryParseExact(date, "dd/MM/yyyy", null,
DateTimeStyles.None, out selectedDate);
model.SelectedDate = selectedDate.ToString("dd/MM/yyyy");
model.LocationId = Id ?? 0;
model.VehicleCards =
vehicleDailyInspectionBLL.GetDailyInspectionDetail(selectedDate, Id).Select(x => new VehicleCard
{
VehicleNumber = x.VehicleNumber,
StartMilage = x.StartMilage,
Driver = x.Driver,
EndMilage = x.EndMilage,
VehicleId = x.VehicleId,
VehicleDailyInspectionId = x.VehicleDailyInspectionId,
IsEndMilageAdded = (x.EndMilage !=null && x.EndMilage > 0) ? true : false
}).ToList();
return PartialView("_VehicleCard", model);
}
catch (Exception ex)
{
throw;
}
}
You can simply do it via an ajax call.
First, you have to set an id for <div> tag
<div id="htmlContainer">
#Html.Partial("_VehicleCard", Model)
</div>
Then
$('#btnSubmit').click(function (event) {
event.preventDefault();
event.stopImmediatePropagation();
$('#form').submit();
$.ajax({
url: 'url',
dataType: 'html',
success: function(data) {
$('#htmlContainer').html(data);
}
});
});
You controller seems to be like this :
public PartialViewResult GetVehicleCard(...)
{
return PartialView("_VehicleCard", your view model);
}
HttpPost methods are for SENDING data to the server. You do not need to send your data to the server, rather, you need to GET data from the server with specified criteria and then display it. With that being send, you do not need your HTML.BeginForm() method. Moreover, you do not need to declare a PartialViewResult return type, an ActionResult will suffice. Additionally, you don't need to return the the name of the partial view and the associated model. Simply give the partial view the model results like so:
return PartialView(model)
Next, create an AJAX link on the page you will be clicking your button on like so:
#Ajax.ActionLink("GetVehicleForEndMileage", "Vehicles", new AjaxOptions()
{
HttpMethod = "GET",
InsertionMode = InsertionMode.InsertAfter,
UpdateTargetId = "Results"
})
<div id="Results"></div>
You can wrap this link in a button tag to work with your current set-up.
Now just define your Partial View in a separate .cshtml file.
#model ModelName
<div>
// Model attributes to be displayed here.
</div>
Now, embed that partial view within the view you wish to have the callback displayed.
Having said all of that, your javascript/jQuery can be removed.
My View uses the Model like below:
public class ObjectViewModel
{
public int ChosenVariant{ get; set; }
public List<Object> Objects{ get; set; }
}
but on page I am displaying details only of one of Object from the list (whose id is equal ChosenVariant).
On the same page I have radio buttons and each of them is binded to one of the Objects from the list:
#foreach (var obj in Model.Objects)
{
<div class="radio">
#{
var options = new RouteValueDictionary();
options["onchange"] = "UpdatePage()";
if (product.ID == Model.ChosenVariant)
{
options["checked"] = "checked";
}
}
#Html.RadioButtonFor(p => Model.ChosenVariant, #product.ID, options)
</div>
}
My problem is that how I can refresh the Model.ChosenVariant and render once again page without refresh?
My first idea was returning whole Model with new value of Model.ChosenVariant in javascript function (on onchange radio button).
This function will call Post action to a Controler, which return once again whole Model (but with new changed Model.ChosenVariant. Then on done action of this Post call I will use $(panel).html(data); for refresh the page.
Is there any easier way to change the current viewmodel without calling Controller?
First let me say I think this site is a Godsend, and I am extremely grateful for all I've learned. I have an MVC3 component I'm working with. I want to populate a selectlist and when the user selects one of the options, I want a to load a partial view with the data displayed. Everything works so far except I'm missing the piece that refreshes the partial view. When the page originally loads, I see the empty container in the code. I get no JS errors and Firebug shows the properly formatted HTML returned. So what part of the operation am I missing to refresh the partial view on the page? Please advise and thanx in advance.
The View:
<tr>
<th>Select a User to view their Roles:</th>
<td><%= Html.DropDownList("UserListForRoleView", list, "Please choose a User")%></td>
</tr>
<tr>
<td>
<% Html.RenderPartial("ViewUsersInRole");%>
</td>
</tr>
$(document).ready(function () {
$('#UserListForRoleView').change(function () {
var selectedID = $(this).val();
$.get('/UserAdminRepository/ViewUsersInRole/?user=' + selectedID)
});
});
THe Controller:
public ActionResult ViewUsersInRole()
{
string user = Request["user"];
string[] selectedRoles = Roles.GetRolesForUser(user);
List<string> data = new List<string>();
if (selectedRoles.Length > 0)
{
data = selectedRoles.ToList<string>();
}
else
{
data.Add("No data found");
}
ViewData["UsersinRole"] = data;
return PartialView("ViewUsersInRole");
}
The PartialView (in it's entirety):
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
<ul>
<%
List<string> list = ViewData["UsersinRole"] as List<string>;
if (list != null && list.Count > 0)
{
foreach (string item in list)
{ %>
<li><%: item %></li>
<% }
}
%>
</ul>
append html in the td like this:
<td id="partialcontainer">
<% Html.RenderPartial("ViewUsersInRole");%>
</td>
and append html in it:
$(document).ready(function () {
$('#UserListForRoleView').change(function () {
var selectedID = $(this).val();
$.get('/UserAdminRepository/ViewUsersInRole/?user=' + selectedID,function(response){
$('#partialcontainer').html(response);
})
});
});
Little Improved code, always use Url.Action to generate url:
$(document).ready(function () {
$('#UserListForRoleView').change(function () {
var selectedID = $(this).val();
var url = '#Url.Action("ViewUsersInRole","UserAdminRepository")';
url+"?user="+selectedID;
$.get(url,function(response){
$('#partialcontainer').html(response);
});
});
});
I have modified a little your code to make it more clear and readable.
Try RenderAction
<% Html.RenderAction("ViewUsersInRole");%>
I have a drop down list (DropDownListFor) and an ActionLink on my page. Basically, the problem I'm having is I'm trying to capture the selected value from my drop down list and passing that into my ActionLink as an ID. Here's my code:
#Html.DropDownListFor(x => x.Capsules, new SelectList(Model.Capsules, "pk", "name", "pk"))
<br />
#Html.ActionLink("Submit", "Create",
new { controller = "Process", id = /*JavaScript here to get the selected ID for the DropDownList above*/ },
new { data_role = "button" })
For what I'm trying to accomplish, is there a way to embed JavaScript into my Html.ActionLink call? If there's not a way, or if it's not recommended, could you please advise of another solution to solve this problem? Thanks in advance!
You can do this via intercepting the link using javascript Darin has posted an example of this.
However, it looks like you're trying to submit some values using an ActionLink, and you're probably better off creating a viewmodel which holds all the values you want, and then posting everything using a submit button. This allows you to post more data than just the ID, prevents you from being dependent on Javascript, and keeps all of the code server side instead of mixing and matching.
Judging by the small code you've posted - you already have a model, probably some strongly typed entity, and it has a property called Capsules.
In your controller, create the view model which holds the view's data:
public class YourViewModel
{
YourModel YourModel { get; set; }
public int CapsuleId { get; set; }
}
Then your view:
#using( #Html.BeginForm( "Create", "Process" ) )
{
#Html.DropDownListFor(m=> m.CapsuleId, new SelectList(Model.YourModel.Capsules, "pk", "name", "pk"))
<input type="submit">
}
Then your controller action to handle this:
[HttpPost]
public ActionResult Create( YourViewModel model )
{
var id = model.CapsuleId;
// do what you're going to do with the id
return View();
}
You can put dummy value for the id parameter like this :
#Html.ActionLink("Submit", "Create",
new { controller = "Process", id = "dummy" },
new { data_role = "button" })
Then replace that value when the link is clicked.
// Assuming your link's id is `submit`, and the dropdown's id is `capsules`
$('#submit').click(function() {
var id = $('capsules').val();
$(this).href = $(this).href.replace('dummy', id);
});
I have a partial view with a view model that has a collection of sellers. I loop over all of the sellers to render the list. Here is the view model:
public class SellersPartialViewModel
{
public IList<OrderViewModel> Sellers { get; set; }
}
In the partial view I'm using Html.BeginCollectionItem("Sellers") when I loop through the collection and here is my code for the partial (FYI I've stripped away a lot of useless code that doesn't need to be seen):
<div id="sellers-list">
#{
var i = 0;
while (i < Model.Sellers.Count) {
var seller = Model.Sellers[i];
using (Ajax.BeginForm(MVC.Video.PurchaseShares(), purchaseSharesAjaxOptions, new { #class = "seller-form", id = "seller-form-" + i })) {
#using(Html.BeginCollectionItem("Sellers")) {
#Html.TextBoxFor(m => seller.Qty, new { #class = "buyer-qty" })
#Html.ValidationMessageFor(m => seller.Qty)
<input class="buyer-qty-submit" name="Qty" type="hidden" value="" />
<button type="submit">Buy</button>
}
}
}
i++;
}
}
</div>
This works fine for rendering the partial and getting the client-side validation working
however I want each seller to have the inputs named qty and orderId for a controller action called PurchaseShares(int orderId, int qty).
The only problem is the form is being submitted with the odd GUID like Sellers[5b5fd3f2-12e0-4e72-b289-50a69aa06158].seller.Qty which I understand is correct for submitting collections but I don't need to do that.
Right now I have some Javascript that is updating the class="buyer-qty" with whatever they select and it works fine but there has got to be a better way of doing this, no?
Thanks
Why are you using the Html.BeginCollectionItem helper if you don't want to submit collections?
You could have a partial representing your Order collection item (_Order.cshtml):
#model OrderViewModel
#Html.TextBoxFor(m => m.Qty, new { #class = "buyer-qty" })
#Html.ValidationMessageFor(m => m.Qty)
And in your main view simply loop through your collection property and render the partial for each element:
#model SellersPartialViewModel
<div id="sellers-list">
#foreach (var seller in Model.Sellers)
{
using (Ajax.BeginForm(MVC.Video.PurchaseShares(), purchaseSharesAjaxOptions, new { #class = "seller-form" }))
{
#Html.Partial("_Order", seller)
<button type="submit">Buy</button>
}
}
</div>
Now your controller action you are submitting to could directly work with the corresponding view model:
[HttpPost]
public ActionResult PurchaseShares(OrderViewModel order)
{
...
}
because:
[HttpPost]
public ActionResult PurchaseShares(int orderId, int qty)
{
...
}
kinda looks uglier to me but it would also work if you prefer it.
Also please notice that I have deliberately removed the Qty hidden field shown in your code as it would conflict with the input element with the same name. Also don't forget to include an input field for the orderId argument that your controller action is expecting or when you submit it could bomb. Also you could send it as part of the routeValues argument of the Ajax.BeginForm helper if you don't want to include it as an input field.