bind nested ng-repeat to model - angularjs

In the following example, I should ask for the name of six students. They will be grouped according to bedroom type.
2 -> double
1 -> single
3 -> tiple
So, it means that I'll have a array of students (6 students). I would like to get their names. I was trying to create a variable like 'count' and put as ng-model of the input and increment during the loop, but it didn't work.
full html:
<!doctype html>
<html ng-app="sampleApp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body ng-controller='SampleController'>
<div ng-repeat='i in numberOfAccommodations track by $index'>
Bedroom {{$index}}
<span ng-repeat='x in numberOfStudents[$index]'>
Student {{$index}}
<input type='text' ng-model='abroadStudents[???].name' /> <!-- this input to student model -->
</span>
</div>
<input type='button' value='test' ">
<script>
angular.module('sampleApp',[]).controller('SampleController',function($scope){
$scope.abroadStudents = new Array[6];
$scope.abroadAccommodation = new Array();
$scope.abroadAccommodation.push({ "bedroomType": 2}, { "bedroomType": 1 }, {"bedroomType": 3});
$scope.numberOfAccommodations = function()
{
var arr = new Array();
for (var i = 0 ; i < $scope.abroadAccommodation.length ; i++)
{
arr.push(i);
}
return arr;
}();
$scope.numberOfStudents = function()
{
var arr = new Array();
for (var x = 0 ; x < $scope.abroadAccommodation.length ; x++)
{
var temp = 0;
var intArr = new Array();
do
{
intArr.push(temp);
temp++;
}
while(temp < $scope.abroadAccommodation[x].bedroomType);
arr.push(intArr);
}
return arr;
}();
});
</script>
</body>
</html>

I rewrote your logic to create a more logical structure of objects which does not require relying upon the $index. It creates an Array of room objects, then iterates through the array of abroadAccommodation. For each abroadAccommodation, it adds a room, and based on type, adds the appropriate number of student objects. It is then very easy to use ng-repeat to iterate through each room to identify each student.
Note I also am using angular.forEach here.
<!doctype html>
<html ng-app="sampleApp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body ng-controller='SampleController'>
<div ng-repeat="room in rooms">
{{room.roomNum}}
<div ng-repeat="student in room.students">
{{student.bed}}
<input ng-model="student.name" />
</div>
</div>
Student List:
<div ng-repeat="room in rooms">
<div ng-repeat="student in room.students">
{{student.name}}
</div>
</div>
<script>
angular.module('sampleApp', []).controller('SampleController', function($scope) {
$scope.abroadAccommodation = new Array();
$scope.abroadAccommodation.push({
"bedroomType ": 2
}, {
"bedroomType ": 1
}, {
"bedroomType ": 3
});
$scope.rooms = function() {
var arr = [];
angular.forEach($scope.abroadAccommodation, function(type, count) {
var room = {
"roomNum": "room " + (count + 1),
students: []
};
angular.forEach(type, function(numBeds) {
for (i = 0; i < numBeds; i++) {
room.students.push({
"bed": "bed " + (i + 1),
"name": "student" + Math.random()
});
}
arr.push(room);
})
});
return arr;
}();
});
</script>
</body>
</html>
http://plnkr.co/edit/YaPo54NUBPk9AnZkGcCc?p=preview

Related

How to match both the arrays in Angularjs and have to display matched one?

