How to send partial view to ajax in mvc4 - c#

I have an ajax call function. Inside that I'm calling a partial view. This view is for displaying comments. How can I refresh this view using ajax? I don't like json in my context, because my linq queries are set up with models. So these models with partial view should be send to ajax method. Ajax method should replace my div. Note that before ajax call, this view should be rendered at first as the page loads. I am not getting this. What is my fault?
$.ajax({
url: '/Home/Item',
type: 'POST',
data: { itemid: itemid },
success: function (data) {
$('.mycontainer').html(data);
}
});
Controller
public ActionResult Item(int itemid)
{
FoodContext db = new FoodContext();
ViewBag.FoodItems = db.FoodItems.Where(row => row.itemid == itemid);
List<ImageComment> comments = (from user in db.TxtComments
join o in db.Logins on user.username equals o.username
where user.itemid == itemid
select new ImageComment
{
ImageUrl = o.imgurl,
Comment = user.txtcmt,
ImgCmntUrl = user.imgurl,
Cmntdate = user.cmtdate,
Username = user.username,
}).OrderByDescending(x => x.Cmntdate).ToList();
ViewModel vm = new ViewModel { ImageComments = comments };
return PartialView("_Comments", vm);
}
Partial View
#model ViewModel
#foreach (ImageComment comment in Model.ImageComments)
{
<table width="100%" height="152" border="0">
<tr>
<td width="101" rowspan="2" valign="top"><img src="#comment.ImageUrl" width="100%" height="100%" /></td>
<td height="27" colspan="3" valign="middle"><p> #comment.Username Commented On On #comment.Cmntdate</p></td>
</tr>
<tr>
<td colspan="2" rowspan="2"><div style="width:70%;">
#if (#comment.ImgCmntUrl != null)
{
<img src="#Url.Content(comment.ImgCmntUrl)" width="100%" height="100%" />
}
</div>
<div style="background-color:#E3EEFA;width:68%;min-height:50px;padding:5px;">#comment.Comment</div></td>
<td width="209" height="29"> </td>
</tr>
<tr>
<td> </td>
<td> </td>
</tr>
<tr>
<td height="23"> </td>
<td>Like this.</td>
<td>Unlike this</td>
<td> </td>
</tr>
<tr>
<td height="23"> </td>
<td width="303"> </td>
<td width="588"> </td>
<td> </td>
</tr>
</table>
}
My view
<div class="mycontainer">
</div>

You could use the jquery load function:
<div class=".mycontainer"></div>
<script>
function ReloadComments(){
$(".mycontainer").load("#Url.Action("Item", new { itemId = Model.Id })");
}
$(function(){
setInterval(ReloadComments, 10000);
ReloadComments();
});
</script>
Your action method and partial view don't need to be edited.

We have did something similar in our project. first of all we have two action methods one is to get the data (doesnot have any view related things) and pass it to other one which have view , it will do nothing but get the input and render view directly.
The context is we have a timer which will call the ajax request in particular interval and get the data pass it to action (which has view) that will update the view in the background.
Hope i made it clear.

Related

how to get the id of a checkbox inside foreach loop in razor

I have a view which shows the list of files from a folder and the file count may differ for every user
my view is as follows
<div class="container" style="padding-top:10px; height:100%; width:100%;padding:0;margin:0;">
<table class="table table-bordered table-striped">
<thead>
<tr style="text-align:center;">
<th>File Name</th>
<th>Download</th>
</tr>
</thead>
<tbody>
#foreach (handbook.Data.EmpDoc files in Model)
{
<tr style="text-align:center;">
<td>
<input type="checkbox" id="chk(#files.Filename)" />
</td>
<td>#files.Filename</td>
<td class="text-nowrap">#Html.ActionLink("Download", "DownloadFile", new { fileName = files.Filename, id = files.EmployeeId })</td>
</tr>
}
</tbody>
</table>
</div>
and this is the script i am using to check if the check box is checked
<script>
// this is the scrpt for checkbox
$(document).on("click", "[type='checkbox']", function (e) {
if (this.checked) {
$(this).attr("value", "1");
} else {
$(this).attr("value", "0");
}
});
</script>
I am able to generate id for each file like chkDocs or chkpayslip but when i click in it, it sends value =0 to the controller
please help

