Autocomplete google map api use to find postal code only by addresspicker - google-app-engine

I want to search postal code using address,city etc by auto complete Google API .
I am using code like this .it is providing all location and place details but i need only postal ,if there is any suggestion then please provide.
<!DOCTYPE html>
<html>
<head>
<link class="jsbin" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes /base/jquery-ui.css" rel="stylesheet" type="text/css" />
<script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js">
</script>
<script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js"></script>
<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script src="http://xilinus.com/jquery-addresspicker/src/jquery.ui.addresspicker.js">
</script>
<meta charset=utf-8 />
<title>JS Bin</title>
<style type="text/css">
#map {
border: 1px solid #DDD;
width:300px;
height: 300px;
float:left;
margin: 0px 0 0 10px;
-webkit-box-shadow: #AAA 0px 0px 15px;
}
div {
font-family: Arial;
font-size: 10pt;
}
</style>
<script type="text/javascript">
$(document).ready(function () {
var geocoder = new google.maps.Geocoder();
$("#addresspicker").autocomplete({
source: function (request, response) {
geocoder.geocode({ address: request.term }, function (results, status) {
if (status === google.maps.GeocoderStatus.OK) {
response($.map(results, function(result) {
if ($.inArray("street_address", result.types) >= 0) {
return result.formatted_address;
}
}));
}
});
},
select: function (event, ui) {
var parts = ui.item.label.split(",")
, address1 = parts[0]
, address2 = parts.slice(1).join(",").trim();
$("#postal").val(address1 + "\n" + address2);
}
});
});
$(function() {
var addresspicker = $("#addresspicker").addresspicker();
var addresspickerMap = $( "#addresspicker_map" ).addresspicker({
elements: {
map: "#map",
lat: "#lat",
lng: "#lng",
locality: '#locality',
country: '#country'
}
});
var gmarker = addresspickerMap.addresspicker( "marker");
gmarker.setVisible(true);
addresspickerMap.addresspicker( "updatePosition");
});
</script>
</head>
<body>
<div>
<label>Address : </label><input id="addresspicker" />
</div>
<br/>
<br/>
<div>
<div>
<label>Address : </label> <input id="addresspicker_map" /> <br/>
<label>Locality: </label> <input id="locality" disabled=disabled> <br/>
<label>Country: </label> <input id="country" disabled=disabled> <br/>
<label>Latitude: </label> <input id="lat" disabled=disabled> <br/>
<label>Longitude: </label> <input id="lng" disabled=disabled> <br/>
<label>postal: </label> <input id="postal" disabled=disabled> <br/>
</div>
<br/>
<div id="map"></div>
</div>
</body>
</html>
Thanks in advance.......

I haven't used jquery.ui.addresspicker but you may find this usefull
You can use the autocomplete.getPlace(); function to get a JSON object that "can" contain post code dependent on the search query.
I'll try keep this vanilla JS
The docs here explain it well
https://developers.google.com/places/documentation/autocomplete
// autocomplete search restriction (if required)
var options = {
types: ['(regions)'],
componentRestrictions: { country: "au" }
}
// create you autocomplete feild
var input = (document.getElementById('addresspicker'));
var autocomplete = new google.maps.places.Autocomplete(input, options);
var infowindow = new google.maps.InfoWindow();
// fired when an autocomplete option is selected or the input is submitted
google.maps.event.addListener(autocomplete, 'place_changed', function() {
infowindow.close();
var place = autocomplete.getPlace();
// pull out the data you need
...
});
I have some validation function i wrote for this as well. If you need more help, comment and i will add links.

I have the same prob.
The PlaceResult objet returned when calling getPlace() doesnt automatically contains a Zipcode, and when it does, its in the "administrative_area_level_2" field.
I'm now heading on calling the main gmap geocoding service in order to get the zipcode associated to the chosen city.

I created a method called get postal code, that extracts the postal code from the result provided by address picker.
Basic setup of addresspicker and calling the function with the address components.
addressPicker.bindDefaultTypeaheadEvent($('#addresssearch'));
$(addressPicker).on('addresspicker:selected', function (event, result) {
var postal_code = getPostalcode(result.placeResult.address_components);
});
Function that extracts postal_code from address components.
function getPostalcode(address_components) {
for(var i = 0; i < address_components.length; i++){
if (address_components[i]['types'].includes("postal_code")) {
var final_value = address_components[i]['long_name'];
}
}
return final_value || ''
}
If no postal code available, it would return empty string.

Related

AngularJS code is not running and getting no error message when inspected

