Please suggest the best way of rendering Partials - c#

I have a new development task , I am trying to do reports dashboard and my requirement is to
I will have a form and I need to select values from form and depending upon user selection I need to display high charts in the same page and tabular view of my data in same page. So my form content is static and my Highcharts data and tabular contains dynamic data.
Steps I have done so far:
Login form and if credentials are valid Displays my mainform.aspx
My mainform.aspx contians form with a submit button
<form id="StatsForm" name="StatsForm" action="../Stats/Index/" method="POST"
enctype="multipart/form-data">
<%= Html.AntiForgeryToken()%>
<% Html.RenderPartial("OptionalFields"); %>
</form>
On button click I am sending my form data to controller
//
$(document).ready(function () {
$("#GetReport").click(function () {
$("form[name=StatsForm]").submit();
});
});
//]]>
</script>
I am doing some repository functions from my form data in my controller action and I am adding form values to a model class.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(FormCollection form)
{
var manufacturerId = Convert.ToInt32(form["manufacturerId"]);
var reportId = Convert.ToInt32(form["reportId"]);
var categoryId = Convert.ToInt32(form["categoryId"]);
var retailerId = Convert.ToInt32(form["retailerId"]);
var countryId = Convert.ToInt32(form["countryId"]);
var regionId = Convert.ToInt32(form["regionId"]);
var manufacturerWidgetId = (form["ManufacturerWidgetId"]);
var startDate = new DateTime(1, 1, 1, 0, 0, 0, 0);
var endDate = new DateTime(1, 1, 1, 0, 0, 0, 0);
if (!String.IsNullOrEmpty(form["StartDate"]))
{
startDate = Convert.ToDateTime(form["StartDate"]);
}
if (!String.IsNullOrEmpty(form["EndDate"]))
{
endDate = Convert.ToDateTime(form["EndDate"]);
}
var reportName = _reportRepository.GetReport(reportId);
var stats = new Stats
{
ManufacturerId = manufacturerId,
CountryId = countryId,
ReportName = reportName.ToString(),
StartDate = startDate,
EndDate = endDate
};
Now I am struck, I did below steps not sure if I am right. I thought because my mainform.aspx has to display dynamic partials I am trying to create partials foreach report and on selection of uservalue I am planning to inject corresponding partial in my mainform.aspx.
for that I am doing : (continuation of my Action method)
switch (reportName.Code)
{
case "INTER":
return RedirectToAction("InterStats",
new
{
manufacturerId = manufacturerId,
countryId = countryId,
startDate = "2013-01-01",
endDate = "2013-01-31"
});
break;
case "CUMLEADS":
return RedirectToAction("ParametersCumLeads",
new
{
manufacturerId = manufacturerId,
countryId = countryId,
categoryId = categoryId,
startDate = startDate.ToString("yyyy-MM-dd"),
endDate = endDate.ToString("yyyy-MM-dd")
});
break;
case "IMP":
break;
}
5.My partial view:
[AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
public JsonResult InterStats(int manufacturerId, int countryId, DateTime startDate, DateTime endDate)
{
//Get all manufacturerwidgets for manufacturer
var manufacturerWidget = _manufacturerWidgetsRepository.GetManufacturerWidgetByManufacturerAndCountry(manufacturerId, countryId);
var interReport = new InterReport();
var interRecordList = new List<InterRecord>(); // a list of my anonymous type without the relationships
interReport.InterRecordList = new List<InterRecord>();
var count = 1;
foreach (var mw in manufacturerWidget)
{
var widgetName = mw.Description;
//Get the product stats data
var imps = _productStatsRepository.GetSumImpressionsProductStatsForManufacturerCountryDate(
mw.Id, countryId, startDate, endDate);
var clicks = _productStatsRepository.GetSumClicksProductStatsForManufacturerCountryDate(
mw.Id, countryId, startDate, endDate);
float ctr = 0;
if (imps != 0 && clicks != 0)
{
ctr = ((clicks / (float)imps) * 100);
}
// Create the data for the report
var interRecord = new InterRecord
{
WidgetName = widgetName,
Impressions = imps,
Interactions = clicks,
Ctr = ctr,
Count = count
};
interReport.InterRecordList.Add(interRecord);
count++;
}
interReport.Counter = count;
return Json(interReport, JsonRequestBehavior.AllowGet);
}
And I tried in my mainform.aspx to write a small ajax function to render partial data , but $("#GetReport").click(function () I am sending form back to controller dont know how it will again here ?
<script type="text/javascript" language="javascript">
//<![CDATA[
$(document).ready(function () {
$("#GetReport").click(function () {
$.ajax({
url: "/Stats/InterStats/<%: Model.ManufacturerId %>/<%: Model.CountryId %>/<%: Model.StartDate %>/<%: Model.EndDate %>",
type: 'get',
success: function (data) {
<% Html.RenderPartial("InterStats"); %>
}
});
$("form[name=StatsForm]").submit();
});
});
//]]>
</script>
So I ahve my partial views, my data ready and I am not able to display corresponding partial in my mianform.aspx .Please help how can I do this?

$.ajax({
url: "/Stats/InterStats/<%: Model.ManufacturerId %>/<%: Model.CountryId %>/<%: Model.StartDate %>/<%: Model.EndDate %>",
type: 'get',
success: function (data) {
<% Html.RenderPartial("InterStats"); %>
}
});
Instead of this, you need some javascript in the success function to handle the response. Probably something like:
success: function (data) {
$('#someDivId').html(data);
}

Related

Razor Pages return Json for DataTables

i have a razor project where i implemented DataTables. I'm trying to retrieve data from the database dynamically with ajax in this way:
$('#orariDipendenti').DataTable({
'orderMulti': false,
'stateSave': true,
'paging': true,
'pageLength': 10,
'filter': false,
'processing': true,
'serverSide': true,
'ajax': {
url: '?handler=LoadData',
type: 'POST',
dataType: 'json',
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
},
});
my back code is this:
public JsonResult LoadTable()
{
try
{
var idDipendente = HttpContext.Session.GetInt32("IdDipendente");
var draw = HttpContext.Request.Form["draw"].FirstOrDefault();
var length = Request.Form["length"].FirstOrDefault();
var start = Request.Form["start"].FirstOrDefault();
int pagesize = length != null ? Convert.ToInt32(length) : 0;
int skip = start != null ? Convert.ToInt32(start) : 0;
int recordstotal = 0;
var recordData = context.Pres_Orari.Where(x => x.IdDipendente == idDipendente).ToList();
recordstotal = recordData.Count;
var data = recordData.Skip(skip).Take(pagesize).ToList();
return new JsonResult(new { draw = draw, recordsFiltered = recordstotal, recordsTotal = recordstotal, data = data });
}
catch (Exception)
{
throw;
}
}
the error i get when i open the page is this:
DataTables warning: table id={id} - Invalid JSON response.
I know the broblem is with the returned json but i don't know where. somebody can help me?
Firstly,your handler name is LoadTable,your url in ajax is url: '?handler=LoadData'.You need to change url to url: '?handler=LoadTable'.And here is a working demo(I also change xhr.setRequestHeader("XSRF-TOKEN" to xhr.setRequestHeader("RequestVerificationToken",if your code can work,you don't need to changexhr.setRequestHeader("XSRF-TOKEN"):
cshtml:
#Html.AntiForgeryToken()
<table id="orariDipendenti" class="table table-striped table-bordered" style="width:100%">
<thead class="thead-dark">
<tr class="table-info">
<th>IdDipendente</th>
<th>Name</th>
</tr>
</thead>
</table>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.css">
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.js"></script>
<script>
<script>
$(function () {
$('#orariDipendenti').DataTable({
'orderMulti': false,
'stateSave': true,
'paging': true,
'pageLength': 10,
'filter': false,
'processing': true,
'serverSide': true,
ajax: {
url: '?handler=LoadTable',
type: 'POST',
beforeSend: function (xhr) {
xhr.setRequestHeader("RequestVerificationToken",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
},
columns: [
{ data: 'idDipendente' },
{ data: 'name' },
]
});
});
</script>
Model:
public class MyModel1 {
public int IdDipendente { get; set; }
public string Name { get; set; }
}
cshtml.cs(I use fake data to test):
public static List<MyModel1> list = new List<MyModel1> { new MyModel1 { IdDipendente = 1, Name = "name1" }, new MyModel1 { IdDipendente = 2, Name = "name2" }, new MyModel1 { IdDipendente = 3, Name = "name3" } };
public JsonResult OnPostLoadTable()
{
try
{
var idDipendente = 1;
var draw = HttpContext.Request.Form["draw"].FirstOrDefault();
var length = Request.Form["length"].FirstOrDefault();
var start = Request.Form["start"].FirstOrDefault();
int pagesize = length != null ? Convert.ToInt32(length) : 0;
int skip = start != null ? Convert.ToInt32(start) : 0;
int recordstotal = 0;
var recordData = list.Where(x => x.IdDipendente==idDipendente).ToList();
recordstotal = recordData.Count;
var data = recordData.Skip(skip).Take(pagesize).ToList();
return new JsonResult(new { draw = draw, recordsFiltered = recordstotal, recordsTotal = recordstotal, data = data });
}
catch (Exception)
{
throw;
}
}
}
result:

Kendo UI DatePicker Javascript and HttpContext.Session C#, MVC

We are using a Kendo UI date picker (Javascript version), in which I want to populate with an HttpContext.Session variable that has a date passed from our KendoUI datepicker and passed to our controller, Session is set in the controller.
The KendoUI DatePicker is used on multiple pages in multiple templates.
My goal is to have the date selected and set in Session be passed back to the KendoUI DatePicker if the variable is set. And if the date selected is not set, I want the Date Picker's value to be set to today or new Date().
My Javascript:
<script>
$(document).ready(function () {
var SelectedDate = new Date();
//Is this even correct?
if('#HttpContext.Current.Session["CalendarSelectedDate"]' != '#DateTime.Now'){
SelectedDate == '#HttpContext.Current.Session["CalendarSelectedDate"]';
console.log("In if");
}else{
SelectedDate == new Date();
console.log("In else");
}
console.log('Selected date: ' + SelectedDate);
// WANT TO SET VALUE FROM SESSION DATE HERE!!!
$("#datepicker").kendoDatePicker({
value: SelectedDate,
min: new Date(),
format: "MM/dd/yyyy",
change: function () {
var value = this.value();
console.log(value); //value is the selected date in the datepicker
initialGetEventTypes();
}
});
initialGetEventTypes();
});
</script>
//The AJAX call to the controller
<script type="text/javascript">
function initialGetEventTypes() {
#{
var dateFromHub = DateTime.Now;
var obj = HttpContext.Current.Session["CalendarSelectedDate"];
if(obj != null)
{
dateFromHub = Convert.ToDateTime(obj);
}
}
console.log('Session Selected Date: #dateFromHub.ToShortDateString()');
$('#categoryLoading').show();
var startDateTime = $("#datepicker").val();
var endDateTime = startDateTime;
var url = '#Url.Action("GetTotalEventTypeIdsByDate", "MuseumUniversalCalendar")';
$.ajax({
url: url,
type: "GET",
cache: false,
dataType: "json",
data: { startDateTime: startDateTime, endDateTime: endDateTime },
success: function (data) {
$('#categoryLoading').hide();
$('.product-item').find('.categoryAvaiableCapacity').html("Not Available");
var list = JSON.stringify(data);
$("#eventTypeName").find('option').remove().end();
$.each(data.result, function (i, eventTypes) {
$('.product-item').each(function () {
if ($(this).attr('data-galaxyeventnamefromnop') == eventTypes.EventName) {
$(this).find('.categoryAvaiableCapacity').html(eventTypes.Available + ' Available');
}
});
});
if (data.result.length === 0) {
$("#noEvents").text('#T("museum.noeventavailablemessage")');
}else{
// console.log("we are here")
$("#noEvents").text("");
}
},
error: function(xhr, error, data) {
console.log(xhr, error, data);
$('#categoryLoading').hide();
$("#eventTypeName").find('option').remove().end();
alert("An error occurred getting the Event Types");
}
});
}
</script>
My Controller method:
public class MuseumUniversalCalendarController : Controller
{
//[NonAction]
public JsonResult GetTotalEventTypeIdsByDate(MuseumUniversalCalendarModel model, DateTime startDateTime, DateTime endDateTime)
{
//Set selected Date for session
HttpContext.Session["CalendarSelectedDate"] = startDateTime;
var result = eventListOfEvents(model, startDateTime, endDateTime);
return Json(new { result }, JsonRequestBehavior.AllowGet);
}
public List<cEvent> eventListOfEvents(MuseumUniversalCalendarModel model, DateTime startDateTime, DateTime endDateTime)
{
var eventTypeIdList = ExternalDataAccess.HubServiceCalls.GetAvailableEventsByEventDate(startDateTime, endDateTime);
foreach(var eventTypeItem in eventTypeIdList)
{
model.AvailableGalaxyEventTypes.Add(new SelectListItem
{
Text = eventTypeItem.EventName,
Value = eventTypeItem.EventTypeId.ToString()
});
}
var fullOutEventlist = eventTypeIdList;
var totalsList = eventTypeIdList.GroupBy(e => e.EventName.ToString()).Select(grp => grp.First()).ToList();
totalsList.ForEach(x => x.Available = eventTypeIdList.Where(y => y.EventName == x.EventName).Select(z => z.Available).Sum());
return totalsList;
}
I would wrap the datapicker in a partial view that can read the session value out into the view's JS with razor. You could even isolate it to its own controller.
Views/Shared/_DatePickPartial.cshtml
<div id='datepicker'></div>
<script>
$("#datepicker").kendoDatePicker({
value: '#HttpContext.Session["CalendarSelectedDate" ] ?? new Date()',
min: new Date(),
format: "MM/dd/yyyy",
change: function () {
//send ajax to partial action DatePickPartialUpdate which will add value to session
}
});
</script>
SomeController _DatePickPartial
public ActionResult _DatePickPartialUpdate(DateTime2 value)
{
Session["CalendarSelectedDate"] = value;
}

Can't set selected value in select2 plugin in Bootstrap

I use a select2 plugin my website. I can't set selected value in select2. Please see my code below.
Html
<input id="drpEditProvider" class="form-control" type="text" value="" tabindex="8" name="ProviderId" data-required="true" />
Script
var attendeeUrl = '#Url.Action("GetProvider", "Admin")';
var pageSize = 100;
$('#drpEditProvider').select2(
{
placeholder: 'Please Select Provider',
//Does the user have to enter any data before sending the ajax request
minimumInputLength: 0,
allowClear: true,
//tags:["red", "green", "blue"],
ajax: {
////How long the user has to pause their typing before sending the next request
//quietMillis: 150,
//The url of the json service
url: attendeeUrl,
dataType: 'jsonp',
//Our search term and what page we are on
data: function (term, page) {
return {
pageSize: pageSize,
pageNum: page,
searchTerm: term
};
},
results: function (data, page) {
//Used to determine whether or not there are more results available,
//and if requests for more data should be sent in the infinite scrolling
var more = (page * pageSize) < data.Total;
return { results: data.Results, more: more };
}
},
initSelection: function (element, callback) {
var data = [];
$(element.val().split(",")).each(function () {
data.push({ id: this, text: this });
});
callback(data);
},
});
Controller and model
public class Select2PagedResult
{
public int Total { get; set; }
public List<Select2Result> Results { get; set; }
}
public class Select2Result
{
public string id { get; set; }
public string text { get; set; }
}
public JsonResult GetProvider(string searchTerm, int pageSize, int pageNum)
{
int Count = 0;
List<Provider> provideres = ProviderHelper.GetAllProvider(searchTerm, out Count);
//Translate the attendees into a format the select2 dropdown expects
Select2PagedResult pagedProvider = new Select2PagedResult();
pagedProvider.Results = new List<Select2Result>();
//Loop through our attendees and translate it into a text value and an id for the select list
foreach (Provider a in provideres)
{
pagedProvider.Results.Add(new Select2Result { id = a.Id.ToString(), text = a.Name });
}
//Set the total count of the results from the query.
pagedProvider.Total = Count;
//Return the data as a jsonp result
return new JsonpResult
{
Data = pagedProvider,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
Finally I found the answer. You can set selected value in select2 plugin like below.
Select 2 Single selection
$("#drpselector").select2("data", { id: "1", text:"Test 1" });
Select 2 Multiple selection
var arrdata = "1:Test 1,2:Test 2"
var thdprdata = [];
$(arrdata.split(",")).each(function () {
thdprdata.push({ id: this.split(':')[0], text: this.split(':')[1] });});
$("#drpselector").select2("data", thdprdata);
I use this code in my application. It works fine for me.

Binding image in AutoCompleteExtender like facebook?

i have an ajax AutoCompleteExtender. I am able to bind the text only with my AutoCompleteExtender not image. So How can i bind the image and text in an ajax AutoCompleteExtender? Any help is greatly appreciated.
Add below mentioned files in your header section
<script type="text/javascript">
$(document).ready(function () {
$("#searchtext").autocomplete
({
source:
function (request, response) {
$.ajax
({
url: "../BeanService.asmx/GetCompletionList",
data: "{prefixText:'" + request.term + "'}", // term is the property that contains the entered text
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
success: function (data) {
response(data["d"]); // property d contains list of names sent from service
//$("#dynamiccontainer").append(data["d"]);
},
error: function (xhr, callStatus, errorThrown) {
// alert(callStatus);
}
});
},
// Attempt to remove click/select functionality - may be a better way to do this
select: function (event, ui) {
var mylink = ui.item.value;
var doc = document.createElement("html");
doc.innerHTML = mylink;
var links = doc.getElementsByTagName("a")
var urls = [];
for (var i = 0; i < links.length; i++) {
urls.push(links[i].getAttribute("href"));
}
window.location.href = urls[0];
return false;
}
});
});
</script>
Below is the Textbox on which autocomplete will be applied
<asp:TextBox ID="searchtext" runat="server"></asp:TextBox>
This is your bean class which will be filled by webservice and returned to jquery method through ajax call
public class SearchBean
{
public int Id
{
get;
set;
}
public string Title
{
get;
set;
}
public string reUrl
{
get;
set;
}
public string stype
{
get;
set;
}
public string photoAdd
{
get;
set;
}
}
This is your webservice which will be called by your jquery automplete ajax method
public string[] GetCompletionList(string prefixText)
{
BDBEntities db = new BDBEntities();
List<SearchBean> lstfinaldata = new List<SearchBean>();
List<MaCatMaster> lstcatlist = db.MaCatMasters.Where(z => z.CatName.Contains(prefixText) && z.Status == true).ToList();
foreach (MaCatMaster obj in lstcatlist)
{
SearchBean objbean = new SearchBean();
objbean.Id = obj.Id;
objbean.Title = obj.CatName;
objbean.stype = "Category";
objbean.reUrl = www.demo.com + "/Pages/Coupons/" + obj.Id;
lstfinaldata.Add(objbean);
}
string[] st = new string[lstfinaldata.Count];
int i = 0;
foreach (SearchBean obj in lstfinaldata)
{
StringBuilder sb = new StringBuilder();
sb.Append("<html><body>");
sb.AppendFormat("<a href='{0}' name='urllink'>", obj.reUrl);
sb.Append("<table width='420px'>");
sb.AppendFormat("<tr><td width='60px'><img src='{0}' style='border:1px solid #eeeeee' width='60px' height='40px'></td><td align='left' width='300px'>{1}</td><td align='left' width='60px' style='font-size:14px;'>{2}</td></tr>", obj.photoAdd, obj.Title, obj.stype);
sb.Append("</table>");
sb.Append("</a>");
sb.Append("</body></html>");
st[i] = sb.ToString();
i++;
}
return st;
}
In your search method you can use AutoCompleteExtender.CreateAutoCompleteItem() method to create pairs of the text to display and the image path:
public static List<string> Search(string prefixText, int count)
{
var items = new List<string>();
// ...
items.Add(AjaxControlToolkit.AutoCompleteExtender.CreateAutoCompleteItem(
text,
imagePath));
// ...
return items;
}
Then create the img tags on the client side with a javascript:
function Items_Populated(sender, e) {
var items = sender.get_completionList().childNodes;
for (var i = 0; i < items.length; i++) {
var div = document.createElement(“div”);
div.innerHTML = ”<img src=' + items[i]._value + ’ /><br />”;
items[i].appendChild(div);
}
Here are some examples:
AJAX AutoComplete with prefix image
Auto Complete with images

Change button status (MVC)

I wanna make twitter like microblog site which other users can follow my posts.
For that i made page with all currently registered users. In front of each name there is button to follow/unfollow user. (Like in Twitter)
View -
#{
ViewBag.Title = "Users";
}
#model MembershipUserCollection
#foreach (MembershipUser item in Model)
{
if(User.Identity.Name != item.UserName)
{
<li>#item.UserName
<span id="sp-#item.UserName"><input id="#item.UserName" name="submit" type="submit" value="Follow" class="follow-user fg-button ui-state-default"/></span>
</li>
}
}
<script type="text/javascript">
$(".follow-user").live("click", function (e) {
e.preventDefault();
var data = $(this).attr("id");
var spid = '#sp-' + data;
var btnid = '#' + data;
var val = $(this).attr('value');
$.ajax({
type: "POST",
url: "User/FollowUser",
data: { id: data },
cache: false,
dataType: "json",
success: function () {
if (val == 'Follow') {
$(btnid).attr('value', 'Unfollow');
}
else {
$(btnid).attr('value', 'Follow');
}
}
});
});
</script>
Controller -
public ActionResult Index()
{
return View(Membership.GetAllUsers());
}
public void FollowUser(string id)
{
ViewData["test"] = "test";
var n = FollowingUser.CreateFollowingUser(0);
n.FollowingId = id;
n.FollowerId = User.Identity.Name;
string message = string.Empty;
var list = new List<FollowingUser>();
list = (from a in db.FollowingUsers where a.FollowerId == User.Identity.Name && a.FollowingId == id select a).ToList();
if (list.Count() == 0)
{
try
{
db.AddToFollowingUsers(n);
db.SaveChanges();
}
catch (Exception ex)
{
message = ex.Message;
}
}
else
{
db.DeleteObject((from a in db.FollowingUsers where a.FollowerId == User.Identity.Name select a).FirstOrDefault());
db.SaveChanges();
}
}
FollowingUsers Table -
Now i wanna change button status on page load checking database whether he is already followed or not.
Ex- If user already followed it should display like below.
When you show this view to a user where this button is displayed, Load the status also, if the person is following or not.
public ActionResult Index()
{
var model = new MemberShipViewModel();
//We check here if the logged in user is already following the user being viewd
foreach(var member in Membership.GetAllUsers())
{
var user = (from a in db.FollowingUsers where a.FollowerId == User.Identity.Name && a.FollowingId == member.UserName select a).FirstOrDefault();
model.Members.Add(new Member{UserName = member.UserName,IsFollowing=user!=null});
}
//This line will remove the logged in user.
model.Members.Remove(model.Members.First(m=>m.UserName==User.Identity.Name));
return view(model);
}
In your index view model, you need to make some changes.
#model MemberShipViewModel
#foreach (var item in Model)
{
<li>#item.UserName
if(!item.IsFollowing)
{
<span id="sp-#item.UserName"><input id="#item.UserName" name="submit" type="submit" value="Follow" class="follow-user fg-button ui-state-default"/></span>
}
else
{
<span id="sp-#item.UserName"><input id="#item.UserName" name="submit" type="submit" value="Follow" class="unfollow-user fg-button ui-state-default"/></span>
}
</li>
}
$(".follow-user").live("click", function (e) {
e.preventDefault();
var data = $(this).attr("id");
var spid = '#sp-' + data;
var btnid = '#' + data;
var val = $(this).attr('value');
$.ajax({
type: "POST",
url: "User/FollowUser",
data: { id: data },
cache: false,
dataType: "json",
success: function () {
if (val == 'Follow') {
$(btnid).attr('value', 'Unfollow');
}
else {
$(btnid).attr('value', 'Follow');
}
}
});
});
You need to write some javascript now. Nobody is going to write full software for you.
Seems you are missing very basic programming skills.
cheers

Categories