How can I update model view data in jquery? - c#

How can the model data for the page be updated? I want to take full advantage of its presence
in view
#model List<Table.Invoice_Details>
#foreach (Table.Invoice_Details invoice_Details in Model)
{
#Html.TextBoxFor(modelitem => invoice_Details.ID_Invoice_Details, new { id = "ID_Invoice_Details-" + invoice_Details.ID_Invoice_Details })
#Html.TextBoxFor(modelitem => invoice_Details.Sale_Price, new { id = "Sale_Price-" + invoice_Details.ID_Invoice_Details })
<button id="btnSave-" + #invoice_Details.ID_Invoice_Details>save</button>
}
in script :
<script>
$('button[id*=btnSave-]').click(function ()
{
var FullID = $(this).attr('id');
var ID_Number = ID.substring(FullID.indexOf('-') + 1);
var Sale_Price = $('Sale_Price-' + ID_Number).val();
$.get(
{
url: '/Invoice/SaveInvoice',
contents: 'application/json; charset=utf-8',
type: 'post',
dataType: 'json',
data: { ID_Invoice_Details: ID_Number, Sale_Price: Sale_Price },
success: function (result) {
//[Here I want to update model with the new data]
}
})
})
</script>
controller :
private Table.Smart_PosEntities Cn = new Table.Smart_PosEntities();
public JsonResult SaveInvoice(int ID_Invoice_Details, int Sale_Price)
{
Table.Invoice_Details invoice_Details = Cn.Invoice_Details.Where(L => L.ID_Invoice_Details == ID_Invoice_Details).FirstOrDefault();
invoice_Details.Sale_Price = Sale_Price;
Cn.SaveChanges();
return Json(new
{
ID_Invoice_Details = ID_Invoice_Details,
Sale_Price = Sale_Price
}
, JsonRequestBehavior.AllowGet);
}
I just want to update the new data to #Model, to take full advantage
of its presence and also to use it in the calculations, since in the
control there is a column showing the row sum after multiplying by the
quantity, and I don't want to use the calculations in jquery

The best way to update a part of the view with ajax is to use partialview.
1.add class JsonData
public class JsonData
{
public string HtmlMsg { get; set; }
public string HtmlBody { get; set; }
public bool Success { get; set; }
}
2.add ViewHelper class
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
public static class ViewHelper
{
public static string RenderPartialToString(this ControllerBase controller, string partialViewName, object model)
{
IView view = ViewEngines.Engines.FindPartialView(controller.ControllerContext, partialViewName).View;
return RenderViewToString(controller, view, model);
}
public static string RenderViewToString(this ControllerBase controller, IView view, object model)
{
using (var writer = new StringWriter())
{
controller.ViewData.Model = model;
var viewContext = new ViewContext(controller.ControllerContext, view, controller.ViewData, controller.TempData, writer);
view.Render(viewContext, writer);
return writer.GetStringBuilder().ToString();
}
}
}
3.change SaveInvoice to :
public JsonResult SaveInvoice(int ID_Invoice_Details, int Sale_Price)
{
Table.Invoice_Details invoice_Details = Cn.Invoice_Details.Where(L => L.ID_Invoice_Details == ID_Invoice_Details).FirstOrDefault();
invoice_Details.Sale_Price = Sale_Price;
Cn.SaveChanges();
var model = //fill list
return Json(new JsonData()
{
HtmlMsg = "",
HtmlBody = this.RenderPartialToString("_MyPartial", model),
Success = true,
});
}
4.in your view change to
#model List<Table.Invoice_Details>
<div id="myPartial">
#Html.Partial("_MyPartial", Model)
</div>
5.add partialview _MyPartial
#model List<Table.Invoice_Details>
#foreach (Table.Invoice_Details invoice_Details in Model)
{
#Html.TextBoxFor(modelitem => invoice_Details.ID_Invoice_Details, new { id = "ID_Invoice_Details-" + invoice_Details.ID_Invoice_Details })
#Html.TextBoxFor(modelitem => invoice_Details.Sale_Price, new { id = "Sale_Price-" + invoice_Details.ID_Invoice_Details })
<button id="btnSave-#invoice_Details.ID_Invoice_Details">save</button>
}
6.change script to
$('button[id*=btnSave-]').click(function() {
var FullID = $(this).attr('id');
var ID_Number = FullID.substring(FullID.indexOf('-') + 1);
var Sale_Price = $('Sale_Price-' + ID_Number).val();
$.get({
url: '/Invoice/SaveInvoice',
contents: 'application/json; charset=utf-8',
type: 'post',
dataType: 'json',
data: {
ID_Invoice_Details: ID_Number,
Sale_Price: Sale_Price
},
success: function(result) {
$("#myPartial").html(result.HtmlBody);
}
});
})

