Passing model to controller from view in JTable MVC using jQuery - model-view-controller

I am trying to pass entire model from View to Controller using jTable.
Here is the code for view
I am having a filter criteria based on which the table will be loaded.
Say DropdownList of ModelId and ModelName, on selection,followed by click of a button, the function below executes.
<script type="text/javascript">
function GetModels() {
var model = {
ModelId:$("#ModelId").val(),
ModelName:$("#ModelName").val(),
ModelAge:$("#ModelAge").val()
};
$(document).ready(function () {
$('#PersonTableContainer').jtable({
title: 'Table of Models',
actions: {
listAction: '/Controller/ActionName'
},
fields: {
ModelName: {
title: 'ModelName',
width: '30%',
list: false
},
ModelId: {
title: 'ModelId',
width: '30%',
key: true,
create: false,
edit: false
}
ModelAge: {
title: 'ModelAge',
width: '30%',
create: false,
edit: false
}
}
});
$('#PersonTableContainer').jtable('load', { ModelName: model });
});
}
Here is the code for the controller.
public JsonResult GetAppropriateModel( ModelName ModelName)
{
try
{
FillAppropriateModel(ModelName);
}
catch(Exception e)
{
return Json(new { Result = "Error", Message=e.Message });
}
}
I am kind of new in AJAX and I am facing an issue where in the returned model is null, However if I cause normal submit-button postaction, then the model is retained.. I googled and got examples where they pass discrete elements and not entire model.
--Edit --
This is the link I referred.
http://www.jtable.org/Demo/Filtering
Kindly help.
Thanks.

For some reason the MVC handler doesn't decode model objects properly when jTable sends them in. I've found that setting the contentType in your jTable ajaxSettings fixes this. In your jTable definitions, add this:
ajaxSettings: {
contentType: "application/json; charset=utf-8"
}
Then you have to stringify your parameter when you send it in:
$('#PersonTableContainer').jtable('load', JSON.stringify({ ModelName: model }));

Related

Asp.net core controller function with return partial view with select2 not working and remote function validation is not firing in modal popup

