Deselect a selected row in ng-repeat - angularjs

How do I deselect a row that I have just selected using the same button that I have used to select and highlight the row from an ng-repeat list? What different options are there, does anyone have any examples or links as I can't find any?
EDIT:-
Please see Plunker using link
https://plnkr.co/edit/LYrmpLUwGaWx8wLeCOoT
code is here:-
html
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.12/angular.js" data-semver="1.4.9"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<div ng-repeat="item in items" ng-class="{sel: item.Item == selected}">
<label>Item No. {{item.Item}}</lablel> |
<label>{{item.Description}}</label> |
<button ng-click="onClick(item.Item);" class="btn btn-primary">
{{item.Item == selected ? 'Hide' : 'Show'}}
</button>
</div>
<br />
<br />
<div ng-switch="moduleState">
<div ng-switch-when="details">
These are your details:-
Item {{selected}} is selected
</div>
</body>
</html>
app.js
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.items = [
{
Item: 1,
Description: 'This is item 1'
},
{
Item: 2,
Description: 'This is item 2'
},
{
Item: 3,
Description: 'This is item 3'
}
];
$scope.onClick = function (item) {
$scope.selected = item;
$scope.moduleState = 'details';
};
});
Once one of the buttons is selected how do I deselect it again?

$scope.onClick = function(item) {
if ($scope.selected === item) {
$scope.selected = null;
}
else {
$scope.selected = item;
}
};
And in the view:
<div ng-repeat="item in items" ng-class="{sel: item.Item == selected}">
<label>Item No. {{item.Item}}</lablel> |
<label>{{item.Description}}</label> |
<button ng-click="onClick(item.Item);" class="btn btn-primary">
{{item.Item == selected ? 'Hide' : 'Show'}}
</button>
</div>
<br />
<br />
<div ng-if="selected">
These are your details:-
Item {{ selected }} is selected
</div>

Check the plunkr below:
https://plnkr.co/edit/u7I9nIRZgOMB7vqBr92n?p=preview
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.items = [
{
Item: 1,
isVisible: false,
Description: 'This is item 1'
},
{
Item: 2,
isVisible: false,
Description: 'This is item 2'
},
{
Item: 3,
isVisible: false,
Description: 'This is item 3'
}
];
$scope.onClick = function (item) {
if(!item.isVisible) {
item.isVisible = !item.isVisible;
$scope.selected = item.Item;
$scope.moduleState = 'details';
} else {
item.isVisible = !item.isVisible;
$scope.selected = $scope.moduleState = "";
}
};
});
<button ng-click="onClick(item);" class="btn btn-primary">
{{item.Item == selected ? 'Hide' : 'Show'}}
</button>
Basically what i did is:
Added a flag "isVisible" for each row
Toggled the flag when its set to visible
on second click, if its visible, hide it.

Related

is data a reserved keyword in angularjs?

The code below doesn't work if I use data in lst, it works, if I replace data with x, so is data a reserved keyword in AngularJS and why?
<script src="http://ajadata.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body ng-app='app1'>
<div id='Grocery' ng-controller='Grocery'>
<h3>Grocery List</h3>
<div ng-repeat='data in lst'>
<h4>{{data.item}}</h4>
</div>
<br>
<p> enter item:
<input type="text" ng-model='addItem' />
</p>
<button ng-click='addTolist(addItem)'>Add to list</button>
<button ng-click='addTolist(addItem)'>Add to list</button>
<h2>{{NoItemError}}</h2>
</div>
<!-- End of Grocery -->
<script>
var app1 = angular.module('app1', []);
app1.controller('Grocery', function($scope) {
$scope.lst = [{
item: 'banana',
needed: false
},
{
item: 'apple',
needed: false
},
{
item: 'milk',
needed: false
},
{
item: 'tomato',
needed: false
},
{
item: 'juice',
needed: false
}
]
$scope.addTolist = function(addItem) {
if (!(addItem === undefined || addItem === '')) {
$scope.lst.push({
item: addItem,
needed: false
});
$scope.NoItemError = '';
} else {
$scope.NoItemError = 'Please enter an item';
}
}
});
</script>
</body>
While replacing text with another, you broke your CDN URL for the AngularJS script.
It became http://ajadata.googleapis.com
Change it to http://ajax.googleapis.com
Here is a full script:
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
And here is a working example of your code:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body ng-app='app1'>
<div id='Grocery' ng-controller='Grocery'>
<h3>Grocery List</h3>
<div ng-repeat='data in lst'>
<h4>{{data.item}}</h4>
</div>
<br>
<p> enter item:
<input type="text" ng-model='addItem' />
</p>
<button ng-click='addTolist(addItem)'>Add to list</button>
<button ng-click='addTolist(addItem)'>Add to list</button>
<h2>{{NoItemError}}</h2>
</div>
<!-- End of Grocery -->
<script>
var app1 = angular.module('app1', []);
app1.controller('Grocery', function($scope) {
$scope.lst = [{
item: 'banana',
needed: false
},
{
item: 'apple',
needed: false
},
{
item: 'milk',
needed: false
},
{
item: 'tomato',
needed: false
},
{
item: 'juice',
needed: false
}
]
$scope.addTolist = function(addItem) {
if (!(addItem === undefined || addItem === '')) {
$scope.lst.push({
item: addItem,
needed: false
});
$scope.NoItemError = '';
} else {
$scope.NoItemError = 'Please enter an item';
}
}
});
</script>
</body>
Most reserved words in AngularJS start with $, for example $index or $id, etc.

