I'm trying to pass form values including checkboxes in angular 6 forms using formbuilder but I'm unable to read the value from checkbox. I am getting all the values from all the other input fields but only checkbox is not responding Here is my code:
<form [formGroup]="myGroup" (submit)="submit(myGroup.value)">
<div class="row">
<div class="col-sm-4" *ngFor="let info of myGroup.controls['myInfo'].controls; let i = index">
<label for="{{labelValue[i].name}}"> {{labelValue[i].label}}
<input type="{{labelValue[i].type}}" class="{{labelValue[i].class}}" [formControl]="info">
</label>
</div>
</div>
<div class="row">
<button class="form-control btn-sub" type=”submit”>
Submit Details
</button>
</div>
My component class:
import { ProposalService, CustomerDetails, ProposalNumber } from 'src/app/Services/Proposal-service/proposal.service';
export interface InputType{
name:string;
type: string;
label: string;
class:string;
}
export class ProposalComponent implements OnInit {
public labelValue: InputType[] = [
{name:"fname",type:"text",label:"First Name", class:"form-control"},
{name:"form60",type:"checkbox",label:"Is Collection Of form 60", class:"form-control"},
{name:"eia-num",type:"number",label:"EIA Number", class:"form-control"}
];
title = "Customer Details";
details: Observable<CustomerDetails>;
pNumber: ProposalNumber ;
public information: CustomerDetails[] = [
{name:"First Name", value:""},//
{name:"IsCollectionOfform60", value:true},
{name:"EIA Number", value:""}
];
myGroup : FormGroup;
constructor(private formBuilder: FormBuilder,
private _proposalService: ProposalService) { }
ngOnInit() {
this.myGroup = this.formBuilder.group({
myInfo: this.constructFormArray()
});
this.pNumber = <ProposalNumber>{proposalNumber: 0 ,message:"", status: ""};
}
constructFormArray()
{
const arr = this.information.map(cat => {
return this.formBuilder.control(cat.value);
});
return this.formBuilder.array(arr);
}
submit(form){
//this.loading = true;
console.log(form);
let mySelectedAddon = form.myInfo.map((currentValue,i)=> {
return { "name" : this.information[i].name , "value" : currentValue}
}
);
console.log(mySelectedAddon);
this._proposalService.loadCustomer(mySelectedAddon).subscribe((res: ProposalNumber) =>{
//this.loading = false;
console.log(res);
this.pNumber.proposalNumber = res.proposalNumber;
this.pNumber.message = res.message;
console.log(this.pNumber.proposalNumber);
return this.myGroup.value;
});
}
}
You need to use the 'change' event and pass the respective input value and event to a method onChange where you check if it's checked, then add the respective value to the formarray, if it's unchecked, remove the chosen email from the form array.
You can refer the below link:
https://stackblitz.com/edit/angular-rskaug?file=src%2Fapp%2Fapp.component.ts
Above example is useful to get the values of checkbox dynamically.
In a table I have a checkbox bound to a bool in an observable array.
If any of the checkboxes in the table are checked / unchecked I want to update some text with the total checked.
I cannot get the computed function to fire, I have tried using ko.utils.unwrapObservable on both the array and location.isSelected in the 'if' statement below, am I just using it in the wrong place?
<input type="checkbox" data-bind="checked: isSelected"/>
<span class="text-left h5 ">Total Selected:</span><span data-bind="text: totalSelected" />
self.totalSelected = ko.computed(function () {
var selected = 0;
ko.utils.arrayForEach(self.SelectedLocations(), function (location) {
if (location.isSelected == true) {
selected = (+selected) + 1;
}
});
return selected;
}, self).extend({ notify: 'always' });
One of the issues is that isSelected is treated like a variable inside the computed: location.isSelected == true. However, if you intend to bind a checkbox to it, it must be an observable.
So, I have declared a function to create the children of self.SelectedLocations as:
var locationObservable = function() {
var self = this;
self.isSelected = ko.observable(false);
};
Then, you could change the counting in the computed variable as follows:
if (loc.isSelected()) {
selected++;
}
var locationObservable = function(selected) {
var self = this;
self.isSelected = ko.observable(selected);
};
var model = function() {
var self = this;
self.SelectedLocations = ko.observableArray();
self.SelectedLocations.push(new locationObservable(false)); // Set the state of the checkbox here.
self.SelectedLocations.push(new locationObservable(true));
self.SelectedLocations.push(new locationObservable(false));
self.totalSelected = ko.computed(function() {
var selected = 0;
ko.utils.arrayForEach(self.SelectedLocations(), function(loc) {
if (loc.isSelected()) {
selected++;
}
});
return selected;
}, self);
};
var vm = new model();
ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div data-bind="foreach: SelectedLocations">
<input type="checkbox" data-bind="checked: isSelected" />
</div>
<span class="text-left h5 ">Total Selected:</span><span data-bind="text: totalSelected" />
How do I populate a dropdown with records/documents created by the logged in user? I have a collection that many users can create schools. I want it to be that if a user that have created more than a school the dropdown should show populated with the number of schools. If it is only one, the _id of the school should just be passed to a hidden field.
This is the school collection:
if (Meteor.isServer) {
Meteor.methods({
SchoolRegister: function (newschoolname, newschoolmotto, newschholvision, sellschool, schooltype,
schoolfeerange, schoolcurriculum) {
if (!Meteor.userId()) {
throw new Meteor.Error('Not authorized', 'You must be logged in to add a new school!');
return false;
}else{
var regUsername = Meteor.user().username;
var year = new Date().getFullYear();
var month = new Date().getMonth() + 1;
var day = new Date().getDate();
var date = (month +"/" +day +"/" +year).toString();
var schoolId = NewSchoolDB.insert({
newschoolnamevar: newschoolname,
newschoolmottovar: newschoolmotto,
newschholvisionvar: newschholvision,
sellschoolvar: sellschool,
schooltypevar: schooltype,
schoolfeerangevar: schoolfeerange,
schoolcurriculumvar: schoolcurriculum,
createdAt: new Date(),
author: regUsername,
authorId: Meteor.userId()
});
return schoolId;
}
},
UserRecords: function () {
if (!Meteor.userId()) {
throw new Meteor.Error('Not authorized', 'You must be logged in to add a new school!');
return false;
}else{
//var UserDocuments = NewSchoolDB.find({authorId: Meteor.userId()}).count();
return NewSchoolDB.find({authorId: Meteor.userId()});
}
}
});
}
I'm using this to call the method:
Template.SchoolContactLayout.helpers({
UsersDocuments: function () {
return Meteor.call('UserRecords');
console.log(Meteor.call('UserRecords'));
}
});
This is the template file
{{# if UsersDocuments == 1 }}
<input type="hidden" name="schoolId" value="{{ UsersDocuments._id }}">
{{else}}
<div class="form-group">
<select class="form-control" name="schoolnames" id="schoolnames" required style="color: black; width: 100%; font-family: 'candara'">
<option value="{{UsersDocuments._id}}">{{UsersDocuments.newschoolnamevar}}</option>
</select>
</div>
{{/if}}
All in all, no error was returned and it did not work.
Meteor.call('UserRecords') is Async function you have to wait for it in a callback and use session instead.
Meteor.call('UserRecords', function(err,res){
// res will be your return value you can set your session here
});
or you can use package for example you can search atmosphere for reactive method
I build a Form in angular2 and typescript.
I try to add a list of checkboxes dynamically and it's not working for me, Where is my mistake?
The template code:
<div formArrayName="categories">
<div class="form-group" *ngFor="let category of updateDetailsForm.controls.categories.controls; let i = index">
<label>
<input type="checkbox" formControlName="{{i}}">
{{category.name}}
</label>
</div>
</div>
The Typescript code:
updateDetailsForm: FormGroup;
private categories : Category[] = []
constructor(private router: Router,
private ss : SearchService,
private formBuilder: FormBuilder)
{
this.initForm() // before the categories loaded
this.ss.getAllCategories().subscribe(
data => {
this.categories = data
this.initForm() // refresh the form with categories
}
)
}
initForm() {
let allCategories: FormArray = new FormArray([]);
for (let i = 0; i < this.categories.length; i++) {
allCategories.push(
new FormGroup({
'name': new FormControl([this.categories[i].categoryName])
})
)
}
this.updateDetailsForm = this.formBuilder.group({
'image' : [''],
'categories': allCategories
})
}
This is my UI result, and I get the following error:
"inline template:17:33 caused by: control.registerOnChange is not a function"
The number of checkboxes is correct but the text is missing and I can't update the form result with user selection.
What the error means?
How can I insert the right text next the checkbox?
How can update the user selection into the form value?
You've built out your form model in such a way that we'll need to access each FormGroup that you pushed onto the array and then access the named control within:
<span formGroupName="{{i}}">
<input type="checkbox" formControlName="{{category.name}}">
{{category.name}}
</span>
We'll also need to tweak how we're pushing values so that the name is set uniquely instead of always set as "name":
let fg = new FormGroup({});
fg.addControl(this.categories[i].name, new FormControl(false))
allCategories.push(fg)
Here's a plunker to demo it: http://plnkr.co/edit/OTiqwr1oCb8uEThQyDHx?p=preview
I think because of same name categories of your component variable and form group control you are getting error. Check it by making below change in your component and form HTML :
You can check FormArrayName directive for more reference.
//Component
updateDetailsForm: FormGroup;
private allCategories : Category[] = []
constructor(private router: Router,
private ss : SearchService,
private formBuilder: FormBuilder) {
this.initForm() // before the categories loaded
this.ss.getAllCategories().subscribe(
data => {
this.allCategories = data
this.initForm() // refresh the form with categories
}
)
}
initForm() {
let allCategories: FormArray = new FormArray([]);
for (let i = 0; i < this.allCategories.length; i++) {
allCategories.push(new FormControl());
}
this.updateDetailsForm = this.formBuilder.group({
'image' : [''],
'categories': allCategories
})
}
// Form HTML
<div formArrayName="categories">
<div class="form-group" *ngFor="let category of categories.controls; let i = index">
<label>
<input type="checkbox" formControlName="i">
{{allCategories[i].name}}
</label>
</div>
</div>
I have created a sample database and test scripts with it.
The database structure is:
I have created a JSFiddle for it: fiddle
Click all the buttons except stress test on the top, then click the tests.
The problem is, it perfectly works with provider webSql, but it fails on the provider indexedDb. I downloaded the pro packages and it makes test 3 work partially but it still fails on test 2 completely.
The problem i found is when i query the database with join relation(ex: employees in with department.ID is 1) indexedDb cannot process this request.
How can circumvent this situation?
Whole code is:
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="jaydataPro/jaydata.min.js"></script>
<script src="jaydataPro/jaydataproviders/IndexedDbProProvider.min.js"></script>
<script src="jaydataPro/jaydataproviders/SqLiteProProvider.min.js"></script>
<script src="jaydataPro/jaydataproviders/WebApiProvider.min.js"></script>
<script src="jaydataPro/jaydataproviders/YQLProvider.min.js"></script>
<script src="sampledatabase.js"></script>
<script src="test.js"></script>
<title>Jaydata Test</title>
</head>
<body>
<div>
<h3>Database Generation</h3>
<div>
<button onclick="TestAddDepartments(5);">Add Departments</button>
</div>
<div>
<button onclick="AddEmployeeList(TestEmployeeList(1,100),1);"> Employees 1</button>
<button onclick="AddEmployeeList(TestEmployeeList(101,100),2);">Employees 2</button>
<button onclick="AddEmployeeList(TestEmployeeList(201,100),3);">Employees 3</button>
<button onclick="AddEmployeeList(TestEmployeeList(301,100),4);">Employees 4</button>
<button onclick="AddEmployeeList(TestEmployeeList(401,100),5);">Employees 5</button>
</div>
<div>
<button onclick="AddStockList(TestStockList(1,400),1);">
Stocks 1</button>
<button onclick="AddStockList(TestStockList(401,400),2);">
Stocks 2</button>
<button onclick="AddStockList(TestStockList(801,400),3);">
Stocks 3</button>
<button onclick="AddStockList(TestStockList(1201,400),4);">
Stocks 4</button>
<button onclick="AddStockList(TestStockList(1601,400),5);">
Stocks 5</button>
</div>
<div>
<button onclick="AddStockList(TestStockList(2001,5000),2);">
Stress Test for Test 3</button>
</div>
</div>
<div>
<h3>Queries</h3>
<button onclick="TestSearchEmployeeName1()">Test 1</button>
<button onclick="TestSearchEmployeeName2()">Test 2</button>
<button onclick="TestSearchEmployeeName3()">Test 3</button>
</div>
<div>
<h3>Results</h3>
<p id='Result'>Result</p>
</div>
</body>
</html>
sampledatabase.js:
/*
x is a database
Database name is Company
Company has 3 tables:
=Departments
-ID(key,computed)
-DepartmentName(string,required)
=Employees
-ID(key,computed)
-Name(string,required)
=Stocks
-ID(key,computed)
-Description(string)
-NumItems(int,required)
Employee is connected to Department
Stock is connected to Department
Department has a list of Stocks and Employees
To do:
-insert websql and indexeddb translations to the document
*/
$data.Entity.extend("Org.Employee",{
ID: {key: true, type: "integer", computed: true},
Name: {type: "string", required: true},
Department: {type: "Org.Department", inverseProperty: "Employees"}
});
$data.Entity.extend("Org.Stock",{
ID: {key: true, type: "integer", computed: true},
Description: {type: "string"},
NumItems: {type: "integer", required: true},
Department: {type: "Org.Department", inverseProperty: "Stocks"}
});
$data.Entity.extend("Org.Department",{
ID: {key: true, type: "integer", computed: true},
DepartmentName: {type: "string", required: true},
Employees:{type: Array, elementType: "Org.Employee", inverseProperty:"Department"},
Stocks:{type: Array, elementType: "Org.Stock", inverseProperty:"Department"}
});
$data.EntityContext.extend("Company",{
Employees: {type: $data.EntitySet, elementType: Org.Employee},
Departments: {type: $data.EntitySet, elementType: Org.Department},
Stocks: {type: $data.EntitySet, elementType: Org.Stock}
});
var x= new Company({
provider: "indexedDb",
databaseName: "DB",
version: 1,
dbCreation: $data.storageProviders.DbCreationType.DropAllExistingTables
});
function AddEmployee(emp,department)
{
x.Departments.first(
function(it){
return it.ID==department.valueOf()
},
{emp:emp,department:department},
function(dep){
x.Departments.attach(dep);
emp.Department=dep;
x.Employees.add(emp);
x.Employees.saveChanges();
}
);
}
function RemoveEmployee(emp_id)
{
x.Employees.first(
function(res){
return res.ID==emp_id.valueOf();
},
{emp_id:emp_id},
function(emp)
{
x.Employees.remove(emp);
x.Employees.saveChanges();
}
);
}
function ChangeEmployeeName(emp_id,new_name)
{
x.Employees.first(
function(res){
return res.ID==emp_id.valueOf();
},
{emp_id:emp_id,new_name:new_name},
function(emp)
{
x.Employees.attach(emp);
emp.Name=new_name;
x.Employees.saveChanges();
}
);
}
function RemoveDepartment(dep_id)
{
x.Employees.filter(
function(res){
return res.Department.ID==dep_id
},
{dep_id:dep_id}
).forEach(
function(it){
x.Employees.remove(it)
});
x.Employees.saveChanges();
x.Departments.first(
function(it)
{
return it.ID==dep_id;
},
{dep_id:dep_id},
function(dep)
{
x.Departments.remove(dep);
x.Departments.saveChanges();
}
);
}
function AddStock(stock,department)
{
x.Departments.first(
function(it){
return it.ID==department.valueOf()},
{emp:emp,department:department},
function(dep){
x.Departments.attach(dep);
stock.Department=dep;
x.Stocks.add(stock);
x.Stocks.saveChanges();
});
}
function AddEmployeeList(list,department)
{
x.Departments.first(
function(it){return it.ID==department.valueOf()},
{department:department,list:list},
function(dep){
for (var i = 0; i < list.length; i++) {
list[i].Department=dep;
};
x.Departments.attach(dep);
x.Employees.addMany(list);
x.Employees.saveChanges();
});
}
function AddStockList(list,department)
{
x.Departments.first(
function(it){return it.ID==department.valueOf()},
{department:department,list:list},
function(dep){
for (var i = 0; i < list.length; i++) {
list[i].Department=dep;
};
x.Departments.attach(dep);
x.Stocks.addMany(list);
x.Stocks.saveChanges();
});
}
test.js:
//testing script
function TestAddDepartments(number) //number of departments
{
var dep='Department';
for (var i = 1; i <= number.valueOf(); i++)
{
var temp=dep+i.toString();
x.Departments.add({DepartmentName:temp});
};
x.Departments.saveChanges();
}
function TestEmployeeList(start,number)
{
emp_list=new Array();
var emp='Employee';
for (var i = start.valueOf(); i < start.valueOf()+number.valueOf(); i++)
{
var temp=emp+i.toString();
emp_list.push({Name:temp});
};
return emp_list;
}
function TestStockList(start,number)
{
stock_list=new Array();
var stock='Stock';
for (var i = start.valueOf(); i < start.valueOf()+number.valueOf(); i++)
{
var temp=stock+i.toString();
var num=Math.floor((Math.random()*1000)+1);
stock_list.push({Description:temp,NumItems:num});
};
return stock_list;
}
/*function TestSearchEmployeeName(number,limit)
{
var start= new Date().getTime();
var emp='Employee';
for (var i = 1; i <= number.valueOf(); i++)
{
num=Math.floor((Math.random()*limit.valueOf())+1);
search=emp+num.toString();
x.Employees.filter(
function(res)
{
return res.Name==search;
}).
forEach(
function(it)
{
console.log(it.Name);
});
};
var elapsed=new Date().getTime()-start;
console.log("Searching the database with "+number.toString()+
" entries took "+elapsed.toString()+" milliseconds");
}
*/
//Static tests
function TestSearchEmployeeName1()
{
var start= new Date().getTime();
x.Employees.filter(
function(res)
{
return res.Name=='Employee43';
},{start:start}).
toArray(function(it){
var elapsed=new Date().getTime()-start;
var res="Query with "+it.length.toString()+" result took "+
elapsed.toString()+" milliseconds";
document.getElementById('Result').innerHTML = res;
},{start:start}
);
}
function TestSearchEmployeeName2()
{
var start= new Date().getTime();
x.Employees.filter(
function(res)
{
return res.Department.ID==1;
},{start:start}).
toArray(function(it){
var elapsed=new Date().getTime()-start;
var res="Query with "+it.length.toString()+" results took "+
elapsed.toString()+" milliseconds";
document.getElementById('Result').innerHTML = res;
},{start:start}
);
}
function TestSearchEmployeeName3()
{
var start= new Date().getTime();
x.Stocks.filter(
function(res)
{
return res.NumItems>258 || res.Department.ID<3;
},{start:start}).
toArray(function(it){
var elapsed=new Date().getTime()-start;
var res="Query with "+it.length.toString()+" results took "+
elapsed.toString()+" milliseconds";
document.getElementById('Result').innerHTML = res;
},{start:start}
);
}
According to the provider feature matrix, the include() and complex type mapping features aren't implemented yet for IndexedDB, this means you cannot have navigation properties in IndexedDB, only in SQLite/WebSQL.
You can propose this feature at the user voice page.