Asp.net razor: model property is called houndred of times when it really should be called just once

I am quite new to ASP.NET with razor, I think I may have gotten a concept wrong.
All I am doing is instantiating my model, letting it retrieve data from the local db and returning it to the view.
The code is working fine, but when I put a stop point into the beginning of the GET it runs into that stoppoint literally hundreds of times before coming to a result.
This of course impacts performance massively.
Let me show you what I have done (briefly):
My controller has one ref to the model:
public class GlobalTaggingController : BaseCmsEditorController
{
public GlobalTaggingViewModel model = new GlobalTaggingViewModel();
public ActionResult Index(string searchword = "")
{
return View(model);
}
// ... cut for brevity
}
The viewmodel looks like that:
public class GlobalTaggingViewModel : BaseViewModel
{
public List<NodeModel> MainNodes
{
get
{
var globalTaggingLocalizedManager = new GlobalTaggingLocalizationManager();
var manager = new GlobalTaggingManager();
var mainlevel = manager.GetAllItemsOnLevel(0);
var subLevel = manager.GetAllItemsOnLevel(1);
var subsubLevel = manager.GetAllItemsOnLevel(2);
var resMainCat = new List<NodeModel>();
// ... cut for brevity
}
}
}
This is my view (which is very long and has many loops):
#model Application.Areas.Administration.Models.GlobalTaggingViewModel
#{
ViewBag.Title = "Administration - Video";
var positionNr = 0;
}
<form action="#Url.Action("Index")" method="POST" id="mainForm">
<div class="divHeader Administration">
<div class="divHeaderInner">
for (int i = 0; i < Model.MainNodes.Count(); i++)
{
string catId = "CatId" + i.ToString();
string classToHideCatId = "classToHideCatId" + i.ToString();
string rowCounter = "rowCounter" + i.ToString();
<tr class="mainCatRow">
<td>
<table class="mytable">
<thead>
</thead>
<tr class="#rowCounter rowHeight">
<td class="column0">
<div>
<img src="#Url.Content("~/Content/images/icons/icon-open.png")" id="#catId" class="buttonLayoutMain" />
</div>
</td>
<td class="column1">
<table class="tableInCol1">
<tr>
<td class="editButtonClassLeft">
<div class="mainCat">
#Model.MainNodes[i].name
</div>
</td>
<td class="editButtonClassRight">
<div>
<a onclick="javascript:Base.Popup.Open('#Url.Action("Index", "GlobalTaggingEditor", new {area = "Cms", id = Model.MainNodes[i].Id})', 1236, 800); return false;" href="#" class="ButtonEdit"><span class="mif-pencil"></span></a>
</div>
</td>
</tr>
</table>
<td>
<td>
<div class="mainCat mainCol">
#Model.MainNodes[i].nameEng
</div>
<td>
<td>
<div class="mainCat mainCol">
#Model.MainNodes[i].name
</div>
<td>
<td>
<div class="mainCat mainCol">
#Model.MainNodes[i].nameSpanisch
</div>
<td>
<td>
<div class="mainCat mainCol">
#Model.MainNodes[i].nameFra
</div>
<td>
<td>
<div class="mainCat mainCol">
#Model.MainNodes[i].namePort
</div>
<td>
<td>
<div class="mainCat mainCol">
#Model.MainNodes[i].nameRuss
</div>
<td class="column9">
Again this is working code, but it is called over and over and over again.
Did I maybe set something up wrong?
EDIT:
Going through my code in single steps, I found out that my model is recreated again once I am going through the razor page.
Specifically here:
<td class="column1">
<table class="tableInCol1">
<tr>
<td class="editButtonClassLeft">
<div class="mainCat">
#Model.MainNodes[i].name
</div>
</td>
<td class="editButtonClassRight">
<div>
<a onclick="javascript:Base.Popup.Open('#Url.Action("Index", "GlobalTaggingEditor", new {area = "Cms", id = Model.MainNodes[i].Id})', 1236, 800); return false;" href="#" class="ButtonEdit"><span class="mif-pencil"></span></a>
</div>
</td>
</tr>
</table>
Why would that start the model over again?
Ok, so as I put everything inside the GET of the model, intead of doing it over a constructor, I was able to get around this issue.

How to pass TextBox value to URL.Action in MVC razor?

I have an ASP.Net MVC website and I want to pass a textbox value from view to controller using URL Action.
Below is my code,
<table class="table table-striped table-bordered table-hover" id="products" width="100%">
<thead>
<tr>
<th>ProductId</th>
<th>Name</th>
<th>ShortName</th>
<th>ProductNamePrefix</th>
<th>Minimum Count</th>
<th>Add Product</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.ProductId)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.ShortName)
</td>
<td>
#Html.DisplayFor(modelItem => item.ProductNamePrefix)
</td>
<td>
#Html.TextBox("MinCount", item.MinimumCount, new {#class = "form-control" + " " + item.ProductId})
</td>
<td>
#if (item.IfExists == true)
{
<div class='isa_success'><i class='fa fa-check'></i></div>
}
#if (item.IfExists == false)
{
<div class='isa_info'><i class='fa fa-plus-circle'></i></div>
}
</td>
</tr>
}
</tbody>
</table>
I want to pass the textbox value in url action method to controller. I am creating a custom class based on the id for textbox but I am not able to retrieve it using javascript or jQuery.
but I am not able to retrieve it using javascript or jQuery
Why not? It's pretty simple.
In the absence of JavaScript, you can't do this with just a link. Instead, you'd need to use a form. So you'd have to wrap each table row in a form element and replace your link with an input type="submit". (And, of course, style it according to your needs.) This would post the values of the contained form elements (including the text box) to the form's action.
This does get a little ugly, since you can't wrap a form around a tr, so you'd have to nest your structure. Something like this:
<table>
<tr>
<td>
<form>
<table><!-- Your 1-row table goes here --></table>
</form>
</td>
</tr>
</table>
The outer tr is what gets repeated for each row of your "table", so each row is actually a single cell containing a nested table which itself has only one row. As I said, a bit ugly. But it gets the job done.