Related

Ajax populating dropdown for c# results in undefined

I only get the text message Selektoni Tipin, but I dont get any values from the tables I only get undefined
AJAX script
script type="text/javascript">
$(document).ready(function () {
$.ajax({
type: "GET",
url: "/Dokument/Dokument",
data: "{}",
success: function (data) {
var s = '<option value="-1">Selektoni Tipin</option>';
for (var i = 0; i < data.length; i++) {
s += '<option value="' + data[i].Id_Tipi + '">' + data[i].Emri_llojit + '</option>';
}
$("#tipiDropdown").html(s);
}
});
});
</script>
Controller method
public ActionResult Dokument()
{
return View();
}
// GET: NgarkoDokument
public ActionResult GetTipi(int tipiId)
{
Test_kristiEntities db = new Test_kristiEntities();
return Json(db.Tipi.Select(x => new
{
Id_Tipi = x.Id_Tipi,
Emri_llojit = x.Emri_llojit
}).ToList(), JsonRequestBehavior.AllowGet);
// return View();
}
Model i built with some tables
public class NgarkoDokument
{
public Dokumenti Dokumenti { get; set; }
public Fusha_Indeksimit FushaIndeksimit { get; set; }
public Vendndodhja_Fizike Vendndodhja_fizike { get; set; }
public Tipi Tipi { get; set; }
}
And here is the html
<select title="Lloji i dokumentit" name="lloji" class="form-control col-md-3 box" id="tipiDropdown"> </select>

Filter products based on multiple check boxes

I am working on e-commerce site. I want to filter product based on multiple check boxes. I use ajax. It sends check boxes' IDs to the controller. But selected counts zero like in the picture. What is wrong with this code?
Ajax:
<script type="text/javascript">
$(function () {
$('.filterprod').click(function () {
var ProdID = "";
$('.checks').each(function () {
if ($(this).is(':checked')) {
ProdID += $(this).val() + ",";
}
});
var data = {};
data.Id = ProdID.slice(0, ProdID.length - 1);
$.ajax({
url: '/Shop/GetProd',
method: 'POST',
dataType: "json",
contentType: 'application/json',
data: JSON.stringify(data),
success: function (response) {
$("#Prodlist").remove();
},
error: function (err, response) {
console.log(err, response);
alert(err, response.responseText);
}
})
});
});
</script>
Controller:
[HttpPost]
public JsonResult GetProd(string Id)
{
var ids = new List<int>();
IQueryable<Product> prods = null;
if (!string.IsNullOrEmpty(Id))
{
for (int i = 0; i < Id.Split(',').Length; i++)
{
ids.Add(Convert.ToInt32(Id.Split(',')[i]));
}
prods =_context.Products.Where(t => ids.Contains(t.id));
}
else
{
prods = _context.Products.Take(5);
}
var selected = (from v in prods
select new
{
v.ProdName,
v.Price,
v.Description
}).ToList();
return Json(selected, JsonRequestBehavior.AllowGet);
}
Try to do it in a console like this: https://dotnetfiddle.net/AMwxiP
using System;
using System.Collections.Generic;
using System.Linq;
public class Product
{
public int Id { get; set; }
public string ProdName { get; set; }
public decimal? Price { get; set; }
public string Description { get; set; }
}
public class Program
{
public static void Main(string[] args)
{
IQueryable<Product> products = (new List<Product> {
new Product
{
Id = 1,
},
new Product
{
Id = 2,
}
}).AsQueryable<Product>();
var Id = "1,2";
var ids = new List<int>();
IQueryable<Product> prods = null;
if (!string.IsNullOrEmpty(Id))
{
for (int i = 0; i < Id.Split(',').Length; i++)
{
ids.Add(Convert.ToInt32(Id.Split(',')[i]));
}
prods = products.Where(t => ids.Contains(t.Id));
}
else
{
prods = products.Take(5);
}
var selected = (from v in prods
select new
{
v.ProdName,
v.Price,
v.Description
}).ToList();
Console.WriteLine(selected.Count);
}
}

AJAX Cascading Dropdowns ASP.NET MVC

