Iterate Session variable in Jquery - c#

I have a .net MVC Project. I assigned a List to a session variable. And in the View, i use jquery to iterate the data in the session variable.
ie,
var doctors = #Html.Raw(Json.Encode(HttpContext.Current.Session["DoctorList"]));
doctorCount = doctors.length;
for(i=0;i<doctorCount ; i++)
{
var totalinvoice =0;
rows = "<tr><td style='text-align:center'>"+ (parseInt(i, 10)+1) +"</td><td colspan='6'><b>" + doctors[i].D_Name + "</b></td></tr>"
$(rows).appendTo("#tbl_doctorwise tbody");
}
This code some time gives null even if the session variable contains list value. But sometimes it works.
Is there any other method to loop a session variable in the mvc view (jquery)?
how I get the session value in jquery ??? ( session variable contains list )

If you are making an ajax call and setting this session item in your action method, it won't available in your original view as that view code was already executed when you requested the action method for that view.
What you should do is, instead of setting this data in session, return that as json from your action method.
[HttpPost]
public ActionResult GetDoctorwiseReport(DateTime fromDate,DateTime toDate)
{
var doctorList = new List<Doctor>();
//populate this list now
return Json(doctorList);
}
and now in your ajax call's success handler will receive this data and you can loop through them.
success: function(data) {
$.each(data,function(ind,item)
{
//build your html here as needed.
console.log(item);
});
}

<script>
$(function ()
{
var doctors= #Html.Raw(Json.Encode(HttpContext.Current.Session["DoctorLis‌​t"]))
$.each(doctors, function (index, value)
{
var totalinvoice =0; rows = "<tr><td style='text-align:center'>"+ (parseInt(i, 10)+1) +"</td><td colspan='6'><b>" + value.D_Name + "</b></td></tr>"
$(rows).appendTo("#tbl_doctorwise tbody");
})
});
</script>

Related

ASP.NET Core MVC: Get values from Ajax, send to new View

This is similar to a previous issue that was resolved earlier. In this case, instead of rendering a table in the same view, I'd like to take the data retrieved and push to a new view:
Populate child area paths in a multiselect dropdown list
Select some of the items in the dropdown list
Take the selected items (as area path children) send back to controller
From controller use area paths as parameters to a method retrieving work items
Take workitem list and populate list in new view
Here is my view script
function GetSelectedAreaPathChildren3() {
alert("TEST1");
var selectedAreaPathItems = '';
$("#AreaPathMultiSelectDropdownList :selected").each(function () {
selectedAreaPathItems += this.value + ";";
});
var selectedIterationPathItems = '';
$("#IterationPathMultiSelectDropdownList :selected").each(function () {
selectedIterationPathItems += this.value + ";";
});
console.log(selectedAreaPathItems);
$.ajax({
url: '#Url.Action("WorkItemTable", "PbcAzureDevOps")',
type: "POST",
data: { selectedAreaPathItems, selectedIterationPathItems },
success: function () {
alert("BLAH!");
}
});
}
Here is my controller method
public async Task<IActionResult> WorkItemTable(string selectedAreaPathItems, string selectedIterationPathItems)
{
//Get the retrieved work items
List<WorkItemInfo> retrievedWorkItems =
await GetAllSelectedWorkItems(selectedAreaPathItems, selectedIterationPathItems);
return View(retrievedWorkItems);
}
Expected result:
retrievedWorkItems is populated and sent to view ("WorkItemTable") -- after sending to view, "WorkItemTable is shown on screen
Actual result:
retrievedWorkItems is populated and sent to view ("WorkItemTable") -- after sending to view, "WorkItemTable is NOT SHOWN (i.e. WorkItemTable does not pop up)
I recognize from my research that I can't get the view to show up from the script and have also tried adding the following to the view:
#using (Html.BeginForm("WorkItemTable", "PbcAzureDevOps", FormMethod.Post))
{
}
Can anyone help me to get the WorkItemTable to render... I can already see the data in the foreach part of the view, it just doesn't show.
So I figured a workaround... instead of pulling the selections from the dropdownlists using Ajax, I pulled the data from the dropdown via IFormCollection:
public async Task<IActionResult> WorkItemTable(IFormCollection collection)
{
List<string> selectedAreaPathItems = collection["apchildrenDropDown"].ToList();
List<string> selectedIterationPathItems = collection["ipchildrenDropDown"].ToList();
//Get the retrieved work items
List<WorkItemInfo> retrievedWorkItems =
await GetAllSelectedWorkItems(selectedAreaPathItems, selectedIterationPathItems);
return View(retrievedWorkItems);
}

