Asp.net Core Editor example
Asp.net Core Editor example
First of all, a bit of background - recently started my first asp.net core project, or it would more precise to say first dev project in like 10 years, so yeah, currently rate myself a newb in development.
So when I got the multi-tenancy, authentication, authorization done, I started to look for UI elements for my project, came across datatables, and was pretty sure that I would love to include this UI element in my project. Editing data grids is a must for me, so it was disappointing to find out that there is no libraries for asp.net core for Editor server-side. Although I haven't yet bought it, I decided to try to implement the server side myself. Long story short, 2 days later I have editable table, and I am willing to share my solution, as it could help someone else or me (by someone improving upon it). So here we go.
- Models
public class ProjectType
{
[Required]
public int Id { get; set; }
[Required]
public string ProjType { get; set; }
}
public class ProjectTypeDTable : ProjectType
{
public string DT_RowId { get; set; }
}
- Editor and datatable initialization
<script type="text/javascript">
$(document).ready(function () {
var editor = new $.fn.dataTable.Editor({
ajax: {
url: '/api/dtprojecttype',
data: function (d) {
return JSON.stringify(d);
},
contentType: "application/json"
},
table: '.projecttypes-table',
idSrc: 'id',
fields: [
{
name: "projType",
label: "Project Type: "
}
],
});
var generateProjectTypesTable =
$('.projecttypes-table').DataTable({
columns: [
{
data: "id",
searchable: false,
},
{ data : "projType" }
],
ordering: true,
paging : true,
pagingType : 'full_numbers',
pageLength : "25",
select : true,
dom: '<"html5buttons"B>lTfgitp',
buttons : [
{ extend: 'create', editor: editor },
{ extend: 'edit', editor: editor },
{ extend: 'remove', editor: editor },
{ extend: 'copy' }
]
});
//$('.projecttypes-table').on('click', 'tbody td', function () {
// editor.inline(this);
//});
});
</script>
- Server side api action
public async Task<IActionResult> Post([FromBody]JObject request)
{
//split incomming JSON object into action and data JTokens
var action = request.GetValue("action").ToString();
var data = request.GetValue("data");
IList<ProjectTypeDTable> testchangedobjects = new List<ProjectTypeDTable> { };
test
//define new list for changed objects
IList<ProjectTypeDTable> changedobjects = new List<ProjectTypeDTable> { };
//parse json to class objects
changedobjects = changedobjects.DTableEditParser(request, "Id", "Int");
//create empty List for response objects
IList<ProjectTypeDTable> responseobjects = new List<ProjectTypeDTable> { };
if (action == "create")
{
foreach (var x in changedobjects)
{
var changed = new ProjectType
{
ProjType = x.ProjType
};
changed = await _tenantdbrepo.AddProjectTypeAsync(changed);
responseobjects.Add(new ProjectTypeDTable { Id = changed.Id, ProjType = changed.ProjType, DT_RowId = "row_" + changed.Id.ToString() });
};
}
else if (action == "edit")
{
foreach (var x in changedobjects)
{
var changed = new ProjectType
{
Id = x.Id,
ProjType = x.ProjType
};
changed = await _tenantdbrepo.UpdateProjectTypeAsync(changed);
responseobjects.Add(new ProjectTypeDTable { Id = changed.Id, ProjType = changed.ProjType, DT_RowId = x.DT_RowId ?? "row_"+changed.Id });
};
}
else if (action == "remove")
{
foreach (var x in changedobjects)
{
var changed = new ProjectType
{
Id = x.Id,
ProjType = x.ProjType
};
await _tenantdbrepo.RemoveProjectTypeAsync(changed);
};
};
if (responseobjects.Any())
{
dynamic response = new
{
data = responseobjects
};
return Json(response);
}
else
{
dynamic response = new { };
return Json(response);
};
}
- My extension that parses the json to objects
public static class DatatablesEdit
{
public static IList<T> DTableEditParser<T>(this IList<T> source, JObject json, string id, string idtype)
{
//split incomming JSON object into action and data JTokens
var action = json.GetValue("action").ToString();
var data = json.GetValue("data");
IList<T> changedobjects = new List<T> { };
foreach (JProperty x in data)
{
//initialize empty object of class
T changedobject = (T)Activator.CreateInstance(typeof(T));
//set object's ID property to JSON objects Name
if (idtype =="int")
{
changedobject.GetType().GetProperty(id).SetValue(changedobject, Int32.Parse(x.Name.ToString()));
} else if (idtype == "string")
{
changedobject.GetType().GetProperty(id).SetValue(changedobject, x.Name.ToString());
}
//loop through each of JSON object sub properties, change the property name from camel case to pascal case and map to object's properties
foreach (JProperty y in x.Value)
{
string propertyname = char.ToUpper(y.Name[0]) + y.Name.Substring(1);
if (changedobject.GetType().GetProperty(propertyname).PropertyType.Name == "String")
{
changedobject.GetType().GetProperty(propertyname).SetValue(changedobject, y.Value.ToString());
}
else if (changedobject.GetType().GetProperty(propertyname).PropertyType.Name == "Integer")
{
changedobject.GetType().GetProperty(propertyname).SetValue(changedobject, Int32.Parse(y.Value.ToString()));
}
}
//add object to changed objects List
changedobjects.Add(changedobject);
}
return changedobjects;
}
}
I am sure that the code is far from optimal, but I am pretty proud of myself to get this working. Any improvements appreciated.
Replies
That's superb! Thank you for sharing this with us.
I can't wait to get Editor support for .NET Core into the distribution. With .NET Core 2.1 it should be possible.
Regards,
Allan
This looks really interesting.
It would be awesome to have this within the following:
https://github.com/garvincasimir/csharp-datatables-parser
Hey thanks for sharing! This is working really well for me at the moment, to handle nullable types, if you have DateTime? or short? for example, I added lines like this:
Anyways, just wondering, after performing an ajax request from the editor, how do you update or refresh the datatable and select the newly selected row?
Ah nevermind, the format must be in the following:
After formatting it worked.