When I inspect it, there are no error and it's returning nothing so, apparently not running :
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles/bootstrap.min.css">
<style>
.message {
font-size: 1.3em;
font-weight: bold;
}
</style>
<script src="angular.min.js"></script>
</head>
<body ng-app='LunchChecker'>
<div class="container" ng-controller='MyLunchCheckController'>
<h1>Lunch Checker</h1>
<div class="form-group">
<input id="lunch-menu" type="text" placeholder="list comma separated dishes
you usually have for lunch" class="form-control" ng-model='MenuInput'>
</div>
<div class="form-group">
<button class="btn btn-default" ng-click="checkInput()">
Check If Too Much</button>
</div>
<div class="form-group message" {{checkInput()}}>
<!-- Your message can go here. -->
</div>
</div>
<script src="app.js"></script>
</body>
</html>
Below is the app.js script for the above view the purpose of the code is to return either msg1 if the input is less than 3 menu or msg2 if the input is more than 3 :
(function() {
'use strict';
angular.module('LunchChecker', [])
.controller('MyLunchCheckController', MyLunchCheckController);
MyLunchCheckController.$inject = ['$scope'];
function MyLunchCheckController($scope) {
$scope.MenuInput = [].slice;
$scope.values = new Array($scope.MenuInput.length);
$scope.msg1 = "Enjoy!";
$scope.msg2 = "Too much!";
//fucntion for the button to check the user input menu-list
$scope.checkInput = function() {
for (var i = 0; i < $scope.values; i++) {
if ($scope.values <= 3) {
return $scope.msg1;
} else {
return $scope.msg2;
}
}
};
}
})();
When I try to reflect your code, I am getting function slice() { [native code] } inside the text box. As you have initialised the value of MenuInput as [].slice.
So to improve and compare the code
'use strict';
angular.module('LunchChecker', [])
.controller('MyLunchCheckController', ['$scope', function($scope) {
$scope.msg1 = "Enjoy!";
$scope.msg2 = "Too much!";
$scope.checkInput = function() {
if($scope.MenuInput.split(",").length <= 3) {
$scope.values = $scope.msg1;
} else{
$scope.values = $scope.msg2;
}
};
}]);
It will print the message in the console according to the length you compare. For displaying the message you can write like:
<div class="form-group message" {{checkInput()}}>
to
<div class="form-group message"> {{values}}</div>

Cofigure Height of the Angular Material inputs

