What is the best way to create Kendo UI grid using angular and web api (for backend)? I am use MVC structure.
My model looks like:
public class Category
{
[Key]
public int CategoryID { get; set; }
[Required]
public string CategoryName { get; set; }
}
In web api controller i have following methods:
public IEnumerable<Category> GetCategories() {}
public HttpResponseMessage PostCategory(Category category) {}
public HttpResponseMessage PutCategory( Category category) {}
public HttpResponseMessage DeleteCategory(Category category) {}
Now, I wish to implement kendo ui grid using angular. How can I do that?
I am read kendo ui demos: http://demos.telerik.com/kendo-ui/grid/angular and documentation but I don't understand how can implement it. Thanks.
I have a mostly working example attached to one of my questions here
AngularJS kendo grid binding to angular service webapi - sorts always null when parsing with [fromuri]
if you attach the service url directly to the dataSource.transport instead of using a service like I did you should be good to go....
Just take out my read:xxxxx section and replace with
read: {
url: "YourWEBAPIURL",
dataType: "json"
}
Related
I'm currently writing a website using ASP.NET Core, HTML, and Javascript. Currently, I have a page of the website that loads a chart of Equipment and stats on them. Below the chart is an area where the user can select specific equipment whose details they want to view. This info is then sent to the controller, which returns info back to the View about them.
However, while I know that the AJAX call does go to the controller when I look at it with breakpoints, and I know the value of my selected equipment is corrected, it always returns a "null" string value to the controller and I don't know why.
I've attempted a couple of different ways of writing it according to code I've seen on SO. My code was similar (structurally speaking) to the code on this page. I attempted the solution, which is the code I have now, but it didn't seem to change anything.
Here is my current javascript code:
function filterInterventions() {
var equipment = $(".equipmentCheckboxes:checkbox:checked").map(function () {
return this.value;
}).get();
$("#IntrvTable tbody tr").remove();
$.ajax({
type: "GET",
data: equipment,
cache: false,
//url: "GiveData?jsonString=",
url: '#Url.Action("GiveData")',
success: function (data) {
if (data) {
alert("success");
var parent = $("#parent");
parent.empty();
parent.append(data);
}
}
});
}
And here is my controller code:
public ActionResult GiveData(string jsonString){
//do stuff....
return View("RawData", myModel);
}
When I step through it in the browser and on my IDE, I know that the equipment in the actual javascript is correct. For example, if I selected equipment 'AA' and 'BB' to look at, I know I'm sending in ["AA/", "BB/"]. But I just cannot get the "jsonString" in the controller action to be non-null.
I thought it might be because I'm sending in an array, but the things I've found online about turning on traditional have also not helped.
I would love any help. Thanks.
I believe what you'd be looking for would be:
data: { 'jsonString': JSON.stringify(equipment) }
Normally though JSON would be used for an object rather than an array of strings, and the method signature would reflect the object definition of the data being passed as a POCO class. If you just want an array then something like this should work:
data: { 'equipment' : equipment }
with the controller action signature:
public ActionResult GiveData(string[] equipment)
Edit: JSON / POCO example
For a typical JSON example let's say you have a view model representing editing a new or existing order. This may have an Order ID, an order date, a customer ID, delivery address details, and a list of order lines. (product ID, quantity) On the client side you would construct a JS object view model for the data and then compose that to JSON to look something like:
{
"order": {
"orderId": 1234,
"orderDate": "2019-07-21",
"customerId": 216,
"deliveryAddress": {
"street": "216 Cuckoo Crescent"
"city": "Sydney"
}
"orderLines": {
{ "productId": 22, "quantity":1 },
{ "productId": 15, "quantity":3 }
}
}
}
where the Ajax call data component would look like:
data: { 'order': orderJson }
If the order data was just a Javascript object then you would use JSON.stringify(order) to pass the JSON representation.
In your server you would define these view models:
[Serializable]
public class OrderViewModel
{
public int? OrderId { get; set; }
public DateTime OrderDate { get; set; }
public int CustomerId { get; set; }
public AddressViewModel Address { get; set;}
public ICollection<OrderLineViewModel> OrderLines { get; set; } = new List<OrderLineViewModel>();
}
[Serializable]
public class AddressViewModel
{
public string Street { get; set; }
public string City { get; set; }
// ...
}
[Serializable]
public class OrderLineViewModel
{
public int ProductId { get; set; }
public int Quantity { get; set; }
}
In your method signature you would like:
public ActionResult CreateOrder(OrderViewModel order)
ASP.Net will accept the JSON object and your code can work with the POCO classes automatically. This is pulling from memory, and might require/involve a library like JSON.Net with some attribute goodness or extra steps so there may be some tweaking and config needed, especially to accommodate Pascal vs. Camel casing conventions between the JS and C# code. The onus though is on the developers to keep the POCO definitions and JS objects in-sync, and ensure the data types are compatible.
It is now quiet a default behavior - to map raw data to plain string.
Instead of mapping to string it is usually a better way - to map the JSON to the corresponding class type.
If raw data is the goal - here might be something you are looking for.
Let say that I do have the following url:
"/api/requests/cbd?[{"requestid":"fd45001b-339f-ac28-e053-a24c07d4e3fb"},{"requestid":"fd45001b-329f-ac28-e053-a24c07d4e3fb"},{"requestid":"fd45001b-319f-ac28-e053-a24c07d4e3fb"}]"
How to bind the parameters - array with asp.net web api 2 action?
This I have tried but it is not working.
[HttpGet]
[Route("api/requests/cbd")]
public IHttpActionResult CanBeDeleted([FromUri] string[] requestIds )
{
return Ok(result);
}
You are passing an array of objects so viable option would be create a class like:
public class Ids
{
public Guid requestid {get;set;}
}
and use it like:
[HttpGet]
[Route("api/requests/cbd")]
public IHttpActionResult CanBeDeleted([FromUri] IEnumerable<Ids> requestIds )
{
return Ok(result);
}
or send only ids, without property name.
you can keep the action in the web api like that and just change the http call into:
"/api/requests/cbd?requestid=1&requestid=2&requestid=3"
if you need the http call to be as you presented it, you can take Kamo's approach and create objects for your parameter collection.
You can use this in your Controller:
public IHttpActionResult CanBeDeleted(JObject request)
{
Dictionary<string, object> myCollection = JsonConvert.DeserializeObject<Dictionary<string, object>>(request["NameOfYourParam"].ToString());
return OK();
}
I have a quick question. I've created a custom drop-down HTML control that dynamically grabs "nodes" from a database. I turned this into an Umbraco (v7) datatype that can be used as an Umbraco property in the admin section.
Unfortunately, when the user picks one of the items and saves, it does not properly store this info. I've determined that this is because when Umbraco tries to save to the DB, it's NodeId is empty. I need to populate this before we save the data. Unfortunately, I haven't found any easy way to do this.
Can anyone point me in the right direction? Populating the NodeId before I push the model to the CS Controller (which should update the SQL DB) should work... or is it possible to make an angularJS that pushes TWO parameters and let the C# handle this?
Anyone have any ideas?
Here's the HTML Editor:
<select ng-controller="Dmns.DDLAllNodesController" data-ng-model="selectedOption">
<option ng-repeat="gNode in galaxyNodes.data" value="{{gNode}}">
{{gNode.KioskNodeId}} -- {{gNode.MachineName}}
</option>
</select>
And here's the AngularJS, where I'd like to add the Umbraco's Node Id to the model before submitting to the C#
$scope.$on("formSubmitting", function () {
$scope.selectedOption({
Id: $routeParams.Id // This does not update properly
});
$scope.$apply();
getAllNodesResource.save($scope.selectedOption); // Sends old data
});
And here's the model I'm returning, in case this helps:
[Serializable]
[DataContract]
public class KioskNode
{
[DataMember]
public int Id { get; set; }
[DataMember]
public int NodeId { get; set; }
[DataMember]
public int KioskNodeId { get; set; }
[DataMember]
public string MachineName { get; set; }
}
So I found the reason why it wasn't populating correctly. I wasn't deserialing the object from JSON, which means I couldn't get the child properties.
This fixed my problem:
var deJson = angular.fromJson(node);
return $http.post("/umbraco/backoffice/api/DDLNodes/PostSave", {
Id: 0,
NodeId: id,
KioskNodeId: deJson.KioskNodeId,
MachineName: deJson.MachineName
});
This let me pass the variables (updated) I need back to Backoffice to save it to the DB.
I'm new to MVC, but have done a bunch of reading the past few months, and I've ran into some issues when trying to build a one to many relationship dynamically on the page. I've set up the logic and can accomplish this through multiple page loads but I want the form to be more dynamic, so I'm not sure what the correct way to do this is.
For testing purposes I scaled down my Model just to see if I can get the interaction I want before I apply it to my project and what I have is this:
Generated models from my Db.
public partial class TestIncident
{
public TestIncident()
{
this.TestGeoKits = new HashSet<TestGeoKit>();
}
public int RecordID { get; set; }
public string OwnerFirstName { get; set; }
public string OwnerMiddleName { get; set; }
public string OwnerLastName { get; set; }
public virtual ICollection<TestGeoKit> TestGeoKits { get; set; }
}
RecordID being my PKey for the class above
public partial class TestGeoKit
{
public int RecordID { get; set; }
public int KitID { get; set; }
public bool SubmittedForTestingFlag { get; set; }
public string SubmissionLocation{ get; set; }
public Nullable<System.DateTime> SubmissionDate { get; set; }
public bool Processed { get; set; }
public Nullable<System.DateTime> ReturnDate { get; set; }
public string Notes { get; set; }
public virtual TestIncident TestIncident { get; set; }
}
RecordID being my FKey relation and KitID being my PKey for this table.
Now, I need to set up a Create View that contains both the Form associated with the TestIncident AND has the option to click an ADD button to populate Partials containing the Form associated with my TestGeoKits on the same page, instead of after a postback and redirect (How I currently have it). I've tried piecing information from multiple posts together to accomplish this, but one way or another I run into a bunch of problems and even more questions..
Logically I would think, being MVC uses Entity Framework, that on my Create TestIncident page I can have an ADD button that adds a TestGeoKit form to the page each time its clicked, in the form of a partial view. Then, when you click submit the entire Object is passed back to the Controller, binds all the values for the incident to the database, gets the next Identity Value (set up in sql) for RecordID, and uses that information for the ICollection of TestGeoKits in TestIncident to build the foreign key relationship and save all the data.
How do I go about building a dynamic page like this? I've read MANY articles, played with Ajax commands and jQuery form controls, played with LazyLoading / EagerLoading, and I think I'm over complicating it for myself at this point.
I have a, not so dynamic, version currently running that when you submit your TestIncident form, the Method called in the Controller checks for a GeoKitCollectedFlag after its saved and if its true redirects you to a separate page to fill out the GeoKit Form. But, again my ideal form is to combine these two actions on one page.
Any help would be greatly appreciated!
Really the key thing is in the naming of your fields. MVC is actually pretty competent at constructing complex object graphs based on posted data from a form, as long as you simply follow its conventions. For enumerable properties, that's making sure your field names follow the form ListProperty[N].Property. So, for your TestGeoKit instances you should have input names like TestGeoKits[0].RecordID.
To ensure this happens with Razor generated inputs, you need to iterate over existing instances using for rather than foreach:
#for (var i = 0; i < Model.TestGeoKits.Count(); i++)
{
#Html.HiddenFor(m => m.TestGeoKits[i].RecordID)
<!-- etc -->
}
Adding new records dynamically obviously requires a JavaScript solution. There's many different ways you could handle this. You could construct the HTML manually via JavaScript. You could submit an AJAX request to some action that would return HTML for all the fields. You could use JavaScript to copy the HTML for an existing record on the page and replace the id and name attributes with the proper index.
Personally, I would recommend going with a framework geared towards handling data binding and templating. Knockout is a popular choice, but your could use things like Backbone, Angular, etc. The idea, simply, is that you want something where you can merely add a data object to an array in JavaScript, and have it generate the appropriate HTML for you with the right index for the names and such. Trying to keep up with this manually is kind of a nightmare.
I am using MVC.
I have a view model which contains a Business object.
I need to post this Business Object back to a controller action using AJAX.
For now, I am using Url.Action function to create my request Url for AJAX and pass the Business Object id as a request parameter to the action. I then have to retrieve the object from the database to use it.
Is there a way (using Json) to pass this object as an Object? The object is shown below
public class BusinessObject : BaseBusinessObject
{
public virtual string Id { get; set; }
public virtual IDictionary Data { get; set; }
public virtual IDictionary Collections { get; set; }
}
The controller action should ideally have a deifinition like ...
public ActionResult DOThis(BusinessObject bo) {}
What you are looking for is FORM Binding, there are lot of resources available, This link gives you some insight.
You should use the JsonResult for going from the server to the client. http://www.ajaxprojects.com/ajax/tutorialdetails.php?itemid=399#start
The DefaultModelBinder will take care of the binding to the server. There is also a section in this page talking about calling from JQuery to the server and getting back the JsonResult.
Hope this helps!