I have user_id in two array, one is available user_id's for projects and other is selected user_id.
availableusers = ["00000000a447a9160c9d6b74", "000000005c05c11764445bdb"]
selected Users = ["000000005c05c11764445bdb"]
Now I need to match both the array and have to display matched in selected div and unmatched in availabe div.
How can I able to do this?
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.availableusers = ["00000000a447a9160c9d6b74", "000000005c05c11764445bdb"]
$scope.selectedUsers = ["000000005c05c11764445bdb"]
$scope.matchUser = [];
for (var i = 0; i < $scope.availableusers.length; i++) {
for (var j = 0; j < $scope.selectedUsers.length; j++) {
if ($scope.availableusers[i] === $scope.selectedUsers[j]) {
$scope.matchUser.push($scope.availableusers[i]);
}
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.5/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<span>Available users</span>
<div ng-repeat="available in availableusers">{{available}}</div>
<span>Selected Users</span>
<div ng-repeat="selectUser in selectedUsers">{{selectUser}}</div>
<span>Users</span>
<div ng-repeat="Users in matchUser">{{Users}}</div>
</div>
var result=[];
for(var i = 0 ;i<availableUsers.length;i++){
if(availableusers[i] === selectedUsers[i])
{
result.push(availableusers[i]);
}
}

How to create autogenerate ID in angular?

Want to create autogenerate code in angular inputbox on refresh page
like rand(function) in php. Im using this script for this. But problem
is its vanished on page refresh not working properly.
<script type="text/javascript">
function randString(x){
var s = "OL-";
while(s.length<x&&x>0){
var r = Math.random();
s+= (r<0.1?Math.floor(r*100):String.fromCharCode(Math.floor(r*26) + (r>0.5?97:65)));
}
return s;
}
document.getElementById("referal_code").value = randString(10);
</script>
<input required type='text' class='span2' id='referal_code' ng-model='empInfo.referal_code'>
Try this
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function getNewID() {
try {
var myDate = new Date();
var varID = myDate.getHours() + "" + myDate.getMinutes() + "" + myDate.getSeconds() + "" + myDate.getMilliseconds();
if (varID.Length > 15) {
varID = varID.substr(0, 15);
}
return varID;
} catch (e) {
console.log(e.message);
}
}
function randString(x){
var s = getNewID();
return s;
}
window.onload = function(){
document.getElementById("referal_code").value = randString(10);
}
</script>
</head>
<body>
<input required type='text' class='span2' id='referal_code' ng-model='empInfo.referal_code'>
</body>
</html>
For any attribute in angular world you can use interpolation like this:
<input id="{{randString(10)}}"/>
If you want to have a certain value as id and not get lost after refresh you have to save it on some web storage (localstorage, sessionstorage).
e.g. :
function randString(x){
// ... your function's logic
//Save it in localStorage before returning it
localStorage.inputId = s;
return s;
}
document.getElementById("referal_code").value = localStorage.inputId || randString(10)

Change Different type of Attributes for Dynamically added every element

How can I Change (type) Attribute for each added dynamic buttons? In below code, label names were changing perfectly, but when i am trying to change button types it is applying to all added dynamic buttons,
My requirement is have to change every button type with different types (means: first added button type to submit, second added type to reset, third added button to cancel). but in my code if i change second button type to 'Reset' at the same time the first button type also going to Reset type... can u please tell me how can i change button type for every added element ...
Working DEMO
Updated:
var app = angular.module('myapp', ['ngSanitize']);
app.controller('MainCtrl', function($scope, $compile) {
var counter = 0;
$scope.buttonFields = [];
$scope.add_Button = function(index) {
$scope.buttonFields[counter] = {button: 'Submit'};
var buttonhtml = '<div ng-click="selectButton(buttonFields[\'' + counter + '\'])"><button id="button_Type">{{buttonFields[' + counter + '].button}}</button>//click//</div>';
var button = $compile(buttonhtml)($scope);
angular.element(document.getElementById('add')).append(button);
$scope.changeTosubmit = function (val) {
$scope.buttonField = val;
var els = document.body.querySelectorAll('#button_Type');
for (var i = 0, ils = els.length; i < ils; i++) {
var el = els[i];
el.setAttribute("type", "submit");
compile(el);
}
};
$scope.changeToreset = function (val) {
$scope.buttonField = val;
var els = document.body.querySelectorAll('#button_Type');
for (var i = 0, ils = els.length; i < ils; i++) {
var el = els[i];
el.setAttribute("type", "reset");
compile(el);
}
};
$scope.changeTocancel = function (val) {
$scope.buttonField = val;
var els = document.body.querySelectorAll('#button_Type');
for (var i = 0, ils = els.length; i < ils; i++) {
var el = els[i];
el.setAttribute("type", "cancel");
compile(el);
}
};
++counter;
};
$scope.selectButton = function (val) {
$scope.buttonField = val;
$scope.showButton_Types = true;
};
});
function compile(element) {
var el = angular.element(element);
$scope = el.scope();
$injector = el.injector();
$injector.invoke(function ($compile) {
$compile(el)($scope);
});
};
<!DOCTYPE html>
<html ng-app="myapp">
<head>
<script src="https://code.angularjs.org/1.4.8/angular.js"></script>
<script src="https://code.angularjs.org/1.5.0-rc.0/angular-sanitize.min.js"></script>
</head>
<body ng-controller="MainCtrl">
<button ng-click="add_Button($index)">Add Buttons</button>
<hr>
<div id="add"></div>
<form ng-show="showButton_Types">
<div>
<label>Button Name(?)</label><br/>
<input ng-model="buttonField.button">
</div>
<div>
<label>change button types(?)</label><br/>
<input ng-click="changeTosubmit(buttonFields['' + counter + ''])" name="submit" type="radio"> Submit
<input ng-click="changeToreset(buttonFields['' + counter + ''])" name="submit" type="radio"> Reset
<input ng-click="changeTocancel(buttonFields['' + counter + ''])" name="submit" type="radio"> Cancel
</div>
</form>
</body>
</html>

$watch configuration error angularjs

I want to display some items in several rows. The user can choose if displaying 3 or 4 items per row.
Columns get updated with the correct class, but items per row doesn't.
I've commented the $watch sentence where I think the problem is.
html file:
<!DOCTYPE html>
<html lang="en" ng-app="miTienda">
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href=" node_modules/bootstrap/dist/css/bootstrap.min.css">
</head>
<body ng-controller="TiendaController as tienda">
<div class="container">
<div class="row">
Número de columnas: <input ng-model="tienda.numColumnas" type="number" min="3" max="4" />
</div>
<div class="row" ng-repeat="fila in tienda.filas">
<div ng-class="{'col-sm-4': tienda.numColumnas == 3, 'col-sm-3': tienda.numColumnas == 4}" ng-repeat="producto in fila">
<h4>
{{producto.nombre}}
<span class="label" ng-class="tienda.stockClass({{producto.stock}})">Stock: {{producto.stock}}</span>
</h4>
<p>{{producto.precio|currency}}</p>
<img class="img-responsive" ng-src="{{producto.imagen}}">
<button type="button" class="btn btn-primary pull-right" ng-disabled="producto.stock===0">
<span class="glyphicon glyphicon-shopping-cart" aria-hidden="true"></span> Añadir al carro</button>
</div>
</div>
</div>
<script src="node_modules/angular/angular.min.js"></script>
<script src="scripts/angular-locale_es-es.js"></script>
<script src="scripts/app7c.js"></script>
</body>
</html>
js file:
'use strict';
var app = angular.module('miTienda', []);
app.controller('TiendaController', function() {
this.productos = articulos;
this.stockClass = function(stock) {
if (stock >= 15) {
return 'label-info';
} else if (stock === 0) {
return 'label-danger';
} else {
return 'label-warning';
}
};
/*las columnas que quiero por cada fila*/
this.numColumnas = 3;
this.getFilas = function(array, columns) {
var filas = [];
//http://stackoverflow.com/questions/8495687/split-array-into-chunks
var i, j, temparray, chunk = columns;
for (i = 0, j = array.length; i < j; i += chunk) {
temparray = array.slice(i, i + chunk);
filas.push(temparray);
}
return filas;
};
this.filas = this.getFilas(this.productos, this.numColumnas);
/*el observador:*/
/*this.$watch('this.numColumnas', function() {
this.filas = this.getFilas(this.productos, this.numColumnas);
});*/
});
var articulos = [{
nombre: 'FUJIFILM FinePix S8600 - negro - Cámara fotográfica digital',
precio: 149.00,
imagen: 'img/fujifilm.jpg',
stock: 5
}, {
nombre: 'PANASONIC VIERA TX-55AS650E - Televisor LED 3D Smart TV',
precio: 1499.00,
imagen: 'img/tv.jpg',
stock: 9
}, {
nombre: 'SAMSUNG Galaxy S4 Value Edition - blanco - 16 GB - Smartphone',
precio: 399.00,
imagen: 'img/fujifilm.jpg',
stock: 22,
}, {
nombre: 'WD WD Red WD40EFRX - 4 TB - Disco duro interno - 3.5"',
precio: 174.90,
imagen: 'img/disco-duro.jpg',
stock: 0,
}, {
nombre: 'SAMSUNG Gear Fit - negro - Reloj conectado',
precio: 199.00,
imagen: 'img/samsung-gear.jpg',
stock: 34,
}];
I'm guessing the problem has to do with this not referring to what you think it does within the watch callback. If you try binding this to a variable, does it work?
var self = this;
this.$watch('this.numColumnas', function() {
self.filas = self.getFilas(self.productos, self.numColumnas);
});
This way it works:
'use strict';
var app = angular.module('miTienda', []);
app.controller('TiendaController', ['$scope', function($scope) {
this.productos = articulos;
.....
var self=this;
$scope.$watch('tienda.numColumnas', function() {
self.filas = self.getFilas(self.productos, self.numColumnas);
});

ngRepeat dont refresh when I change the values - AngularJS

I'm doing a application to a calendar and I create a function that everytime change the values of my variable called "$scope.days", when I was using the version 1.0 didnt give error, but now the ngRepeat doesnt refresh, the new values go to the variable, but the ngRepeat dont show the new result...
$scope.loadMonth = function()
{
$scope.titleCalendar = $scope.months[$scope.month-1].name + ' ' + $scope.year;
getTotalFebruary($scope.year);
var dtString = $scope.year + '/' + $scope.month + '/' + 1,
date = new Date(dtString),
day = 1,
weekday = date.getDay(),
totalDays = $scope.months[date.getMonth()].qty + date.getDay();
$scope.days = [];
for(var i = 0; i < totalDays; i++)
{
if(i < weekday)
$scope.days.push('');
else
$scope.days.push(day++);
}
};
my html:
<div class="day" ng-repeat="day in days"><p>{{ day }}</p></div>
If I put an alert after push new values, I can see the new values, but my ngRepeat doesnt refresh the results, I already try many things but didnt work. Somebody know the solution?
Not sure I understand what you are trying to achieve given the small sample of code you provided but if you look at this sample you'll see that it should update the display every time you click the click me text, just enter either 1,2, or 3 in the input area. you might want to check that looping logic of yours.
<html lang="en-US" ng-app="mainModule">
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js"></script>
</head>
<body>
<div ng-controller="mainController">
<input type="text" ng-model="monthModel" placeholder="enter 1 2 or 3"/>
<h1 ng-click="loadMonth(monthModel)">Click Me to Repeat</h1>
<span class="day" ng-repeat="day in days">{{ day }} , </span>
</div>
<script type="text/javascript">
var app = angular.module("mainModule", []);
app.controller("mainController", function ($scope) {
//$scope.monthModel = 1; // default some date
$scope.year = "2014";
$scope.months = [
{"name":"January", "qty":10},
{"name":"February", "qty":5},
{"name":"March", "qty":10},
];
$scope.loadMonth = function(monthModel)
{
$scope.month = monthModel;
$scope.titleCalendar = $scope.months[$scope.month-1].name + ' ' + $scope.year;
//getTotalFebruary($scope.year);
var dtString = $scope.year + '/' + $scope.month + '/' + 1,
date = new Date(dtString),
day = 1,
weekday = date.getDay(),
totalDays = $scope.months[date.getMonth()].qty + date.getDay();
$scope.days = [];
for(var i = 0; i < totalDays; i++)
{
//if(i < weekday)
// $scope.days.push('');
//else
$scope.days.push(day++);
console.log($scope.days) ;
}
};
});
</script>
</body>
</html>

Resources