I need to modify the height of the Angular-Material inputs to the minimun.
This is because i need to insert many inputs in a small box (500px and it is positioned on bottom of the screen), but I need that the height of the inputs do not change the height of the box, then i need that one of two things DO NOT HAPPEN:
1- The box grows-down wich is causing that the send button and other inputs are offscreen.
2- If the height of the box is configured with percentage (height:80%), then appears a scroll control in the right border of the box.
Here is the code:
<!doctype html>
<html lang="en">
<head>
<title>FORM</title>
<!-- Firebase -->
<script src="https://cdn.firebase.com/js/client/2.2.4/firebase.js"></script>
<!-- AngularFire -->
<script src="https://cdn.firebase.com/libs/angularfire/1.2.0/angularfire.min.js"></script>
<!-- Angular Material style sheet -->
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.min.css">
</head>
<body ng-app="mmadera">
<div class="box" style="position:relative; width:500px; height:500px;">
<div ng-controller="DemoCtrl" layout="column" ng-cloak="" class="md-inline-form inputdemoBasicUsage" >
<md-content md-theme="docs-dark" layout-gt-sm="row" layout-padding="">
<div>
<md-input-container flex-gt-sm="">
<label>Título</label>
<input ng-model="user.titulo">
</md-input-container>
<md-input-container flex-gt-sm="">
<label>Email</label>
<input ng-model="user.email" type="email">
</md-input-container>
</div>
</md-content>
<md-content layout-padding="">
<div>
<form name="userForm">
<div layout-gt-xs="row">
<md-input-container flex-gt-xs=""> <!-- class="md-block" disabled="" -->
<label>Empresa</label>
<input ng-model="user.empresa" >
</md-input-container>
</div>
<div layout-gt-sm="row">
<md-input-container class="md-block" flex-gt-sm="">
<label>Nombre</label>
<input ng-model="user.nombre">
</md-input-container>
<md-input-container class="md-block" flex-gt-sm="">
<label>Teléfono</label>
<input ng-model="user.nombre">
<!-- ng-model="theMax" -->
</md-input-container>
</div>
<md-input-container class="md-block">
<label>Dirección</label>
<input ng-model="user.direcdion">
</md-input-container>
<div layout-gt-sm="row">
<md-input-container class="md-block" flex-gt-sm="">
<label>País</label>
<input ng-model="user.pais">
</md-input-container>
<md-input-container class="md-block" flex-gt-sm="">
<label>Estado</label>
<input ng-model="user.estado">
</md-input-container>
</div>
<md-input-container class="md-block">
<label>Mensaje</label>
<textarea ng-model="user.mensaje" md-maxlength="150" rows="5" md-select-on-focus=""></textarea>
</md-input-container>
<div>
<md-button type="submit" >ENVIAR</md-button>
</div>
</form>
</div>
</md-content>
</div>
</div>
<!-- ............................. ANGULAR - A.MATERIAL ......................................-->
<!-- Angular Material requires Angular.js Libraries -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-animate.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-aria.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-messages.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/X.Y.Z/angular-touch.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-animate.js"></script>
<!-- Angular Material Library -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.min.js"></script>
<!-- Your application bootstrap -->
<script type="text/javascript">
angular.module('mmadera',['ngMaterial','ngMessages'])
.controller('SwitchDemoCtrl', function($scope) {
$scope.data = {
cb1: true,
cb4: true,
cb5: false
};
$scope.message = 'false';
$scope.onChange = function(cbState) {
$scope.message = cbState;
};
})
/* __________________________ PANEL js __________________________*/
/* __________________________ FOOTER __________________________*/
.controller('footsoc', function($scope) {
$scope.abre = false;
$scope.mov = {
isOpen: false,
count: 0,
selectedDirection: 'right'
};
})
/* __________________________ FOOTER __________________________*/
/* __________________________ SIDE BAR (Proceso) __________________________*/
.controller('AppCtrl', function ($scope, $timeout, $mdSidenav, $log) {
$scope.toggleLeft = buildDelayedToggler('left');
$scope.toggleRight = buildToggler('right');
$scope.isOpenRight = function(){
return $mdSidenav('right').isOpen();
};
/**
* Supplies a function that will continue to operate until the
* time is up.
*/
function debounce(func, wait, context) {
var timer;
return function debounced() {
var context = $scope,
args = Array.prototype.slice.call(arguments);
$timeout.cancel(timer);
timer = $timeout(function() {
timer = undefined;
func.apply(context, args);
}, wait || 10);
};
}
/**
* Build handler to open/close a SideNav; when animation finishes
* report completion in console
*/
function buildDelayedToggler(navID) {
return debounce(function() {
// Component lookup should always be available since we are not using `ng-if`
$mdSidenav(navID)
.toggle()
.then(function () {
$log.debug("toggle " + navID + " is done");
});
}, 200);
}
function buildToggler(navID) {
return function() {
// Component lookup should always be available since we are not using `ng-if`
$mdSidenav(navID)
.toggle()
.then(function () {
$log.debug("toggle " + navID + " is done");
});
}
}
})
.controller('LeftCtrl', function ($scope, $timeout, $mdSidenav, $log) {
$scope.close = function () {
// Component lookup should always be available since we are not using `ng-if`
$mdSidenav('left').close()
.then(function () {
$log.debug("close LEFT is done");
});
};
})
.controller('RightCtrl', function ($scope, $timeout, $mdSidenav, $log) {
$scope.close = function () {
// Component lookup should always be available since we are not using `ng-if`
$mdSidenav('right').close()
.then(function () {
$log.debug("close RIGHT is done");
});
};
})
.controller('DemoCtrl', function() {
this.isOpen = false;
this.availableModes = ['md-fling', 'md-scale'];
this.selectedMode = 'md-fling';
this.selectedDirection = 'right';
})
.controller('DropdownCtrl', function ($scope, $log) {
$scope.items = [
'The first choice!',
'And another choice for you.',
'but wait! A third!'
];
$scope.status = {
isopen: false
};
$scope.toggled = function(open) {
$log.log('Dropdown is now: ', open);
};
$scope.toggleDropdown = function($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.status.isopen = !$scope.status.isopen;
};
$scope.appendToEl = angular.element(document.querySelector('#dropdown-long-content'));
})
.controller('DemoCtrl', function($scope) {
$scope.user = {
titulo: 'Quiero vender mas!',
email: 'ejemplo#koomkin.com',
nombre: '',
telefono: '',
empresa: 'Koomkin',
direccion: '1600 Amphitheatre Pkwy',
pais: 'México',
estado: 'CDMX',
mensaje: 'Escribe tu mensaje',
postalCode: '94043'
};
})
.config(function($mdThemingProvider) {
// Configure a dark theme with primary foreground yellow
$mdThemingProvider.theme('docs-dark', 'default')
.primaryPalette('yellow')
.dark();
});
</script>
</body>
</html>
THANK YOU.
If the height of the box must not change, apply the max-heightstyle to it, with the overflow property too.
the max-height will fix your box height, while the overflow property set to hidden will hide elements that are out of it, and won't give you a scrollbar.
To change the inputs height, give them a class like this :
<input ng-model="user.titulo" class="myInput">
and give them a height of your own.
FYI, the class that applies the height of an input is md-container .md-input, so you can either overwrite it or add a new class like I told you before.
Depending on how you import your css sheets, you may need to use the !importantproperty on your class like so :
.myInput {
height: 20px !important;
max-height: 20px !important;
}

Angular Formly - Custom type which generates the model from the controller