Binding knockoutjs / mapping in ASP.NET with EF objects

I am trying to bind a select and table to the result of an AJAX call in ASP.NET with the objects coming from EntityFramework backend.
Here is the script:
<script type="text/javascript">
function QuizListViewModel() {
var self = this;
self.quizList = ko.observableArray([]);
}
var qlvm = new QuizListViewModel();
ko.applyBindings(qlvm);
function FetchQuizzes() {
$.getJSON(
"/DesktopModules/personify/QuizAdminDos/API/QuizAdmin/QuizList",
function (result) {
var mapping = {
'observe': ["IdQuiz", "Name"]
}
parsedJsonQuizzes = jQuery.parseJSON(result);
console.log(parsedJsonQuizzes);
ko.mapping.fromJS(parsedJsonQuizzes, mapping, qlvm.quizList);
});
}
$(document).ready(function () {
FetchQuizzes();
});
</script>
Here is the View:
<select data-bind="options: quizList,
optionsText: function(quiz) { return quiz.Name() + '(Id: ' + quiz.IdQuiz() + ')'},
optionsCaption: 'Select a quiz...'"></select>
I have verified through debugging that I am getting objects back from my JSON call. I have also verified that the 'quizList' observable has values after the ko.mapping.fromJS call. However, nothing is showing in my select. I don't even get the "optionsCaption" value.
Am I allowed to bind directly to EF objects (generated from the DB)? Here is what is coming back from the console.log output of the parsedJsonQuizzes:
And for full disclosure, this is how I am returning the objects from my AJAX call:
using (var db = new LinuxDatabase())
{
List<Quiz> qzs = db.Quizs.ToList();
db.ContextOptions.LazyLoadingEnabled = false;
var json = JsonConvert.SerializeObject(qzs);
return Request.CreateResponse(HttpStatusCode.OK, json);
}
Thanks for the help!
I think you need to move your call to applyBindings into your $(documnent).ready function so that you can ensure the DOM has been loaded before you're trying to bind.

nothing display in the second view in MVC c#

In my web site I'm getting data from xml in first controller action method and display as dropdown (html select and option).When a user selects an item in first dropdown, selected item sent to the next view's controller as a parameter using jquery $.post. I have keep breakpoints and see what is going on. Data trasfer is success until second view . But display nothing. I have attached screenshot of my break points and codes.
This is my controllers.
public ActionResult First()
{
//get the location data
var Loc = getData("Location", "", "", "");
List<FirstData> Ilc = new List<FirstData>();
foreach(var val in Loc)
{
Ilc.Add(new Firstdata
{
Destination = val
});
}
ViewBag.Loc = Ilc;
return View();
}
this is how I pass data from first view to second action controller method
<script type:"text/javascript">
$(document).ready(function() {
$("#chk a").addCIass("btn btn-default");
$("#chk a").click(function () {
var url = '#Url.Action("Check","Cruise")';
$.post(url, { LocNane: $("#desti").val() }, function (data) {
//alert("succes");
});
});
});
</script>
this is how my second controller gets pass data[I made a breakpoint here]
public ActionResult Check(string LocName)
{
string d = LocNane;
var Nan = getData('Location',"Name",d,"");
List<Seconddata> nf = new List<Seconddata>();
foreach (var val in Nam)
{
nf.Add(new Seconddata
{
Naneof = val
});
}
ViewBag.Nn = nf;
}
and this is my second view and display data in break point
<body>
<div>
#foreach( var item in #VieuBag.Nm)
{
<h3>one</h3>
}
</div>
</body>
I put "#item.Nameof" inside the header tags , but it didn't work. so just to chek I put one. after go through the loop nothing display.what's the wrong.please help me with this.
The problem here is the success handler of $.post does not append/insert the returned html in any element. You can do something like this in success handler where divId is element Id in page where you want to show the returned html.
$("#divId").append(data);

