I am using Jquery-JTable in my website to load details in a grid view and to let user be able to modify, delete app accordingly.
I am loading data successfully from 2 tables and then display them in my div. Now the user would like to modify a record accordingly to his/her wish.
I would like to let the user choose from a dropdown list obtained from another table. Can this be done?
Code Below: As you can see I am loading data from multiple tables using InnerJoin. For example I would like to let the user choose another Category or Language etc.
$queryString = "SELECT `app_id`,`app_name`,`app_type`,`app_url`,`AppAccepted`,`BenefitApp`, application_ageGroup.ageGroup,application_category.category, application_Country.country,application_Language.language FROM application INNER JOIN application_ageGroup ON application.ageGroup_id = application_ageGroup.ageGroup_id INNER JOIN application_category ON application.Category = application_category.category_id INNER JOIN application_Country ON application.country_id = application_Country.country_id INNER JOIN application_Language ON application.language_id = application_Language.language_id ORDER BY $jtSorting LIMIT $jtStartIndex,$jtPageSize";
Regards,
Make the Category column as dropdown and bind it with your query dataset :
$('#Table').jtable({
paging: true,
pageSize: 200,
sorting: true,
defaultSorting: 'Category ASC',
selecting: false,
multiselect: false,
selectingCheckboxes: false,
actions: {
listAction: '/Application/GetData',
updateAction: '/Application/EditData'
},
fields: {
Category: {
title: 'Category',
width: '10%',
list: false,
sorting: true,
options: '/Application/GetCategories'
}
});
In your controller action, fetch Category lists:
[HttpPost]
public JsonResult GetCategories()
{
try
{
DataTable dtCategories = new DataTable();
string query = "SELECT .....";
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
using (SqlCommand command = new SqlCommand(query, connection))
{
connection.Open();
dtCategories.Load(command.ExecuteReader());
}
List<Store> categoryList = DatatableToGenericList(dtCategories);
var categories = categoryList.Select(category => new { DisplayText = category.Name , Value = category.Id }).OrderBy(s => s.DisplayText);
return Json(new { Result = "OK", Options = categories });
}
catch (Exception ex)
{
return Json(new { Result = "ERROR", Message = ex.Message });
}
}
private static List<Store> DatatableToGenericList(DataTable table)
{
var categoryList = new List<Category>(table.Rows.Count);
foreach (DataRow row in table.Rows)
{
var values = row.ItemArray;
var store = new Category()
{
Id = values[0].ToString(),
Name = values[1].ToString()
};
categoryList.Add(store);
}
return categoryList;
}
Category Model
public class Category
{
public string Id { get; set; }
[Required]
public string Name { get; set; }
}
Hope this helps..
Related
I need to bind a Kendo grid to a model class. I am returning the same from controller using Json result but the gird is not getting bind. Also find below code snippets used.
Model:
public DataTable ErrorData { get; set; }
public List<string> Groups { get; set; }
public Dictionary<string, System.Type> ErrorColumns { get; set; }
Controller :
public JsonResult PopulateData()
{
ErrorPage _objError = new ErrorPage();
//Getting the details from Database
_objError.ErrorData = dbl.GetDataTable(DbConnectionString,Table,whereCondition, columns);
//Poplulating the Column list as it is dynamically generated every time as per the filter on front end(View)
//Column description: Name and Type
var columnlist = new Dictionary<string, System.Type>();
foreach (System.Data.DataColumn column in _objError.ErrorData.Columns)
{
var t = System.Type.GetType( column.DataType.FullName );
columnlist.Add(column.ColumnName, t);
}
_objError.ErrorColumns = columnlist;
return Json(_objError);
}
View:
This is a code return on button click
$.post(path, { application: app, columns: columns, machine: machine, pages: pages,
startDate: startDate, endDate: endDate }, function (result) {
var grid = $("#ErrorLog").data(result);
grid.dataSource.read();
grid.refresh();
});
This is Kendo grid code which also get bind to data on page load:
#(Html.Kendo().Grid<dynamic>()
.Name("ErrorLog")
.Columns(columns =>
{
//Define the columns
foreach (var c in Model.ErrorColumns)
columns.Bound(c.Value, c.Key);
})
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
foreach (System.Data.DataColumn column in Model.ErrorData.Columns)
{
model.Field(column.ColumnName, column.DataType);
}
})
.Read(read => read.Action("populateData", "Common"))
)
.Groupable()
.Sortable(s => s.AllowUnsort(true))
.Filterable(ftb => ftb.Mode(GridFilterMode.Menu))
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(true)
//.ButtonCount(5)
)
)
The column list is populated properly. but i am not sure about the returning the JsonResult to a kendo grid. Kindly help on how to bind a kendo grid using Json result.
Here we go with the solution:
This is my controller where i have serialized the object we are trying to send to View:
public JsonResult populateData(string application, string columns, string machine, string pages, string startDate, string endDate)
{
ErrorPage _objError = new ErrorPage();
var ErrorResult = _objError.GetErrorData(application, columns, machine, pages, startDate, endDate);
//Column description: Name and Type
var columnlist = new Dictionary<string, System.Type>();
foreach (System.Data.DataColumn column in _objError.ErrorData.Columns)
{
var t = System.Type.GetType(column.DataType.FullName);
columnlist.Add(column.ColumnName, t);
}
_objError.ErrorColumns = columnlist;
var result = JsonConvert.SerializeObject(ErrorResult.ErrorData, Formatting.Indented,
new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});
return Json(result, JsonRequestBehavior.AllowGet);
}
Here is my view which binds the datatable send from controller to Kendo grid:
$.ajax({
type: "POST",
url: '#Url.Content("~/Common/PopulateData")',
contentType: "application/json;charset=utf-8",
dataType: 'json',
data: JSON.stringify({ application: app, columns: columns, machine: machine, pages: pages, startDate: startDate, endDate: endDate }),
success: function (data) {
$('#ErrorLog').data("kendoGrid").dataSource.data(JSON.parse(data));
}
});
Thanks
I have following data that I have serialized as JSON from my code behind file.
public class PieModel {
public string label { get; set; }
public double data { get; set; }
}
var data = new List<PieModel> {
new PieModel { label = "Pending", data = 10d }
new PieModel { label = "New", data = 40d }
new PieModel { label = "Overdue", data = 50d }
};
hdnData.Value = new JavaScriptSerializer().Serialize(data);
I read this serialized data in JavaScript like this
var tempHdnData = $("#hdnData");
But now I want to iterate on tempHdnData and get label and data members separately in JavaScript code. How can I achieve that?
You could write your code like this in the code behind:
protected List<PieModel> GetData() {
return new List<PieModel> {
new PieModel { label = "Pending", data = 10d }
new PieModel { label = "New", data = 40d }
new PieModel { label = "Overdue", data = 50d }
};
}
And in your webform:
var tempHdnData = <%= new JavaScriptSerializer().Serialize(GetData()) %>
Now you can write
$.each(tempHdnData, function (_, data) {
console.log(data)
})
I am using a jQuery plugin, jTable. The plugin has the following function to load the table:
$('#PersonTable').jtable('load', { CityId: 2, Name: 'Halil' });
The values in the load function is send as POST data. The plugin also sends two query string parameters (jtStartIndex, jtPageSize) through the URL for paging the table.
An example in the documentation shows a function on how to handle this in ASP.NET MVC but not in Web API Example :
[HttpPost]
public JsonResult StudentListByFiter(string name = "", int cityId = 0, int jtStartIndex = 0, int jtPageSize = 0, string jtSorting = null)
{
try
{
//Get data from database
var studentCount = _repository.StudentRepository.GetStudentCountByFilter(name, cityId);
var students = _repository.StudentRepository.GetStudentsByFilter(name, cityId, jtStartIndex, jtPageSize, jtSorting);
//Return result to jTable
return Json(new { Result = "OK", Records = students, TotalRecordCount = studentCount });
}
catch (Exception ex)
{
return Json(new { Result = "ERROR", Message = ex.Message });
}
}
How my function currently looks: It works fine except that I can't manage to read the POST data (name param):
public dynamic ProductsList(string name = "", int jtStartIndex = 0, int jtPageSize = 0 )
{
try
{
int count = db.Products.Count();
var products = from a in db.Products where a.ProductName.Contains(name) select a;
List<Product> prods = products.OrderBy(x => x.ProductID).ToList();
return (new { Result = "OK", Records = prods, TotalRecordCount = count });
}
catch (Exception ex)
{
return (new { Result = "ERROR", Message = ex.Message });
}
}
My jTable load: (This get called when the user enters text in a input)
$('#ProductTable').jtable('load', {
name: $('#prodFilter').val()
});
I would appreciate any help with how to read both the string parameters in the URL and the POST data in a Web API function.
EDIT:
I used an alternative way to send the data to the API. Instead of sending it in the load function formatted as JSON I used a function for the listAction and sent the data through the URL (See jTable API reference for details):
listAction: function (postData, jtParams) {
return $.Deferred(function ($dfd) {
$.ajax({
url: 'http://localhost:53756/api/Product/ProductsList?jtStartIndex=' + jtParams.jtStartIndex + '&jtPageSize=' + jtParams.jtPageSize + '&name=' + $('#prodFilter').val(),
type: 'POST',
dataType: 'json',
data: postData,
success: function (data) {
$dfd.resolve(data);
},
error: function () {
$dfd.reject();
}
});
});
}
To reload the table based on your filtered results:
$('#ProductTable').jtable('load');
Instead of this:
$('#ProductTable').jtable('load', {
name: $('#prodFilter').val()
});
Try applying the [FromBody] attribute to the name parameter
public dynamic GetProductList([FromBody]string name = "", int jtStartIndex = 0, jtPageSize = 0)
{
...
}
The default binder in Web API will look in the URI for simple types like string, specifying the FromBody attribute will force it to look in the body.
I have been reading ALL of the documentation on this and I still cannot get it to work.
I have a Web API which provides a JSON object. It's a list of 22 things. Just 22 lines of text.
I want to take these and form a TreeView. Each of these 22 strings will have items under them but I just want to get the first part working.
My first question is, how do I extract data from an API and populate a treeView with it?
On my main page, I have this:
<div id="treeView"></div>
On my JavaScript file I have this:
$("#treeView").kendoTreeView({
checkboxes: true,
dataSource: {
transport: {
read: {
url: "http://...",
dataType: "json"
}
}
}
});
When I try to run the page, I get "Request failed." [Retry]
If I open up a browser and go to this URL, data is returned fine as a JSON object.
What am I doing wrong here?
EDIT -
Code that is returning the JSON:
public List<string> getNotificationByUser(int id)
{
List<string> notificationTitles = new List<string>();
foreach (var notification in notifications)
{
notificationTitles.Add(notification.ToString());
}
return notificationTitles;
}
Ok! I've been able to reproduce your error. The question is that 22 lines of text are not a valid JSON.
Returning something like:
This
is
a
test
Is not a valid JSON.
But a valid JSON is not enough, you should return something like this:
[
{ "text": "This" },
{ "text": "is" },
{ "text": "a" },
{ "text": "test" }
]
I.e.: The result should be an array of objects where each object has a text field.
NOTE I know that it does not have to be called text but for simplicity I used it since it is the default value.
I figured out all of my answers:
function CreateNotificationTree(userId)
{
debugger;
var data = new kendo.data.HierarchicalDataSource({
transport: {
read: {
url: "../api/notifications/byuserid/" + userId,
contentType: "application/json"
}
},
schema: {
model: {
children: "notifications"
}
}
});
$("#treeview").kendoTreeView({
dataSource: data,
loadOnDemand: true,
dataUrlField: "LinksTo",
checkboxes: {
checkChildren: true
},
dataTextField: ["notificationType", "NotificationDesc"],
select: treeviewSelect
});
function treeviewSelect(e)
{
var node = this.dataItem(e.node);
window.open(node.NotificationLink, "_self");
}
}
[HttpGet]
public List<Node> getNotifications(int id)
{
var bo = new HomeBO();
var list = bo.GetNotificationsForUser(id);
var notificationTreeNodes = (from GBLNotifications n in list
where n.NotificationCount != 0
select new NotificationTreeNode(n)).ToList();
var li = notificationTreeNodes.Select(no => new Node
{
notificationType = no.NotificationNode.NotificationType + " " + "(" + no.NotificationNode.NotificationCount + ")", notifications = bo.GetNotificationsForUser(id, no.NotificationNode.NotificationTypeId).Cast<GBLNotifications>().Select(item => new Notification
{
ID = item.NotificationId, NotificationDesc = item.NotificationDescription, Params = new List<NotificationParam>
{
new NotificationParam
{
ParamName = item.Param1, ParamVal = item.ParamValue1
},
new NotificationParam
{
ParamName = item.Param2, ParamVal = item.ParamValue2
},
new NotificationParam
{
ParamName = item.Param3, ParamVal = item.ParamValue3
},
new NotificationParam
{
ParamName = item.Param4, ParamVal = item.ParamValue4
},
new NotificationParam
{
ParamName = item.Param5, ParamVal = item.ParamValue5
},
},
ActionPageName = item.ActionPageName
}).ToList()
}).ToList();
li.ForEach(i => i.notifications.ForEach(x => x.SetNotificationLink()));
return li;
}
Here are the domain classes
class Settings {
static constraints = {
uid(nullable: false, unique: true)
data()
}
static hasMany = [items: Item]
Map data
}
class Item{
static constraints = {
name()
email()
approved()
}
static mapping = {
email index: true, indexAttributes: [unique: true]
}
String name
String email
Boolean approved = false;
}
Basically there are many Settings objects that have many items (see illustration below):
Now I'm finding and updating an item like so:
...
def item = (Item)Item.findByEmail(email);
if (!item.approved) {
item.approved = true;
item.save(flush: true);
}
...
Not Saved what am I missing here?
MongoDB does not except null fields by default. Once I've added a value all works well:
...
def item = (Item)Item.findByEmail(email);
if (!item.approved) {
item.approved = true;
item.name = "MyName";
item.save(flush: true);
}
...