I am working on a request form for work. The request deals with series of products. There are many series, so I am trying to filter them down by the product line that they are produced on. I am attempting this using cascading dropdown lists from Ajax. I know the script is working to a degree, because the default selected option changes to "Make Selection". However, the rest of the dropdown does not populate.
Here are the two dropdowns.
#Html.DropDownListFor(model => model.SelectedProductLine, new SelectList(Model.ProductLines, "Value", "Text"), "Select a Product Line", new { #class = "form-control", #style = "width: 400px;", #id = "ProductLineID"})
#Html.DropDownListFor(model => model.SelectedSeries, new SelectList(string.Empty, "Value", "Text"), "Select a Series", new { #class = "form-control", #id = "SeriesID"})
The Ajax Script.
$(document).ready(function () {
//Dropdownlist Selectedchange event
$('#ProductLineID').change(function () {
$.ajax({
url: '/SMRMaster/RequestForm/GetSeries',
type: 'GET',
datatype: 'JSON',
data: { id: $('#ProductLineID').val() },
success: function (result) {
$('#SeriesID').html('');
$('#SeriesID').append($('<option>Make Selection</option>'));
$.each(result, function (index, item) {
$('#SeriesID').append($('<option></option>').val(item.Value).html(item.Text));
});
}
});
});
});
The Controller.
public JsonResult GetSeries(string id)
{
int Id = Convert.ToInt32(id);
db.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNOCMMITTED;");
var productLineName = "";
switch (Id)
{
case 0:
productLineName = "Electric";
break;
case 1:
productLineName = "Europe Gas";
break;
case 2:
productLineName = "Gas";
break;
case 3:
productLineName = "Miscellaneous";
break;
case 4:
productLineName = "Water";
break;
default:
productLineName = "Electric";
break;
}
IEnumerable<SelectListItem> series = (from s in db.Series
where s.ProductLineName == productLineName
select new SelectListItem { Value = s.ProductLineName, Text = s.ProductLineName }).ToList();
return Json(series, JsonRequestBehavior.AllowGet);
}
public List<ProductLine> GetProductLines()
{
db.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");
var productLineList = (from p in db.ProductLines
select p).ToList();
return productLineList;
}
public ActionResult RequestForm()
{
var count = 0;
var productLineList = new List<SelectListItem>();
foreach (var item in GetProductLines())
{
productLineList.Add(new SelectListItem { Text = item.ProductlineName, Value = count.ToString() });
}
db.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");
var requestViewModel = new RequestViewModel { SMRMaster = new SMRMaster(), Engineers = GetEngineers(), ProductLines = productLineList };
return View(requestViewModel);
}
And the view model.
public class RequestViewModel
{
public List<SelectListItem> ProductLines { get; set; }
public string SelectedProductLine { get; set; }
public SMRMaster SMRMaster { get; set; }
public List<string> Engineers { get; set; }
[Required(ErrorMessage = "Engineer is required.")]
public string SelectedEngineer { get; set; }
public List<Series> Series { get; set; }
public string SelectedSeries { get; set; }
}
I do not know where the error is coming from. Any help is appreciated.
Try this
$.each(result, function (i, item) {
var optionData = '<option value="' + item.Value + '">' + obj.Text + '</option>';
$(optionData).appendTo('#SeriesID')
});
Or debug and see what's your response from server.
A colleague helped me solve this problem. Firstly, the Ajax script was using the wrong URL. Secondly, my controller functions were unnecessarily complicated.
Here is the updated AJAX script:
$(document).ready(function () {
//Dropdownlist Selectedchange event
$('#ProductLine').change(function () {
$.ajax({
url: '/SMRMaster/GetSeries',
type: 'GET',
datatype: 'JSON',
data: { productLine: $('#ProductLine').val() },
success: function (result) {
$('#SeriesID').html('');
$('#SeriesID').append($('<option>Make Selection</option>'));
$.each(result, function (i, item) {
var optionData = '<option value="' + item.Value + '">' + item.Text + '</option>';
$(optionData).appendTo('#SeriesID')
});
}
});
});
});
And here is the updated Controller:
public JsonResult GetSeries(string productLine)
{
db.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");
List<SelectListItem> series = (from s in db.Series
where s.ProductLineName == productLine
select new SelectListItem { Value = s.SeriesName, Text = s.SeriesName }).Distinct().ToList();
return Json(series, JsonRequestBehavior.AllowGet);
}
public List<ProductLine> GetProductLines()
{
db.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");
var productLineList = (from p in db.ProductLines
select p).ToList();
return productLineList;
}
public ActionResult RequestForm()
{
var productLineList = new List<SelectListItem>();
foreach (var item in GetProductLines())
{
productLineList.Add(new SelectListItem { Text = item.ProductlineName, Value = item.ProductlineName });
}
db.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");
var requestViewModel = new RequestViewModel { SMRMaster = new SMRMaster(), Engineers = GetEngineers(), ProductLines = productLineList };
return View(requestViewModel);
}

