Checklist-model in Angular usage - javascript

i have departments as a title and employees as a subtitle. what i want to do is when the user check the title or department all employees or subtitles should be checked. i am using fieldset and table in html and ng-repeat. it looks like this issue but the main differ is getting data from db Angular checklist-model checkboxes with reverse action
i cannot find what i miss. any idea any help. thanks .
The HTML
<fieldset id="field3">
<table>
<tr ng-repeat="emp in empdepts | groupBy:'dep_LDesc'">
<td>
<label ng-click="showContent = !showContent"></label>
<details ng-open="showContent">
<summary> <input type="checkbox" class="test" ng-model="check_all_domains" ng-click="toggle_select_all()" /> {{emp[0].dep_LDesc}}</summary>
<div ng-repeat="semployee in emp" class="test">
<input type="checkbox" checklist-model="objects_selected" checklist-value="semployee">
{{semployee.Sname}}<div style="display:none;">{{semployee.staffkey}}{{semployee.depkey}}</div>
</div>
</details>
</td>
</tr>
</table>
</fieldset>
The Controller
/// <reference path="Scripts/angular.js" />
///
///
Assign.controller("AssignController", function ($scope, Assignments) {
Loaddepts();
function Loaddepts()
{
Assignments.getdepts().then (function(response){
$scope.depts = (response.data);
console.log($scope.depts);
})
}
//$scope.employees = [];
//$scope.checked = { employees: ['semployee'] }
//$scope.checkAll = function () {
// $scope.checked.employees = angular.copy($scope.employees);
//};
//$scope.uncheckAll = function () {
// $scope.checked.employees = [];
//};
//$scope.emp = $scope.empdepts;
$scope.objects_selected = [];
$scope.check_all_domains = false;
$scope.toggle_select_all = function () {
$scope.objects_selected = true;
//$scope.check_all_domains = true;
//$scope.objects_selected = angular.copy($scope.emp);
//angular.copy($scope.emp, $scope.objects_selected);
};
LoadEmpDepts();
function LoadEmpDepts()
{
Assignments.getempdepts().then (function (response){
$scope.empdepts = (response.data);
console.log($scope.empdepts);
})
}
$scope.selectedRow1 = null; // initialize our variable to null
$scope.setClickedRow1 = function (employee) { //function that sets the value of selectedRow to current index
$scope.selectedRow1 = employee;
}
$scope.save = function()
{
}
});
}
Thanks in advance

<table>
<tr ng-repeat="e in empdepts | groupBy:'dep_LDesc'">
<td>
<label ng-click="showContent = !showContent"></label>
<details ng-open="showContent">
<summary><input type="checkbox" ng-model="chk" /> {{e[0].dep_LDesc}}</summary>
<div ng-repeat="employee in e">
<input type="checkbox" ng-checked="chk"> {{employee.Sname}}
</div>
</details>
</td>
</tr>
</table>

Related

Why does not work the addition / removal of elements in “LocalStorage”?