Access a bound value inside HTML element with KO

I have this view that loops a collection so that, using KO, it can do very basic pagination. Now, the last column for the table is just a bunch of actions for the record in each row. If this were simple MVC generated table, they would carry the proper Id in the generated URL.
Not anymore.
#using Newtonsoft.Json
#model IEnumerable<SensorSauce.Models.Business>
#{
ViewBag.Title = "Business Manager";
}
<h2>Business Manager</h2>
<table class="table table-striped table-bordered">
<thead>
<tr>
<td><strong>#Html.DisplayNameFor(model => model.Name)</strong></td>
<td><strong>#Html.DisplayNameFor(model => model.ServiceType)</strong></td>
<td><strong>#Html.DisplayNameFor(model => model.Specialties)</strong></td>
<td><strong>Actions</strong></td>
</tr>
</thead>
<tbody data-bind="foreach:currentBusinesses">
<tr>
<td data-bind="text:Name"></td>
<td data-bind="text:ServiceType"></td>
<td data-bind="text:Specialties"></td>
<td >
|
|
|
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="4">
<span data-bind="click:previousPage,visible:currentPage() > 1" class="glyphicon glyphicon-circle-arrow-left" style="cursor: pointer"></span>
Page #: <span data-bind="text:currentPage"></span>
<span data-bind="click:nextPage,visible:currentPage() < lastPage" class="glyphicon glyphicon-circle-arrow-right" style="cursor: pointer"></span>
</td>
</tr>
<tr>
<td >
<span class="glyphicon glyphicon-plus-sign"></span> Create Business
</td>
<td></td>
<td></td>
<td></td>
</tr>
</tfoot>
</table>
And here is the script after the above table:
<script src="~/Scripts/knockout-3.3.0.js"></script>
<script>
function BusinessViewModel() {
var self = this;
// properties
self.businesses = #Html.Raw( JsonConvert.SerializeObject(Model, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }));
self.pageSize = 10;
self.currentPage = ko.observable(1);
self.lastPage = Math.ceil(self.businesses.length / self.pageSize);
self.currentBusinesses = ko.computed(function() {
var startIndex = (self.currentPage() - 1) * self.pageSize;
var endIndex = startIndex + self.pageSize;
return self.businesses.slice(startIndex, endIndex);
});
// methods
self.nextPage = function() {
self.currentPage(self.currentPage() + 1);
};
self.previousPage = function() {
self.currentPage(self.currentPage() - 1);
};
}
ko.applyBindings(new BusinessViewModel());
</script>
The action for Edit, Delete, and Details etc require the parameter to be passed to the controller's action. Rendering the table like above creates an issue that the actions such as Details never receives the ID parameter.
I need to bind something to the Id property of the Model and combine it with the Url.Action() method's generated Url. Or so i understand.
Any suggestions?
You can use the attr binding and combing the URL generated by the URL.Action with the businessId (I am assuming that is what you are calling your Business Model's Id) just like the sample below ...
<a data-bind="attr: { href: '#Url.Action("MapLocation", "Business")'+'?BusinessId='+BusinessId()" class="glyphicon glyphicon-map-marker"></a>

ASP.Net MVC Controller not being called

I have a MasterPage, in my Views\Shared folder. I have an index.aspx in my Views\Home folder. And I have a login.ascx (user control) in my Views\User folder. The ascx file is added to my MasterPage:
<% Html.RenderPartial(#"~\Views\User\login.ascx");%>
The code in the ascx is pointing the submit form to a UserController.cs in my Controllers folder.
Here's the ascx:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<BudgieMoneySite.Models.SiteUserLoginModel>" %>
<% using (Html.BeginForm("UserLogin", "User"))
{%>
<table width="300">
<tr>
<td colspan="3" align="center">
User Login
</td>
</tr>
<tr>
<td align="right">
<%=Html.LabelFor(m => m.Username)%>
</td>
<td>
<%=Html.TextBoxFor(m => m.Username)%>
</td>
<td>
</td>
</tr>
<tr>
<td align="right">
<%=Html.LabelFor(m => m.Password)%>
</td>
<td>
<%=Html.PasswordFor(m => m.Password)%>
</td>
<td>
</td>
</tr>
<tr>
<td>
</td>
<td>
<%=Html.CheckBoxFor(m => m.RemeberMe)%><%=Html.LabelFor(m => m.RemeberMe)%>
</td>
</tr>
<tr>
<td colspan="2">
</td>
<td colspan="3" align="right">
<input id="Submit1" type="submit" runat="server" value="Login" />
</td>
</tr>
</table>
<%
} // End Using.%>
If I ctrl+click the Controller name and the method, in the Html.BeginForm area, it takes me to my method that should be called when I click Sybmit.
The method that this should call, in my UserController, has this code defined:
[HttpPost]
public ActionResult UserLogin(SiteUserLoginModel model)
{
try
{
if (MembershipService.ValidateUser(model.Username, model.Password))
{
FormService.SignIn(model.Username, model.RemeberMe);
PersonDto user = SiteUserLoginModel.LoadLoggedInUserDetails(model.Username);
Session.Add("current_firstname", user.Firstname);
Session.Add("current_userid", user.PersonId);
}
return RedirectToAction("Index", "Home");
}
catch (ArgumentException e)
{
ViewData["ErrorMessage"] = e.Message;
return RedirectToAction("Index", "Home");
}
}
However, when I click the submit button at runtime, this method is never called. The screen just refreshed. The HomeController does fire though, as the index screen is refreshed, I think. But the breakpoint in my method above never fires.
What am I doing wrong?
I would start removing the runat="server" attribute from your submit button...
<input id="Submit1" type="submit" value="Login" />
Your form in BeginForm isn't set to POST.
Try this: Html.BeginForm("UserLogin", "User", FormMethod.Post).
Guys, I found the issue, and it's an issue I had 2 weeks back, but totoally forgot. The master page had a Form tag! And the user control's Form tage was being hidden by the master page's one. I remove the Form tags from the master page, and it's resolved.

Categories

Resources