angularjs - Assigned value in controller but select field is still invalid - javascript

I have a select item that the values (multi-select) can be populated in the controller. But when I populate the value in the controller, the select still shows as invalid since this field is required.
Markup as per below.
<div ng-controller="host.views.newAnnouncement.index as vm">
<div class="portlet light bordered" id="form_wizard_1">
<div class="portlet-title">
<div class="caption">
<i class=" icon-speech font-blue"></i>
<span class="caption-subject font-blue bold">
New Announcement
</span>
</div>
</div>
<div class="portlet-body">
<div class="col-md-12">
<div class="alert alert-danger" ng-show="vm.isInError">
<p ng-repeat="message in vm.errorMessages">{{message}}</p>
</div>
<ng-form name="vm.announcementForm">
<div class="form-group form-md-line-input form-md-floating-label no-hint"
ng-class="{'has-error': (vm.announcementForm.announcementTypes.$dirty || vm.isValidated) && vm.announcementForm.announcementTypes.$invalid}">
<select class="form-control" name="announcementTypes" id="announcementTypes"
ng-class="{'edited': vm.model.announcementType}"
ng-model="vm.model.announcementType"
ng-options="announcementType.id as announcementType.name for announcementType in vm.announcementTypes"
required></select>
<label for="announcementTypes">Announcement Type</label>
</div>
<div class="form-group form-md-line-input no-hint"
ng-class="{'has-error': (vm.announcementForm.audienceTypes.$dirty || vm.isValidated) && vm.announcementForm.audienceTypes.$invalid}">
<select class="form-control" name="audienceTypes" id="audienceTypes"
ng-class="{'edited': vm.model.audienceType}"
ng-model="vm.model.audienceType"
ng-options="audienceType.id as audienceType.name for audienceType in vm.audienceTypes"
ng-change="vm.onAudienceTypeChange()"
required></select>
<label for="audienceTypes">Audience Type</label>
</div>
<div class="form-group form-md-line-input no-hint"
ng-class="{'has-error': (vm.announcementForm.audiences.$dirty || vm.isValidated) && vm.announcementForm.audiences.$invalid}">
<select class="form-control" name="audiences" id="audiences"
ng-class="{'edited': vm.model.audiences}"
ng-model="vm.model.audiences"
ng-options="audience.id as audience.name for audience in vm.audienceList | orderBy:'name'"
multiple required
style="min-height:300px;"></select>
<label for="audiences">Audience List <span ng-if="vm.model.audiences.length > 0">(Selected: {{vm.model.audiences.length}})</span></label>
</div>
<div class="form-group form-md-line-input form-md-floating-label no-hint"
ng-class="{'has-error': (vm.announcementForm.subject.$dirty || vm.isValidated) && vm.announcementForm.subject.$invalid}">
<input type="text" name="subject" class="form-control" ng-class="{'edited':vm.model.subject}" ng-model="vm.model.subject" maxlength="50" required>
<label>Subject</label>
</div>
<br />
<div class="form-group">
<label>Details</label>
<text-angular ta-text-editor-class="form-content" ta-html-editor-class="form-content" ng-model="vm.model.body"></text-angular>
</div>
<div class="row form-group col-md-12">
<label class="control-label">Attachement (zip)</label>
<input name="file" type="file" id="attachements" nv-file-select="" uploader="vm.fileUploader" accept=".zip"/>
</div>
</ng-form>
</div>
<hr />
<div class="row">
<div class="col-md-12">
<button type="button" class="btn default button-previous" ng-click="vm.back()">
<i class="fa fa-angle-left"></i> Back
</button>
<button type="button" class="btn green button-submit"
button-busy="vm.saving"
busy-text="#L("SavingWithThreeDot")"
ng-click="vm.submit()"
ng-disabled="vm.announcementForm.$invalid">
Submit
<i class="fa fa-check"></i>
</button>
</div>
</div>
</div>
</div>
Controller
(function () {
appModule.controller('host.views.newAnnouncement.index', [
'$scope', '$state', 'FileUploader', 'abp.services.app.hostAnnouncement', 'abp.services.app.hostSettings',
function ($scope, $state, FileUploader, announcementService, hostSettingsService) {
var vm = this;
vm.model = {
subject: '',
body: '',
announcementType: null,
audienceType: 0,
audiences: [],
feedbackId: null
};
vm.audienceList = [];
vm.announcementTypes = [
{ id: 0, name: 'General' },
{ id: 1, name: 'Penalty Invoice' },
{ id: 2, name: 'Other' }
];
vm.audienceTypes = [
{ id: 0, name: 'By Tenant' },
{ id: 1, name: 'By Store Category' },
{ id: 2, name: 'By Floor Location' },
{ id: 3, name: 'By Zone' }
];
vm.fileUploader = new FileUploader({
url: abp.appPath + 'AnnouncementDocument/UploadFileAsync',
filters: [
{
'name': 'enforceMaxFileSize',
'fn': function (item) {
return item.size <= 2097152; // 2 MiB to bytes
}
}
]
});
vm.submit = submit;
vm.back = back;
vm.onAudienceTypeChange = onAudienceTypeChange;
initialize();
vm.errorMessages = [];
vm.tenants = [];
vm.storeCategories = [];
vm.floorLocations = [];
vm.zones = [];
vm.announcementData = {
announcementId: null,
setAnnouncementId: function (announcementId) {
this.announcementId = announcementId;
}
}
function onAudienceTypeChange() {
vm.model.audiences = [];
if (vm.model.audienceType === 0) {
vm.audienceList = vm.tenants;
} else if (vm.model.audienceType === 1) {
vm.audienceList = vm.storeCategories;
} else if (vm.model.audienceType === 2) {
vm.audienceList = vm.floorLocations;
} else if (vm.model.audienceType === 3) {
vm.audienceList = vm.zones;
}
}
function initialize() {
vm.loading = true;
hostSettingsService.getAllSettings()
.success(function (result) {
_.each(result.storeCategories.split("|"), function (item) {
if (item !== "") {
vm.storeCategories.push({
name: item,
id: item
});
}
});
_.each(result.floorLocations.split("|"), function (item) {
if (item !== "") {
vm.floorLocations.push({
name: item,
id: item
});
}
});
_.each(result.zones.split("|"), function (item) {
if (item !== "") {
vm.zones.push({
name: item,
id: item
});
}
});
}).finally(function () {
announcementService.getTenants()
.success(function (result) {
vm.tenants = result;
vm.audienceList = vm.tenants;
}).finally(function () {
vm.loading = false;
autoSelectTenant($state.params);
});
});
}
function autoSelectTenant(stateParams) {
if (stateParams.tenantId && stateParams.feedbackId) {
vm.model.feedbackId = stateParams.feedbackId;
vm.model.audienceType = 0;
vm.model.audiences.push(stateParams.tenantId);
}
}
function submit() {
validate();
if (vm.isInError) return;
vm.saving = true;
vm.isValidated = true;
announcementService.createAnnouncementAsync(vm.model)
.success(function (announcementId) {
if (vm.fileUploader.queue.length > 0) {
vm.announcementData.setAnnouncementId(announcementId);
vm.fileUploader.uploadAll();
} else {
showSuccessNotification();
}
});
}
function back() {
$state.go('host.announcement');
}
function validate() {
vm.isInError = false;
vm.errorMessages = [];
if (vm.model.audiences.length < 1) {
vm.errorMessages.push("Please select an audience list.");
vm.isInError = true;
}
vm.isValidated = true;
}
vm.fileUploader.onBeforeUploadItem = function (fileItem) {
fileItem.formData.push(vm.announcementData);
};
vm.fileUploader.onCompleteAll = function () {
showSuccessNotification();
};
function showSuccessNotification() {
$state.go('host.announcement');
vm.saving = false;
abp.notify.success("Announcement has been successfully published.");
}
}
]);
})();
How do I programmatically set the selection values from the controller and make sure that the field is not invalid? The audiences value is being passes through the $state.params and I've added it to the vm.model.audiences array. But in the UI, vm.model.audiences is still marked as required even though it had values already.
EDIT : I've updated my question with full html and controller. For more clear understanding.