I want to add: the name, phone and mail of the user in the localStorage using the method: addContact() and with the data that is there in localStorage, I create the table using the method show().
Also does not happen delete the contact, I'm trying to do with the method: deleteContact(e).
When I add contact I receive the following error: Uncaught TypeError: Cannot read property 'value' of undefined
When I deleting I receive the following error: Uncaught TypeError: Cannot read property 'splice' of undefined
Help me fix that
//Product Creation Class
class LocalStorage {
constructor(name, phone, email) {
this.name = name;
this.phone = phone;
this.email = email;
}
}
// Сlass where products are recorded
class Book {
constructor() {
this.products = [];
this.name = document.getElementById("name");
this.phone = document.getElementById("phone");
this.email = document.getElementById("email");
this.buttAdd = document.getElementById("add");
this.book = document.getElementById("addBook");
}
//method for adding a product
addContact() {
let isNull = this.name.value != '' && this.phone.value != '' && this.email.value != '';
if (isNull) {
let obj = new LocalStorage(this.name.value, this.phone.value, this.email.value);
this.products.push(obj);
localStorage['addbook'] = JSON.stringify(this.products);
this.show();
}
}
//method for remove product by name
deleteContact(e) {
if (e.target.className === "delbutton") {
let remID = e.target.getAttribute('data-id');
this.products.splice(remID, 1);
localStorage['addbook'] = JSON.stringify(this.products);
this.show();
}
}
// method to draw the table with product property (
// name, phone, email)
show() {
if (localStorage['addbook'] === undefined) {
localStorage['addbook'] = '';
} else {
this.products = JSON.parse(localStorage['addbook']);
this.book.innerHTML = '';
for (let e in this.products) {
let table = ` <table id="shop" class="entry">
<tr>
<th>Name:</th>
<th id="filter">Phone:</th>
<th>Email:</th>
<th class="dels"></th>
</tr>
<tbody>
<tr class="data">
<td>${this.products[e].name}</td>
<td>${this.products[e].phone}</td>
<td>${this.products[e].email}</td>
<td class="del">Delete</td>
</tr>
</tbody>
</table>`;
this.book.innerHTML += table;
}
}
}
OperationsWithContacts() {
// add new product by click
this.buttAdd.addEventListener('click', this.addContact);
// delete product by name after click
this.book.addEventListener('click', this.deleteContact);
console.log(this.products);
}
}
let shop = new Book();
shop.show();
shop.OperationsWithContacts();
<div class="Shop">
<div class="add-product">
<h1>Add product</h1>
<form name="addForm">
<label for="name" >Name of product</label>
<input type="text" id="name" class="input-product">
<label for="phone">Price of product</label>
<input type="number" id="phone" class="input-product">
<label for="email">Count of product</label>
<input type="text" id="email" class="input-product">
<button id="add" type="button">Add</button>
</form>
</div>
<div class="product-table">
<h2>Address book</h2>
<div id="delete-form">
<label for="name-delete">Search product by name</label>
<input type="text" id="name-delete" class="input-delete">
</div>
<div id="addBook"></div>
</div>
</div>
enter code here
The obivous issue I see is that this in both your functions addContact() and deleteContact() represents a button-HTML-Element and not the class you think it does.
Just change the code a bit and you will see:
//method for adding a product
addContact() {
console.log('addContact()', this);
let isNull = this.name.value != '' && this.phone.value != '' && this.email.value != '';
if (isNull) {
let obj = new LocalStorage(this.name.value, this.phone.value, this.email.value);
this.products.push(obj);
localStorage['addbook'] = JSON.stringify(this.products);
this.show();
}
}
So you might want to change your bind from:
document.querySelector('#add').addEventListener('click', this.addContact);
to
document.querySelector('#add').addEventListener('click', this.addContact.bind(this));
to properly reuse the this shortcut.
Edit:
//Product Creation Class
//REM: Not the best name choice here.. localStorage <> LocalStorage
class LocalStorage{
constructor(name, phone, email){
this.name = name;
this.phone = phone;
this.email = email
}
};
//Сlass where products are recorded
class Book{
constructor(){
this.products = [];
this.name = document.getElementById("name");
this.phone = document.getElementById("phone");
this.email = document.getElementById("email");
this.buttAdd = document.getElementById("add");
this.book = document.getElementById("addBook")
};
//method for adding a product
addContact(){
let isNull = this.name.value != '' && this.phone.value != '' && this.email.value != '';
if(isNull){
let obj = new LocalStorage(this.name.value, this.phone.value, this.email.value);
this.products.push(obj);
localStorage['addbook'] = JSON.stringify(this.products);
this.show();
}
};
//method for remove product by name
deleteContact(e) {
if(e.target.className === "delbutton"){
let remID = e.target.getAttribute('data-id');
this.products.splice(remID, 1);
localStorage['addbook'] = JSON.stringify(this.products);
this.show();
}
};
//method to draw the table with product property (
//name, phone, email)
show(){
if(localStorage['addbook'] === undefined) {
//REM: An empty string is no valid JSON to be serialised
localStorage['addbook'] = '[]'
}
else{
this.products = JSON.parse(localStorage['addbook']);
this.book.innerHTML = '';
for(let e in this.products){
let table = ` <table id="shop" class="entry">
<tr>
<th>Name:</th>
<th id="filter">Phone:</th>
<th>Email:</th>
<th class="dels"></th>
</tr>
<tbody>
<tr class="data">
<td>${this.products[e].name}</td>
<td>${this.products[e].phone}</td>
<td>${this.products[e].email}</td>
<td class="del">Delete</td>
</tr>
</tbody>
</table>`;
this.book.innerHTML += table;
}
}
};
OperationsWithContacts(){
// add new product by click
this.buttAdd.addEventListener('click', this.addContact.bind(this));
// delete product by name after click
this.book.addEventListener('click', this.deleteContact.bind(this));
console.log(this.products);
}
};
;window.onload = function(){
let shop = new Book();
shop.show();
shop.OperationsWithContacts()
};
<div class="Shop">
<div class="add-product">
<h1>Add product</h1>
<form name="addForm">
<label for="name" >Name of product</label>
<input type="text" id="name" class="input-product">
<label for="phone">Price of product</label>
<input type="number" id="phone" class="input-product">
<label for="email">Count of product</label>
<input type="text" id="email" class="input-product">
<button id="add" type="button">Add</button>
</form>
</div>
<div class="product-table">
<h2>Address book</h2>
<div id="delete-form">
<label for="name-delete">Search product by name</label>
<input type="text" id="name-delete" class="input-delete">
</div>
<div id="addBook"></div>
</div>
</div>

