Autocomplete for Two <Input> - forms

I get a code from Google to autocomplete address fields. It works well for one "Input type=text". I use it for "Departure"
Problem is when i duplicate these code to have a second "Input type=text" as "Arrival" : it only works for one of them.
I Tried to change input id="autocomparr" and some var without success.
Regards
<input id="autocompdep"
placeholder="Enter your address"
onFocus="geolocate()"
type="text"/>
<script>
var placeSearch, autocomplete;
var componentForm = {
street_number: 'short_name',
route: 'long_name',
locality: 'long_name',
administrative_area_level_1: 'short_name',
country: 'long_name',
postal_code: 'short_name'
};
var options = {
componentRestrictions: {country: 'fr'}
};
function initAutocomplete() {
// Create the autocomplete object, restricting the search predictions to
// geographical location types.
autocomplete = new google.maps.places.Autocomplete(
document.getElementById('autocompdep'), options, {types: ['geocode']});
// Avoid paying for data that you don't need by restricting the set of
// place fields that are returned to just the address components.
autocomplete.setFields(['address_component']);
// When the user selects an address from the drop-down, populate the
// address fields in the form.
autocomplete.addListener('place_changed', fillInAddress);
}
function fillInAddress() {
// Get the place details from the autocomplete object.
var place = autocomplete.getPlace();
for (var component in componentForm) {
document.getElementById(component).value = '';
document.getElementById(component).disabled = false;
}
// Get each component of the address from the place details,
// and then fill-in the corresponding field on the form.
for (var i = 0; i < place.address_components.length; i++) {
var addressType = place.address_components[i].types[0];
if (componentForm[addressType]) {
var val = place.address_components[i][componentForm[addressType]];
document.getElementById(addressType).value = val;
}
}
}
// Bias the autocomplete object to the user's geographical location,
// as supplied by the browser's 'navigator.geolocation' object.
function geolocate() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var geolocation = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
var circle = new google.maps.Circle(
{center: geolocation, radius: position.coords.accuracy});
autocomplete.setBounds(circle.getBounds());
});
}
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=***&libraries=places&callback=initAutocomplete"
async defer></script>````

Answer to myself (and for others that will have this problem)
It is now working for 2 input text field on the same page. Geolococate is set for France and French Riviera to be more accurate for my needs.
Regards
<html>
<head>
<script src="https://maps.googleapis.com/maps/api/js?key=****&sensor=true&libraries=places"></script>
</head>
<body>
<label for="locationTextField1">Departure</label>
<input id="locationTextField1" type="text" size="50" >
<script>
var defaultBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(43.093595, 6.153839),
new google.maps.LatLng(43.467646, 6.237595));
var options = {
bounds: defaultBounds,
componentRestrictions: {country: 'fr'}
};
function initDep() {
var autocomplete = new google.maps.places.Autocomplete(
document.getElementById('locationTextField1'), options, {types: ['geocode']});
}
google.maps.event.addDomListener(window, 'load', initDep);
</script>
<br />
<br />
<label for="locationTextField2">Arrival</label>
<input id="locationTextField2" type="text" size="50">
<script>
function initArr() {
var autocomplete = new google.maps.places.Autocomplete(
document.getElementById('locationTextField2'), options, {types: ['geocode']});
}
google.maps.event.addDomListener(window, 'load', initArr);
</script>
<script>
</script>
</body>
</html>

Related

sending Angular 6 form including checkbox values not working with template driven forms

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.

updating text using knockout computed function

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" />

Populate dropdown based on logged in user created records

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

Dynamic FormArray for checkboxes

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>

jaydata indexedDb joined database

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.