How do I pass multiple objects from a ViewModel to a jQuery function?

I am coding a MVC 5 internet application and would like to know how to pass values from a ViewModel into a jQuery function where I have a list of data to pass.
Usually, I would create a hidden field in the MVC View code, and then retrieve this value in the jQuery code. However, in this situation, there is not just one value from the ViewModel, but a List of objects, where each object has many values.
My ViewModel has a List<MapMarker>, where each MapMarker has the following attributes:
latitude
longitude
title
draggable
This is the jQuery function that I need to call for each MapMarker object:
function LoadMapMarker(latitude, longitude, title, draggable)
How can I call the LoadMapMarker function, with data from each of the MapMarker objects in the ViewModel list?
Thanks in advance
You can serialize your list and storage it in a hidden field. Then call LoadMapMarker by means of Javascript on client side.
Server:
using System.Web.Script.Serialization;
var MapMarkers = new List<MapMarker>();
var jsonSerialiser = new JavaScriptSerializer();
var json = jsonSerialiser.Serialize(MapMarkers);
return View(new MyViewModel({JsonList = json }));
View:
<input type="hidden" id= "MyHiddenFieldForMapMarker" value="#Model.JsonList" >
Client:
var MapMarkers = $("#MyHiddenFieldForMapMarker").val();
for (var MapMarker in MapMarkers) {
LoadMapMarker(MapMarker["latitude"],
MapMarker["longitude"],
MapMarker["title"],
MapMarker["draggable"]);
}
You can serialize to JSON and then store in a hidden field, or as a Javascript object like :
myJsonData= [{"id":"15aea3fa","firstname":"John","lastname":"Doe"}];
Alternatively, you can retrieve the data via an ajax call.
If you don't want to use JSON and use the data you have on your page you can do this:
You can add class (or some other attribute, for me it is easier to use classes, but it is better "programming" to use another attribute)
#foreach ()...
{
<div class="main_Marker">
<input ... class="lat"/> //using the #Model render ofc...
<input ... class="long"/>
</div>
}
Then jQuery:
$("main_Marker").each(function(index, item)) {
var lat = $(item).child(".lat");
.
.
LoadMapMarker(lat, long....);
}
If your jQuery function is present in a view, use #Html.Raw(Json.Encode(Model.JSonData)) like this
//JavaScript or jQuery function
function javascriptFunction()
{
var data = #Html.Raw(Json.Encode(Model.JSonData))
}
In the above code, JSonData is the name of the collection variable that contains data from model. In your case a List.
If your jQuery function is in a separate JavaScript file, then an AJAX request can be used to get the data from model
Controller Code
public ActionResult GetData()
{
//Your logic to get data from model
//Here data is the variable that holds the collection List<MapMarker>
return Json(data);
}
JavaScript Code for AJAX Request
function myJavaScriptFunction()
{
$.ajax({
url: '/GetData',
type: 'post',
success: function (data) {
alert("data retrieved successfully");
},
error: function () {
alert("Error retrieving data");
}
});
}

Getting a framework to deal with knockout.js not persisting via hidden field