How to assign reassign checkbox ng-model on ng-repeat

Please help me out. I have a checkboxes with models defined. I am displaying checkboxes and using the model to set if the checkbox is selected or not. Below is the code for setting the ng-model.
LoadValues(obj) {
vm.index = false;
vm.create = false;
vm.edit = false;
vm.delete = false;
vm.other = false;
var pList = obj.Functions;
var currentModule = obj.Name;
for (var i = 0; i < pList.length; i++) {
var currentItem = pList[i];
console.log(currentItem)
if (currentItem.search("Index") > 0) {
vm.index = true;
console.log(vm.index);
} else if (currentItem.search("Create") > 0) {
vm.create = true;
} else if (currentItem.search("Edit") > 0) {
vm.edit = true;
} else if (currentItem.search("Delete") > 0) {
vm.delete = true;
} else if (currentItem.search("Other") > 0) {
vm.other = true;
}
}
}
Below is the check boxes.
<tbody>
<tr ng-repeat="item in list">
<td>
{{item.Name}}
</td>
<td>
<input id="Index" type="checkbox" ng-model="vm.index" ng-click="EditRole(Right,item.Module,'Index')">
</td>
<td>
<input id="Create" type="checkbox" ng-model="vm.create" ng-click="EditRole(item.Role,'Create')">
</td>
<td>
<input id="Edit" type="checkbox" ng-model="vm.edit" ng-click="EditRole(item.Role,item.Module,'Edit')">
</td>
<td>
<input id="Delete" type="checkbox" ng-model="vm.delete" ng-click="EditRole(item.Role,item.Module,'Delete')">
</td>
<td>
<input id="Other" type="checkbox" ng-model="vm.other" ng-click="EditRole(item.Role,item.Module,'Other')">
</td>
</tr>
</tbody>
The problem is it assigns the same ng-model to all the items in the list. I have tried to find solutions nothing is helping. Your help would be very much appreciated.
i am reading my data from a json file. Below is some example data:
[
{"Role":"Staff","Admins":[{"Name":"Username","userRights":["UserEdit","UserCreate"]
}]
The easiest way to use ng-model on a checkbox is to pass it an abject. The code below converts an array of items into an object for the checkboxes.
I created a variable called $scope.userRights which contains all of the available options.
In the HTML we loop though each field displaying its name and then loop though all of the userRights.
The submit button then converts the object back into the array format we received.
HTML
<div ng:controller="MainCtrl">
<button ng-click="submit()">Submit</button>
<table>
<tr ng-repeat="field in fields">
<td ng-bind="field.Name"></td>
<td ng-repeat="right in userRights">
<label>
<input type="checkbox" ng-model="field.userRights[right]" /> {{right}}
</label>
</td>
</tr>
</table>
<pre ng-bind="fields | json"></pre>
</div>
JavaScript
app.controller('MainCtrl', function($scope) {
$scope.userRights = ["UserEdit","UserCreate","UserSomethingElse"];
$scope.fields = [
{"Name":"Username","userRights":["UserEdit","UserCreate"]},
{"Name":"Password","userRights":["UserEdit"]}
];
// Convert array to object
$scope.fields.forEach(function(field) {
var res = {};
field.userRights.forEach(function(right) {
res[right] = true;
});
field.userRights = res;
});
function objectValues(obj) {
var res = [];
var keys = Object.keys(obj);
for (var i=0; i<keys.length; i++) {
if (obj[keys[i]]) res.push(keys[i]);
}
return res;
}
// Convert object to array
$scope.submit = function() {
$scope.fields.forEach(function(field) {
field.userRights = objectValues(field.userRights);
});
};
});
Demo
Your ng-model has to be like so:
ng-model="item.index"
And then in your controller inside the for loop:
current_item.index = true;
Hope it helps =)

Show only clicked element values from multiple ng-click events angularjs

i have 10 more ng-click events, but i want to show only clicked element value where i have to change, but i updated in code there was so many true or false duplicates i have to write, pls help me that have to show only clicked ng-show values without using 'true or false' booleen functions in each click event.
var app = angular.module('myapp', ['ngSanitize']);
app.controller('AddCtrl', function ($scope, $compile) {
$scope.field = {single: 'untitled',single2:'default',single3:'enter'};
$scope.addName1 = function (index) {
var name1html = '<fieldset id="name1" ng-click="selectName1($index)"><label ng-bind-html="field.single"></label><input type="text" placeholder="Enter name"><button ng-click="removeName1($index)">-</button></fieldset>';
var name1 = $compile(name1html)($scope);
angular.element(document.getElementById('drop')).append(name1);
};
$scope.removeName1 = function (index) {
var myEl = angular.element(document.querySelector('#name1'));
myEl.remove();
};
$scope.selectName1 = function (index) {
$scope.showName1 = true;
$scope.showName2 = false;
$scope.showName3 = false;
};
$scope.addName2 = function (index) {
var name2html = '<fieldset id="name2" ng-click="selectName2($index)"><label ng-bind-html="field.single2"></label><input type="text" placeholder="Enter name"><button ng-click="removeName2($index)">-</button></fieldset>';
var name2 = $compile(name2html)($scope);
angular.element(document.getElementById('drop')).append(name2);
};
$scope.removeName2 = function (index) {
var myEl = angular.element(document.querySelector('#name2'));
myEl.remove();
};
$scope.selectName2 = function (index) {
$scope.showName2 = true;
$scope.showName1 = false;
$scope.showName3 = false;
};
$scope.addName3 = function (index) {
var name3html = '<fieldset id="name3" ng-click="selectName3($index)"><label ng-bind-html="field.single3"></label><input type="text" placeholder="Enter name"><button ng-click="removeName3($index)">-</button></fieldset>';
var name3 = $compile(name3html)($scope);
angular.element(document.getElementById('drop')).append(name3);
};
$scope.removeName3 = function (index) {
var myEl = angular.element(document.querySelector('#name3'));
myEl.remove();
};
$scope.selectName3 = function (index) {
$scope.showName3 = true;
$scope.showName1 = false;
$scope.showName2 = false;
};
});
<!DOCTYPE html>
<html ng-app="myapp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.2/angular.min.js"></script>
<script src="https://code.angularjs.org/1.5.0-rc.0/angular-sanitize.min.js"></script>
</head>
<body ng-controller="AddCtrl">
<div id="drop"></div>
<button ng-click="addName1($index)">Name1</button>
<button ng-click="addName2($index)">Name2</button>
<button ng-click="addName3($index)">Name3</button>
<form ng-show="showName1">
<div class="form-group">
<label>Field Label(?)</label>
<br/>
<input ng-model="field.single">
</div>
</form>
<form ng-show="showName2">
<div class="form-group">
<label>Field Label(?)</label>
<br/>
<input ng-model="field.single2">
</div>
</form>
<form ng-show="showName3">
<div class="form-group">
<label>Field Label(?)</label>
<br/>
<input ng-model="field.single3">
</div>
</form>
</body>
</html>
here is plunkr http://plnkr.co/edit/oFytWlQMIaCaeakHNk71?p=preview
You will need "ng-repeat" in the HTML. Set an Array on $scope and let the template determine what HTML elements to add. Typically, $index is only set by ng-repeat.
Read more here: https://docs.angularjs.org/api/ng/directive/ngRepeat

push increment item into an array in Angularjs

http://plnkr.co/edit/NDTgTaTO1xT7bLS1FALN?p=preview
<button ng-click="addRow()">add row</button>
<div ng-repeat="row in rows">
<input type="text" placeholder="name"><input type="tel" placeholder="tel">
</div>
I want to push new row and save all the fields but now I'm stuck at adding new rows. How to know the current number of row and do increment to push into the array?
Look at this example I created which allows you to generate up to eight unique input fields for Telephone and Text Entries.
var app = angular.module("MyApp", []);
app.controller("MyCtrl", function($scope) {
$scope.rows = [];
var Row = function(tel, text) {
// Private data
var private = {
tel: tel,
text: text
}
// Expose public API
return {
get: function( prop ) {
if ( private.hasOwnProperty( prop ) ) {
return private[ prop ];
}
}
}
};
$scope.addRow = function(){
if($scope.rows.length < 8){
var newItemNum = $scope.rows.length + 1;
var row = new Row('item' + newItemNum, 'item' + newItemNum);
$scope.rows.push(row);
}
};
$scope.saveAll = function(){
// $scope.result = 'something';
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="MyApp">
<div ng-controller="MyCtrl">
<h2>Setting</h2>
<button ng-click="addRow()">Add Row</button>
<br />
<div ng-repeat="row in rows">
<input type="text" placeholder="Text" ng-model="row.textModel" >
<input type="tel" placeholder="Phone" ng-model="row.telModel" >
</div>
<br />
{{rows}}
</div>
</div>
Move functions inside controller 'Ctrl'.
In your script:
function Ctrl($scope) {
$scope.result = "something";
$scope.rows = ['1'];
$scope.addRow = function(){
if ($scope.rows.length < 8) {
$scope.rows.push($scope.rows.length + 1);
}
}
$scope.saveAll = function(){
// $scope.result = 'something';
}
}

How to call/use 1 controller of $scope in another controller in AngularJS

My question is that how to call 1 controller $scope to another controller in Angular JS.
Bascially The structure is that, I have two controller one is AddController and the other one is ViewController. Basically I want the form with fields of AddController in ViewController. $rootScope.name = data.name, email and phone is not showing the data on the form fields once I click on Edit.
What I've already tried.
In HTML
<div ng-app="app">
<div ng-controller="AddController">
<legend>Add Students</legend>
<form class="well">
<label>Name</label>
<input type="text" name="name" ng-model="name" />
<label>Email</label>
<input type="text" name="email" ng-model="email" />
<label>Phone</label>
<input type="text" name="phone" ng-model="phone" />
<br/>
<div ng-if="isUpdate">
<input type="hidden" name="id" ng-model="id" />
</div>
<div ng-show="addData">
<input type="button" value="Save" ng-click="saveStudent()" class="btn btn-primary" />
</div>
<div ng-show="!addData">
<input type="button" value="Update" ng-click="updateStudent()" class="btn btn-primary" />
</div>
</form>
</div>
<div ng-controller="ViewController">
<legend>View Students</legend>
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Email</th>
<th>Phone</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="student in students">
<td>{{ $index; }}</td>
<td>{{ student.name }}</td>
<td>{{ student.email }}</td>
<td>{{ student.phone }}</td>
<td>Edit | Delete</td>
</tr>
</tbody>
</table>
</div>
</div>
In JS
var app = angular.module('app', []);
app.service('StudentsData', function($rootScope){
var s;
var students = [
{name: 'Tariq Ali', email: 'chk.webstar#gmail.com', phone: '58757'},
{name: 'Faizan Ali', email: 'kdjy.webstar#gmail.com', phone: '24545'}
];
this.list = function(){
return students;
}
this.single = function(id){
for(s=0; s<=students.length; s++){
if(s == id){
return students[s];
}
}
}
this.insert = function(data){
students.push(data);
}
this.update = function(updatedData, id){
for(s=0; s<=students.length; s++){
if(s == id){
students[s] = updatedData;
}
}
}
this.delete = function(id){
students.splice(id, 1);
}
this.name = function(){
}
});
app.controller('AddController', function($scope, StudentsData, $rootScope){
$scope.$broadcast('someEvent', [1,2,3]);
$rootScope.addData = true;
$scope.saveStudent = function(){
StudentsData.insert({name: $scope.name, email: $scope.email, phone: $scope.phone});
$scope.name = '';
$scope.email = '';
$scope.phone = '';
}
$scope.updateStudent = function(){
var updatedData = {name: $scope.name, email: $scope.email, phone: $scope.phone};
StudentsData.update(updatedData, $scope.id);
/*$scope.name = '';
$scope.email = '';
$scope.phone = '';
$rootScope.addData = true;*/
}
});
app.controller('ViewController', function($scope, StudentsData, $rootScope){
$scope.$on('someEvent', function(event, mass) {console.log(mass)});
$scope.students = StudentsData.list();
$scope.delete = function(id){
StudentsData.delete(id);
}
$scope.edit = function(id){
var data = StudentsData.single(id);
$rootScope.name = data.name;
$rootScope.email = data.email;
$rootScope.phone = data.phone;
$rootScope.addData = false;
$rootScope.isUpdate = true;
$rootScope.id = id;
//console.log($rootScope.addData);
//StudentsData.update(id);
}
});
Here is my fiddler http://jsfiddle.net/npm5u5h0/
For first time if you click on edit its working fine but if you add a new student and after edit the newly created student the textfields are not showing the data.
Why not have two controllers that both call the same service? They you could put the information in the service and have them both reference that.
angular.module('mycontrollers').controller('controllername', ['myService', function (myService) {
$scope.email = myService.getEmail;
}]);
angular.module('mycontrollers').controller('controllername2', ['myService', function (myService) {
$scope.email = myService.getEmail;
}]);
angular.module('myservices').service('myService', ['$rootScope', function ($rootScope) {
var self = this;
self.getEmail = function () {
...
return $rootScope.email;
};
self.setEmail = function (email) {
$rootScope.email = email;
};
}]);
You could name the addContoller div with an ID such as "addController"
Then from within your viewController, you could grab the other scope with
var myEl = angular.element(document.querySelector('#addController'));
var myScope = angular.element(myEl).scope();
and then $scope.name = myScope.name

Categories

Resources