How to databind a dropdownlist using knockout and MVC and Entity Framework

I have two cascading dropdownlists which I would like to bind based on my knockout.js. Essentially what I want to achieve is two dropdownlist that populate from a database for each branch of the company and one which will populate the various departments based on the branch that was selected in the other dropdownlist. I am having problems converting to a list and then binding to dropdownlist.
function CompanyViewModel() {
var self = this;
self.DepartmentName = ko.observable(" ")
self.Department =ko.observableArray([]);
self.DepartmentName = ko.Observable([]);
self.Branch =ko.observableArray([]);
self.BranchName = ko.Observable([])
}
CompanyViewModel = new CompanyViewModel();
ko.applyBindings(CompanyViewModel);
function populateCompanyBranches() {
$.ajax({
type: "GET",
$.when(getSecureData("/api/Branches/" ))
.done(function (Branches) {
Branch.unshift({ "BranchID": 0, "department name": "Please select a Branch." });
CompanyViewModel.Branch(Branch);
})
.fail(function (message) {
$.msgbox(message);
});
};
function populateBranchDepartments() {
$("#Branches").change(function () {
var BranchID = $("#Branches").val();
$.ajax({
type: "GET",
$.when(getSecureData("/api/Departments/GetDepartment" + BranchID))
.done(function (Department) {
CompanyDepartment.unshift({ "CompanyID": 0, "departmentName": "Please select a department" });
CompanyViewModel.Department(Department);
})
.fail(function (message) {
$.msgbox(message);
});
};
}
View
Branch Name: <select data-bind="options: CompanyViewModel. CompanyViewModel, optionsCaption: 'Select a Branch',
optionsValue: function (item) { return item.BranchId; },
optionsText: function (item) { return item.BranchName; }, value: Branch,
valueUpdate: 'change'" id="Branches" name="Branch"></select>
<br />
Deaprtment Name: <select data-bind="options: CompanyViewModel.Department, optionsCaption: 'Choose Department...',
optionsValue: function (item) { return item.DepartmentId; },
optionsText: function (item) { return item.DepartmentName; }, value: DepartmentName,
valueUpdate: 'change'" id="Department" name="Department"></select>
<br />
</div>
public class CompanyDTO
{
public int BranchId { get; set; }
public string BranchName { get; set;}
public int DepartmentId { get; set; }
public string DepartmentName { get; set;}
}
public static class CompanyBranchList
{
public static CompanyDTO DepartmentToBranchDTO(listing e)
{
return new CompanyDTO
{
BranchId = e.BranchId,
BranchName = e.BranchName
DepartmentId = e.DepartmentId
DepartmentName = e.DepartmentName
};
}
public static List<CompanyDTO> ListBranchToDepartmentDTO(List<listing> e)
{
List<CompanyDTO> lstCompanyDTO= e.Select(
lstng => new CompanyDTO()
{
BranchId = lsting.BranchId,
BranchName = lsting.BranchName
DepartmentId = lsting.DepartmentId
DepartmentName = lsting.DepartmentName
}).ToList();
return ListBranchToDepartmentDTO;
}
Repository
public class CompanyRepository : IComapnyRepository
{
public List<CompanyDTO> GetBranches()
{
using (TestDBEntities dbcontext1 = new TestDBEntities())
{
var lstCountries = from r in dbcontext1.Branches select r;
List<CompanyDTO> lst = new List<CompanyDTO>();
lst = CompanyBranchList.DepartmentToBranchDTO(lstCompanyDTO.ToList());
return lst;
}
}
Controller
public List<CompanyDTO> GetDepartments(int deparmentId)
{
using (TestDBEntities dbcontext = new TestDBEntities())
{
var lstDep = dbcontext.States.Where(b => b.DepartmentID == departmentId).ToList();
List<CompanyDTO> list = new List<CompanyDTO>();
list = CompanyBranchList.ListBranchToDepartmentDTO(lstDep.ToList());
return list;
}
}
You achieve cascading dropdown lists by doing this:
// the view model bound to the view
var vm = {
branches: ko.observableArray([]),
selectedBranch: ko.observable(),
departments: ko.observableArray([]),
selectedDepartment: ko.observable()
}
// subscription to listen to changes to the selected branch
vm.selectedBranch.subscribe(function(current, last){
if(!current) return; // do nothing if nothing is selected
if(current == last) return; // do nothing if nothing changed
$.ajax({
type: 'GET',
url: '/api/Departments/GetDepartment/' + current.BranchId,
contentType: 'application/json'
})
.then(function(result){
vm.departments(result)
});
}
// load the list of branches
$.ajax({
type: 'GET',
url: '/api/Branches',
contentType: 'application/json'
})
.then(function(result){
vm.branches(result); // populate branch observable array
ko.applyBindings(vm);// bind view model to view
});

Posting an array from view to controller using jQuery

function myItemsViewModel(ItemID, GroupID, ItemName, Quantity) {
this.ItemID = ItemID;
this.GroupID = GroupID;
this.ItemName = ItemName;
this.Quantity = Quantity;
}
And i have below code for posting to the controller
var CreateRecord = function () {
var Name = $.trim($("#divCreate").find("#txtName").val());
var Department = $.trim($("#divCreate").find("#txtDepartment").val());
var ItemsList = [];
$('#myDynamicTable').find('tr').each(function () {
var row = $(this);
var itemName = $.trim(row.find(".itemName input").val());
var itemQty = $.trim(row.find(".itemQty input").val());
var myItems = new myItemsViewModel("", "", itemName, itemQty);
ItemsList.push(myItems);
});
var obj = new myRecordEntryViewModel("", Name, Department, ItemsList);
var viewmodel = JSON.stringify(obj);
$.ajax({
type: 'POST',
cache: false,
dataType: 'html',
data: viewmodel,
headers: GetRequestVerificationToken(),
contentType: 'application/json; charset=utf-8',
url: '/' + virtualDirectory + '/RecordEntry/Save',
success: function (data) {
$("#divMaster").html(data);
return false;
},
error: function (msg) {
alert("Error Submitting Record Request!");
}
});
}
At the line var viewmodel = JSON.stringify(obj);, viewmodel has all the values that i want in my ItemsList array variable.
Problem is my ItemsList array is coming as null in the controller. Name and Department are coming through with the correct passed values.
Below is my controller code.
Class
public class myRecordEntryViewModel
{
public long ID { get; set; }
public string Name { get; set; }
public string Department { get; set; }
public string[] ItemsList { get; set; }
}
Save action
[ActionName("Save")]
[NoCache]
public ActionResult Save(myRecordEntryViewModel viewModel)
{
//here viewModel.ItemsList is null, what could i be missing
if (this.SaveEntry(viewModel.Name,viewModel.Department,viewModel.ItemsList))
{
}
return this.View();
}
I'm wondering why viewModel.ItemsList is coming as null in controller yet it has values during the post from jQuery.
You should create a class for the Item in Item List (In C#)
public class Item {
public string ItemName { get; set; }
public int Quantity { get; set; }
}
And then change the viewmodel class
public class myRecordEntryViewModel
{
public long ID { get; set; }
public string Name { get; set; }
public string Department { get; set; }
//public string[] ItemsList { get; set; }
public List<Item> ItemsList {get ; set;}
}
The controller can not map the Item List from your request into model because one is a list of string and other is a list of object.
There are several problems in your codes...
1) ItemList in your class and your javascript code are not same - The frist one is an array of strings, and the second is an array of objects
2) In your action method, you should change parameter type like the following:
public ActionResult Save(string viewModel)
3) In the body of your action method, you should deserialize the json string (viewModel) and make the model object from it. The following is an example...
https://stackoverflow.com/a/17741421/1814343
Try the below code and see if your model gets the values.
Let me know if you face any problems, because I've already implemented this in one of my projects
var CreateRecord = function () {
var Name = $.trim($("#divCreate").find("#txtName").val());
var Department = $.trim($("#divCreate").find("#txtDepartment").val());
var model="";
var ItemsList = [];
$('#myDynamicTable').find('tr').each(function () {
var row = $(this);
var itemName = $.trim(row.find(".itemName input").val());
var itemQty = $.trim(row.find(".itemQty input").val());
var myItems = new myItemsViewModel("", "", itemName, itemQty);
ItemsList.push(myItems);
});
model = ['Name' : Name , 'Department' : Department , 'ItemsList' :ItemsList];
$.ajax({
type: 'POST',
cache: false,
dataType: 'html',
data: JSON.stringify(model),
headers: GetRequestVerificationToken(),
contentType: 'application/json; charset=utf-8',
url: '/' + virtualDirectory + '/RecordEntry/Save',
success: function (data) {
$("#divMaster").html(data);
HideLoader();
return false;
},
error: function (msg) {
alert("Error Submitting Record Request!");
HideLoader();
}
});
}

Categories

Resources