I'm using angular-winjs to display a list. The HTML as well as the controller code is below. When I click the item, the selection is not set. As a result, the watch never gets called.
How can I get the selected item in the selection variable? My code looks similar to this issue, but have the problem still. I'm using the latest WinJS.
<div ng-app="myApp">
<div ng-controller="HomeTilesController">
<div>Selected count: {{selection.length}}, indexes: {{selection}}</div>
<win-list-view item-data-source="homeTiles" selection-mode="'single'" selection="selection">
<win-item-template>
<div class="tile">
<h5 class="win-h5">{{item.data.title}}</</h5>
</div>
</win-item-template>
<win-grid-layout></win-grid-layout>
</win-list-view>
</div>
</div>
HomeTilesController:
angular.module('myApp', ['winjs'])
.controller("HomeTilesController", ['$scope', function ($scope) {
$scope.homeTiles = [
{ title: 'Agents' },
{ title: 'Center' },
{ title: '' },
{ title: '' },
{ title: '' },
{ title: '' }];
$scope.selection = [1];
$scope.$watch('selection', function handleSelectionChange(newValue, oldValue) {
console.log('item selected');
})
}]);
The tiles are displayed correctly as below. You may notice that the Center tile (tile with the blue border) that has been selected as a result of setting the selection. But any other selection still shows the same value - selecting any other item wont set the selection.
The libraries are below:
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="https://cdn.rawgit.com/twbs/bootstrap/v4-dev/dist/js/bootstrap.js"></script>
<script src="~/lib/hammer.js/hammer.js"></script>
<script src="https://code.angularjs.org/tools/system.js"></script>
<script src="https://code.angularjs.org/tools/typescript.js"></script>
<script src="~/lib/angular/angular.min.js"></script>
<script src="https://code.angularjs.org/2.0.0-alpha.44/angular2.dev.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/winjs/4.4.0/css/ui-light.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/winjs/4.4.0/js/base.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/winjs/4.4.0/js/ui.js"></script>
<script src="https://cdn.rawgit.com/winjs/angular-winjs/master/js/angular-winjs.js"></script>
<script src="~/app/my-app.js"></script>
<link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>
<script src="~/js/site.js" asp-append-version="true"></script>
You have to use selection-mode="'single'" tap-behavior="'directSelect'"
var myApp = angular.module("myApp", ['winjs']);
myApp.controller("myCtrl", ['$scope', myCtrl]);
function myCtrl($scope) {
$scope.selection = [];
$scope.homeTiles = [{
title: 'A1'
}, {
title: 'A2'
}, {
title: 'A3'
}, {
title: 'A4'
}, {
title: 'A5'
}, {
title: 'A6'
}];
}
HTML
<div ng-app="myApp">
<div ng-controller="myCtrl">
<div>Selected count: {{selection.length}}, indexes: {{selection.toString()}}</div>
<win-list-view item-data-source="homeTiles" selection="selection" selection-mode="'single'" tap-behavior="'directSelect'" class="listview win-selectionstylefilled">
<win-item-template>This list view item's rating is: {{item.data.rating}}</win-item-template>
<win-list-layout></win-list-layout>
</win-list-view>
</div>
</div>
Working code JSFiddle
WinJS ListView Interaction Examples ( Choose from dropdown )
Related
I can't seem to get the selected item from an input checkbox.
<ul>
<li ng-repeat='shoe in shoebox'>
<input type='checkbox' ng-model='shoe.selected' id='shoe-{{shoe.name}}'>
<label for='shoe-{{shoe.name}}'>{{shoe.name}}</label>
</li>
<button ng-click='whatIsChecked(shoe.selected)'>Apply</button>
</ul>
Then in my controller:
$scope.whatIsChecked = function(selectedThing) {
console.log(selectedThing);
};
The above returns undefined.
The list items are displayed correctly, but the shoe.name or checked item doesn't seem to be stored by the ng-model.
the variable shoe is only valid in ng-repeat block.
If you want to got what is selected, you should try filter.
UPD:
Since you don't have the selected property, you should keep the selected items somewhere else by firing the ng-click event.
refer below code snippet.
angular.module("app", [])
.controller("myCtrl", function($scope) {
$scope.checkedShoes = [];
$scope.shoebox = [{
name: 'shoe1'
},
{
name: 'shoe2'
},
{
name: 'shoe3'
},
{
name: 'shoe4'
}
];
$scope.save = function(e, shoe) {
if (e.target.checked) {
$scope.checkedShoes.push(shoe);
} else {
var index = $scope.checkedShoes.indexOf(shoe);
if( index > -1) {
$scope.checkedShoes.splice(index, 1);
}
}
};
$scope.whatIsChecked = function() {
//var selected = $scope.shoebox.filter(function(item) {
// return item.selected === true;
//});
console.log($scope.checkedShoes);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<div ng-app="app" , ng-controller="myCtrl">
<ul>
<li ng-repeat='shoe in shoebox'>
<input type='checkbox' ng-click="save($event, shoe)" id='shoe-{{shoe.name}}'>
<label for='shoe-{{shoe.name}}'>{{shoe.name}}</label>
</li>
<button ng-click='whatIsChecked()'>Apply</button>
</ul>
</div>
You can get the checked items using a angular.Foreach it becomes easy when you have multiple items checked.
$scope.checkedItems = [];
angular.forEach($scope.shoebox, function(value, key) {
if (value.selected)
$scope.checkedItems.push(value.name);
});
Demo
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.shoebox = [{
name: 'Reboke',
selected: false
}, {
name: 'woodlands',
selected: false
}, {
name: 'Nike',
selected: false
}, {
name: 'Fila',
selected: false
}];
$scope.checkedItems = function() {
$scope.checkedItems = [];
angular.forEach($scope.shoebox, function(value, key) {
if (value.selected)
$scope.checkedItems.push(value.name);
});
}
});
<html>
<head>
<meta charset="utf-8" />
<title>AngularJS </title>
<link rel="stylesheet" href="style.css" />
<script src="https://code.angularjs.org/1.4.7/angular.js"></script>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<ul>
<li ng-repeat='shoe in shoebox'>
<input type='checkbox' ng-model='shoe.selected' id='shoe-{{shoe.name}}'>
<label for='shoe-{{shoe.name}}'>{{shoe.name}}</label>
</li>
<button ng-click='checkedItems()'>Apply</button>
Checked items are: {{checkedItems}}
</ul>
</body>
</html>
I have the following checkboxes generated with AngularJS on my html page:
<div ng-controller="MirrorCheckboxController">
<div ng-repeat="setting in settings">
<input type="checkbox"
ng-attr-id="{{ setting.id }}"
ng-model="checkedElements[setting.id]"
ng-click="callSaveFunction(setting.id)">
<label ng-attr-for="{{ setting.id }}">
<span class="checkbox">{{setting.name}}</span>
</label>
</div>
</div>
<div ng-show="showEvents(checkedElements)" id="events">
...show something
</div>
If the last checkbox (Weather) is checked, the DIV with the ID "events" should be shown. This actually already works fine, I just have the problem that if I load the page and Weather is already true from the storage, the "DIV" events container doesn't show up. So I would need something to check that when loading the page and that works fine and doesn't get in the way of ng-show
My controller is:
exampleApp.controller('MirrorCheckboxController', ['$scope', function($scope) {
$scope.checkedElements = {};
$scope.settings = [{
name: 'Weather',
value: '',
id: 'mirror-1'
}, {
name: 'Date and Clock',
value: '',
id: 'mirror-2'
}, {
name: 'Traffic Situation',
value: '',
id: 'mirror-3'
}, {
name: 'Personal Calendar',
value: '',
id: 'mirror-4'
}];
// the method to display or hide the event container
$scope.showEvents = function(obj) {
return (obj['mirror-4']);
};
}]);
The storage works fine as well and the checkbox is also checked onload. Is there a possibility to use something else at the same time as ng-show just to catch that case when loading the page? I'm struggling with that for a while and tried some JQuery solutions, but nothing worked.
edit:
<script type="text/javascript">
// wait until bus service is available
window.name = 'NG_DEFER_BOOTSTRAP!';
window["Client"] = {
SID: "{{SID}}",
throwErrorOnBootFailure: true,
readyCallback: function () {
(function() {
$(document).ready(function() {
angular.resumeBootstrap([]);
});
})();
//load current checkbox states from the storage API while loading
loadMirror_WeatherEnabler();
}
};
</script>
<!-- Model API dependencies -->
<script type="text/javascript" src="/hcc/jquery-2.1.0.min.js"></script>
<script type="text/javascript" src="/bus/ModelAPICommunicationObject.js"></script>
<script type="text/javascript" src="/bus/ModelAPI.js"></script>
<script type="text/javascript" src="/bus/ModelAPIWebsocketClientFactory.js"></script>
<script type="text/javascript" src="/bus/bus-client-bootstrap.js"></script>
I have a Kendo model instance (person for this example) and watching it is modified or not by using dirty property.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Kendo + Angular</title>
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.714/styles/kendo.common.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.714/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.714/styles/kendo.default.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.714/styles/kendo.mobile.all.min.css">
<script src="http://code.jquery.com/jquery-1.12.3.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2016.2.714/js/angular.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2016.2.714/js/jszip.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2016.2.714/js/kendo.all.min.js"></script>
</head>
<body>
<div ng-app="app" ng-controller="MainCtrl">
<div>Person name: {{ person.name }}</div>
<input type="text" name="name" ng-model="person.name"> <!-- This input don't work -->
<button ng-click="foo()">Foo</button> <!-- This button work because I call person.set method manually -->
<div>This person is modified? {{ person.dirty }}</div>
</div>
<script>
var Person = kendo.data.Model.define({
id: "personId", // the identifier of the model
fields: {
"name": {
type: "string"
},
"age": {
type: "number"
}
}
});
angular.module("app", ["kendo.directives"])
.controller("MainCtrl", function ($scope) {
$scope.person = new Person({
name: "John Doe",
age: 42
});
$scope.foo = function () {
$scope.person.set('name', "Kendo");
}
});
</script>
</body>
</html>
But when I type to text box dirty don't change because Angular ngModel doesn't fire Kendo "change" event. My real app have dozens of models like this, so is there any way to fix this automatically???
Thanks.
You can write a directive to replace for ng-model,
<input type="text" name="name" k-bind-model="person.name">
angular.module('app')
.directive("kBindModel", ["$parse", function ($parse) {
return {
restrict: "A",
scope: false,
link: function (scope, element, attributes, controller) {
var key = null;
var strs = attributes.kBindModel.split('.');
if (strs && strs.length > 1) {
key = strs[1];
}
var model = scope[strs[0]];
element.change(function () {
scope.$apply(function () {
model.set(key, element.val());
});
});
scope.$watch(attributes.kBindModel, function (n, o) {
element.val(n);
});
}
}
}]);
I have a list of options pulled from the database via json based on product selection in angular.js
Here's a sample code:
<ion-checkbox ng-repeat="extra in extras" ng-model="order.extras" checklist-value="{{ extra.id }}"><strong>{{ extra.name }}</strong></ion-checkbox>
I want a user to be able to select multiple extras but can't seem to be able to bind these selections.
I think it could work with ng-model="order.extras[extra.id]" then you can track the checked extras in order.extras.
Please have a look at the demo below or at this jsfiddle.
angular.module('demoApp', ['ionic'])
.controller('mainController', mainController);
function mainController($scope) {
$scope.order = {};
$scope.extras = [
{
id: 0,
name: 'first'
},
{
id: 1,
name: 'second'
},
{
id: 2,
name: 'third'
}
]
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/ionic/1.2.4/css/ionic.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ionic/1.2.4/js/ionic-angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ionic/1.2.4/js/ionic.bundle.js"></script>
<div ng-app="demoApp" ng-controller="mainController">
<ion-content>
<ion-checkbox ng-repeat="extra in extras" ng-model="order.extras[extra.id]" checklist-value="{{ extra.id }}"><strong>{{ extra.name }}</strong></ion-checkbox>
current order: {{order}}
</ion-content>
</div>
I want to write treeview using angularjs. I am using ng-include for recursive call..everything is fine except from ng-click..when each node is clicked..the hierarchy call is from child to it's parents and for every node in this hierarchy the ng-click fires. how can i solve this problem??..I have this exact problem using another approach (appending element on post-link which I think is not a good way) instead of ng-include.here is my code:
index.html:
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0-rc.0/angular.min.js"></script>
</head>
<body >
<div ng-app="app" ng-controller='AppCtrl'>
<ul>
<li ng-repeat="category in categories" ng-click='nodeSelected(category)' ng-include="'template.html'"></li>
</ul>
</div>
<script src="controller.js"></script>
</body>
</html>
template.html:
{{ category.title }}
<ul ng-if="category.categories">
<li ng-repeat="category in category.categories" ng-click='nodeSelected(category)' ng-include="'template.html'">{{ category.title }}</li>
</ul>
controller.js
var app = angular.module('app', []);
app.controller('AppCtrl', function ($scope) {
$scope.nodeSelected = function(category){
alert('This node is selected' + category.title);
}
$scope.categories = [
{
title: 'Computers',
categories: [
{
title: 'Laptops',
categories: [
{
title: 'Ultrabooks'
},
{
title: 'Macbooks',
categories:[
{
title:'Paridokht'
},
{
title:'Shahnaz',
categories:[
{
title:'Sohrab'
}
]
}
]
}
]
},
{
title: 'Desktops'
},
{
title: 'Tablets',
categories: [
{
title: 'Apple'
},
{
title: 'Android'
}
]
}
]
},
{
title: 'Printers'
}
];
});
here is the output picture:
for example when paridokht node is selected, the alert hierarchy in order is paridokht,macbooks,laptops,computers (from child to parents). please help me to solve this issue. it's killing me! :(
Try stopping event from bubble-ing up in the DOM tree.
In you ng-click:
ng-click='nodeSelected($event, category)'
In your controller:
$scope.nodeSelected = function($event, category){
$event.stopPropagation();
alert('This node is selected' + category.title);
}