VS2013, WebForms, .NET 4.51
I want to use a hidden field to maintain the contents of my Knock Out view model across postbacks. So I took the KO code from http://knockoutjs.com/examples/cartEditor.html and then read http://www.codeproject.com/Articles/153735/Using-KnockoutJS-in-your-ASP-NET-applications for some ideas.
The end result is the following:
<asp:HiddenField ID="HiddenField1" runat="server" />
<script type='text/javascript' src="http://knockoutjs.com/examples/resources/sampleProductCategories.js"></script>
<script type="text/javascript">
function formatCurrency(value) {
return "$" + value.toFixed(2);
}
var CartLine = function () {
var self = this;
self.category = ko.observable();
self.product = ko.observable();
self.quantity = ko.observable(1);
self.subtotal = ko.computed(function () {
return self.product() ? self.product().price * parseInt("0" + self.quantity(), 10) : 0;
});
// Whenever the category changes, reset the product selection
self.category.subscribe(function () {
self.product(undefined);
});
};
var Cart = function () {
// Stores an array of lines, and from these, can work out the grandTotal
var self = this;
self.lines = ko.observableArray([new CartLine()]); // Put one line in by default
self.grandTotal = ko.computed(function () {
var total = 0;
$.each(self.lines(), function () { total += this.subtotal() })
return total;
});
// Operations
self.addLine = function() {
self.lines.push(new CartLine());
SaveList();
};
self.removeLine = function(line) {
self.lines.remove(line);
SaveList();
};
self.save = function () {
var dataToSave = $.map(self.lines(), function (line) {
return line.product() ? {
productName: line.product().name,
quantity: line.quantity()
} : undefined
});
alert("Could now send this to server: " + JSON.stringify(dataToSave));
};
self.SaveList = function () {
var myHidden = document.getElementById('<%= HiddenField1.ClientID %>');
if (myHidden)//checking whether it is found on DOM, but not necessary
{
var dataToSave = $.map(self.lines(), function (line) {
return line.product() ? {
productName: line.product().name,
quantity: line.quantity()
} : undefined;
});
alert("Saving - " + JSON.stringify(dataToSave));
myHidden.value = JSON.stringify(dataToSave);
}
};
};
var stringViewModel = document.getElementById('<%=HiddenField1.ClientID %>').value;
var viewModel;
if (document.getElementById('<%=HiddenField1.ClientID %>').value == '') {
alert('Nothing In Hidden Field');
viewModel = new Cart();
} else {
viewModel = ko.utils.parseJson(stringViewModel);
for (var propertyName in viewModel) {
viewModel[propertyName] = ko.observable(viewModel[propertyName]);
}
}
ko.applyBindings(viewModel);
$(document.forms[0]).submit(function () {
alert('In Submit');
viewModel.SaveList();
});
</script>
So basically when the page loads we create a new instance of the Cart. And when the form is posted we successfully have the cart serialized to HiddenField1 and I can see the expected value in the code behind:
protected void btnSave_OnClick(object aSender, EventArgs aE)
{
if (HiddenField1.Value == null)
{
}
}
however after the postback the contents of stringViewModel
var stringViewModel = document.getElementById('<%=HiddenField1.ClientID %>').value;
is always blanl / empty? Why is that?
And then assuming I have the correct JSON is the following the correct way to apply it back to the view model?
viewModel = ko.utils.parseJson(stringViewModel);
for (var propertyName in viewModel) {
viewModel[propertyName] = ko.observable(viewModel[propertyName]);
}
EDIT: I tried a few things with no luck
Added all JS code to jQuert OnReady() handler
Tried using instead of ASP:HiddenField
In all cases in PostBack I can see the value assigned to the hidden field by SaveList(), but when the page is displayed again (after postback) the value of the hidden field is an empty string
For the first part, what you're doing is correct. Use the console (press F12 in your browser) to examine the hidden field, and check if it has the value. If you see it in the server side, it should be in the client side. You can also run js code, and set breakpoints to discover what the problem is. You can also add a PreRender handler in the server side, and add a breakpoint and debug to check that the Value has not been deleted in the server side (this event happens just before the page is rendered to be sent to the browser).
For the second part, the fastest way to do what you need is to use knockout mapping, which creates a model from a JavaScript object, or from JSON. You need to use this: ko.mapping.fromJSON. This will create a new viewmodel, which you can directly bind, from your JSON. (As you can read in the docs, you can customize how the view model is created).
However, what you're doing is quite strange. You normally use Knockout with Web API, or Web Services, or Page methods, without reloading the page. The model is recovered, and updated, changed, etc. through one of those technologies, using AJAX.

Categories