Ajax.BeginForm alternatives to onchange=this.form.submit() - asp.net-mvc

I have a table with a Ajax.BeginForm on each row. This works good to pass the data to the controller.
However, it wont fire the Request.IsAjaxRequest() on the controller because of the form post(thanx HTX9 for pointing that out!). The real problem is that it returns a partial view instead of updating it in the current view.
Below you can see two fieldsets. The first is the one i want to update and the one below it is the one which sends data to the controller with the Ajax.BeginForm.
With other words: When I choose something in a dropdownlist it updates the table above but it opens it in a new partial view.
I have the unobtrusive ajax js in the _layout view and a similar setup works in an other part of the application from with a post data with a button instead.
<fieldset>
<legend>Direktbyten</legend>
<div id="container-grid2">
#Html.Partial("_RatingList2", Model.Models2)
</div>
</fieldset>
<fieldset>
<legend>Omarkerade byten(#ViewBag.DirectCount)</legend>
<div id="RatingList">
<table>
<thead>
<tr>
<td>Se hela</td>
<td>Hyra</td>
<td>Rum</td>
<td>Kvm</td>
<td>Gata</td>
<td>Område</td>
<td>Deras prio</td>
<td>Totaltvärde</td>
<td>Min prio</td>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Models1)
{
using (Ajax.BeginForm("UpdateRatingListRow", new AjaxOptions { UpdateTargetId = "container-grid2" }))
{
#Html.Hidden("RatingListId", item.RatingListId)
<tr>
<td>#Html.ActionLink("Till annons", "ViewAd", "Ad", new { id = item.CustomerId }, null)
</td>
<td>#item.Rent</td>
<td>#item.Rooms</td>
<td>#item.SquareMeters</td>
<td>#item.Street</td>
<td>#item.Area</td>
<td>#item.TheirRating</td>
<td>#item.TotalRating</td>
<td>
#Html.Raw("<div id='" + item.RatingListId + "'>")
<select name="SelectedValue" onchange="this.form.submit();">
<option value="0"#if (item.MyRating == "00")
{
#Html.Raw("selected")
}>Ny</option>
<option value="10" #if (item.MyRating == "10")
{
#Html.Raw("selected")
}>Inget intresse</option>
<option value="50"#if (item.MyRating == "50")
{
#Html.Raw("selected")
}>Svagt intressse</option>
<option value="60"#if (item.MyRating == "60")
{
#Html.Raw("selected")
}>Litet intresse-vill ej ha kontakt</option>
<option value="70"#if (item.MyRating == "70")
{
#Html.Raw("selected")
}>Intresserad-Vill ha kontakt</option>
<option value="80"#if (item.MyRating == "80")
{
#Html.Raw("selected")
}>Varit på visning-Vill gå vidare</option>
<option value="90"#if (item.MyRating == "90")
{
#Html.Raw("selected")
}>Intresserad-Vill ha kontakt</option>
<option value="100"#if (item.MyRating == "100")
{
#Html.Raw("selected")
}>Avvaktar värdar</option>
</select>#item.MyRating
#Html.Raw("</div>")
</td>
</tr>
}
}
</tbody>
</table>
</div>
</fieldset>
Here is the Controller:
[HttpPost]
public ActionResult UpdateRatingListRow()
{
if (Request.IsAjaxRequest())
{
//Do stuff, it does not hit this part because of the isAjaxRequest().
return this.PartialView("_RatingList2", myRatingListMarked);
}
return this.PartialView("_RatingList2", null);
}
Generated Html:

Here is my "fulhack"(ugly hack in swedish), added a button with each row id and then i call it for submit. Still hoping for a clean solution without having to rewrite a lot of code.
using (Ajax.BeginForm("UpdateRatingListRow", new AjaxOptions { UpdateTargetId = "container-grid2", OnSuccess = "OnSuccess('" + item.RatingListId + "')" }))
{
<input type="submit" id="#item.RatingListId" style="position: absolute; top: -1000px">
#Html.Hidden("RatingListId", item.RatingListId)
<tr>
<td>#Html.ActionLink("Till annons", "ViewAd", "Ad", new { id = item.CustomerId }, null)</td>
<td>#item.Rent</td>
<td>#item.Rooms</td>
<td>#item.SquareMeters</td>
<td>#item.Street</td>
<td>#item.Area</td>
<td>#item.TheirRating</td>
<td>#item.TotalRating</td>
<td>#Html.Raw("<div id='" + item.RatingListId + "'>")
<select name="SelectedValue" onchange="document.getElementById(#item.RatingListId).click();">
<option value="0"#if (item.MyRating == "00")

Related

How to make radiobutton marked based on dropdown index changed event in mvc 4 entity framework?

This is my view code.
#using (Html.BeginForm())
{
#Html.LabelFor(m=>m.GroupID)
#Html.DropDownListFor(m => m.GroupID, Model.GroupList, "Please select", new { id = "ddlgrp" })
if (ViewBag.selectedperms!=null)
{
foreach(var permission in Model.Permissions)
{
<label>
#Html.RadioButtonFor(m=>m.perm_id,permission.perm_id)
<span>#permission.perm_levelname</span>
</label>
}
}
else
{
foreach(var permission in Model.Permissions)
{
<label>
#if (Model.perm_id.Equals(ViewBag.selectedperms))
{
#Html.RadioButtonFor(m=>m.perm_id,permission.perm_id,true)
<span>#permission.perm_levelname</span>
}
else
{
#Html.RadioButtonFor(m=>m.perm_id,permission.perm_id)
<span>#permission.perm_levelname</span>
}
</label>
}
}
<p><input type="submit" value="Submit" /></p>
This is my jquery code.
$(document).ready(function () {
$("#ddlgrp").change(function () {
$("#log").ajaxError(function (event, jqxhr, settings, exception) {
alert(exception);
});
var grpselected = $("select option:selected").val();
alert(grpselected);
$.get('#Url.Action("CheckPermissions")',
{ id: grpselected }, function (data) {
});
});
});
This is actionmethod
public ActionResult CheckPermissions(int id)
{
tblperm od = new tblperm();
var selectedperms = (from c in db.tblperm where c.grp_id==id select c.perm_id).SingleOrDefault();
ViewBag.selectedperms = selectedperms;
return View(od);
}
Assume for groupip id 1 there is a permisson with permid 1. So when i select 1 from dropdwon corresponding dropdown with id 1 should be checked. I have tried with above code but its not working. Can anybody suggest me where i am going wrong?
I think you need something like following snippet.
$("#GroupID").change(function () {
$('input[name="perm_id"][value="' + this.value + '"]').prop('checked', true);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="GroupID">
<option value="">Select group</option>
<option value="1">Group 1</option>
<option value="2">Group 2</option>
<option value="3">Group 3</option>
<option value="4">Group 4</option>
</select>
<input type="radio" value="1" name="perm_id" /><label>Permission 1</label>
<input type="radio" value="2" name="perm_id" /><label>Permission 2</label>
<input type="radio" value="3" name="perm_id" /><label>Permission 3</label>
<input type="radio" value="4" name="perm_id" /><label>Permission 4</label>
Update
Action method
public ActionResult CheckPermissions(int id)
{
tblperm od = new tblperm();
var selectedperms = (from c in db.tblperm where c.grp_id == id select c.perm_id).SingleOrDefault();
return Json(selectedperms, JsonRequestBehavior.AllowGet);
}
jQuery
$("#ddlgrp").change(function () {
var grpselected = $(this).val();
$.getJSON('#Url.Action("CheckPermissions")', { id: grpselected }, function (data) {
$('input[name="perm_id"][value="' + data + '"]').prop('checked', true);
});
});

Saving a moved item

When I use a move item from a selection list to another list using jQuery it moves well but when I reload the page it goes back to the previous list. I want to know how can I save it so when I reload the page it doesn't go back?
<script>
$(document).ready(function () {
$('#btnRight').click(function (e) {
var selectedOpts = $('#lstBox1 option:selected');
if (selectedOpts.length == 0) {
alert("Nothing to move.");
e.preventDefault();
}
$('#lstBox2').append($(selectedOpts).clone());
$(selectedOpts).remove();
e.preventDefault();
});
$('#btnLeft').click(function (e) {
var selectedOpts = $('#lstBox2 option:selected');
if (selectedOpts.length == 0) {
alert("Nothing to move.");
e.preventDefault();
}
$('#lstBox1').append($(selectedOpts).clone());
$(selectedOpts).remove();
e.preventDefault();
});
$('#btnRight2').click(function (e) {
var selectedOpts = $('#lstBox2 option:selected');
if (selectedOpts.length == 0) {
alert("Nothing to move.");
e.preventDefault();
}
$('#lstBox3').append($(selectedOpts).clone());
$(selectedOpts).remove();
e.preventDefault();
});
$('#btnLeft2').click(function (e) {
var selectedOpts = $('#lstBox3 option:selected');
if (selectedOpts.length == 0) {
alert("Nothing to move.");
e.preventDefault();
}
$('#lstBox2').append($(selectedOpts).clone());
$(selectedOpts).remove();
e.preventDefault();
});
});
</script>
#foreach (var item in Model)
{
<hr />
<table>
<tr>
<td style='width:160px;'>
<b>TO DO:</b><br />
<select multiple="multiple" id='lstBox1'>
<option>#Html.DisplayFor(model => item.Events.Vanue)</option>
</select>
</td>
<td style='width:50px;text-align:center;vertical-align:middle;'>
<input type="button" id="btnRight" value="-" />
<br /><input type="button" id="btnLeft" value="<" />
</td>
<td style='width:200px;'>
<b>IN PROGRESS: </b><br />
<select multiple="multiple" id='lstBox2'>
</select>
</td>
<td style='width:50px;text-align:center;vertical-align:middle;'>
<input type="button" id="btnRight2" value="-" />
<br /><input type="button" id="btnLeft2" value="<" />
</td>
<td style='width:160px;'>
<b>DONE: </b><br />
<select multiple="multiple" id='lstBox3'>
</select>
</td>
</tr>
</table>
You need to find a way to save the website's state. There are a lot of options. You can start with this article on localStorage. I found it be a good primer.

Paging issue in ASP.Net Mvc Application

I am developing an MVC application in which I use a DropdownList to select "vendor". When I select a vendor from the dropdown then the view shows products related to the selected vendor.
I use paging to display multiple pages of particular vendor's products.
My issue is when I select a vendor from dropdown, at change event it displays products on all pages properly. If I select 2nd page it shows products from 2nd page. But next time if I select another vendor from dropdown, it shows 2nd page of selected vendor. But what I want is to display first page of selected vendor initially.
Controller code as below
public ActionResult Index(int? page ,int VendorId = 0)
{
var pageNumber = (page ?? 1);
var pagesize = 2;
if (VendorId == 0)
{
VendorId = Convert.ToInt32(Session["InventoryVendorId"]);
}
VendorService vendorService = new VendorService();
SelectList SelectList = new SelectList(vendorService.GetAll().OrderBy(t => t.Name), "Id", "Name", VendorId);
ViewData["list"] = SelectList;
int id = Convert.ToInt32(Session["loggedEmpId"]);
CommonService.SetEmployeeId(id);
if (VendorId != 0)
{
Session["InventoryVendorId"] = VendorId;
ProductService ProductService = new ProductService();
var productList = ProductService.GetProductInventory().Where(x=>x.VendorId == VendorId);
return View(productList.ToPagedList(pageNumber, pagesize));
}
else
{
return View();
}
}
code for view as below
#model PagedList.IPagedList<StockWatch.DTO.ProductDTO>
#using PagedList.Mvc;
#using System.Web.UI.WebControls
#{
ViewBag.Title = "Index";
int VendorId = Convert.ToInt32(Session["InventoryVendorId"]);
}
<link href="~/Content/PagedList.css" rel="stylesheet" />
<div class="row-fluid">
<div id="vendorDropdownDiv4" class="span12 " style="margin-left:0px;margin-top:10px;">
<div class="span6" >
<div class="span4" style="margin-left:1px;" >
<label >Vendor</label>
</div>
<div class="span6" >
#Html.DropDownList("VendorId", ViewData["list"] as SelectList, "-- Select vendor --", new { #id = "vendorIdforInventory", #name = "VendorId" })
</div>
</div>
<div class="span3" style="text-align:right">
#* <input class="btn btn-primary" type="submit" value="Load" id="create"/>*#
#*<input class="btn btn-default" value="Cancel" style="width:45px;" onclick="window.location.href='#Url.Action("index") '"/>*#
</div>
</div>
</div>
<div id="Newindexview"></div>
#if(Model != null)
{
</div>
<div class="span12" style="margin-left:0px;">
<table>
<thead>
<tr >
<th style="width:250px;" >Product Name
</th>
<th style="width:180px; text-align:left;" >Product Code
</th>
<th style="border-right: solid #e8eef4 thick; width: 0px; text-align:right;">Avg. Weight
</th>
#{
foreach (var location in ViewBag.loc)
{
<th style="width:10px;text-align:right;">#location.Name</th>
}
}
</tr>
</thead>
<tbody>
#foreach (var p in Model)
{
<tr>
<td style="width:250px;">
#p.Name
</td>
<td style="width:180px;text-align:left;">
#p.ProductCode
</td>
<td style="border-right: solid #e8eef4 thick; width: 15px; text-align:right">
#p.AvgWeight
</td>
#foreach (var location in ViewBag.loc)
{
flag = false;
if(p.Inventory != null)
{
foreach (var loc in p.Inventory)
{
if (location.Name == loc.LocationName)
{
<td style="width:10px; text-align:right;">#loc.Quantity</td>
flag = true;
}
}
}
if (flag == false)
{
<td style="width:10px; text-align:right;">0</td>
}
}
</tr>
}
</tbody>
</table>
</div>
<div class="span12" style="margin-left:0px;">
<div class="span6" style="margin-left:0px;">
#Html.PagedListPager(Model, page => Url.Action("Index", new {page ,searchContent=searchcontent}))
</div>
</div>
</div>
}
and jquery code as below
$("#vendorIdforInventory").change(function () {
var vendorid = $('#vendorIdforInventory').val();
$.ajax({
url: '#Url.Action("Index", "Inventory")',
data: {
VendorId: vendorid
},
type: "POST",
success: function (data) {
location.reload();
$('#modeldiv1').empty();
$('#vendorDropdownDiv4').hide();
$('#Newindexview').html("");
$('#Newindexview').html(data);
}
});
});
How to solve this paging issue?
You need to pass the currentFilter from your view back into your controller (which you have with VendorID), and set the page accordingly. Details are in the ASP.NET tutorial on paging at http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application.
Look at how they've implemented filtering using the searchString and currentFilter variable, that's what will make sure that when a new string is entered (or selected from a drop down list in your case) that the paging responds accordingly.
Specifically, this is what I think you're missing in your code
if (searchString != null)
{
page = 1;
}
else
{
searchString = currentFilter;
}
...
int pageNumber = (page ?? 1);

Button in polymer element not calling on-click function

So I have some select elements and a button declared like this within a polymer-element
...
<tr>
<td>
<select name="taskTypes" selectedIndex="{{selectedTaskTypeFilter}}">
<option template repeat="{{key in taskTypeIndexes}}" value="{{key.toString()}}">
{{taskTypes[key]}}
</option>
</select>
</td>
<td>
<select name="taskStatusFilter" selectedIndex="{{selectedStatusFilter}}">
<option template repeat="{{key in statusFilterIndexes}}" value="{{key.toString()}}">
{{statusFilters[key]}}
</option>
</select>
</td>
<td>
<select name="targetLanguage" selectedIndex="{{selectedTargetFilter}}">
<option template repeat="{{language in activeTargetLanguages}}" value="{{language.code}}">
{{language.name}}
</option>
</select>
</td>
</tr>
<button value="Filter" class="btn btn-primary" on-click="{{filterStream}}">
<i class="icon-refresh icon-white"></i> {{localisation.getTranslation("index_filter_task_stream")}}
</button>
...
(Inb4 someone bemoans use of tables; it's not my code originally and I kind of would like to replace them but it's not top priority.)
This is the filterStream() function the button is supposed to call but it seems not to get called at all as is evident from the output of the print statement not showing up.
void filterStream()
{
print("Entered filterStream");
filter = "";
if (isFiltered) {
filteredTasks.clear();
filteredTasks.addAll(filteredTasksBackup);
}
if (filteredTasksBackup.length == 0) {
UserDao.getUserTasks(userid, taskCount)
.then((List<Task> userTasks) {
filteredTasks = userTasks;
filteredTasksBackup = userTasks;
isFiltered = true;
});
}
if (selectedTaskTypeFilter > 0) {
//Remove all tasks but those of the selected type
filteredTasks.removeWhere((task) => task.taskType != selectedTaskTypeFilter);
}
if (selectedStatusFilter > 0) {
//Remove all tasks but those with the selected status
//The + 2 is to adjust the values so that they match correctly; task status 3 and 4 are in progress and
//complete, respectively, but on the UI filter they are the 2nd and 3rd options (hence index 1 and 2).
filteredTasks.removeWhere((task) => task.taskStatus != selectedStatusFilter + 2);
}
goToFirstPage();
}
The full ClaimedTaskStream.dart file can be found here if it helps. Also, as it may be relevant, I should mention I am running the code as JS compiled by dart2js.
The method needs to have three arguments Event, detail, and target
filterStream(MouseEvent e, detail, Element target) { }

Enable/Disable Validation of certain hidden textboxes in mvc 2

I have got [hide] and [unhide] input buttons , the hide button shows some text boxes while the hidden button hide some text boxes, What I want to do is to enable validation only for those boxes which are visible and disable validation for the boxes which are not visible to client. Currently I am validating on all the boxes, the post action also validates the text boxes which are hidden through jquery , below is the code :
View
<script type="text/javascript">
$(document).ready(function () {
var $startdates = $('#startDates');
var $endDates = $('#endDates');
var $showEvents = $('#showEvents');
$startdates.hide();
$endDates.hide();
$showEvents.hide();
$('#all').click(function () {
$startdates.show();
$endDates.show();
$('#showEvents').show();
$('#eventdids').hide();
$(this).hide();
return false;
});
$('#showEvents').click(function () {
$startdates.hide();
$endDates.hide();
$('#eventdids').show();
$('#all').show();
$(this).hide();
return false;
});
});
</script>
<tr id="startDates">
<td>
<div class="editor-label">
<%: Html.LabelFor(model => model.StartDate) %>
</div>
</td>
<td>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.StartDate) %>
<%: Html.ValidationMessageFor(model => model.StartDate) %>
</div>
</td>
</tr>
<tr id="endDates">
<td>
<div class="editor-label">
<%: Html.LabelFor(model => model.EndDate) %>
</div>
</td>
<td>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.EndDate) %>
<%: Html.ValidationMessageFor(model => model.EndDate) %>
</div>
</td>
</tr>
<tr id="eventdids">
<td>
<label>Events</label>
</td>
<td>
<% foreach (var item in (SelectList)ViewData["events"]) { %>
<input type="checkbox" name="Name" value="<%=item.Value %>" />
<label for="<%=item.Value%>"><%=item.Text%></label>
<br />
<% } %>
</td>
<td><input type="button" name="Select" id="all" style="width:auto" value="Hide" /></td>
</tr>
</table>
<input type="button" name="show" id="showEvents" style="width:auto" value="Show" />
<p>
<input type="submit" value="Create" />
</p>
Controller:
[HttpPost]
public ActionResult Create(FormCollection collection, int[] Name)
{
IVoucherRepository voucherResp = new VoucherRepository();
string empty = "";
if (Name != null)
{
for (int i = 0; i < Name.Length; i++)
{
empty += Convert.ToString(Name[i]) + ",";
}
}
else
{
ModelState.AddModelError("Venue", "Required");
}
if (Convert.ToBoolean(collection["pound"].ToLower().StartsWith("false")) && Convert.ToBoolean(collection["percentage"].ToLower().StartsWith("false")))
{
ModelState.AddModelError("","Please Select £ or % for discount");
}
if (collection["UsageQtyAvailable"] == null) { ModelState.AddModelError("UsageQtyLeft", "Required "); }
Voucher voucher = new Voucher();
if (TryUpdateModel(voucher) && ModelState.IsValid)
{
voucher.Status = true;
voucher.DateAdded = DateTime.Now;
voucher.DateModified = DateTime.Now;
if(Convert.ToBoolean(collection["pound"].ToLower().StartsWith("true")))
{
voucher.DiscountType = 1;
}
else if (Convert.ToBoolean(collection["percentage"].ToLower().StartsWith("true")))
{
voucher.DiscountType = 2;
}
voucher.VoucherType = 1; //Discount Code
voucher.UsageQtyLeft = Convert.ToInt32(collection["UsageQtyAvailable"]);
string removeComma = empty.Remove(empty.Length - 1,1);
voucher.EventIDs = removeComma;
voucherResp.Add(voucher);
voucherResp.Save();
return RedirectToAction("Index");
}
ITrackdayRepository trackdayResp = new TrackdayRepository();
IQueryable<Object> getAllEvents = trackdayResp.GetEventsSelectlist();
ViewData["events"] = new SelectList(getAllEvents.ToList(), "EventID", "Name");
return View();
}
You could check via jquery if the text boxes are hidden and remove them before submitting the form and subsequently only validate submitted form elements.
...
<input type="submit" value="Create" id="create" />
...
$("#create").click(function() {
$('#eventdids:hidden').remove();
$('#all:hidden').remove();
$("#formID").submit();
});
You can also remove validation for all hidden fields in a form with this little plugin:
(function($) {
$.fn.refreshValidator = function() {
var form = this;
// Get validation settings object
var settings = form.validate().settings;
// Remove validation for hidden elements
$(this).find(':hidden').each(function(){
var id = $(this).attr('id');
delete settings.rules[id];
delete settings.messages[id];
});
};
})(jQuery);
You can call it like this:
$('#yourFormId').refreshValidator();
It's more reusable this way.

Resources