Select2 is not working and remote validation is not firing, this is only happens when I convert the code to modal popup but if not everything is working properly. What Am I missing in my code? Any advise or help much appreciated.. Thank you
Here is my code the modal:
$('#tbProducts tbody').on('click', 'button', function () {
var data = productsTable.row($(this).parents('tr')).data();
//alert(data.id);
$.ajax({
url: '#Url.Action("Edit", "Products")',
type: 'GET',
data: { id: data.id },
success: function (result) {
$('#EditUnitModal .modal-content').html(result);
$('#EditUnitModal').modal()
}
});
});
Here is the controller edit code:
public async Task<IActionResult> Edit(int? id)
{
//code here
return PartialView("__Edit", product);
}
And here is my partial view __Edit code:
#model intPOS.Models.Master.ViewModel.ProductViewModel
//code here
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script type="text/javascript">
$(function () {
$('#Unit').select2({
theme: 'bootstrap4',
dropdownParent: $('#EditUnitModal')
})
$('#Category').select2({
theme: 'bootstrap4',
dropdownParent: $('#EditUnitModal')
})
})
</script>
}
And View model code:
[Display(Name = "Product Code"), Required]
[Remote("CheckProduct", "Products", AdditionalFields = "Id", ErrorMessage = "Product already exists.")]
public string ProductCode
{
get
{
return _productcode;
}
set
{
_productcode = value.Trim();
}
}
Sample screen for not firing validation and select2 is not working:
sections aren't allowed in partial views. You can still use modals and partial views via Ajax for edit forms but there is a small modification you need to do in order for this to work:
Include all the necessary scripts in your page (this is mandatory as sections aren't allowed in partial views).
In your javascript code add these lines in order to parse the new form via jquery validation unobtrusive and your select elements via Select2.
$('#tbProducts tbody').on('click', 'button', function () {
var data = productsTable.row($(this).parents('tr')).data();
//alert(data.id);
$.ajax({
url: '#Url.Action("Edit", "Products")',
type: 'GET',
data: { id: data.id },
success: function (result) {
$('#EditUnitModal .modal-content').html(result);
//Here we parse the new form via jquery validation unobtrusive.
$.validator.unobtrusive.parse($('#EditUnitModal .modal-content form')[0]);
//Here we initialize select2 for the selected elements.
$(".yourSelect2ElementClass").select2({//options...});
//Now we launch the modal.
$('#EditUnitModal').modal()
}
});
});
Don't forget to remove the section from your partial view and include your scripts in the containing view.

Send data from extjs popup window to spring controller

I have an extjs popup window with form panel inside and I wanted to know how can I send datas in the form panel to my spring controller ?
var formPanel = {
xtype : 'form',
height : 125,
autoScroll : true,
id : 'formpanel',
defaultType : 'field',
frame : true,
items : [
{
fieldLabel : 'Name'
},
{
fieldLabel : 'Age'
}
]
};
function openIFrame() {
Ext.create('Ext.window.Window', {
title : 'Import your devices',
width: 500,
height: 500,
layout: 'fit',
items: [formPanel]
}).show();
}
Get the form by some selector from controller and then call getForm().getValues() method. Method returns an object made by form fields and its values.
Then you can use send this object to the server using Ext.Ajax.request method (docs: http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.Ajax-method-request)
You can send request to server with params via this code:
Ext.Ajax.request({
url: '/requestUrl',
params: {
param1: data1,
param2: data2
},
method: 'POST',
success: function(response) {
//do something...
}
})
Also you need to add this code to some listener on your popup, for example in onButtonClick
function openIFrame() {
Ext.create('Ext.window.Window', {
title : 'Import your devices',
width: 500,
height: 500,
layout: 'fit',
items: [formPanel],
buttons: [
{
text: 'Submit',
handler: function () {
//function which listed above
}
}
]
}).show();
And to handle request at BE you need create controller like this:
#ResponseBody
#RequestMapping(value = "/requestUrl")
public void handler(#RequestParam ("param1") String param1,
#RequestParam ("param2") String param2) throws Exception {
//do something with data
}

how to return table on ajax call in mvc

I am new in MVC. I have a DropDown in index view and i want to show entire table basis on selected item from dropdown. I fire ajax on onChange function of dropdown using jQuery.
$(document).ready(function () {
$("#ddlUser").change(function () {
$("#ddl2").empty();
$.ajax({
type: "POST",
url: '#Url.Action("getState")',
dataType: "json",
data: { id: $("#ddlUser").val() },
success: function (city) {
},
error: function (ex) {
alert('failed to retrieve' + ex);
}
})
});
return false;
});
and i get data from database using this code
public JsonResult getState(int id)
{
MvcDemo9Feb.Models.ModelData MD = new Models.ModelData(); //MD is object of model and dt is DataTable type property
MD.dt = obDB.getCity(id);//obDB is class and getCity is method of it that return datatable
return Json(MD);
}
here i don't know how to bind data of model object MD to table on view. Please suggest something

kendo grid delete command not working

i have developed a web application using kendo ui tools and theres a kendo grid with batch edit mode..
but when i press the delete button for any record in kendo grid it will erase from the list in grid but actually not in the data source.when i reload the page or grid the deleted item will still exist..
here is the code of my grid
<div id="grid">
</div>
<script type="text/javascript">
$("#submitMarketUser").click(function () {
var grid = $("#grid").data("kendoGrid");
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "WholeSaleTrade/GetTradeProductDetail",
dataType: "json",
data: {
test: $("#Names").val()
}
},
destroy: {
url: "WholeSaleTrade/DeletePro",
type: "POST",
dataType: "jsonp",
data: {
DAKy: $("#Names").val(),
DIKy: $("#btntxt").val()
}
},
create: {
url: "WholeSaleTrade/CreateProduct",
type: "POST",
dataType: "jsonp",
data: {
AKy: $("#Names").val(),
IKy: $("#btntxt").val()
}
}
},
pageSize: 5,
schema: {
model: {
id: "ProductKey",
fields: {
ProductKey: { editable: false, nullable: true },
ProductName: { validation: { required: true} }
}
}
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
editable: true,
toolbar: ["create", "save"],
autobind: true,
pageable: true,
columns: [
{ field: "ProductName", title: "Product Name",
editor: function (container, options) {
var model = options.model;
$('<input id="btntxt" name="' + options.field + '"/>').appendTo(container).kendoComboBox({
dataSource: {
type: "POST",
transport: {
read: {
url: "MarketInformation/PopulateProducts",
success: function (data) {
var prod = data[0];
model.set("ProductName", prod.ItmNm);
model.set("ItmKy", prod.ItmKy);
model.set("UserKey", $("#Names").val());
}
}
}
},
dataValueField: "ItmKy",
dataTextField: "ItmNm"
});
}
},
{ command: ["destroy"], title: " " }
]
});
});
</script>
can not identify that where is the fault going and can somebody please help me to solve this matter.
There are three common reasons delete won't work:
1. Not setting editable of grid to inline or popup. The deleted items will be automatically processed through transport destroy only for "inline"/"popup" edit modes. Ex:
editable: {
mode: "inline",
}
//or
editable: "inline"
2. If on your datasource, you have the batch flag set to true, this means the datasource will make the call only after you tell it to, e.g calling sync(). Ex:
var dataSource = new kendo.data.DataSource({
batch: true,
//.....
});
//... in some where e.g in a save button click event call the following line:
dataSource.sync();
3. You should define id to your primary key of database field name inside model of datasource. Ex:
model: {
id: "ProductID",
fields: {
ProductID: { editable: false, nullable: true },
}
}
So the problem with your code is first one, i.e you did not set editable to inline or popup
If you choose not to include editable.mode in order to utilize the in-cell editing, you can set the toolbar of the grid to include the option save:
$("#grid").kendoGrid({
dataSource: {
transport: {
....
},
schema: {
....
}
},
toolbar: ["create", "save", "cancel"],
columns: [
....
],
editable: true
});
This will create a save button at the toolbar of the grid. After deleting any records by clicking the destroy command button, click on the save button to have the grid to make an Ajax call to the server to delete the record.
If you would rather delete the record automatically without including the save button, you could add a change event handler to the datasource of the grid:
$("#grid").kendoGrid({
dataSource: {
transport: {
....
},
schema: {
....
},
change: function(e) {
if (e.action === "remove") {
this.sync();
}
}
},
columns: [
....
],
editable: true
});
This will automatically sync the changes you made to the grid with the server when there's a data change.
Hmm try not including type: "POST", and see if it now works since as far as I can see that bit isn't included on the demo's and I don't think I included it when I last did inline edits/deletes.
I had put an arbitray name for an int on the server Delete Method.
[HttpPost]
public ActionResult DeleteRandomTest(Int32 randomTestId)
{
...
}
The default modelbinder was probably looking for a property called Id (same as the primary key of my type according to the configuration of the model).
.Model(config => config.Id(p => p.Id))
In fact, I proved this by changing the signature to the following:
[HttpPost]
public ActionResult DeleteRandomTest(Int32 Id)
{
...
}
My break point was hit after that.
Ultimately, I used the full type as the parameter as shown in the Kendo examples because I didn't want to have poorly named parameter names (not camel case) in the action. Shown as follows:
[HttpPost]
public ActionResult DeleteRandomTest([DataSourceRequest]
DataSourceRequest request, RandomDrugTest randomDrugTest)
{
...
}
This seems to the be the reason it wasn't working.
I had the same issue. My issue was caused by having a data property in the kendo model. Example:
{id: 1, data: ""}

Creating a column in KendoGrid that is not bound to datasource

I am using Kendo UI to bind a datasource to the Kendo Grid. I am trying to find the best way to create a column in the grid that is not bound to the datasource.
Currently, I am creating a field in the datasource and using some javascript and jQuery to set the values of that column after the data is read from the remote endpoint.
Datasource:
schema: {
model: {
fields: {
blah: {},
empty_column: {}
}
}
}
Grid:
columns: {
field: "empty_column",
width: 100,
title: "Empty"
}
Javascript:
datasource.data[item].set("empty_column", computed_value);
All code edited for brevity, it all works fine.
My question: is there a way to set the defaultValue for this new, empty column which is not connected to the remote endpoint?
When I set:
empty_column: {defaultValue: "None"}
the grid still displays 'undefined', I think because it is not receiveing any data for that field in the read operation. Is there a way to set the defaultValue in the grid? I haven't seen any examples of this...
defaultValue applies when you create a record, not when it is going to be displayed.
You can do:
Option 1: use parse in schema.fields.fieldName that would be something like this.
model: {
fields: {
empty_column: {
type : "string",
defaultValue: "none",
parse : function (data) {
if (!data.empty_columns) {
data.empty_column = "none";
}
return data;
}
},
blah : { type: "number" }
}
},
Option 2: Use schema.parse for adding the extra field value.
schema: {
model: {
fields: {
empty_column: {type: "string", defaultValue: "none"},
blah : { type: "number" }
}
},
parse: function (response) {
$.each(response, function (idx, item) {
if (!item.empty_column) {
item.empty_column = "none";
}
});
return response;
}
}
Of course, (for both options) if you certainly know that there is no previous value in empty_column you might save the test condition and leave only the assignment.

Resources