How to bind Kendo grid to json data using angularjs - angularjs

HI i am using kendo grid to bind data with json and angularjs
here is my code below.
this is the .cshtml page code below.
<div ng-app="Sample" ng-controller="SampleController">
<div>Products: {{products.length}}</div>
<div kendo-grid k-data-source="products" k-selectable="'row'"
k-pageable='{ "pageSize": 2, "refresh": true, "pageSizes": true }'
k-columns='[
{ "field": "EmployeeKey", "title": "EmployeeId"},
{ "field": "FirstName", "title": "First Name"},
{ "field": "LastName", "title": "Last Name"},
{ "field": "DepartmentName", "title": "Department Name" },
{ "field": "EmailAddress", "title": "Email Id" }
]'>
</div>
</div>
<script>
var app = angular.module('Sample', ['kendo.directives']);
app.controller('SampleController', function ($scope, $http) {
debugger;
$http.get('~/api/Employee/Employee_Read').success(function (thisdata) {
var myData = $.parseJSON(JSON.parse(thisdata));
$scope.myData = myData;
});
$scope.filterOptions = {
filterText: '',
useExternalFilter: true,
};
});
</script>
and in controller which name is EmployeeController i used json data like below:
public ActionResult Employee_Read ([DataSourceRequest] DataSourceRequest request )
{
return Json(employeeRepositary.Employees.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
This code is working fine with #HtmlKendo grid but for this i am not able to display data.
Where i am wrong??
Please help me out from here.

Use kendo.data.ObservableArray for this case
$http.get('~/api/Employee/Employee_Read').success(function (thisdata) {
var myData = $.parseJSON(JSON.parse(thisdata));
$scope.products= new kendo.data.ObservableArray(myData.Data);
});

Related

AngularJS Filed nested array of objects with array of objects

I'm trying to filter a nested array of objects with my own objects, by idSubject. But I'm not getting the right result.
I have articles (which have subjects)
And a array of objects (which are the subjects I want to filter the articles with)
Data looks like this:
So I'm trying to filter the array of articles by its subjects.
I tried the following:
<div class="panel panel-default"
ng-repeat="searchArticle in searchArticles | filter: {subjects: filterSubjects} as articleSearchResult">
So filterSubjects is the second screenshot and SearchArticles is the first screenshot.
Without much luck.
Hope you can help, please tell me if things are still unclear.
This custom filter will help you.
Example : http://plnkr.co/edit/jMizCLxPH6DtDA5wL15Q?p=preview
HTML:
<body ng-app="myApp">
<div ng-controller="MainCtrl">
<h2>Select Subjects</h2>
<div ng-repeat="subject in subjects">
<label>
<input type="checkbox" ng-model="filterSubjects[subject.id]" ng-true-value="'{{subject.id}}'" ng-false-value="''">{{subject.name}}</label>
</div>
<h2>Filtered Articles</h2>
<div ng-repeat="searchArticle in searchArticles | subjectFilter:filterSubjects">{{searchArticle.name}}</div>
</div>
</body>
JS:
var app = angular.module('myApp', []);
app.controller('MainCtrl', function($scope) {
$scope.searchArticles = [{
"name": "Article1",
"sid": "1"
}, {
"name": "Article2",
"sid": "1"
}, {
"name": "Article3",
"sid": "2"
}];
$scope.subjects = [{
"name": "Subject1",
"id": "1"
}, {
"name": "Subject2",
"id": "2"
}];
$scope.filterSubjects = [];
});
app.filter('subjectFilter', function() {
return function(articles, filterSubjects) {
filtered = articles.filter(function(e){return filterSubjects.indexOf(e.sid) >= 0},filterSubjects);
return filtered;
}
});
if you want to filter based on object :
var app = angular.module('myApp', []);
app.controller('MainCtrl', function($scope) {
$scope.searchArticles = [{
"name": "Article1",
"sid": "1"
}, {
"name": "Article2",
"sid": "1"
}, {
"name": "Article3",
"sid": "2"
}];
$scope.subjects = [{
"name": "Subject1",
"id": "1"
}, {
"name": "Subject2",
"id": "2"
}];
$scope.filterSubjects = [{
"name": "Subject1",
"id": "1"
}, {
"name": "Subject1",
"id": "2"
}];
});
app.filter('subjectFilter', function() {
return function(articles, filterSubjects) {
var sFiltered = [];
for (var i = 0; i < filterSubjects.length; i++) {
sFiltered.push(filterSubjects[i].id);
}
var filtered = articles.filter(function(e) {
return sFiltered.indexOf(e.sid) >= 0;
}, sFiltered);
return filtered;
}
});

angular.forEach() not working

Hi friend I'm beginner in angular and getting stuck by using angular.forEach() function. I just want to call data from a nested array in data.json file. Please check my code below... ****I want to call data from --users-- key****
HTML
<div class="user-container" ng-controller="users">
<ul class="list">
<li ng-repeat="(key, value) in items">
{{key}} <p> {{value}}
</li>
</ul>
</div>
Problems with current code
When run my code in browser Its giving me only 2 <li> in ng-repeat then in {{Key}} I'm getting 0 in first <li> and 1 in second <li>
and in {{value}} I'm getting whole user list in first <li> and in second <li> their is no data
data.json
{
"data": {
"new": true,
"show_page": false,
"status": "signedin",
"users": [{
"Michele": {
"logo": "xyz.jpg",
"status": "active",
"active_since": 2015,
"order": 1
},
"Gerry": {
"logo": "xyz.jpg",
"status": "active",
"active_since": 2015,
"order": 1
}
}]
},
"success": true
}
Controller.js
var myApp = angular.module('app', []);
myApp.service('userData', ['$http', function($http){
return{
userslist : function(){
return $http({'url' : 'data.json', 'method' : 'GET'}).then(function(response){
return response.data;
}, function(data){
console.log(data)
})
}
}
}]);
myApp.controller('users', ['$scope', '$http', 'userData', function($scope, $http, userData){
userData.userslist().then(function(data){
//var provideDataKey = Object.keys(data.users)[0];
$scope.items = [];
angular.forEach(data, function(item){
//console.log(item.users);
$scope.items.push(item.users)
})
console.log($scope.items)
})
}]);
response is the HTTP response, with its body (data), headers, etc.
So response.data is the body, which looks like this:
{
"data": {
"new": true,
"show_page": false,
"status": "signedin",
"users": [{
"Michele": {
"logo": "xyz.jpg",
"status": "active",
"active_since": 2015,
"order": 1
},
"Gerry": {
"logo": "xyz.jpg",
"status": "active",
"active_since": 2015,
"order": 1
}
}]
},
"success": true
}
What you want is to access the users field of the data field of this body. So what you want is
userData.userslist().then(function(data){
$scope.items = data.data.users;
console.log($scope.items)
})
$scope. items is an array, not an object. You want to display the elements of this array. So the syntax is:
{{ user }}
Your JSON is awful, because each user is an object with a single field, and you have no way of knowing the name of that field. You'd better change it to
"users": [
{
"name": "Michele",
"logo": "xyz.jpg",
"status": "active",
"active_since": 2015,
"order": 1
},
{
"name": "Gerry",
"logo": "xyz.jpg",
"status": "active",
"active_since": 2015,
"order": 1
}
]
That way you could just do:
<li ng-repeat="user in items">
{{ user.name }}, active since {{ user.active_since }}.
use this
myApp.controller('users', ['$scope', '$http', 'userData', function($scope, $http, userData){
userData.userslist().then(function(data){
//var provideDataKey = Object.keys(data.users)[0];
$scope.items = [];
angular.forEach(data.users[0], function(item){
$scope.items.push(item);
})
console.log($scope.items)
})
}]);
you were iterating over data and not on users.

tags-input show a a element of an array

hi i have a JSON like this:
pages[
{
"id": "74682309",
"labels": [
{
"term": "test1",
"probability": 0.069
},
{
"term": "test2",
"probability": 0.037
}
]
}];
and using tags-input i want the tags to read only the term and show the term so i can show and update.
i have
<tags-input ng-model="se.labels"></tags-input>
the 'se' comes from ng-repeat="se in searchCtrl.pages
Based on the documentation (http://mbenford.github.io/ngTagsInput/documentation/api) you can change the keyProperty and displayProperty to make it use "term" instead of "text"
I've created a fiddle to demonstrate how you can obtain the data needed, considering that the provided JSON is a valid JSON. Your JSON is invalid.
var myApp = angular.module('myApp',['ngTagsInput']);
myApp.factory('data', function() {
var data = [
{
"id": "74682309",
"labels": [
{
"text": "test1",
"probability": 0.069
},
{
"text": "test2",
"probability": 0.037
}
]
}];
return data;
});
myApp.controller('MyCtrl', ['$scope', 'data', function($scope, data) {
var values = [];
data.map(function(elem) {
return elem.labels.forEach(function(el) {
values.push({
"text" : el.text
});
});
});
$scope.tags = values;
}]);
And the html part:
<div ng-controller="MyCtrl">
<div class="elem">
<tags-input ng-model="tags"></tags-input>
</div>
</div>
Here is the fiddle:
http://jsfiddle.net/HB7LU/16554/
Update:
You haven't included the angular ng-tags-input extension as a tag into your question. Please see my updated fiddle:
http://jsfiddle.net/HB7LU/16557/

Angularjs ng-repeat Array vs Object

I am using ng-repeat to display data in a View coming from an endpoint in a form of atom feed. This endpoint returns JSON if Accept header is 'application/json', that JSON is created from XML on a server-side by an converter, unfortunately if there is one entry in the atom response then the entry in the JSON is not an array and ng-repeat does not work as expected. I had a project where I handled this manually by using a counter and then based on that counter and ng-show I either used ng-repeat or just displayed the single entry from the feed. How do I handle this correctly? Should I rework the incoming JSON on JS side? If yes could someone point me the right way of doing that.
<feed xmlns="http://www.w3.org/2005/Atom">
<id>/record</id>
<title type="text">Search feed</title>
<link href="/record" rel="self"/>
<link href="/record?page=2" rel="next"/>
<entry>
<id>recordid</id>
<link href="/record/id/recordid" rel="self"/>
<content type="recordcontenttype">
<record>...recordhere...</record>
</content>
</entry>
</feed>
{
"feed": {
"entry":
{
"content": {
...recordhere...
},
"type": "recordcontenttype"
},
"id": "recordid",
"link": {
"href": "/record/id/recordid",
"rel": "self"
}
},
-- if there would be more entries then entry would be an array [ { xx }, { xx } ] and ng-repeat would work --
"id": "/record",
"link": [
{
"href": "/record",
"rel": "self"
},
{
"href": "/record?page=2",
"rel": "next"
}
],
"title": {
"content": "Search feed",
"type": "text"
}
}
}
I'd suggest a simple filter, e.g.:
(function (app, ng) {
'use strict';
app.controller('AppCtrl', function AppCtrl() {
var vm = this;
vm.foo = { id: 1 };
vm.bar = [{ id: 2 }, { id: 3 }];
});
app.filter('ensureArray', function () {
return function (input) {
return ng.isArray(input) ? input : [input];
};
})
}(angular.module('app', []), angular));
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.1/angular.min.js"></script>
<div data-ng-app="app" data-ng-controller="AppCtrl as app">
<div data-ng-repeat="foo in app.foo|ensureArray">
{{ foo|json }}
</div>
<div data-ng-repeat="bar in app.bar|ensureArray">
{{ bar|json }}
</div>
</div>

multiselect treeview in backbone

I'm new to backbone and trying to establish some good paradigms.
Right now, I'm working on a search heavy site. There are dozens of attributes to search on, many are min max type, but 6 or so are multi select. Prior to backbone, I was using something called listtree to make a collapsible listtree for the multiselect options. I'm still going to use those css classes, but now I'm trying to use backbone with models and views. TBH, this seems like more work than just using straight jquery, so maybe I'm missing something.
My question is, how should I structure the models and the views for several multiselect widgets in a treeview?
Here is the code I have so far:
<script type='text/template' id='listtree_bs'>
<div class="listtree">
<ul>
<% _.each(context, function(element, index){ %>
<li>
<span>
<input class="checkbox-listview-master" type="checkbox" value="<%= element.value %>"><%= element.name %><i class="glyphicon glyphicon-chevron-up"></i>
</span>
<ul style="display: none;">
<% _.each(element.items, function(childelement, index){ %>
<li>
<span>
<input class="checkbox-listview-master" type="checkbox" value="<%= childelement.value %>"><%= childelement.name %><i class="glyphicon glyphicon-chevron-up"></i>
</span>
</li>
<% }); %>
</ul>
</li>
<% }); %>
</ul>
</div>
</script>
var ListTreeModel = Backbone.Model.extend({
urlRoot: "/search/multiselect/",
idAttribute:'value',
});
var ListTreeModels = Backbone.Collection.extend({
model: ListTreeModel,
url: "/search/multiselect/",
parse: function (response) {
return response.data;
}
});
var listtreemodels = new ListTreeModels();
listtreemodels.fetch()
var ListTreeView = Backbone.View.extend({
events: {
"treechecked": "treechecked"
},
treechecked: function( e ){
console.log('triggered');
});
var listtreeview = new ListTreeView({el: $('#listtree_bs')});
The response.data from above looks kind of like this (I can easily change the backend though to facilitate the front end)
{
"data": [
{
"other": 0,
"values": [
{
"value": 1,
"key": "type (35513)"
}
],
"value": "type_of_code",
"key": "C Type",
"missing": 275793
},
{
"other": 25273,
"values": [
{
"value": 41,
"key": "United States of America (187293)"
}
],
"value": "primary_country_id",
"key": "Primary Country",
"missing": 3475
},
{
"other": 10958,
"values": [
{
"value": 623,
"key": "company 623 (12602)"
}
],
"value": "controller_id",
"key": "Search by Controller",
"missing": 248288
},
{
"other": 1294,
"values": [
{
"value": 6,
"key": "animal type (247267)"
},
{
"value": 7,
"key": "animal type y (23315)"
}
],
"value": "animal_id",
"key": "Animals",
"missing": 0
},
{
"other": 0,
"values": [
{
"value": 5,
"key": "Inactive (63693)"
},
{
"value": 1,
"key": "Active (825)"
}
],
"value": "current_status_code_table_id",
"key": "Current Status",
"missing": 109101
},
{
"other": 0,
"values": [
{
"value": 0,
"key": "stuff (275058)"
},
{
"value": 1,
"key": "more stuff (39860)"
},
{
"value": 2,
"key": "even more stuff (668)"
}
],
"value": "stuff_indicator",
"key": "Stuff Indicator",
"missing": 0
}
]
}
so right now, models are populated at the data level, but should they be populated at the nested level and manage this with some kind of one to many relationship?
What these multiselects do is fill out a search form that will get sent back to the server when the user hits search. Can I bind the above views to the model even if they are nested?
I'm trying backbone as an experiment here, but is this what it was really designed for? The search results are complicated and are sliced down in dozens of views. I was hoping to use backbone to keep the dom light and nimble. Right now it's getting bogged down in a lot of event call backs and just a lot of html.
Setting up a hierarchy of models is not that difficult : you just have to build your submodels when you parse the data. One way to do it is
var ListTreeModel = Backbone.Model.extend({
urlRoot: "/search/multiselect/",
idAttribute:'value',
constructor: function(data, opts) {
// force the parsing of the data
opts = _.extend({}, opts, {parse: true});
// setup the children collection
this.values = new ListTreeModels();
// call the parent constructor
Backbone.Model.call(this, data, opts);
},
parse: function(data) {
// populate the children
if (_.isArray(data.values))
this.values.set(data.values);
// remove the children from th emodel attributes
return _.omit(data, 'values');
}
});
var ListTreeModels = Backbone.Collection.extend({
model: ListTreeModel,
url: "/search/multiselect/",
parse: function (response) {
return response.data;
}
});
A demo showing the result http://jsfiddle.net/nikoshr/pZU5J/
Once your model structure is up and running, you can render your views (generate the associated HTML) and defined events. Here is a sample way to do it:
var ListTreeView = Backbone.View.extend({
'tagName': 'ul',
render: function () {
var $el = this.$el;
//create a view for each model
this.collection.each(function(model) {
var view = new ListItemView({
model: model
});
$el.append(view.render().el);
});
return this;
}
});
var ListItemView = Backbone.View.extend({
'tagName': 'li',
events: {
'click ': function(e) {
e.stopPropagation(); // avoid triggering an event on the parent level
console.log(this.model.get('value'));
}
},
render: function () {
//render the node
var template = _.template($('#listitem').html());
this.$el.html(template(this.model.toJSON()));
//and add a view for the sub collection
var subview = new ListTreeView({
collection: this.model.values
});
this.$el.append(subview.render().el);
return this;
}
});
with the listitem template defined as
<script type='text/template' id='listitem'>
<span>
<input class="checkbox-listview" type="checkbox" value="<%= value %>"> <%= key %>
</span>
</script>
And a demo http://jsfiddle.net/nikoshr/pZU5J/3/
Hierarchical views can be tricky to render, you probably will have to investigate further on the matter.

Resources