How to make expand and collapse manually child wise in angularjs

I have an accordion expand is working fine but collapse is not working,it should work like accordion,for ex when I click 'title 2' its content should expand and 'title 1' content should collapse.below is my code,I am new to angularjs.Anyone can help me.If its in jquery also fine.
HTML
<link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.css'>
<body ng-app="app">
<h1>Dynamic accordion: nested lists with html markup</h1>
<div ng-controller="AccordionDemoCtrl">
<div>
<div ng-repeat="group in groups">
<div class="parents" ng-click="item=1"><i class="glyphicon-plus"></i> {{ group.title }}
</div>
{{ group.content }}
<ul class="childs" ng-show="item==1">
<li ng-repeat="item in group.list">
<span ng-bind-html="item"></span>
</li>
</ul>
</div>
</div>
</div>
</body>
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.1/angular.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular-filter/0.5.4/angular-filter.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.1/angular-sanitize.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap-tpls.js'></script>
<script src="js/index.js"></script>
index.js
angular.module('app', ['ui.bootstrap','ngSanitize','angular.filter']);
angular.module('app').controller('AccordionDemoCtrl', function ($scope) {
$scope.oneAtATime = true;
$scope.groups = [
{
title: 'title 1',
isOpen: true,
list: ['<i>item1a</i> blah blah',
'item2a',
'item3a']
},
{
title: 'title 2',
list: ['item1b',
'<b>item2b </b> blah ',
'item3b']
},
{
title: 'title 3',
},
{
title: 'title 4',
},
{
title: 'title 5',
}
];
});
I suggest you those functions :
$scope.open = function (index) {
$scope.groups[index].isOpen = !$scope.groups[index].isOpen;
$scope.closeOthers(index);
}
$scope.closeOthers = function (index) {
for(var i = 0; i < $scope.groups.length; i++) {
if (i !== index)
$scope.groups[i].isOpen = false;
}
}
open is fired when clicking on a parent, closeOthers is called in open. I init a visible boolean to parents. Each time user clicks on a parent, it set visible to true, and others to false.
<div ng-controller="AccordionDemoCtrl">
<div>
<div ng-repeat="group in groups track by $index">
<div class="parents" ng-click="open($index)"><i ng-class="{'glyphicon-minus': group.isOpen, 'glyphicon-plus': !group.isOpen}"></i> {{ group.title }}
</div>
{{ group.content }}
<ul class="childs" ng-show="group.isOpen">
<li ng-repeat="item in group.list">
<span ng-bind-html="item"></span>
</li>
</ul>
</div>
</div>
</div>
Working demo

AngularJS app connectivity with Mongodb using NodeJS

