I have a method in the controller that return a ViewBag with Json.
public JsonResult FilterCheck(int id, int[] mycheck, string idprot)
{
ViewBag.Utenti = this.GetDbContext().utente.Include(s => s.cod_servizio_utente).Where(x => x.cod_servizio_utente.Select(l => l.id).Contains(5)).ToList();
return Json(ViewBag.Utenti, JsonRequestBehavior.AllowGet);
}
In the view I have this script function ajax, if this function have "success" i would refresh a div that include a foreach on the viebag.Utenti:
$.ajax({
type: "POST",
url: "#Url.Action("FilterCheck","Operatore")",
datatype: "json",
traditional: true,
data: { 'mycheck': mycheck, 'idprot': idprot, 'id': '#Model.id' },
success: function(data) {
var html = $(data).filter('#external-events').html();
$('#external-events').html(data);
}
});
<div id='external-events'>
#foreach (HAnnoZero.Repositories.utente item in ViewBag.Utenti)
{
<div class='col-lg-3'><div class='external-event'>#item.id- #item.cognome #item.nome</div></div>
} </div>
But dont work. How can do for refresh the foreach inside div id "external events"?Who could help me?
Firstly you do not need to assign the collection to ViewBag
public ActionResult FilterCheck(int id, int[] mycheck, string idprot)
{
var data = this.GetDbContext().utente.Include(......
// Build anonymous object collection to avoid circular reference errors
var response = data.Select(d => new
{
id = d.id,
cognome = d.cognome
// other properties as required
});
return Json(response);
}
Secondly you are returning JSON, not html, so in your success function you need to iterate through the properties and build your html (not sure what your properties are, so adjust as necessary)
success: function(data) {
$('#external-events').empty(); // clear existing items
$.each(data, function(index, item) {
var div = $('<div><div>'); // Create new element
div.text(item.id + ' ' + item.cognome); // Set inner text
$('#external-events').append(div); // add the new element
});
}
An alternative is to have the action method return a partial view containing the html and then use
success: function(data) {
$('#external-events').html(data);
}
Related
I have run into this problem. I have a view which gets rendered like this:
#inherits Umbraco.Web.Mvc.UmbracoViewPage
#using MyProject.Web.Models;
#using ContentModels = Umbraco.Web.PublishedContentModels;
#{
Layout = "MasterPage.cshtml";
}
#Html.Partial("_HeroModule")
#foreach (var item in Model.GetPropertyValue<IEnumerable<IPublishedContent>>("generalContentCollection"))
{
var partialViewName = "_" + item.DocumentTypeAlias;
if (partialViewName == "_curtainsModule")
{
Html.RenderPartial("CurtainsModule", new CurtainsModuleModel(Model, item));
}
else
{
#Html.Partial(partialViewName, item);
}
The 'item' here is a nested content general collection. Inside of it there's another collection I need to reach called 'fabricsCollection' which is also Nested Content.
The problem with this is that when I go to a SurfaceController and do this the 'fabricsCollection' returns null probably because it's Nested Content:
[HttpPost]
public JsonResult GetFabrics(int data)
{
//gets the id of the actual page doctype
var page = Umbraco.TypedContent(data);
//fabricsCollection underneath returns null
var fabricsCollection = page.GetPropertyValue<IEnumerable<IPublishedContent>>("fabricsCollection");
return Json(fabricsCollection);
}
}
and the ajax call which works fine:
$(".clearAll-desktop").click(function () {
event.preventDefault;
var pageId = $(".curtains-module").attr('id');
var fabrics = "#Model.FabricsCollection.ToString()";
debugger;
console.log(pageId);
$.ajax({
url: '/umbraco/Surface/CurtainsModuleSurface/GetFabrics',
type: 'POST',
data: { data: pageId, collectionName: fabrics },
dataType: 'string',
success: function (data1) {
console.log('success');
}
});
return false;
})
I'm stuck here for a few days and I don't know what I'm doing wrong. Anyone with a clearer mind can pinpoint what I'm doing wrong?
I'm learning about ajax to make my life a little easier moving forward. I was able to follow an example and get a constant array to POST to my controller normally.
Now that I am trying to get data from an html form, I get a null array in my controller.
using .serialize() I get [0] = "item=teststring1&item=teststring2"
using .serializeArray() I get an array of length 2 (the correct size), with both values null.
I've read about the issues with serializeArray() and how it requires certain tags.
How can I resolve the issue of a null array posting to my controller?
JS
// #EditDate is form id
var data = $('#EditDate').serializeArray();
$.ajax({
url: '#Url.Action("Index", "TrainingDates")',
type: "POST",
dataType: "json",
data: {'dates' : data},
success: function (result) {
alert("success" + result);
},
error: function (result) {
alert("failure" + result);
}
});
$(element).val('Edit');
HTML
#model List<string>
#{
ViewBag.Title = "Dates";
}
#using (Html.BeginForm("Index", "TrainingDates", FormMethod.Post, new { #id = "EditDate", #class = "collapse" }))
{
foreach (var item in Model)
{
<tr>
<td>
<input type="button" class="btn btn-primary btn-sm" style="width:inherit" onclick="editable('#item', this)" value="Edit">
</td>
<td>
#Html.TextBoxFor(m => item, new { #id = item, name = item, #class = "form-control", #readonly = "readonly" })
</td>
</tr>
}
}
Controller
[HttpPost]
public ActionResult Index(List<string> dates)
{
if(dates != null)
{
var json = new { success = true };
return Json(json);
}
return Json(false);
}
Your action method parameter is a list of strings. So basically for model binding to properly work, you should be sending an array like this from your ajax call
["12-12-2011","10-10-2011"]
Your current code uses jquery serializeArray method which will create an array of items,each with name and value properties. So basically your code is sending something like this in the ajax request.
dates[0][name]:item
dates[0][value]:12-12-2011
dates[1][name]:item
dates[1][value]:10-10-2011
The default model binder cannot map this to a list of strings.
All you need to do is, sending a an array of string(or dates) to server. You may simply use the jQuery map method to create an array from the input field values.
This should work.
var d = $.map($("[name='item']"), function(v, k) {
return v.value;
});
$.ajax({
url: '#Url.Action("Index", "TrainingDates")',
type: "POST",
data: JSON.stringify(d),
contentType: "application/json",
success: function (result) {
console.log("success" , result);
},
error: function (result) {
alert("failure" + result);
}
});
I would also strongly advise to use the correct datatype. If you are dealing with dates, why not use DateTime class instead of string ? DateTime class was created to handle usecases like these :)
[HttpPost]
public ActionResult Index(List<DateTime> dates)
{
// to do : return something
}
Your posted data does not match the variable name and data type in your controller.
make these minor adjustments:
Javascript - remove dataType: "json" and pass data as form-url-encoded directly data: $('#EditDate').serializeArray(). No need to convert to JSON format.
$.ajax({
url: '#Url.Action("Index", "TrainingDates")',
type: "POST",
data: $('#EditDate').serializeArray(),
success: function (result) {
alert("success" + result);
},
error: function (result) {
alert("failure" + result);
}
});
Controller - change variable name "dates" to "item" to matched your JavaScript ajax call.
[HttpPost]
public ActionResult Index(List<string> item)
{
if(item != null)
{
var json = new { success = true };
return Json(json);
}
return Json(false);
}
I am trying to update my database when a checkbox is checked or unchecked. I want it to update when the checkbox is clicked. This is what I have so far, but my controller is never being hit. what can I do to fix it? Ideally I want to pass in the new value of customer.IsDone and customer.Id to my controller but I don't know how to do this.
Checkbox in my view
<td>#Html.CheckBoxFor(m => customer.IsDone, new { onclick = "UpdateCustomer(IsDone)" })</td>
The function in my view
function UpdateCustomer(isDone) {
$.ajax({
type: 'POST',
url: #Url.Action("UpdateCustomer", "Home"),
data: { check: isDone },
success: success,
dataType: 'json'
});
}
this is my controller method
[HttpPost]
public ActionResult UpdateCustomer(bool check)
{
//code will be here to update the db
var customers = new CustomerGetAll();
var list = customers.Execute();
return View("Customers", list);
}
I see few issues in your code.
First of all, you are passing IsDone variable when calling the UpdateCustomer method. But where is isDone defined ?
Second, this line,
url: #Url.Action("UpdateCustomer", "Home"),
The Url.Action helper will output a string and your code will be like this when rendered in the browser
url: /Home/UpdateCustomer,
Now the browser's javascript framework usually thinks the second part after : as a js variable and if you have not defined it,it will throw a syntax error about using a not defined variable! But since we have \, you will get another "Invalid regular expression flags" syntax error!
You should wrap the result in quotes to avoid this problem.
The below code should work
#Html.CheckBoxFor(m =>customer.IsDone, new { onclick = "UpdateCustomer(this)" })
and the script
function UpdateCustomer(elem) {
var isDone = $(elem).is(':checked');
$.ajax({
type: 'POST',
url: "#Url.Action("UpdateCustomer", "Home")",
data: { check: isDone },
success: function(res) {
console.log(res);
},
dataType: 'json'
});
}
Also, If you want to update a specific customer record, you probably want to pass the customer Id as well when making the ajax call. You may keep that in html 5 data attribute on the checkbox markup and read that and use that as needed.
#Html.CheckBoxFor(m =>customer.IsDone, new { onclick = "UpdateCustomer(this)",
data_customerid = customer.Id })
This will render the checkbox with html5 data attribute for "data-customerid". All you have to now do is, read this value and send it via ajax
function UpdateCustomer(elem) {
var isDone = $(elem).is(':checked');
var cid = $(elem).data('customerid');
$.ajax({
type: 'POST',
url: '#Url.Action("UpdateCustomer", "Home")',
data: { check: isDone,customerId:cid },
success: function(res) {
console.log(res);
}
});
}
Make sure your server action method has a new parameter to accept the customer id we are sending from client side code
[HttpPost]
public ActionResult UpdateCustomer(bool check,int customerId)
{
// to do : Save and return something
}
I have something similar, and I think you can solve your problem...
My HTML
<td>
#{
bool avalia1 = false;
#Html.CheckBox("avalia1", avalia1, new { autocomplete = "off", data_on_text = "Sim", data_off_text = "Não" })
}
</td>
JS
var avalia1 = $("#avalia1").is(":checked");
var url = "/Telefonia/GravarAvaliacao";
$.ajax({
url: url,
datatype: "json",
data: { 'avalia1': avalia1,'idgravacao': idgravacao },
type: "POST",
success: function (data) {
}
});
}
ON CONTROLLER
public JsonResult GravarAvaliacao(bool avalia1, string idgravacao)
{
string _userId = User.Identity.GetUserId();
var avaliaData = new OperadorAvaliacaoData();
avaliaData.GravaAvaliacao(avalia1, idgravacao);
return Json(true, JsonRequestBehavior.AllowGet);
}
The only diference is your model checkbox, and the action trigger.
I have a javascript function which redirects to given url after i had a json result.I want this json result values in my html inputs on success.Please help me i am new to MVC
function GetSupplierDetail(SupId) {
var url = "/PurchaseOrders/GetSupplierDetails/";
$.ajax({
url: url,
data: { SuppId: SupId },
cache: false,
type: "POST",
success: function (data) {
alert(data.modelList);
},
error: function (reponse) {
}
});
}
This is my C# Action.
[HttpPost]
public ActionResult GetSupplierDetails(int SuppId)
{ var books = entity.P_Supplier.Where(x => x.SupplierId == SuppId).ToList();
var modelList = books.Select(x => new SupplierModel()
{
Firm = x.Firm,
Sname = x.Sname,
SupplierName=x.SupplierName,
Address1=x.Address1,
Cell=x.Cell,
Email=x.Email,
Fax=x.Fax
});
return Json(modelList,JsonRequestBehavior.AllowGet);
alert(data.modelList); returns object which contains a collection.You need to loop over that collection.If you want to bind collection with GridView then there are different open source grids are available i.e Backgrid,flexigrid.
If there is just single result then you can check it by alert(data.modelList.Firm);
or assign it to any input fields.
$('#txtFirm').val(data.modelList.Firm);
I have done searching part for a list in a partialView.
I have multiple partialView in this application as you can see from image.
So my question
Whenever I create search filter for a grid then I have to create another view and partialview to show the success results. How can I show filtered search list within this same partial view and don't need to make a success partialview for that list again?
I've done-
Rendering list from database-
public ActionResult _ProductSearchList() {
List<ProductModel> product;
product = (from u in db.ProductTables
select new ProductModel {
productname = u.ProductName,
productprice = Convert.ToInt32(u.ProductPrice),
productID = u.ProductID,
dateaddproduct = Convert.ToDateTime(u.ProductAddDate)
}).ToList();
return PartialView(product);
}
Searching for records-
<div>
<legend>Prducts</legend>
<input type="text" id="search-products" />
#Html.Action("_ProductSearchList", "LedgerIndex")
</div>
Script for retrieving records-
<script type="text/javascript">
$(function () {
$('#search-products').keyup(function () {
var serachstring = $(this).val();
$.ajax({
url: '/Product/JsonSearchProduct/?stringSearched=' + serachstring,
type: 'get',
datatype: 'json',
success: function (data) {
JSON.stringify(data);
}
});
});
});
</script>
Json result in controller-
public JsonResult JsonSearchProduct(string stringSearched) {
List<ProductModel> product;
product = (from u in db.ProductTables
where u.ProductName.Contains(stringSearched)
select new ProductModel {
productID = u.ProductID,
productname = u.ProductName,
productprice = Convert.ToInt32(u.ProductPrice),
dateaddproduct = Convert.ToDateTime(u.ProductAddDate)
}).ToList();
return Json(product, JsonRequestBehavior.AllowGet);
}
So when I searched String M it retrieves records and showing only records containing M in their name.
Now this filtered result as JSON is what I want to filter in this same partialView without creating extra partialView.
You can let the search method return the same partial view:
public ActionResult JsonSearchProduct(string stringSearched)
{
List<ProductModel> products;
// Search for products...
return PartialView("_ProductSearchList", products);
}
If you wrap the partial view inside a div, you can replace its html with jQuery.
$(function () {
$('#search-products').keyup(function () {
var serachstring = $(this).val();
$.ajax({
url: '/Product/JsonSearchProduct/?stringSearched=' + serachstring,
type: 'get',
datatype: 'json',
success: function (data) {
// data will contain the html of the partial view.
$('div#product-grid').html(data);
}
});
});
});
Note: your Ajax get request can be like this, if you have the JavaScript inside the view:
$.get('#Url.Action("JsonSearchProduct", "Product")',
{
stringSearched: searchstring
},
function (data) {
$('div#product-grid').html(data);
}
});