Code in file view.html:
<label ng-repeat = "agents in acesslevel |filter:{acesslevel: 'Agent'}">
<div class="col-xs-2">
<input type= "checkbox"
ng-model="agentsSelected"
checklist-value="agents.name"
ng-true-value=agents ng-false-value="'NO'">
{{agents.name}}
</div>
</label>
Where acesslevel is JSON format data I'm getting from my database.
For example,
{
"acesslevel": "Quality",
"dob": "1995-02-03",
"name": "anjali",
"password": "tanya",
"username": "anju",
"createdAt": "2014-07-02T16:26:26.816Z",
"updatedAt": "2014-07-02T16:26:26.816Z",
"id": "53b432b230aaa394278522ca"
},
{
"acesslevel": "Agent",
"dob": "1995-02-03",
"name": "christopher",
"password": "tanya",
"username": "anju",
"createdAt": "2014-07-02T16:26:48.170Z",
"updatedAt": "2014-07-02T16:26:48.170Z",
"id": "53b432c830aaa394278522cb"
}
This particular code in HTML is displaying the names of agents in acesslevel (in above case it would display christopher)
How would I get the value of the selected checkbox in the controller?
I want to insert this selected agent's data in a new table in my database server.
The problem is that you are using ng-model which binds to (what I suppose is) an array, but Angular expects a Boolean value (true or false).
If you instead bind to a property of the instances of your filtered accesslevel array you can extract that data later in your controller
<label ng-repeat = "agents in acesslevel |filter:{acesslevel: 'Agent'}">
<div class="col-xs-2">
<input type= "checkbox"
ng-model="agents.isSelected" <!-- bind to another value -->
checklist-value="agents.name"
ng-true-value="agents"
ng-false-value="'NO'">
{{agents.name}}
</div>
</label>
Your controller can access this property later if you for instance have a method to submit values to your backend.
$scope.submit = function() {
var selectedAgents = [];
angular.forEach($scope.acesslevel, function (agent) {
if (agent.acesslevel == 'Agent' && agent.isSelected) {
selectedAgents.push(agent);
}
});
// Here you can make calls to your backend with the selectedAgents variable.
};
Related
I am trying to prepare a dynamic form that generates a form based on the columns present in the database table. Each form field is based on the columns present in the database table.
import { mapGetters } from 'vuex'
export default {
name: 'NewRecord',
data () {
return {
columnName: {
}
}
},
computed: {
...mapGetters(['columns'])
},
}
I am using mapGetters to pull columns from state. Structure of columns is :
[
{ "name": "id", "type": "varchar(255)", "label": "Id", "align": "left", "field": "id", "sortable": true, "__iconClass": "q-table__sort-icon q-table__sort-icon--left", "__thClass": "text-left sortable", "__tdClass": "text-left" },
{ "name": "username", "type": "varchar(80)", "label": "Username", "align": "left", "field": "username", "sortable": true, "__iconClass": "q-table__sort-icon q-table__sort-icon--left", "__thClass": "text-left sortable", "__tdClass": "text-left" }
{.......
.......}
]
I am generating form via following code:
<div class='columns row'>
<div class='col-3'
v-for='col in columns'
:key='col.name'>
<input standard type='text' :label='capital_letter(col.label)'
v-model="col.name"></input>
</div>
</div>
How can I use that v-model="col.name" in data property for two way binding.
Any help will be very much appreciated.
To manage two way binding to the state in a loop, I think you'll need to avoid v-model. Instead, you probably want to call a mutation on the change event. So your input will look like this:
<div class='col-3' v-for='(col, index) in columns' :key='col.id'>
<input
standard
type='text'
:label='capital_letter(col.label)'
:value="col.name"
#input="changeColumn($event, index)"
>
</div>
Notice that we're passing in the index from the loop, so you can target the appropriate column in the method below.
Then, in methods:
changeColumn(event, index) {
this.$store.commit('updateColumn', {i: index, value: event.target.value})
}
Then, using the payload object, change the appropriate column in your store (put this in mutations in the store):
updateColumn(state, payload) {
state.columns[payload.i].name = payload.value
}
Remember that in your view, you'll also need "...mapMutations(['updateColumn'])" etc...
You can read more about v-model with the state in the Vuex docs:
https://vuex.vuejs.org/guide/forms.html
Angular 1 app here.
I have this json file named data.json:
[
{
"rejectionType": "REJECTION_1",
"user": "ALL",
"selected": false
},
{
"rejectionType": "REJECTION_2",
"user": "MALE",
"selected": false
},
{
"rejectionType": "REJECTION_3",
"user": "FEMALE",
"selected": false
}
]
In controller I do the following:
$http.get('data.json').then(function(response) {
var rejectionData = response.data;
myctrl.currentRejections = _.filter(rejectionData, function(item, index) {
return _.contains(["ALL", "MALE"], item.user);
})
console.log("myCtrl.currentRejections:",myCtrl.currentRejections);
$("#modRejectionReason").modal("show");
});
The modal in the view looks like this:
<div id="modRejectionReason">
<div class="modal-body">
<p>
<div ng-repeat="allrejections in myctrl.currentRejections">
<p>
<input type="radio" name="selected" ng-model="allrejections.selected" />
{{allrejections.rejectionType}}
</p>
</div>
</p>
</div>
<div class="modal-footer">
<button type="button" ng-click="myctrl.func()">OK</button>
</div>
</div>
</div>
</div>
And then in the controller I have this:
var declineInvite = function () {
console.log("myctrl.currentRejections:",myctrl.currentRejections);
}
In the log I see that when the modal appears, then the variable myCtrl.currentRejections is printed. And it is an array with all the filtered elements.
For each element I see that the field selected is false.
When I then check a radio button and then click on the OK-button the function func is triggered.
Even here the same data is printed in the console. However, for those radio buttons that have been clicked in the json the value for the field selected is undefined.
What am I missing here?
You need to give the radio buttons a value to set when they are checked.
<input type="radio" name="selected" ng-model="allrejections.selected" ng-value="true"/>
The problem with doing this in your current code is that the selected:true will never be unset, so I suggest adding a new value on the controller called selectedRejection and using that as the model and setting the value to the actual rejection object. Doing this means you can get rid of the selected property on your JSON data too!
var myApp = angular.module('myApp', []).controller("MyCtrl", MyCtrl);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
function MyCtrl() {
var MyCtrl = this;
MyCtrl.currentRejections = [{
"rejectionType": "REJECTION_1",
"user": "ALL",
"selected": false
},
{
"rejectionType": "REJECTION_2",
"user": "MALE",
"selected": false
}
]
MyCtrl.selectedRejection = null;
MyCtrl.submit = function() {
console.log(MyCtrl.selectedRejection)
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp">
<div ng-controller="MyCtrl as MyCtrl">
<div ng-repeat="allrejections in MyCtrl.currentRejections">
<p>
<input type="radio" name="selected" ng-model="MyCtrl.selectedRejection" ng-value="allrejections" /> {{allrejections.rejectionType}}
</p>
</div>
<button type="button" ng-click="MyCtrl.submit()">OK</button>
</div>
</body>
I'm trying to get results from an api based on the user search box. When the user enters a value 'en' or 'de'. They should get the result from that search. I need to bind the user input into my query string. This works when I manually code the country into the template, but not when I bind the value into the string after the user inputs a value for the second time. The 'get' request that uses the user input value 'query' works fine. But not when I bind this a second time
I want to be fit to access
results[i].query.name
But '.query' is not working when I query the data unless I enter the value manually '.en'
I have a json file that looks like the following
[
{
"en": {
"name": "testone",
"id": 5363289,
"location": "messages_en.properties1"
},
"de": {
"name": "testonede",
"id": 5363289,
"location": "messages_en.properties2"
}
},
{
"en": {
"name": "test2",
"id": 5363289,
"location": "messages_en.properties3"
},
"de": {
"name": "test2de",
"id": 5363289,
"location": "messages_en.properties4"
}
}
]
Below is my index.html vue.js template
<div id=#app>
<input type="text" v-model="query" placeholder="Choose Language" />
<div class="medium-6 columns">
<a #click="getResult(query)" class="button expanded">Retrieve</a>
</div>
<template v-for="(result, i) in results">
<div class="card" style="width: 20rem; display:inline-block;">
<div class="card-block"></div>
<p> {{results[i].query}} </p>
<!-- works when I manually code in the 'en' query but when ran with 'query' it returns an error 'Cannot read property 'name' of undefined"' second time it returns that the value is -->
<!-- <p> {{results[i].en.name}} </p> -->
<!-- <p> {{results[i].query.name}} </p> -->
</div>
</template>
</div>
Vue.js
el: '#app',
data () {
return {
search: '',
query: 'en',
results: '',
title: '',
items: '',
section: ''
}
},
methods: {
getResult(query) {
axios.get('http://localhost:3000/api/country?country=' + query + '&blank=true').then(response => {
this.results = response.data;
console.log(this.results);
});
},
You need to use bracket notation to access a property using a param, so:
results[i][query].name
The second issue is that results[i][query] will be undefined until the async call has completed, so you will need to check that the property is not undefined or use a boolean flag. So, to check that it is not undefined you could do something like:
<p v-if="!!results[i][query]">{{results[i][query].name}}</p>
<p v-else>Loading...</p>
Here's a simplified JSFiddle for that: https://jsfiddle.net/4w3dxm22/
Or you could just use a dataLoaded flag:
new Vue({
el: '#app',
methods:{
getResult(query) {
this.dataLoaded = false; // set dataLoaded to false
axios.get('http://localhost:3000/api/country?country=' + query + '&blank=true').then(response => {
this.results = response.data;
this.dataLoaded = true; // Data has loaded so set dataLoaded to true
});
},
data: {
dataLoaded: false
}
})
Then you can do:
<span v-if="dataLoaded">{{results[i][query].name}}</span>
<span v-else>Loading Data...</span>
Here's the simplified JSFiddle for that: https://jsfiddle.net/99ydx82u/
Im using ngOptions for select directive like
<select class="form-control" ng-model="users.jobTitle" name="jobTitle" data-ng-options="job as job.value for job in ds.jobTitle" required>
im setting default in controller like
$scope.users.jobTitle = $scope.ds.jobTitle[0];
ds is a json with array jobtitle:
"jobTitle":[
{"id":1,"value":"Service1"},
{"id":2,"value":"Service2"},
{"id":3,"value":"Service3"}
],
now i'm saving and getting result(console) like
jobTitle:Object
$$hashKey:"object:173"
id:1
value:"Service1"
now when i'm editing, feeding the service call data like
$scope.useredit.jobTitle = data.jobTitle;
for
<select class="form-control input-sm" ng-model="useredit.jobTitle" name="jobTitle" data-ng-options="job as job.value for job in ds.jobTitle" required>
</select>
its not setting the object as selected , instead sets the null value in first option..
what i have to do ?
By default, ngModel watches the model by reference, not value. This is
important to know when binding the select to a model that is an object
or a collection.
One issue occurs if you want to preselect an option. For example, if
you set the model to an object that is equal to an object in your
collection, ngOptions won't be able to set the selection, because the
objects are not identical. So by default, you should always reference
the item in your collection for preselections, e.g.: $scope.selected =
$scope.collection[3].
Another solution is to use a track by clause, because then ngOptions
will track the identity of the item not by reference, but by the
result of the track by expression. For example, if your collection
items have an id property, you would track by item.id.
~ Taken from the official docs regarding ngOptions
I tested it out by using ng-options in separate select boxes and it works.
See demo below.
angular.module('app', [])
.controller('TestController', ['$scope',
function($scope) {
$scope.ds = {};
$scope.ds.jobTitle = [{
"id": 1,
"value": "Service1"
}, {
"id": 2,
"value": "Service2"
}, {
"id": 3,
"value": "Service3"
}];
var data = {
jobTitle: {
"id": 1,
"value": "Service1"
}
};
$scope.useredit = {
jobTitle: data.jobTitle
};
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="TestController">
<br />Without using track by in ngOptions
<select class="form-control" ng-model="useredit.jobTitle" name="jobTitle" data-ng-options="job as job.value for job in ds.jobTitle" required>
</select>
<br />
<br />
<br />Using track by in ngOptions
<select class="form-control" ng-model="useredit.jobTitle" name="jobTitle" data-ng-options="job as job.value for job in ds.jobTitle track by job.id" required>
</select>
</div>
</div>
I'm having a JSON Collection, I wish to dispay Email ID which is marked as IsPreffered = TRUE using AngularJS HTML without .
user.Name
My JSON Collection :
{ "user" : [
{
"Name" : "B. Balamanigandan",
"Email": [
{
"Id": "bala#gmail.com",
"IsPreffered": true
},
{
"Id": "mani#gmail.com",
"IsPreffered": false
}
]}
]};
HTML Source Code:
<div>
<h3>Employee Details:</h3>
<span> {{collection.user.Name}} </span>
<span> {{collection.user.Email.Id}} </span>
</div>
The Collection user contains only one document. So, I didn't use ng-repeat. user is a Collection not a Document. One more check I need. If more than one email has `IsPreferred == true', then I have the take the last one. Kindly assist me.
Kindly filter the condition using HTML Level not in JavaScript Level. Kindly assist me.
instead of this:
<div>
<h3>Employee Details:</h3>
<span> {{collection.user.Name}} </span>
<span> {{collection.user.Email.Id}} </span>
</div>
you will have to do this:
<div>
<h3>Employee Details:</h3>
<span> {{collection.user[0].Name}} </span>
<span ng-repeat="email in collection.user[0].email| filter: {IsPreffered : 'true'}"> {{email.Id}} </span>
</div>
You have to use array syntax, because although there is only 1 user object, it is structured in the json as an array ( note the [ ] , same for Email).
Here is a fiddle: http://jsfiddle.net/Lvc0u55v/5593/
UPDATE: For showing only the last email which is true, use ng-if:
<span ng-repeat="email in collection.user[0].Email| filter: {IsPreffered : true} " ng-if="$last"> {{email.Id}}</span>
Here is the updated fiddle:
http://jsfiddle.net/Lvc0u55v/5594/
One way to do this is to use ngRepeat on the user Emails array with a filter to get only those Emails where "IsPreffered": true. The filter compares each object in the Emails array with the filter object (filterEmail). This filter object is defined in the controller - this way you will be able to change by demand or even set it dynamically.
var app = angular.module('app', []);
app.controller('ctrl', function($scope) {
$scope.collection = {
"user": {
"Name": "B. Balamanigandan",
"Email": [{
"Id": "bala#gmail.com",
"IsPreffered": true
}, {
"Id": "mani#gmail.com",
"IsPreffered": false
}]
}
};
$scope.filterEmail = {
"IsPreffered": true
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="app" ng-controller="ctrl">
<div>
<h3>Employee Details:</h3>
<span> {{collection.user.Name}} </span>
<span ng-repeat="email in collection.user.Email | filter : filterEmail ">
{{email.Id}}
</span>
</div>
</body>
NOTE: To my understanding it doesn't make much sense to have user as an array inside an object (in my example I removed the inner array). If you insist on keeping this data-schema, you will need to change every reference of collection.user to collection.user[0].