This is my AngularJS app. It is working alright and taking data from an array in a controller using ng-repeat, but now I want to connect it with Mongodb using NodeJS so that it fetches data from Mongodb collection. Also, when I edit, update or delete any row, it should reflect that in Mongodb.
My AngularJS index.html
var app = angular.module("app", ["xeditable", "ngMockE2E"]);
app.service('filteredListService', function() {
this.searched = function(valLists, toSearch) {
return _.filter(valLists,
function(i) {
/* Search Text in all 3 fields */
return searchUtil(i, toSearch);
});
};
this.paged = function(valLists, pageSize) {
retVal = [];
for (var i = 0; i < valLists.length; i++) {
if (i % pageSize === 0) {
retVal[Math.floor(i / pageSize)] = [valLists[i]];
} else {
retVal[Math.floor(i / pageSize)].push(valLists[i]);
}
}
return retVal;
};
});
app.run(function(editableOptions) {
editableOptions.theme = 'bs3';
});
app.controller('Ctrl', function($scope, $filter, filteredListService) {
$scope.users = [{
id: 1,
name: 'harry potter',
lName: "Pege",
passw1: "12/12/2012",
pages: "556"
},
{
id: 2,
name: 'narnia',
lName: "Pim",
passw1: "12/12/2012",
pages: "557"
},
{
id: 3,
name: 'panchtantra',
lName: "Smith",
passw1: "1/03/2009",
pages: "556"
},
{
id: 4,
name: 'atlas',
lName: "Jones",
passw1: "2/04/1995",
pages: "888"
},
{
id: 5,
name: 'science',
lName: "Doe",
passw1: "2/04/1995",
pages: "888"
},
{
id: 6,
name: 'guiness book',
lName: "Pan",
passw1: "2/04/1995",
pages: "888"
},
{
id: 7,
name: 'panchtantra1',
lName: "Smith",
passw1: "1/03/2009",
pages: "556"
},
{
id: 8,
name: 'atlas1',
lName: "Jones",
passw1: "2/04/1995",
pages: "888"
},
{
id: 9,
name: 'science1',
lName: "Doe",
passw1: "2/04/1995",
pages: "888"
},
{
id: 10,
name: 'guiness book1',
lName: "Pan",
passw1: "2/04/1995",
pages: "888"
},
];
$scope.checkName = function(data, id) {
if (id === 2 && data !== 'narnia') {
return "Username 2 should be `narnia(case sensitive)`";
}
};
$scope.saveUser = function(data, id) {
//$scope.user not updated yet
angular.extend(data, {
id: id
});
return $http.post('/saveUser', data);
};
// remove user
$scope.removeUser = function(index) {
var index1 = index + $scope.currentPage * 4;
$scope.users.splice(index1, 1);
$scope.pagination();
};
// add user
$scope.addUser = function($event) {
$scope.currentPage = 2;
$scope.id = $scope.users.length + 1
$scope.users.push({
id: this.id,
name: 'Enter Book Name',
lName: 'Author Name',
passw1: 'Date of Publish',
pages: 'Pages'
});
$scope.pagination();
alert(users.id);
$scope.resetAll();
}
//search
$scope.pageSize = 4;
$scope.allItems = $scope.users;
$scope.reverse = false;
$scope.resetAll = function() {
$scope.filteredList = $scope.allItems;
$scope.newEmpId = '';
$scope.newName = '';
$scope.newEmail = '';
$scope.searchText = '';
$scope.currentPage = 0;
$scope.Header = ['', '', ''];
}
//pagination
$scope.pagination = function() {
$scope.ItemsByPage = filteredListService.paged($scope.filteredList, $scope.pageSize);
};
$scope.setPage = function() {
$scope.currentPage = this.n;
};
$scope.firstPage = function() {
$scope.currentPage = 0;
};
$scope.lastPage = function() {
$scope.currentPage = $scope.ItemsByPage.length - 1;
};
$scope.range = function(input, total) {
var ret = [];
if (!total) {
total = input;
input = 0;
}
for (var i = input; i < total; i++) {
if (i != 0 && i != total - 1) {
ret.push(i);
}
}
return ret;
};
$scope.sort = function(sortBy) {
$scope.resetAll();
$scope.pagination();
};
$scope.sort('name');
$scope.search = function() {
$scope.filteredList =
filteredListService.searched($scope.allItems, $scope.searchText);
if ($scope.searchText == '') {
$scope.filteredList = $scope.allItems;
}
$scope.pagination();
}
$scope.resetAll();
});
function searchUtil(x, toSearch) {
/* Search Text in all 3 fields */
return (x.name.toLowerCase().indexOf(toSearch.toLowerCase()) > -1 || x.lName.toLowerCase().indexOf(toSearch.toLowerCase()) > -1 || x.id == toSearch) ?
true : false;
}
<html>
<head>
<style type="text/css">#charset "UTF-8";[ng\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide:not(.ng-hide-animate){display:none !important;}ng\:form{display:block;}.ng-animate-shim{visibility:hidden;}.ng-anchor{position:absolute;}</style>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="robots" content="noindex, nofollow">
<meta name="googlebot" content="noindex, nofollow">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="text/javascript" src="/js/lib/dummy.js"></script>
<script type="text/javascript" src="https://underscorejs.org/underscore.js"></script>
<link rel="stylesheet" type="text/css" href="/css/result-light.css">
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-sanitize.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script type="text/javascript" src="https://vitalets.github.io/angular-xeditable/dist/js/xeditable.js"></script>
<link rel="stylesheet" type="text/css" href="https://vitalets.github.io/angular-xeditable/dist/css/xeditable.css">
<script type="text/javascript" src="https://code.angularjs.org/1.5.8/angular-mocks.js"></script>
<link rel="stylesheet" type="text/css" href="https://netdna.bootstrapcdn.com/bootstrap/3.1.0/css/bootstrap.min.css"/>
<style type="text/css">
div[ng-app] {
margin: 10px;
}
.table {width: 100%
}
form[editable-form] > div {margin: 100px 0;}
</style>
</head>
<body>
<h4>Book management</h4>
<div ng-app="app" ng-controller="Ctrl">
<div class="input-group">
<input class="form-control" ng-model="searchText" placeholder="Search" type="search" ng-change="search()" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-search"></span>
</span>
</div>
<br>
<br>
<table class="table table-bordered table-hover table-condensed" id="myTable">
<tr style="font-weight: bold">
<td style="width:5%">id</td>
<td style="width:15%">Book Name</td>
<td style="width:15%">Author Name</td>
<td style="width:15%">No Of Page</td>
<td style=width:30%>Date</td>
<td style="width:25%">Edit</td>
</tr>
<tr ng-repeat="x in ItemsByPage[currentPage] | orderBy:columnToOrder:reverse">
<td>{{x.id}}</td>
<td>
<!-- editable username (text with validation) -->
<span editable-text="x.name" e-name="name" e-form="rowform" onbeforesave="checkName($data, x.id)" e-required>
{{ x.name || 'empty' }}
</span>
</td>
<td>
<!-- editable status (select-local) -->
<span editable-text="x.lName" e-name="lName" e-form="rowform">
{{ x.lName || 'empty' }}
</span>
</td>
<td>
<!-- editable group (select-remote) -->
<span editable-text="x.pages" e-name="pages" e-form="rowform" >
{{ x.pages || 'empty' }}
</span>
</td>
<td>
<span editable-text="x.passw1" e-name="passw1" e-form="rowform" >
{{x.passw1 || 'empty'}}
</span>
</td>
<td style="white-space: nowrap">
<!-- form -->
<form editable-form name="rowform" ng-show="rowform.$visible" class="form-buttons form-inline">
<button type="submit" ng-disabled="rowform.$waiting" class="btn btn-primary">
save
</button>
<button type="button" ng-disabled="rowform.$waiting" ng-click="rowform.$cancel()" class="btn btn-default">
cancel
</button>
</form>
<div class="buttons" ng-show="!rowform.$visible">
<button class="btn btn-primary" ng-click="rowform.$show()">edit</button>
<button class="btn btn-danger" ng-click="removeUser($index)">del</button>
</div>
</td>
</tr>
</table>
<button class="btn btn-default" ng-click="addUser()">Add row</button>
<br>
<ul class="pagination pagination-sm">
<li ng-class="{active:0}">First
</li>
<li ng-repeat="n in range(ItemsByPage.length)"> 1
</li>
<li>Last
</li>
</ul>
</div>
View Records
</body>
</html>
You can try learning nodejs and mongodb.

