I'm having troubles getting the kendo.binding working for a nested array. First level list rendering correct but second has some troubles.
Working fiddle
Html:
<script id="ul-template" type="text/x-kendo-template">
<h3>#=NAME#</h3>
<ul data-template="il-template" data-bind="source: ad">
</ul>
</script>
<script id="il-template" type="text/x-kendo-template">
<li> #=ATT_NAME#</li>
</script>
Javascript:
var model = {items: [
{ NAME: "Group 1", ID: 1, ad: [{ ATT_NAME: "Attribute 1" }, { ATT_NAME: "Attribute 2" }] },
{ NAME: "Group 2", ID: 2, ad: [{ ATT_NAME: "Attribute 3" }, { ATT_NAME: "Attribute 4" }] },
{ NAME: "Group 3", ID: 3, ad: [{ ATT_NAME: "Attribute 5" }, { ATT_NAME: "Attribute 6" }] },
{ NAME: "Group 4", ID: 3, ad: [{ ATT_NAME: "Attribute 7" }, { ATT_NAME: "Attribute 8" }] }]};
kendo.bind($('#view'), model);
Result:
<div id="view">
<div data-template="ul-template" data-bind="source: items">
<h3>Group 1</h3>
<ul data-template="il-template" data-bind="source: ad">
<li> Attribute 3</li>
<li> Attribute 4</li>
</ul>
<h3>Group 2</h3>
<ul data-template="il-template" data-bind="source: ad">
<li> Attribute 7</li>
<li> Attribute 8</li>
</ul>
<h3>Group 3</h3>
<ul data-template="il-template" data-bind="source: ad">
</ul>
<h3>Group 4</h3>
<ul data-template="il-template" data-bind="source: ad">
</ul>
</div>
Related
I've been doing a thinkster tutorial on combining rails and angular. I've been doing it steadily, but have been halted by an issue with the ui.router. The moment I place ['ui.router'] into my angular module it messes up my page. Any help would be greatly appreciated.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>My Angular App!</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.js"></script>
<script src="js/vendor/angular.min.js"></script>
<script src="js/app.js"></script>
</head>
<body ng-app="flapperNews" ng-controller="MainCtrl">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="page-header">
<h1>Flapper News</h1>
</div>
<div ng-repeat="post in posts | orderBy: '-upvotes'">
<span class="glyphicon glyphicon-thumbs-up" ng-click="incrementUpvotes(post)">^</span>
{{ post.upvotes }}
<span style="font-size:20px; margin-left:10px;">
<a ng-show="post.link" href="{{post.link}}">
{{ post.title}}
</a>
<span ng-hide="post.link">
{{ post.title }}
</span>
</div>
<form ng-submit="addPost()" style="margin-top:30px">
<h3>Add a new post</h3>
<div class="form-group">
<input type="text" placeholder="Title" ng-model="title"></input>
<input type="text" placeholder="Link" ng-model="link"></input>
</div>
<button type="submit">Post</button>
</form>
</div>
</div>
</body>
</html>
angular.module('flapperNews', ['ui.router'])
.factory("posts", [function(){
var o = {
posts: []
};
return o;
}])
.controller('MainCtrl', [
'$scope',
"posts",
function($scope, posts){
$scope.test = 'Hello world!';
$scope.posts = posts.posts;
$scope.posts = [
{title: "post 1", upvotes: 5},
{title: "post 2", upvotes: 2},
{title: "post 3", upvotes: 15},
{title: "post 4", upvotes: 9},
{title: "post 5", upvotes: 4}
];
$scope.addPost = function(){
if(!$scope.title || $scope.title === "") {return; }
$scope.posts.push({
title: $scope.title,
link: $scope.link,
upvotes: 0
});
$scope.title = "";
$scope.link = "";
};
$scope.incrementUpvotes = function(post) {
post.upvotes += 1;
};
}]);
My guess is, that you already have the module flapperNews declared, and you are loosing the dependencies that where previously added. Check if elswehere (maybe in app.js) you have another code like this:
angular.module('flapperNews', [/** other deps**/]);
If you have it, just add ui.router to that module declaration.
Remember that if you pass a second parameter to angular.module, you will declare/redeclare that module. If you only pass the first parameter, the method will act as a getter and retreive the module.
I want to use autocomplete and popover in one input tag.
But autocomplete can't display , I see google chrome developer tools, autocomplete is work, just can't display . I don't know how to do .
HTML code
<span class="form-labelTitle img-searchForm02">place</span>
<input class="auto-input" placeholder="city" data-toggle="popover" data-placement="bottom">
<div class="leave-btn"></div>
<div class="autocomplete-div auto1"></div>
<div id="popover-content" class="hide">
<div role="tabpanel">
<ul class="nav nav-tabs arrival-tabs" role="tablist" id="myTab">
<li class="active" role="presentation" ><a href='#JPN' role='tab' data-toggle='tab'>japan</a></li>
<li role="presentation" ><a href='#TPE' role='tab' data-toggle='tab'>taiwan</a></li>
</ul>
<div class="tab-content">
<div class='tab-pane active city' id='JPN'>
<span>Tokyo</span>
<span>okinawa</span>
</div>
<div class='tab-pane' id='TPE'>
<span>taipei</span>
</div>
JS code
$(function(){
$('.auto-input').popover({
'html': true,
'content': function () {
return $('#popover-content').html();
}
});
$('.auto-input').autocomplete({
open:function(event, ui){
$(this).popover('hide');
},
source: [
"tokyo",
"okinawa",
"taipei
],
appendTo:($('.auto1')),
});
});
I'm having issues with a jquery mobile listview when I add the items through jquery code.
If I add the following < ul > to the page and let the "normal" page processing happen, my list appears correctly with expandable sub lists, etc.
<ul data-role="listview" id="Ul2" class="ui-listview-outer ui-listview ui-listview-inset ui-corner-all ui-shadow" data-inset="true">
<li data-role="collapsible" data-iconpos="right" data-shadow="false" data-corners="false" data-icon="plus">
<h2 vid="CA175191-FA4D-4F2A-AAA7-2898971AB0F4">Parent 1</h2>
<ul data-role="listview" data-shadow="false" data-inset="true" data-corners="false">
<li data-role="collapsible" data-iconpos="right" data-shadow="false" data-corners="false">
<h2 vid="65E74F52-54E6-4A84-B4AC-F24E638FE559">Sub 1</h2>
<ul data-role="listview" data-shadow="false" data-inset="true" data-corners="false">
<li>Child</li>
<li>Child</li>
<li>Child</li>
<li>Child</li>
</ul>
</li>
<li data-role="collapsible" data-iconpos="right" data-shadow="false" data-corners="false">
<h2 vid="86628CD0-87BD-4649-8899-1029AD38DD9C">Sub 2</h2>
<ul data-role="listview" data-shadow="false" data-inset="true" data-corners="false">
<li>Child</li>
<li>Child</li>
<li>Child</li>
<li>Child</li>
</ul>
</li>
<li data-role="collapsible" data-iconpos="right" data-shadow="false" data-corners="false">
<h2 vid="12C6A457-EEA1-47A0-A63D-3222DF3069F2">Sub 2</h2>
<ul data-role="listview" data-shadow="false" data-inset="true" data-corners="false">
<li>Child</li>
<li>Child</li>
<li>Child</li>
<li>Child</li>
</ul>
</li>
</ul>
</li>
<li data-iconpos="right" data-shadow="false" data-corners="false" data-icon="plus">
<h2 vid="864FCB4E-98A1-4C0C-9421-E89F5C5423A6">Parent 2</h2>
</li>
</ul>
But, if I add the same code in dynamically
var myData = '<li>' + ........ + '</li>';
$('ul').append(myData);
and then run
$('ul').listview("refresh")
The list behaves differently.
The list physically displays differently on the page
When clicking on the "Parent 1", rather than expanding to show "Sub 1", it redirects the page to show a list with "Sub 1" as a header to the list, and 4 empty list items.
I'm confused as to what to try next. Is there ANOTHER step I should take to refresh my list. OR have I added some incorrect classes to the elements.
Here is the JSON I'm trying to display in the lists and sub lists, it's a bit cut-down so there are probably extra square brackets that appear not to be necessary - It starts as XML and is converted to JSON from the server-side before being returned to the client :
{
"parents":
{
"parent":
[{
"parName": "Parent 1", "parID": "CA175191-FA4D-4F2A-AAA7-2898971AB0F4",
"subs":
{
"sub":
[{
"group_Name": "Sub 1", "group_ID": "65E74F52-54E6-4A84-B4AC-F24E638FE559",
"children":
{
"child":
[
{ "vID": "367806EA-493F-45BB-BAC9-DF11E946E21A", "dispName": "Child 1" },
{ "vID": "4DE698E0-E395-4FF9-9F74-E8679B992AED", "dispName": "Child 2" },
{ "vID": "747EF952-C565-41C6-AF96-B7192AD3599A", "dispName": "Child 3" },
{ "vID": "5BDD8BD5-27E3-4E71-9C02-7E41CADF327E", "dispName": "Child 4" }
]
}
}]
}
}]
}
}
Thanks
So it turns out that upgrading my JQM version to 1.4.5 and using .enhanceWithin() on the parent div rather than using .listview("refresh") solved my issue.
Thanks #Omar for pointing me in the right direction.
I'm trying to recreate the following erb template in angularjs using ngResource, but can't seem to figure out how to access the event.spikes (it's a has_many relationship).
The erb file I want to change:
<div class='event-list'>
<ul>
<% #events.each do |event| %>
<li><%= event.name %> || <small><%= event.date %></small>
<ul>
<% event.spikes.each do |spike| %>
<li>Time of Spike: <%= spike.date_time %> || Spike Velocity: <%= spike.peak_velocity %></li>
<% end %>
</ul>
</li>
<% end %>
</ul>
</div>
The half finished .html without erb:
<div class='event-list' ng-controller='EventsCtrl'>
<ul>
<li ng-repeat='event in events'>
{{ event.name }} || <small>{{ event.date }}</small>
<ul>
<<<<<SOMETHING GOES HERE???>>>>>>>>
</ul>
</li>
</ul>
</div>
Here's my service, app/assets/javascripts/angular/controllers/event.js:
App.factory('Event', ['$resource', function($resource) {
return $resource('/events/:id', { id: '#id' });
}]);
My angular controller, app/assets/javascripts/angular/controllers/events.ctrl.js:
App.controller('EventsCtrl', ['$scope', 'Event', function($scope, Event) {
$scope.events = Event.query();
}]);
And where my angular app is defined, app/assets/javascripts/app.js:
window.App = angular.module('sportsSpike', ['ngResource']);
You can nest in Angular like this
<li ng-repeat='event in events'>
{{ event.name }} || <small>{{ event.date }}</small>
<ul>
<li ng-repeat='spike in event.spikes'>
{{ spike.some_output_value }}
</li>
</ul>
</li>
You will, however need to ensure that the way you are passing the data to angular has already resolved the spike property of events.
Hope this helps
Following the answer from muttonlamb here it is a complete HTML file. As explained before you can easily nest ng-repeat with AngularJS and new child isolated scopes will be created.
You can see full code below or plunker here (http://plnkr.co/edit/jRG4xcRIab8sgHJFffWV)
P.S.: I am not using any ngResource just for simplicity as I am fetching the data via an array, but the ng-repeat code will work either way.
<!doctype html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>Events</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script>
'use strict';
var myApp = angular.module('myApp',[]);
myApp.events = [
{
name: 'Event 1',
date: '01/02/2013',
spikes: [
{
date_time : '1288323623006',
peak_velocity: '10m/s'
},
{
date_time : '1288323623004',
peak_velocity: '20m/s'
},
{
date_time : '1288323623003',
peak_velocity: '10m/s'
},
{
date_time : '1288323623001',
peak_velocity: '20m/s'
}
]
},
{
name: 'Event 2',
date: '05/03/2013',
spikes: [
{
date_time : '1288323623003',
peak_velocity: '40m/s'
},
{
date_time : '1288323623002',
peak_velocity: '50m/s'
},
{
date_time : '1288323623007',
peak_velocity: '80m/s'
},
{
date_time : '1288323623001',
peak_velocity: '60m/s'
}
]
},
{
name: 'Event 2',
date: '05/03/2013',
spikes: [
{
date_time : '1288323623005',
peak_velocity: '40m/s'
},
{
date_time : '1288323623009',
peak_velocity: '50m/s'
},
{
date_time : '1288323623003',
peak_velocity: '80m/s'
},
{
date_time : '1288323623002',
peak_velocity: '60m/s'
}
]
}
];
myApp.controller('EventsCtrl', ['$scope', 'Event', function($scope, Event) {
$scope.events = Event.query();
}]);
myApp.factory('Event', function() {
return {
query: function() {
return myApp.events;
}
}
});
</script>
</head>
<body>
<div class='event-list' ng-controller='EventsCtrl'>
<ul>
<li ng-repeat='event in events'>
<h3>{{ event.name }} || {{ event.date }}</h3>
<ul>
<li ng-repeat='spike in event.spikes'>
Time of Spike: {{ spike.date_time | date : 'short' }} || Spike Velocity: {{ spike.peak_velocity }}
</li>
</ul>
</li>
</ul>
</div>
</body>
</html>
I changed the approch, now, I get selected radio value correctly.
Issue: One of my radio is selected when initialize (first load then user can change the selection), but radio is not selected first time, how to initialize "Selected" appropriately?
#model Demo.Web.ViewModels.HomeViewModel
#{
ViewBag.Title = "Two Page";
}
#using (Html.BeginForm("Index", "Two", FormMethod.Post, new Dictionary<string, object> { { "data-bind", "submit:onSubmit" } }))
{
<table>
<tr>
<td>
<div data-bind="foreach: items">
<input type="radio" name="items" data-bind="attr: { value: id }, checked: $root.selected" />
<span data-bind="text: name"></span>
</div>
<div data-bind="text: selected">
</div>
</td>
</tr>
</table>
<input type="submit" name="send" value="Send" />
}
<script type="text/javascript">
var viewModel = {
items: [
{ "id": 1, "name": "one", "selected": false },
{ "id": 2, "name": "two", "selected": true },
{ "id": 3, "name": "three", "selected": false }
],
selected: ko.observable(),
onSubmit: function(){
var x = this.selected();
}
};
$(function() {
ko.applyBindings(viewModel);
});
When bound against inputs of type radio, the checked binding in Knockout tries to write the input's value to whatever value is bound against. The idea is that you all of the radios are bound against the same observable.
Something like:
var viewModel = {
items: [
{ id: 1, name: "one" },
{ id: 2, name: "two" },
{ id: 3, name: "three" }
],
selected: ko.observable()
};
Bound against a UI like:
<div data-bind="foreach: items">
<input type="radio" name="items" data-bind="attr: { value: id }, checked: $root.selected" />
<span data-bind="text: name"></span>
</div>
<div data-bind="text: selected"></div>
Sample: http://jsfiddle.net/rniemeyer/BbX4S/
So, in your case, you should be able to bind your radios against $root.IsSelected and use it rather than looping through the items.
When you initialize it, you might want to look to see if any button is checked, and then populate the root level IsSelected appropriately.