Try like this
var app = angular.module("app", []);
app.controller('mainCtrl', function($scope) {
var vm = this;
vm.model = {
audiences: []
};
vm.audienceList = [{
"name": "name1",
"id": 1
}, {
"name": "name2",
"id": 2
}, {
"name": "name3",
"id": 3
}];
vm.stateParams = {};
vm.stateParams.tenantId = 1;
vm.stateParams.feedbackId = 1;
vm.autoSelectTenant = function(stateParams) {
if (stateParams.tenantId && stateParams.feedbackId) {
vm.model.feedbackId = stateParams.feedbackId;
vm.model.audienceType = 0;
vm.model.audiences.push(stateParams.tenantId);
}
}
vm.autoSelectTenant(vm.stateParams);
vm.stateParams.tenantId = 2;
vm.stateParams.feedbackId = 2;
vm.autoSelectTenant(vm.stateParams);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.2/css/font-awesome.min.css" rel="stylesheet" />
<div ng-app="app" ng-controller="mainCtrl as vm">
<select ng-model="vm.model.audiences" ng-options="audience.id as audience.name for audience in vm.audienceList | orderBy:'name'" multiple required></select>
</div>

Related

Vue array updates in developer tools but doesn't re-render

I have a fairly complicated object with nested components. It looks sort of like this (stripped down for easier reading):
<script type="text/x-template" id="fieldset-template">
<div class="fieldset">
<div class="fieldset-repetition" v-for="(repetition, key) in repetitions">
<div class="field-list">
<field v-for="field in fields" v-bind:key="field.key" v-bind:fieldset="field.fieldset" v-bind:fieldset-key="key" v-bind:field-data="field"></field>
</div>
<div class="repetition-meta">
<a class="move-repetition" v-on:click="moveUp(key)">Up</a>
</div>
</div>
</div>
</script>
<script type="text/x-template" id="field-template">
<div class="field">
<div class="form-group">
<label class="control-label" v-html="name"></label>
<div class="field-repetition" v-for="(repetition, key) in repetitions">
<div class="field-text">
<input class="form-control" v-model="values[key]" />
</div>
</div>
</div>
</div>
</script>
<script>
Vue.component('set', {
components: {
field: {
created: function() {
// populate with data
this.populateData();
},
data: function() {
return {
repetitions: [],
values: [],
}
},
methods: {
populateData: function() {
this.repetitions = this.fieldData.repetitions;
this.repetitions.forEach(function(repetition, key) {
this.values = this.fieldData.value[this.fieldsetKey];
}.bind(this));
},
repeatField: function() {
var field = Object.clone(this);
delete field.repetitions;
this.repetitions.push(field);
if (this.widget != 'checkbox') {
this.values.push(this.fieldData.default);
}
else {
this.values.push([this.fieldData.default]);
}
},
},
props: {
fieldData: {
type: Object
},
fieldset: {
type: Object
},
fieldsetKey: {
type: Number
}
},
template: '#field-template'
}
},
data: function() {
return {
fields: [FieldObject1, FieldObject2, FieldObject3],
repetitions: [RepetitionObject1, RepetitionObject2, RepetitionObject3, RepetitionObject4, RepetitionObject5],
}
},
methods: {
moveUp: function(key) {
var field = this.fields[0];
var value = field.value[key];
field.value[key] = field.value[key - 1];
field.value[key - 1] = value;
this.$set(this.fields, 0, field);
}
},
template: '#fieldset-template'
});
</script>
Whenever the moveUp method runs, it updates the fields object, but the field component doesn't re-render.
I have suspicion it is because of the secondary (outer) for cycle for the repetitions, but I couldn't figure a way around it.
this.$set(this.fields, 0, field); won't do anything as this.fields[0] is already equal to field.
Assuming field.value is an array, it's this step that's making a non-reactive change:
field.value[key] = field.value[key - 1];
field.value[key - 1] = value;
See https://v2.vuejs.org/v2/guide/list.html#Caveats
You could write it as:
this.$set(field.value, key, field.value[key - 1]);
this.$set(field.value, key - 1, value);
Or use splice:
field.value.splice(key - 1, 2, field.value[key], field.value[key - 1]);

Trying to access a global variables method in javascript, but only works certain times

I have three files: tasker_matic.js, tasker.js, and tasker.html. I am not allowed to edit tasker.html or tasker.js AT ALL. I am to use tasker_matic to communicate with the tasker.js library.
Right now I am trying to access its login function. When the login is correct, it should pop up with an alert saying it worked, and when it isn't correct, it should pop up with an alert saying forbidden. This is where I am having the problem. If I continually click on the login button, it will eventually pop up with an alert, but not every time. Does anyone know why this is?
Tasker_matic.js:
function login(e) {
var userName = document.getElementById("usernameInput").value;
var password = document.getElementById("passwordInput").value;
tasker.login( userName, password, (err, user) => {
if (err) {
alert( err );
}
else if (user) {
alert("it worked");
}
});
}
function createTask(s) {
let descNode;
let theTable = document.getElementById('tasks');
let row = document.createElement('tr');
let description = document.createElement('th');
descNode = document.createTextNode(s);
description.append(descNode);
row.append(description);
theTable.append(row);
}
tasker.html:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Tasker</title>
<script src="tasker.js"></script>
<link rel="stylesheet" href="tasker_matic.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="tasker_matic.js"></script>
</head>
<body>
<div class="container">
<div id="login" class="on">
<h1>Login</h1><br>
<form style="width:50%">
<input id="usernameInput" type="text" name="username" placeholder="Username" class="form-control">
<input id="passwordInput" type="password" name="password" placeholder="Password" class="form-control">
<input type="submit" value="Login" class="btn btn-primary pull-right" onclick="login(event)">
</form>
</div>
<div id="home" class="off">
<h1>Tasker <small><span class="pull-right btn btn-primary btn-sm" id="logout" onclick="logout()"></span></small></h1>
<div class="well well-sm">
<form class="form-inline">
<div class="form-group">
<label for="descField">Description</label>
<input class="form-control" type="text" placeholder="Description" id="descField">
</div>
<div class="form-group">
<label for="cField">Color Code</label>
<input class="form-control" type="color" id="cField"/>
</div>
<div class="form-group">
<label for="dField">Due Date</label>
<input class="form-control" type="date" id="dField"/>
</div>
<input class="form-control" type="button" value="+" id="addButton" onclick="addTask()"/>
</form>
</div>
<div class="well well-sm">
<form class="form-inline">
<input class="form-control" type="text" placeholder="search" id="searchField" style="width:25%" onkeyup="searchTextChange()"/>
<div class="checkbox">
<label>
<input type="checkbox" id="incompleteBox" onclick="incompleteChange()"/>Incomplete Only
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" id="overdueBox" onclick="overdueChange()"/>Over-due only
</label>
</div>
</form>
</div>
<table id="tasks" class="table table-striped">
</table>
</div>
</div>
</body>
</html>
tasker.js:
let tasker = (function () {
let verbs = [
"make",
"install",
"update",
"generate data for",
"talk to",
"schedule a time for",
"develop a plan for",
"knit",
"create",
"build",
"write",
"get",
"finish",
"call",
"arrange",
"submit",
"talk to",
"do",
"protest",
"collect",
"shop for"
];
let nouns = [
"a cake",
"the boat",
"our wedding",
"the garage",
"the tow truck",
"our shed",
"1090 tax form",
"the IRS agent",
"milk",
"some LED lights",
"monthly budget",
"marketing plan",
"the flowers",
"an albatross"
];
let userNames = [
"frodo baggins",
"gandalf gray",
"smaug dragon"
];
let Task = function (id, ownerId, desc, due, color, complete) {
this.ownerId = ownerId;
this.desc = desc;
this.due = due;
this.color = color;
this.complete = complete;
this.id = id || randomId();
};
let randomId = function () {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
let randomColor = function () {
let pad = function (v) {
return v.length == 1 ? '0' + v : v;
}
r = Math.floor(Math.random() * 256).toString(16);
g = Math.floor(Math.random() * 256).toString(16);
b = Math.floor(Math.random() * 256).toString(16);
return '#' + pad(r) + pad(g) + pad(b);
}
let randomDate = function () {
year = Math.floor(Math.random() * 14 + 2010);
month = Math.floor(Math.random() * 12);
day = Math.floor(Math.random() * 31);
return new Date(year, month, day);
};
let choose = function (things) {
let i = Math.floor(Math.random() * things.length);
return things[i];
}
let randomDescription = function () {
return choose(verbs) + ' ' + choose(nouns);
};
let makeList = function (ownerId, n) {
result = [];
for (i = 0; i < n; i += 1) {
result.push(new Task(null,
ownerId,
randomDescription(),
randomDate(),
randomColor(),
choose([true, false])));
}
return result;
}
let updateTask = function( oldTask, editedTask ) {
let propertiesToCopy = ['desc', 'due', 'color', 'complete' ];
propertiesToCopy.forEach( prop => {
if( editedTask.hasOwnProperty( prop ) ) {
oldTask[prop] = editedTask[prop];
}
});
}
let state = {
users: userNames.reduce(function (acc, cv) {
let parts = cv.split(' '); //
let name = parts[0];
let email = parts[0][0] + parts[1] + '#uwlaxer.edu';
let id = randomId();
let password = parts[1];
let tasks = makeList(id, Math.random() * 50 + 20).reduce((acc, t) => { acc[t.id] = t; return acc; }, {});
acc[id] = {
name: name,
email: email,
id: id,
password: password,
tasks: tasks
};
return acc;
}, {}),
user: null
};
let getTask = function (ownerId, id) {
try {
return state.users[ownerId].tasks[id];
} catch (e) {
return null;
}
}
let getUserByName = function (name) {
for (id in state.users) {
if (state.users[id] && state.users[id].name === name) {
return state.users[id];
}
}
return null;
}
let taskList = function (ownerId) {
let result = [];
for (let tid in state.user.tasks) {
result.push(state.user.tasks[tid]);
}
return result.sort((a, b) => b.due.getTime() - a.due.getTime());
}
let respond = function (error, value, cb) {
window.setTimeout(() => cb(error, value), Math.random() * 1500);
}
let copyTask = function( task ) {
return new Task(task.id, task.ownerId, task.desc, task.due, task.color, task.complete);
}
return {
login: function ( username, passwd, cb) {
let user = getUserByName( username );
if (user && user.password === passwd) {
state.user = user;
let cleansedUser = { name: user.name, email: user.email, id: user.id };
respond(null, cleansedUser, cb);
} else {
respond('forbidden', null, cb);
}
},
logout: function (cb) {
state.user = null;
respond(null, true, cb);
},
tasks: function (ownerId, cb) {
if (ownerId === state.user.id) {
let tasks = taskList(ownerId).map(u => new Task(u.id, u.ownerId, u.desc, u.due, u.color, u.complete));
respond(null, tasks, cb);
} else {
respond('forbidden', null, cb);
}
},
add: function (ownerId, task, cb) {
if (state.user.id == ownerId) {
if (task.desc && task.due && task.color) {
let due = new Date(task.due);
let task = new Task(task.id, ownerId, task.desc, due, task.color, Boolean(task.complete));
state.users[ownerId].tasks[task.id] = task;
respond(null, task, cb);
} else {
respond('invalid task', null, cb);
}
} else {
respond('forbidden', null, cb);
}
},
delete: function (ownerId, taskId, cb) {
if (state.user.id === ownerId) {
let task = state.users[ownerId].tasks[taskId];
delete state.users[ownerId].tasks[taskId];
if (task) {
respond(null, task, cb);
} else {
respond('no such task', null, cb);
}
} else {
respond('forbidden', null, cb);
}
},
edit: function (ownerId, taskId, task, cb) {
if (state.user.id == ownerId) {
if (taskId) {
let oldTask = getTask(ownerId, taskId);
if( oldTask) {
updateTask( oldTask, task );
respond( null, copyTask( oldTask ), cb );
} else {
respond( 'no such task', null, cb );
}
} else {
respond( 'no such task', null, cb );
}
} else {
respond( 'forbidden', null, cb );
}
}
}
})();

How to get checked values from checkbox using Angular JS

Am new to angular JS. I have following check box and the data is coming from web service:
<label ng-repeat="r in MedicalConditions track by $index">
<input ng-model="ids[$index]" type="checkbox" ng-checked="r.value">
{{r.conditions_name}}
</label>
In console.log value is perfectly right as per my requirements. How to push value to an array i.e., arr[] and stringify it. I tried code like this..
//To fetch Medical Conditions List
$scope.parameter = "{}";
$scope.class0 = "{}";
$http.get('http://192.168.1.129:8080/apartment//member/medical/conditions/list').then(function(response) {
$scope.MedicalConditions = response.data.list;
});
$scope.$watchCollection('ids', function(newVal) {
$scope.parameter.class0 = $scope.ids;
});
$scope.alertdata = function() {
var parameter = {
"first_name": $scope.first_name,
"role": [{
"role_id": 1,
"name": "Admin",
"details": "text"
}],
"associated": [{
"associated_id": 1,
"associated_name": "Parent",
"primary_member_id": 1
}],
"class0": $scope.ids
}
parameter = JSON.stringify(parameter);
May be this will help:
angular.module('app', [])
.controller('Controller', function($scope) {
$scope.ids = {};
$scope.arr = {};
$scope.MedicalConditions = {};
$scope.MedicalConditions[0] = {};
$scope.MedicalConditions[0].value= true;
$scope.MedicalConditions[0].conditions_name= 'first value';
$scope.MedicalConditions[1] = {};
$scope.MedicalConditions[1].value= false;
$scope.MedicalConditions[1].conditions_name= 'seconde value';
$scope.$watchCollection('ids', function(newVal) {
$scope.parameter.class0 = $scope.ids;
});
$scope.parameter = {};
$scope.parameter.firstname = 'dummy name';
$scope.parameter.class0 = $scope.ids;
});
<!DOCTYPE html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="app">
<div ng-controller="Controller">
<label ng-repeat="r in MedicalConditions track by $index">
<input ng-model="ids[$index]" type="checkbox" ng-checked="r.value" > {{ r.conditions_name}}
</label>
<br>
Parameter: {{parameter}}
</div>
</body>
</html>
Try like below...
var app = angular.module('exApp',[]);
app.controller('ctrl', function($scope){
$scope.ids = [];
$scope.arr = [];
$scope.checkSelected = [];
$scope.MedicalConditions = [{"conditions_name":"xxz","conditions_id":"1"}, {"conditions_name":"yyz","conditions_id":"2"}, {"conditions_name":"zzz","conditions_id":"3"}];
$scope.$watchCollection('ids', function(newVal) {
for (var i = 0; i < newVal.length; ++i) {
console.log(newVal[i]);
$scope.arr.push(newVal[i]);
}
});
$scope.checkAllR = function () {
$scope.checkAll = !$scope.checkAll;
if ($scope.checkAll) {
$scope.checkSelected = [];
angular.forEach($scope.MedicalConditions, function (checkR) {
checkR.check = $scope.checkAll;
$scope.checkSelected.push(checkR);
});
}
else {
$scope.checkSelected = [];
angular.forEach($scope.MedicalConditions, function (checkR) {
var idx = $scope.checkSelected.indexOf(checkR);
checkR.check = $scope.checkAll;
$scope.checkSelected.splice(idx, 1);
});
}
};
$scope.addChecked = function (checked) {
if ($scope.checkSelected == undefined || $scope.checkSelected == null) {
$scope.checkSelected = [];
}
var idx = $scope.checkSelected.indexOf(checked);
// delete if exists
if (idx > -1) {
$scope.checkSelected.splice(idx, 1);
checked.check = false;
}
// add
else {
$scope.checkSelected.push(checked);
checked.check = true;
}
$scope.checkAll = $scope.checkSelected.length == $scope.MedicalConditions.length ? true : false;
};
var parameter = {
"first_name": $scope.first_name,
"middle_name": $scope.middle_name,
//"class0": /*stringified data i.e., arr[] */
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body ng-app="exApp" ng-controller="ctrl">
Select All : <input type="checkbox" name="checkbox" value="1" ng-checked="checkAll" ng-click="checkAllR()"><br>
<label ng-repeat="r in MedicalConditions">
<input type="checkbox" name="checkbox" class="check-nolabel" value="1" ng-checked="r.check" ng-click="addChecked(r)"> {{ r.conditions_name}}
</label><br><br>
{{checkSelected}}
</body>
Hope this helps.
<div ng-app="myApp" ng-controller="MyCtrl">
<label ng-repeat="r in MedicalConditions track by $index">
<input ng-model="ids[$index]"
ng-init="ids[$index] = r.value"
type="checkbox">
{{r.condition}}
</label>
</div>
And here is your controller.
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', function($scope){
$scope.ids = [];
$scope.MedicalConditions = [{
_id: 1,
value: true,
condition: 'Condition 1'
}, {
_id: 2,
value: false,
condition: 'Condition 2'
}, {
_id: 3,
value: true,
condition: 'Condition 3'
}];
});
JsFiddle
<label ng-repeat="r in MedicalConditions track by $index">
<input ng-model="ids[$index]" type="checkbox" ng-change="valCh(r)"> {{r.conditions_name}}
</label>
Controller code will look like this :
var postApp = angular.module('EntityApp', []);
postApp.controller('EntityAppCntroller', function($scope, $http, $window, $timeout, $location) {
//To fetch Medical Conditions List
$http.get('http://111.222.444:8080/apartment//member/medical/conditions/list').then(function(response) {
$scope.MedicalConditions = response.data.list;
});
var list = [];
$scope.valCh = function(value) {
list.push(value);
JSON.stringify(list);
}
$scope.alertdata = function() {
var parameter;
parameter = {
"parameter": {
"first_name": $scope.first_name,
"medicalconditions": list
}
}
$http({
url: 'http://111.222.333:8080/apartment//save/member/details',
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
data: JSON.stringify(parameter)
}).success(function(data, status) {
if (data.status == 'success') {
alert("User Created");
$location.reload();
} else if (data.status == 'failure') {
alert("Some failure please try again later !!!");
}
});
};
});

Angular filter by multiple strings in array

The issue is that filtering for items with 2 categories does not return anything. So by filtering for 'mulder' an item with the categories "mulder" and "scully" should be returned
I have data which defines the following:
$scope.allnodes = [
{ name: "This is node 1", category: ["mulder"] },
{ name: "Another title is this one", category: ["scully"] },
{ name: "This is Another title", category: ["mulder"] },
{ name: "And finally a fourth title", category: ["mulder","scully"] }
];
The relevant app js is:
$scope.categories = ['Mulder','Scully'];
$scope.filterByCategory = function (node) {
return $scope.filter[node.category] || noFilter($scope.filter);
};
function noFilter(filterObj) {
for (var key in filterObj) {
if (filterObj[key]) {
return false;
}
}
return true;
}
This is the partial rendering:
<div ng-controller="myCtrl">
<b>Category:</b>
<div ng-repeat="cat in categories">
<b><input type="checkbox" ng-model="filter[cat]" />{{cat}}
</b>
</div>
<hr />
<div ng-repeat="node in filtered=(allnodes | filter:filterByCategory)">
{{node.title}}
<div ng-repeat="term in node.category">
<label class="label label-info">{{term}}</label>
</div>
</div>
<hr />
Number of results: {{filtered.length}}
</div>
http://jsfiddle.net/kevinhowbrook/h2bekshb/6/
The problem is that node.category is an array.
Your filterByCategory should look something like this:
$scope.filterByCategory = function(node) {
for (var key in $scope.filter) {
if ($scope.filter[key] && (!node.category || node.category.indexOf(key) < 0)) {
return false;
}
}
return true;
};
This function checks that the categories of the current item contain all of the selected categories in the filter.
http://jsfiddle.net/cutm3p9c/1/

ngClick not firing in nested ngRepeat filled with data from $http.post()

I have an AngularJS app to search for journeys. In the part of the problem I am trying to show all available countries per region. The idea is that when you click a country, a function has to be executed. But it never fires...
Any help?
View
<div id="headersearch" ng-controller="ProductSearchController">
<div id="headersearchContainer">
<input id="tripchoise" class="field" type="text" placeholder="Hoe ver wil je gaan?" ng-model="country" ng-change="switchView('countries')" ng-blur="switchView('')" ng-focus="switchView('countries')" />
<div id="triptypechoise">
<div class="triptype" ng-class="{active: filter=='single'}" title="Singlereizen" ng-click="switchFilter('single')"><img src="/Resources/Images/Layout/singlereis.png" alt="Singlereizen" /></div>
<div class="triptype" ng-class="{active: filter=='custom'}" title="Maatwerkreizen" ng-click="switchFilter('custom')"><img src="/Resources/Images/Layout/maatwerk.png" alt="Maatwerkreizen" /></div>
<div class="triptype" ng-class="{active: filter=='group'}" title="Groepsreizen" ng-click="switchFilter('group')"><img src="/Resources/Images/Layout/groepsreis.png" alt="Groepsreizen" /></div>
</div>
<div id="tripdeparturedatechoise" class="field arrow">
{{date}}
</div>
</div>
<div id="headersearchButton">
<span>ZOEK</span>
</div>
<div class="clear"></div>
<input type="text" class="datepicker datehide" id="searchdepartureDate" ng-model="date" datepicker/>
<div id="searchList" ng-class="{hide:view==''}">
<div class="loadingproducts" data-ng-show="loading">Loading products...</div>
<article class="searchentry" ng-show="view=='countries'">
<div class="" ng-repeat="region in regions">
<p>{{region.Name}}</p>
<ul>
<li ng-repeat="country in region.Countries">
<a ng-click="test()">{{country.Name}}</a>
</li>
</ul>
</div>
</article>
</div>
</div>
CONTROLLER
SearchApp.controller("ProductSearchController", function ($scope, $http) {
$scope.date = "Vertrek";
$scope.filter = "single";
$scope.view = "";
$scope.country = "";
$scope.switchFilter = function (filter) {
if ($scope.filter != filter) {
$scope.filter = filter;
$scope.search();
}
}
$scope.switchView = function (view) {
if ($scope.view != view)
$scope.view = view;
if ($scope.view != "" && $scope.view != "countries")
$scope.search();
}
$http.post("/AVProductList/GetCountriesByRegionAsync")
.success(function (response) {
$scope.regions = response.regions;
});
$scope.search = function () {
$scope.loading = true;
$http.post("/AVProductList/SearchProductsHeader?view="+ $scope.view +"&filter=" + $scope.filter, { SearchParameters: {Country: $scope.country}})
.success(function (data) {
if ($scope.filter == "custom")
$scope.trips = data.results;
else {
if ($scope.view == "trips")
$scope.trips = data.grouped.RoundtripgroupCode.doclist.docs;
else if ($scope.view == "departures")
$scope.trips = data.response.docs;
}
});
};
$scope.changeDate = function () {
if (isValidDate($scope.date)) {
$scope.view = "departures";
$scope.search();
}
else {
$scope.date = "Vertrek";
$scope.view = "trips";
}
}
$scope.selectCountry = function (name, code) {
$scope.countrycode = code;
$scope.country = name;
$scope.view = isValidDate($scope.date) ? "departures" : "trips";
$scope.search();
}
$scope.test = function () {
alert("Hoi");
}
});
Json result example of
$http.post("/AVProductList/GetCountriesByRegionAsync")
.success(function (response) {
$scope.regions = response.regions;
});
{
regions:[
{
Name:"Asia",
Countries:
[
{
Name: "China",
Code: "CH"
}
,...
]
}
,...
]
}
I made a stupid mistake:
The ngBlur on "tripchoise" was fired before the ngClick.

Categories