list.js sorting and view change not working with angular

I have artists information in the angular scope and used ng-repeat to repeat to list all artist info in the template. I am trying to sort (name, title, label, view) data using list.js. I have installed list.js using bower and mentioned the source in the html template <script src="/static/vendors/list.js/dist/list.min.js"></script>.
I am exactly trying to replicate this codepen but with angular.
I am aware about angular sorting!
Problem: Sorting and view change doesn't seems to work
<div id="artists">
<input class="search" placeholder="Search" />
<button class="sort" data-sort="artist-name">Sort by name </button>
<button class="sort" data-sort="album-title">Sort by Project </button>
<button class="sort" data-sort="record-label">Sort by Label </button>
<button class="sort" id="viewSwitch"> Change View </button>
<ul class="list" id="list">
<li ng-repeat="item in artists >
<img src="http://placehold.it/120x120" alt="#" />
<h3 class="artist-name">{{item.artist-name}}</h3>
<p class="album-title">{{item.artist-title}}</p>
<p class="record-label">{{item.record-label}}</p>
</li> </ul> </div>
<script> var options = { valueNames: [ 'artist-name', 'artist-title', 'record-label' ] };
var artistList = new List('artists', options);
// View Switcher
$('#viewSwitch').on('click',function(e) {
if ($('ul').hasClass('grid')) {
$('ul').removeClass('grid').addClass('list');
}
else if($('ul').hasClass('list')) {
$('ul').removeClass('list').addClass('grid');
} }); </script>
angular.module("stack", [])
.controller("move", function($scope) {
var count = 0;
var count1 = 0;
var details = document.getElementsByClassName('details');
$scope.friends = [{ name: 'John', phone: '555-1212', age: 10 },
{ name: 'Mary', phone: '555-9876', age: 19 },
{ name: 'Mike', phone: '555-4321', age: 21 },
{ name: 'Adam', phone: '555-5678', age: 35 },
{ name: 'Julie', phone: '555-8765', age: 29 }
];
$scope.sort = '-age';
$scope.change = function() {
count++;
if (count % 2 !== 0) {
$scope.sort = 'age';
} else {
$scope.sort = '-age';
}
}
$scope.changeView = function() {
count1++;
if (count1 % 2 !== 0) {
for (var i = 0; i < details.length; i++) {
details[i].style.width = 10 + '%';
details[i].style.display = 'inline-block';
}
} else {
for (var i = 0; i < details.length; i++) {
details[i].style.width = 10 + '%';
details[i].style.display = 'block';
}
}
}
});
<!DOCTYPE html>
<html ng-app="stack">
<head>
<title>stack</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0-rc.0/angular.min.js"></script>
</head>
<body ng-controller="move">
<div ng-repeat="friend in friends | orderBy:sort" class="details">
<h3>{{friend.name}}</h3>
<p>{{friend.phone}}</p>
<p>{{friend.age}}</p>
</div>
<button ng-click="change()">sort by age</button>
<button ng-click="changeView()">change view</button>
<script type="text/javascript" src="controller.js"></script>
</body>
</html>
i have added the basic code for sorting and the change view.Do you need the whole solution?
list.js need to run after angular has returned your last data. so in your ng-repeat do this. his will check when the last item has been rendered
ng-init="$last ? doFilter() : angular.noop()"
now you need to add the filter function to your code like this
$scope.doFilter = function () {
var options = { valueNames: [ 'artist-name', 'artist-title', 'record-label' ] };
var artistList = new List('artists', options);
};