I've been all the day searching for a way to accomplish this, any help would be really appreciated.
We want to create a date selector, but not using the javascript Date format but a string 'YYYY-MM-DD'. So we tried to create a custom type which has two inputs, a type="date" so that the user can introduce the date he wants to and a hidden type="text" which stores the actual model.
It looked well at the beginning:
formlyConfig.setType({
'name': 'nativeDateSelect',
template: `
<input type="text" class="form-control" style="display: none;"
ng-model="model[options.key]" />
<input type="date" class="form-control"
ng-model="dateValue"
formly-skip-ng-model-attrs-manipulator />
`,
wrapper: ['bootstrapLabel', 'bootstrapHasError'],
controller: function ($scope, moment) {
$scope.dateValue = null;
$scope.$watch('model[options.key]', function (newValue) {
if (angular.equals($scope.dateValue, moment(newValue).toDate())) return;
$scope.dateValue = moment(newValue).toDate();
});
$scope.$watch('dateValue', function (newValue) {
if (angular.equals($scope.model[$scope.options.key], moment(newValue).format('YYYY-MM-DD'))) return;
$scope.model[$scope.options.key] = moment(newValue).format('YYYY-MM-DD');
});
},
'defaultOptions': {
'extras': {
'validateOnModelChange': true
}
}
});
This is it, it actually works, changing any of the input will modify the other one.
But here's the problem, once I introduce this type in an actual form and try to work with it, lets say for example adding an onChange function, it won't trigger as I'm not doing a change on the text input.
/* global angular */
(function() {
'use strict';
var app = angular.module('formlyExample', ['formly', 'formlyBootstrap', 'angularMoment'], function config(formlyConfigProvider) {
// set templates here
formlyConfigProvider.setType([
{
'name': 'nativeDateSelect',
template:
'<input type="text" class="form-control" style="display: block;" ' +
'ng-model="model[options.key]" /> ' +
'<input type="date" class="form-control" ' +
'ng-model="dateValue" ' +
'formly-skip-ng-model-attrs-manipulator />',
wrapper: ['bootstrapLabel', 'bootstrapHasError'],
controller: function ($scope, moment) {
$scope.dateValue = null;
$scope.$watch('model[options.key]', function (newValue) {
if (angular.equals($scope.dateValue, moment(newValue).toDate())) return;
$scope.dateValue = moment(newValue).toDate();
});
$scope.$watch('dateValue', function (newValue) {
if (angular.equals($scope.model[$scope.options.key], moment(newValue).format('YYYY-MM-DD'))) return;
$scope.model[$scope.options.key] = moment(newValue).format('YYYY-MM-DD');
});
},
'defaultOptions': {
'extras': {
'validateOnModelChange': true
}
}
}
]);
});
app.controller('MainCtrl', function MainCtrl(formlyVersion) {
var vm = this;
// funcation assignment
vm.onSubmit = onSubmit;
vm.exampleTitle = 'Default Options'; // add this
vm.model = {};
vm.fields = [
{
'type': 'nativeDateSelect',
'key': 'startDate',
'expressionProperties': {
'templateOptions.label': '\'startDate\''
},
'templateOptions': {
'required': true,
'onChange': function (modelValue, field, scope) {
alert('startDate: ' + modelValue);
}
}
}
];
vm.originalFields = angular.copy(vm.fields);
// function definition
function onSubmit() {
alert(JSON.stringify(vm.model), null, 2);
}
});
})();
<!DOCTYPE html>
<html>
<head>
<!-- Twitter bootstrap -->
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.css" rel="stylesheet">
<!-- apiCheck is used by formly to validate its api -->
<script src="//npmcdn.com/api-check#latest/dist/api-check.js"></script>
<!-- This is the latest version of angular (at the time this template was created) -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.js"></script>
<!-- This is the current state of master for formly core. -->
<script src="//npmcdn.com/angular-formly#latest/dist/formly.js"></script>
<!-- This is the current state of master for the bootstrap templates -->
<script src="//npmcdn.com/angular-formly-templates-bootstrap#latest/dist/angular-formly-templates-bootstrap.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-moment/0.10.3/angular-moment.min.js"></script>
<title>Angular Formly Example</title>
</head>
<body ng-app="formlyExample" ng-controller="MainCtrl as vm">
<div>
<h1>Changing our model from the controller</h1>
<hr />
<form ng-submit="vm.onSubmit()" novalidate>
<formly-form model="vm.model" fields="vm.fields" form="vm.form">
<button type="submit" class="btn btn-primary submit-button">Submit</button>
</formly-form>
</form>
<h2>Model</h2>
<pre>{{vm.model | json}}</pre>
<h2>Fields <small>(note, functions are not shown)</small></h2>
<pre>{{vm.originalFields | json}}</pre>
<h2>Form</h2>
<pre>{{vm.form | json}}</pre>
</div>
</body>
</html>
Do anyone know how to manage a scenario like this? I need one input to actually input and the other to be the model, so this one should track changes/validation/etc. whenever it is modified.
Thanks again!

Angularjs 1.4.7 - Clear and set form to pristine state after submission

After submission, my form displays as dirty with a red border and no submission text. I've tried adding various combinations of .$setPristine and/or .$setUntouched to line 34 in app.js with a return of a green border with submission text still in place.
I've read in articles about using $scopes. Not sure if it is required, I'm not familiar with them.
app.js
* the page hello-world auto-reloads the preview on the right c9 panel */
/* global angular */ /* angular is defined in html document as a src'ed js file. linter says to declare as a global in a comment here */
(function(){
// variables are declared at the top of the function's scope
// three default entries to start with
var entries = [{
title: 'Title1',
body: 'This is a test, 1.',
createdOn: 1397490980837
}, {
title: 'Title2',
body: 'This is a test, 2.',
createdOn: 1397490980837
}, {
title: 'Title3',
body: 'This is a test, 3.',
createdOn: 1397490980837
}];
var app = angular.module('blogPosts', []);
app.controller('EntriesController', function(){
// `this` entry, the current entry for this method, is defaulted to an empty object
this.entry = {};
this.entries = entries;
// method is called when adding an entry
this.addEntry = function() {
// does this.entry exist here? good way to find out is with `console.log(this.entry);` or `debugger;`
this.entry.createdOn = Date.now();
entries.push(this.entry);
console.log("entries",entries);
// reset `this.entry` back to an empty object
this.entry.$setPristine();
this.entry = {};
//this.entry.$setPristine = {};
//this.entry.$clearForm = {};
};
});
})();
index.html
<!DOCTYPE html>
<html ng-app="blogPosts">
<head>
<link rel="stylesheet" type="text/css" href="style.css" /><!-- load Bootstrap -->
<link rel="stylesheet" type="text/css" href="https://bootswatch.com/united/bootstrap.min.css" /><!-- load Bootstrap -->
<script src="angular.js"></script><!-- load angular -->
<script type="text/javascript" src="app.js"></script>
</head>
<body ng-controller="EntriesController as entryCtrl">
<div ng-repeat="entry in entryCtrl.entries">
<h3>{{entry.title}}</h3><cite class="clearfix">{{this.entry.createdOn | date}}</cite><br>
{{entry.body}}
</div>
<!-- Entry Form -->
<form name="entryForm"
ng-submit="entryForm.$valid &&entryCtrl.addEntry(entry)"
noValidate>
<!-- Live Preview -->
<blockquote>
<h3>{{entryCtrl.entry.title}}</h3><br>
{{entryCtrl.entry.body}}
<cite class="clearfix">{{this.entry.createdOn | date}}</cite>
</blockquote>
<!-- Entry Form -->
<h4>Submit an Entry</h4>
<fieldset class="form-group">
<input type="title" class="form-control" placeholder="Title" title="Title" ng-model="entryCtrl.entry.title" required/>
</fieldset>
<fieldset class="form-group">
<textarea class="form-control" placeholder="Write your entry.." title="Entry" ng-model="entryCtrl.entry.body" required></textarea>
</fieldset>
<fieldset class="form-group">
<input type="submit" class="btn btn-primary pull-right" value="Submit Entry" />
</fieldset>
</form>
</body>
</html>
CSS
.ng-invalid.ng-dirty {
border-color: red;
}
.ng-valid.ng-dirty {
border-color: green;
}
From Reddit /u/mcassagnes
app.controller('EntriesController', ['$scope', function($scope){
// ...
this.addEntry = function() {
// ...
$scope.entryForm.$setPristine();
};
}]);
Works!
Yeah this in your this.addEntry is not bound to the lexical this. Basically lost its binding. Best to assign this to a variable in your main controller definition. Something like this to abstract this in controllers. Note you'd have to change the way you'd like to use this syntax. In your view it be EntriesController as vm, and instead of variable just by itself it be vm.variable. Here is a style guide to help solidify what I mean. Hope this helps in your future.
app.controller('EntriesController', function() {
// `this` entry, the current entry for this method, is defaulted to an empty object
var vm = this;
vm.entry = {};
vm.entries = entries;
// method is called when adding an entry
vm.addEntry = function() {
// does this.entry exist here? good way to find out is with `console.log(this.entry);` or `debugger;`
this.entry.createdOn = Date.now();
entries.push(this.entry);
console.log("entries", entries);
// reset `this.entry` back to an empty object
vm.entry.$setPristine();
vm.entry = {};
//this.entry.$setPristine = {};
//this.entry.$clearForm = {};
};
});

Kendo UI + PhoneGap not working