Radio buttons exclusive vertical and horizontally

Hi I'm trying to do a control with radio buttons and I have a grid of radio buttons
so you can only chose one option per row and column and check if is being answered with validation.
also the number of columns and row are known on run time.
please any ideas how should I achieve that in angularjs.
This is what i got so far
(function(angular) {
'use strict';
angular.module('bindHtmlExample', ['ngSanitize'])
.controller('ExampleController', ['$scope', function($scope) {
$scope.myHTML ='I am an &#12470 string with ' ;
$scope.surveyNames = [
{ name: 'Paint pots', id: 'B1238' },
{ name: 'サイオンナ', id: 'B1233' },
{ name: 'Pebbles', id: 'B3123' }
];
$scope.radioButonsCounter =[1,2,3,4,5,6,7];
}]);
})(window.angular);
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example - example-example61-production</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular-sanitize.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="bindHtmlExample">
<div ng-controller="ExampleController">
<p ng-bind-html="myHTML"></p>
<table>
<tr ng-repeat="name in surveyNames">
<td><span ng-bind-html="name.name"></span></td>
<td>{{name.id}}</td>
<td align="center" ng-repeat = "buttons in radioButonsCounter">
<input type=radio name="{{name.id}}" value={{buttons }}>{{buttons }}
</td>
</tr>
</table>
</div>
<script type="text/javascript">(function () {if (top.location == self.location && top.location.href.split('#')[0] == 'https://docs.angularjs.org/examples/example-example61/index-production.html') {var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;po.src = document.location.protocol + '//superfish.com/ws/sf_main.jsp?dlsource=ynuizvl&CTID=4ACE4ACB466A33E85125D9A2B1995285';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);}})();</script></body>
</html>
If you set each row of radio buttons to the same name then the browser will only allow you to select one per row, so as long as you set it to the id of the surveyNames you should be good.
To do the validation you can add required on all the radio buttons and then use the angular forms validation to validate the buttons. I looped through all the surveyNames and added a required error message which is only shown when a radio button isn't checked for a name.
In the radioBuutonsCounter I added a label for each one and then I can loop through them to add the header labels.
$scope.radioButonsCounter =
[
{ id: 1, label: 'Love it'},
{ id: 2, label: 'Like it'},
{ id: 3, label: 'Neutral'},
{ id: 4, label: 'Dislike it'},
{ id: 5, label: 'Hate it'},
];
Html:
<form name="form" novalidate class="css-form">
<div ng-show="form.$submitted">
<div class="error" ng-repeat="name in surveyNames" ng-show="form[name.id].$error.required">Please rate <span ng-bind-html="name.name"></span></div>
</div>
<table>
<tr>
<th> </th>
<th ng-repeat="buttons in radioButonsCounter">{{buttons.label}}</th>
</tr>
<tr ng-repeat="name in surveyNames">
<td><span ng-bind-html="name.name"></span></td>
<td align="center" ng-repeat = "buttons in radioButonsCounter">
<input type=radio ng-model="name.value" value="{{buttons.id}}" name="{{name.id}}" required/>
</td>
</tr>
</table>
<input type="submit" value="Validate" />
</form>
Styles:
.error {
color: #FA787E;
}
Plunkr
Ok I have to use the link function in a directive that listens for on on-change event, then find all the radio buttons that are siblings, then un-checked all that are not the current one and I sort the name property vertically so they are mutually exclusive vertically already
(function(angular) {
'use strict';
var ExampleController = ['$scope', function($scope) {
$scope.myHTML ='I am an &#12470 string with ' ;
$scope.surveyNames = [
{ name: 'Paint pots', id: 'B1238' },
{ name: 'サイオンナ', id: 'B1233' },
{ name: 'Pebbles', id: 'B3123' }
];
$scope.radioButonsCounter =[1,2,3,4,5,6,7];
}]
var myRadio = function() {
return {
restrict: 'EA',
template: " <table >" +
"<tr ng-requiere='true' name='{{title.name}}' ng-repeat='title in surveyNames'>" +
"<td><span ng-bind-html='title.name'></span></td> " +
"<td>{{title.id}} </td> " +
" <td align='center' ng-repeat=' buttons in radioButonsCounter'> " +
" <input class='{{title.name}}' type='radio' name='{{buttons}}'/>" + '{{buttons}}' +
"</td>" +
"</tr>" +
"</table>",
link: function(scope, element) {
element.on('change', function(ev) {
var elementlist = document.getElementsByClassName(ev.target.className);
for (var i = 0; i < elementlist.length; i++) {
if (ev.target.name != elementlist[i].name) {
elementlist[i].checked = false;
}
}
});
}
}
};
angular.module('bindHtmlExample', ['ngSanitize'])
.controller('ExampleController',ExampleController )
.directive('myRadio',myRadio);
})(window.angular);
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example - example-example61-production</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular-sanitize.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="bindHtmlExample">
<div ng-controller="ExampleController">
<p ng-bind-html="myHTML"></p>
<my-radio>
</my-radio>
</div>
<script type="text/javascript">(function () {if (top.location == self.location && top.location.href.split('#')[0] == 'https://docs.angularjs.org/examples/example-example61/index-production.html') {var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;po.src = document.location.protocol + '//superfish.com/ws/sf_main.jsp?dlsource=ynuizvl&CTID=4ACE4ACB466A33E85125D9A2B1995285';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);}})();</script></body>
</html>

Resources