I downloaded KENDO UI and imported /js and /css folders to my project directory. Now, I'm crreating new index.html project and referencing my all Kendo UI files in the /js and /css folders. But nothing happening. No styles, no js, nothing. Just plain HTML and nothing else. I just don't know what I'm doing wrong so I hope someone could help me with this. Here is my index.html file
<!DOCTYPE html>
<html>
<head>
<title>Where is my car?</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<script src="js/jquery.min.js"></script>
<script src="js/kendo.mobile.min.js"></script>
<link href="styles/kendo.common.min.css" rel="stylesheet" />
<link href="styles/kendo.mobile.all.min.css" rel="stylesheet" />
</head>
<body>
<header data-role="header">
<h1>Where is my car?</h1>
</header>
<div id="content" data-role="content">
<p>asfdasfdasdfasdfasdfasdfs</p>
<a class="button" data-role="button" href="map.html?requestType=set" id="set-car-position">Set position</a>
<a class="button" data-role="button" href="map.html?requestType=get" id="find-car" data-role="button">Find car</a>
<a class="button" data-role="button" href="positions.html" id="positions-history" data-role="button">Positions history</a>
</div>
<footer data-role="footer">
<h3>Created by </h3>
<a data-icon="info" data-iconpos="notext" class="ui-btn-right">Credits</a>
</footer>
<style scoped>
#button-badge .button {
margin-left: 1em;
text-align: center;
}
#button-home .head, #facility .head, #sports .head {
display: block;
margin: 1em;
height: 120px;
-webkit-background-size: 100% auto;
background-size: 100% auto;
}
.km-ios .head, .km-blackberry .head {
-webkit-border-radius: 10px;
border-radius: 10px;
}
</style>
</body>
</html>
DEMO in jsfiddle ->> http://jsfiddle.net/ep5e8/.
Thank you for any help.
EDIT:
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Where is my car?</title>
<script src="cordova.js"></script>
<script src="http://maps.google.com/maps/api/js?sensor=true"></script>
<script src="js/functions.js"></script>
<script src="js/maps.js"></script>
<script src="js/positions.js"></script>
<!-- Kendo UI Mobile CSS -->
<link href="styles/kendo.mobile.all.min.css" rel="stylesheet" />
<!-- jQuery JavaScript -->
<script src="js/jquery.min.js"></script>
<!-- Kendo UI Mobile combined JavaScript -->
<script src="js/kendo.mobile.min.js"></script>
<script src="js/jquery.min.js"></script>
<script src="js/kendo.mobile.min.js"></script>
<script src="content/shared/js/console.js"></script>
<link href="styles/kendo.common.min.css" rel="stylesheet" />
<link href="styles/kendo.mobile.all.min.css" rel="stylesheet" />
<script>
$(document).one('deviceready', initApplication);
</script>
</head>
<body>
<div id="welcome-page" data-role="view">
<header data-role="header">
<div data-role="navbar">
<span data-role="view-title">Where is my car?</span>
</div>
</header>
<div id="content" data-role="content">
<p>Where is my car? lets you bookmark where you parked your car on a map and then find a route when you want to return to it. The app will also save a log of your saved positions (up to 50).</p>
Set position
Find car
Positions history
</div>
<!--Kendo Mobile Footer -->
<footer data-role="footer">
<!-- Kendo Mobile TabStrip widget -->
<div data-role="tabstrip">
<h3>Created by</h3>
</div>
</footer>
</div>
<script>
// Initialize a new Kendo Mobile Application
var app = new kendo.mobile.Application();
</script>
</body>
</html>
positions.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Positions' history</title>
</head>
<body>
<div id="positions-page" data-role="page">
<header data-role="header">
Back
<h1>Positions' history</h1>
</header>
<div id="content" data-role="content">
<ul id="positions-list" data-role="listview" data-inset="true" data-split-icon="delete" data-filter="true">
</ul>
</div>
<footer data-role="footer">
<h3>Created by </h3>
</footer>
</div>
</body>
</html>
map.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Where is my car?</title>
<script src="cordova.js"></script>
<script src="http://maps.google.com/maps/api/js?sensor=true"></script>
<script src="js/functions.js"></script>
<script src="js/maps.js"></script>
<script src="js/positions.js"></script>
<!-- Kendo UI Mobile CSS -->
<link href="styles/kendo.mobile.all.min.css" rel="stylesheet" />
<!-- jQuery JavaScript -->
<script src="js/jquery.min.js"></script>
<!-- Kendo UI Mobile combined JavaScript -->
<script src="js/kendo.mobile.min.js"></script>
<script src="js/jquery.min.js"></script>
<script src="js/kendo.mobile.min.js"></script>
<script src="content/shared/js/console.js"></script>
<link href="styles/kendo.common.min.css" rel="stylesheet" />
<link href="styles/kendo.mobile.all.min.css" rel="stylesheet" />
<script>
$(document).one('deviceready', initApplication);
</script>
</head>
<body>
<div id="map-page" data-role="layout">
<header data-role="header">
<div data-role="navbar">
Back
<span data-role="view-title">Where is my car?</span>
</div>
</header>
<div id="content" data-role="content">
<div id="map">
</div>
</div>
</div>
<script>
// Initialize a new Kendo Mobile Application
var app = new kendo.mobile.Application();
</script>
</body>
</html>
functions.js:
function checkRequirements()
{
if (navigator.network.connection.type == Connection.NONE)
{
navigator.notification.alert(
'To use this app you must enable your internet connection',
function(){},
'Warning'
);
return false;
}
return true;
}
function updateIcons()
{
if ($(window).width() > 480)
{
$('a[data-icon], button[data-icon]').each(
function()
{
$(this).removeAttr('data-iconpos');
}
);
}
else
{
$('a[data-icon], button[data-icon]').each(
function()
{
$(this).attr('data-iconpos', 'notext');
}
);
}
}
function urlParam(name)
{
var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(window.location.href);
if (results != null && typeof results[1] !== 'undefined')
return results[1];
else
return null;
}
/**
* Initialize the application
*/
function initApplication()
{
$('#set-car-position, #find-car').click(function() {
if (checkRequirements() === false)
{
$(this).removeClass('ui-btn-active');
return false;
}
});
$(document).on('pagebeforecreate orientationchange', updateIcons);
$('#map-page').live(
'pageshow',
function()
{
var requestType = urlParam('requestType');
var positionIndex = urlParam('index');
var geolocationOptions = {
timeout: 15 * 1000, // 15 seconds
maximumAge: 10 * 1000, // 10 seconds
enableHighAccuracy: true
};
var position = new Position();
$.mobile.loading('show');
// If the parameter requestType is 'set', the user wants to set
// his car position else he want to retrieve the position
if (requestType == 'set')
{
navigator.geolocation.getCurrentPosition(
function(location)
{
// Save the position in the history log
position.savePosition(
new Coords(
location.coords.latitude,
location.coords.longitude,
location.coords.accuracy
)
);
// Update the saved position to set the address name
Map.requestLocation(location);
Map.displayMap(location, null);
navigator.notification.alert(
'Your position has been saved',
function(){},
'Info'
);
},
function(error)
{
navigator.notification.alert(
'Unable to retrieve your position. Is your GPS enabled?',
function(){
alert("Unable to retrieve the position: " + error.message);
},
'Error'
);
$.mobile.changePage('index.html');
},
geolocationOptions
);
}
else
{
if (position.getPositions().length == 0)
{
navigator.notification.alert(
'You have not set a position',
function(){},
'Error'
);
$.mobile.changePage('index.html');
return false;
}
else
{
navigator.geolocation.watchPosition(
function(location)
{
// If positionIndex parameter isn't set, the user wants to retrieve
// the last saved position. Otherwise he accessed the map page
// from the history page, so he wants to see an old position
if (positionIndex == undefined)
Map.displayMap(location, position.getPositions()[0]);
else
Map.displayMap(location, position.getPositions()[positionIndex]);
},
function(error)
{
console.log("Unable to retrieve the position: " + error.message);
},
geolocationOptions
);
}
}
}
);
$('#positions-page').live(
'pageinit',
function()
{
createPositionsHistoryList('positions-list', (new Position()).getPositions());
}
);
}
/**
* Create the positions' history list
*/
function createPositionsHistoryList(idElement, positions)
{
if (positions == null || positions.length == 0)
return;
$('#' + idElement).empty();
var $listElement, $linkElement, dateTime;
for(var i = 0; i < positions.length; i++)
{
$listElement = $('<li>');
$linkElement = $('<a>');
$linkElement
.attr('href', '#')
.click(
function()
{
if (checkRequirements() === false)
return false;
$.mobile.changePage(
'map.html',
{
data: {
requestType: 'get',
index: $(this).closest('li').index()
}
}
);
}
);
if (positions[i].address == '' || positions[i].address == null)
$linkElement.text('Address not found');
else
$linkElement.text(positions[i].address);
dateTime = new Date(positions[i].datetime);
$linkElement.text(
$linkElement.text() + ' # ' +
dateTime.toLocaleDateString() + ' ' +
dateTime.toLocaleTimeString()
);
// Append the link to the <li> element
$listElement.append($linkElement);
$linkElement = $('<a>');
$linkElement.attr('href', '#')
.text('Delete')
.click(
function()
{
var position = new Position();
var oldLenght = position.getPositions().length;
var $parentUl = $(this).closest('ul');
position.deletePosition($(this).closest('li').index());
if (oldLenght == position.getPositions().length + 1)
{
$(this).closest('li').remove();
$parentUl.listview('refresh');
}
else
{
navigator.notification.alert(
'Position not deleted. Something gone wrong so please try again.',
function(){},
'Error'
);
}
}
);
// Append the link to the <li> element
$listElement.append($linkElement);
// Append the <li> element to the <ul> element
$('#' + idElement).append($listElement);
}
$('#' + idElement).listview('refresh');
}
maps.js:
function Map()
{
}
/**
* Display the map showing the user position or the latter and the car position
*/
Map.displayMap = function(userPosition, carPosition)
{
var userLatLng = null;
var carLatLng = null;
if (userPosition != null)
userLatLng = new google.maps.LatLng(userPosition.coords.latitude, userPosition.coords.longitude);
if (carPosition != null)
carLatLng = new google.maps.LatLng(carPosition.position.latitude, carPosition.position.longitude);
var options = {
zoom: 20,
disableDefaultUI: true,
streetViewControl: true,
center: userLatLng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById('map'), options);
var marker = new google.maps.Marker({
position: userLatLng,
map: map,
title: 'Your position'
});
// If carLatLng is null means that the function has been called when the
// user set his current position and that is when he parked the car so the
// icon will be shown accordingly.
if (carLatLng == null)
marker.setIcon('images/car-marker.png');
else
marker.setIcon('images/user-marker.png');
var circle = new google.maps.Circle({
center: userLatLng,
radius: userPosition.coords.accuracy,
map: map,
fillColor: '#70E7FF',
fillOpacity: 0.2,
strokeColor: '#0000FF',
strokeOpacity: 1.0
});
map.fitBounds(circle.getBounds());
if (carLatLng != null)
{
marker = new google.maps.Marker({
position: carLatLng,
map: map,
icon: 'images/car-marker.png',
title: 'Car position'
});
circle = new google.maps.Circle({
center: carLatLng,
radius: carPosition.position.accuracy,
map: map,
fillColor: '#70E7FF',
fillOpacity: 0.2,
strokeColor: '#0000FF',
strokeOpacity: 1.0
});
// Display route to the car
options = {
suppressMarkers: true,
map: map,
preserveViewport: true
}
this.setRoute(new google.maps.DirectionsRenderer(options), userLatLng, carLatLng);
}
$.mobile.loading('hide');
}
/**
* Calculate the route from the user to his car
*/
Map.setRoute = function(directionsDisplay, userLatLng, carLatLng)
{
var directionsService = new google.maps.DirectionsService();
var request = {
origin: userLatLng,
destination: carLatLng,
travelMode: google.maps.DirectionsTravelMode.WALKING,
unitSystem: google.maps.UnitSystem.METRIC
};
directionsService.route(
request,
function(response, status)
{
if (status == google.maps.DirectionsStatus.OK)
directionsDisplay.setDirections(response);
else
{
navigator.notification.alert(
'Unable to retrieve a route to your car. However, you can still find it by your own.',
function(){},
'Warning'
);
}
}
);
}
/**
* Request the address of the retrieved location
*/
Map.requestLocation = function(position)
{
new google.maps.Geocoder().geocode(
{
'location': new google.maps.LatLng(position.coords.latitude, position.coords.longitude)
},
function(results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
var positions = new Position();
positions.updatePosition(0, positions.getPositions()[0].coords, results[0].formatted_address);
}
}
);
}
positions.js
function Position(position, address, datetime)
{
var _db = window.localStorage;
var MAX_POSITIONS = 50;
this.position = position;
this.address = address;
this.datetime = datetime;
this.getMaxPositions = function()
{
return MAX_POSITIONS;
}
this.savePosition = function(position, address)
{
if (!_db)
{
console.log('The database is null. Unable to save position');
navigator.notification.alert(
'Unable to save position',
function(){},
'Error'
);
}
var positions = this.getPositions();
if (positions == null)
positions = [];
positions.unshift(new Position(position, address, new Date()));
// Only the top MAX_POSITIONS results are needed
if (positions.length > this.MAX_POSITIONS)
positions = positions.slice(0, this.MAX_POSITIONS);
_db.setItem('positions', JSON.stringify(positions));
return positions;
}
this.updatePosition = function(index, position, address)
{
if (!_db)
{
console.log('The database is null. Unable to update position');
navigator.notification.alert(
'Unable to update position',
function(){},
'Error'
);
}
var positions = this.getPositions();
if (positions != null && positions[index] != undefined)
{
positions[index].coords = position;
positions[index].address = address;
}
_db.setItem('positions', JSON.stringify(positions));
return positions;
}
this.deletePosition = function(index)
{
if (!_db)
{
console.log('The database is null. Unable to delete position');
navigator.notification.alert(
'Unable to delete position',
function(){},
'Error'
);
}
var positions = this.getPositions();
if (positions != null && positions[index] != undefined)
positions.splice(index, 1);
_db.setItem('positions', JSON.stringify(positions));
return positions;
}
this.getPositions = function()
{
if (!_db)
{
console.log('The database is null. Unable to retrieve positions');
navigator.notification.alert(
'Unable to retrieve positions',
function(){},
'Error'
);
}
var positions = JSON.parse(_db.getItem('positions'));
if (positions == null)
positions = [];
return positions;
}
}
function Coords(latitude, longitude, accuracy)
{
this.latitude = latitude;
this.longitude = longitude;
this.accuracy = accuracy;
}
style.css:
.ui-header .ui-title,
.ui-footer .ui-title,
.ui-btn-inner *
{
white-space: normal !important;
}
.photo
{
display: block;
margin: 0px auto;
}
dl.informations dt
{
font-weight: bold;
}
#map
{
width: 100%;
height: 600px;
}
Sorry for this amount of code, but I just can't convert a design and functionality from jQM to KendoUI Mobile.
Kendo initialization
You are missing the code bits that let kendo do its magic. I am assuming that you are using Kendo UI Mobile.
The following should be inserted before your closing body tag.
<script>
// Initialize a new Kendo Mobile Application
var app = new kendo.mobile.Application();
</script>
You can read the following doc with more related details:
http://docs.kendoui.com/getting-started/introduction
Kendo Views
Also I noticed that you are not using any view. I am not sure what you want to achieve but tipically when using Kendo you should have a view that wraps the header, content and footer code.
View documentation: http://docs.kendoui.com/getting-started/mobile/view
I suggest reading the documentation stated above (if you haven´t already do so) and to try the examples first, and then start writing your code.
Snippet
<!-- Kendo Mobile View -->
<div data-role="view" data-title="View" id="index">
<!--Kendo Mobile Header -->
On the other hand, it is difficult to check the full code working as it should be in the jsfiddle as you are not linking or copy pasting the CSS and JS files that you are stating in the code.
EDIT
Regarding data source
I just skimmed your code but It seems you are not using the Kendo DataSource.
Read the following document which explains how to bind data to your controls.
http://docs.kendoui.com/howto/use-the-datasource-component
http://docs.kendoui.com/getting-started/data-attribute-initialization
Bear in mind that jQM and Kendo UI mobile have very different approaches. Kendo uses a Model View ViewModel (MVVM) so a bit of work should be required to move the jquery - jQM code to Kendo, it is basically a matters of structure.
Again, before start playing with Kendo I strongly recommend reading the documentation. You could think you are wasting time, however reading the doc will save you tons of time and headaches.

Resources