TVML - Navigate through templates - apple-tv

I´m doing something very wrong, but I´m not very sure of what.
I am trying to create an app which loads a TVML template. From there, you can navigate to a new view (also a template) with information about the selected item. Finally, in this view, you can choose to play the video.
It works until I play the view because it loads but the second screen is on top. I have to "go back" with the menu button to see the video...
Here is my code (simplified of menus and buttons):
application.js
var resourceLoader;
App.onLaunch = function(options) {
var javascriptFiles = [
`${options.BASEURL}/js/ResourceLoader.js`,
`${options.BASEURL}/js/Presenter.js`
];
evaluateScripts(javascriptFiles, function(success) {
if(success) {
resourceLoader = new ResourceLoader(options.BASEURL);
resourceLoader.loadResource(`${options.BASEURL}/templates/Stack.xml.js`, function(resource) {
var doc = Presenter.makeDocument(resource);
doc.addEventListener("select", Presenter.load.bind(Presenter));
Presenter.pushDocument(doc);
});
} else {
var errorDoc = createAlert("Evaluate Scripts Error", "Error attempting to evaluate external JavaScript files.");
navigationDocument.presentModal(errorDoc);
}
});
}
Presenter.js
function getDocument(url) {
var templateXHR = new XMLHttpRequest();
templateXHR.responseType = "document";
templateXHR.addEventListener("load", function() {
pushDoc(templateXHR.responseXML);}, false);
templateXHR.open("GET", url, true);
templateXHR.send();
return templateXHR;
}
function pushDoc(document) {
navigationDocument.pushDocument(document);
}
var Presenter = {
makeDocument: function(resource) {
if (!Presenter.parser) {
Presenter.parser = new DOMParser();
}
var doc = Presenter.parser.parseFromString(resource, "application/xml");
return doc;
},
modalDialogPresenter: function(xml) {
navigationDocument.presentModal(xml);
},
pushDocument: function(xml) {
navigationDocument.pushDocument(xml);
},
load: function(event) {
console.log(event);
var self = this,
ele = event.target,
videoURL = ele.getAttribute("video"),
templateURL = ele.getAttribute("template"),
presentation = ele.getAttribute("presentation");
if(videoURL) {
var player = new Player();
var playlist = new Playlist();
var mediaItem = new MediaItem("video", videoURL);
player.playlist = playlist;
player.playlist.push(mediaItem);
player.present();
}
if(templateURL) {
self.showLoadingIndicator(presentation);
resourceLoader.loadResource(templateURL,
function(resource) {
if (resource) {
var doc = self.makeDocument(resource);
doc.addEventListener("select", self.load.bind(self));
//doc.addEventListener("highlight", self.load.bind(self));
if (self[presentation] instanceof Function) {
self[presentation].call(self, doc, ele);
} else {
self.defaultPresenter.call(self, doc);
}
}
}
);
}
},
showLoadingIndicator: function(presentation) {
if (!this.loadingIndicator) {
this.loadingIndicator = this.makeDocument(this.loadingTemplate);
}
if (!this.loadingIndicatorVisible && presentation != "modalDialogPresenter" && presentation != "menuBarItemPresenter") {
navigationDocument.pushDocument(this.loadingIndicator);
this.loadingIndicatorVisible = true;
}
},
removeLoadingIndicator: function() {
if (this.loadingIndicatorVisible) {
navigationDocument.removeDocument(this.loadingIndicator);
this.loadingIndicatorVisible = false;
}
},
defaultPresenter: function(xml) {
if(this.loadingIndicatorVisible) {
navigationDocument.replaceDocument(xml, this.loadingIndicator);
this.loadingIndicatorVisible = false;
} else {
navigationDocument.pushDocument(xml);
}
},
loadingTemplate: `<?xml version="1.0" encoding="UTF-8" ?>
<document>
<loadingTemplate>
<activityIndicator>
<text>Loading...</text>
</activityIndicator>
</loadingTemplate>
</document>`
}
I also use a ResourceLoader.js file but I think it is not important as it is the one shown in documentation.
When the app launches, I therefore load my first "template" view.
Stack.xml.js
var Template = function() { return `<?xml version="1.0" encoding="UTF-8" ?>
<document>
<stackTemplate>
<collectionList>
<carousel>
<section>
<lockup>
<img src="${this.BASEURL}/images/main_carousel/main_carousel001.png" width="1740" height="500" />
<overlay>
<title>Title</title>
<subtitle>1902</subtitle>
</overlay>
</lockup>
</section>
</carousel>
<shelf>
<header>
<title>Last Added</title>
</header>
<section>
<lockup template="${this.BASEURL}/templates/Product-001.xml.js" presentation="modalDialogPresenter">
<img src="${this.BASEURL}/images/movies/movie001.png" width="332" height="500" />
<title class="scrollTextOnHighlight">My Title</title>
</lockup>
</section>
</shelf>
</collectionList>
</stackTemplate>
</document>`
}
When click on the image, I load my next template using the template parameter. This template is Product-001.xml.js
var Template = function() { return `<?xml version="1.0" encoding="UTF-8" ?>
<document>
<productTemplate theme="light">
<shelf>
<header>
<title>Last Added</title>
</header>
<section>
<lockup video="http://trailers.apple.com/movies/focus_features/9/9-clip_480p.mov">
<img src="${this.BASEURL}/resources/images/movies/movie_520_e2.lcr" width="332" height="500" />
<title class="showAndScrollTextOnHighlight">Title 2</title>
</lockup>
</section>
</shelf>
</productTemplate>
</document>`
}
This is using the video parameter. On the first "screen" everything works, no matter if I try to load a Template or a video. However, the same code does´t seem to work on the second screen.
Could someone help me with this?
I don´t know much about Javascript.
I have seen some posts where people say you must push the pages on the stack like this:
var parser = new DOMParser();
var newPageDocument = parser.parseFromString(NEW_PAGE_XML, 'application/xml');
navigationDocument.pushDocument(newPageDocument);
If this is the solution, I would be very grateful if someone could explain me where does that code need to be. Or how can I implement it correctly if I want multiple screens.
Thank you all very much!

Most likely this happens because you are using presentation="modalDialogPresenter" to load Product-001.xml.js file.
Your video may be staying behind the modal, try to see if you can see it when you press Escape.
Then remove that part and test it again.
"modalDialogPresenter" is geared for alerts.

Hey did you finally get the answer to this. I had a similar issue, my video was playing in the background. I could hear the audio but it was "covered" by the current template. The way I fixed this was somewhat of a hack, but i just simply dismissedModally the current view in the function that plays the video. I have a function in my presenter class that plays the video.I don't see this in your code. I think this is what your referring to. Let me know if this helps.

I ended up doing this in the Presenter file.
It seems to work ok:
if(templateURL) {
self.showLoadingIndicator(presentation);
resourceLoader.loadResource(templateURL,
function(resource) {
if (resource) {
var doc = self.makeDocument(resource);
doc.addEventListener("select", self.load.bind(self));
//doc.addEventListener("highlight", self.load.bind(self));
if (self[presentation] instanceof Function) {
// self[presentation].call(self, doc, ele);
self.defaultPresenter.call(self, doc);
}
/* else { self.defaultPresenter.call(self, doc); }
*/
}
}
);
Hope it helps!

Related

How to find and highlight text between tags in WKWebView webpage - Like browser find feature

How to find and highlight text in WKWebView? I have search option in my app which will search text inside WKWebview. I have to highlight the searched text in WKWebView.
I want to get "browser Find feature" in WKWebView.
I have tried some code in Mac browser which is working in Mac browser but not working in iPhone WKWebView.
I want search text between tags.
<!DOCTYPE html>
<html>
<head>
<title>Test page for Highlight Search Terms</title>
</head>
<body>
<input type="text" id="search" autofocus onkeyup="highlight(document.getElementById('search').value);" />
<div id="content">
<p>Here is some searchable <b>text</b> with some lápices in it, and more lápices, and some <b>for<i>mat</i>t</b>ing</p>
</div>
<script type="text/javascript">
function highlight(text) {
let colour = "#ff0";
unhighlight(document.body, 'ffff00');
while (window.find(text)) {
var range, sel;
if (window.getSelection) {
// IE9 and non-IE
try {
if (!document.execCommand("BackColor", false, colour)) {
makeEditableAndHighlight(colour);
}
} catch (ex) {
makeEditableAndHighlight(colour)
}
} else if (document.selection && document.selection.createRange) {
// IE <= 8 case
range = document.selection.createRange();
range.execCommand("BackColor", false, colour);
}
}
}
function makeEditableAndHighlight(colour) {
var range, sel = window.getSelection();
if (sel.rangeCount && sel.getRangeAt) {
range = sel.getRangeAt(0);
}
document.designMode = "on";
if (range) {
sel.removeAllRanges();
sel.addRange(range);
}
// Use HiliteColor since some browsers apply BackColor to the whole block
if (!document.execCommand("HiliteColor", false, colour)) {
document.execCommand("BackColor", false, colour);
}
document.designMode = "off";
}
function unhighlight(node, colour) {
if (node.nodeType == 1) {
var bg = node.style.backgroundColor;
node.style.backgroundColor = "";
}
var child = node.firstChild;
while (child) {
unhighlight(child, colour);
child = child.nextSibling;
}
}
</script>
</body>
</html>

Vuetify TreeView + Drag and drop

I am trying to implement drag and drop on Vuetify Treeview and data table. It seems like it is not supported fully but a workaround is described in this thread. The workaround is however not complete. Perhaps the community would benefit if someone created a codepen or similar on this?
What confuses me is that the component DragDropSlot.vue is created but "drag-drop-slot" is used in the code. Also there is a "_.cloneDeep(this.tree)" call where _ is not defined. I assume it should be replaced by something. When I comment that out drag and drop does still not work. Probably missed something more like defining data. Not sure of correct data types. It seems to be based on react which I have not worked with. Have just started to learn vue and vuetify.
I'm open for any suggestion for how to solve this.
All the best
I use V-Treeview with Vue.Draggable (https://github.com/SortableJS/Vue.Draggable).
I use direct link.
<script src="//cdn.jsdelivr.net/npm/sortablejs#1.8.4/Sortable.min.js"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/2.20.0 vuedraggable.umd.min.js"/>
<v-treeview
:active.sync="active"
:items="users"
:search="search"
item-key="Id"
item-text="UserName"
item-children="Children"
:open.sync="open"
activatable
color="warning"
dense
transition
return-object
>
<template v-slot:label="{ item }">
<draggable :list="users" group="node" :id="item.Id" :data-parent="item.ParentId" #start="checkStart" #end="checkEnd" >
<label>
<i class="fas fa-user mr-3" />
<span id="item.id" >{{item.UserName}}</span>
</label>
</draggable>
Also I add ParentId property to item tree model:
{
Id:1,
UserName: "John Doe",
ParentId: null,
Children:[{Id:2, ParentId: 1,...}]
}
Then I use start and end events where I search parent start node from I drag the item and parent end node where I drop the item. When parent is null the item is a root.
new Vue({
el: '#app',
vuetify: new Vuetify(),
components: {
vuedraggable
},
data() {
return {
active: [],
open: [],
users: [],
selectedItems: [],
}
},
mounted: function () {
this.fetchUsers();
},
methods: {
findTreeItem: function (items, id) {
if (!items) {
return;
}
for (var i = 0; i < items.length; i++) {
var item = items[i];
// Test current object
if (item.Id === id) {
return item;
}
// Test children recursively
const child = this.findTreeItem(item.Children, id);
if (child) {
return child;
}
}
},
checkStart: function (evt) {
var self = this;
self.active = [];
self.active.push(self.findTreeItem(self.users, evt.from.id))
},
checkEnd: function (evt) {
var self = this;
var itemSelected = self.active[0];
var fromParent = itemSelected.ParentId ? self.findTreeItem(self.users, itemSelected.ParentId) : null;
var toParent = self.findTreeItem(self.users, evt.to.id);
var objFrom = fromParent ? fromParent.Children : self.users;
objFrom.splice(objFrom.indexOf(itemSelected), 1);
if (toParent.Id === itemSelected.Id) {
itemSelected.ParentId = null;
self.users.push(itemSelected);
}
else {
itemSelected.ParentId = toParent.Id;
toParent.Children.push(itemSelected);
}
self.saveUser(itemSelected);
// self.active = [];
return false;
},
fetchUsers: function () {
//load from api
},
saveUser: function (user) {
//save
},
},
computed: {
selected() {
if (!this.active.length) return undefined
return this.active[0];
},
}
})
Hope I help you.
IngD.
After some additional work I ended up with implementing Drag and Drop on top of vuetify tree view and data table using this library:
https://www.vuetoolbox.com/projects/vue-drag-drop
At first I looked at draggable and similar but realized it was always based on that you move an element from position A to position B. I needed more control. For example I wanted the element to disappear when dropping on some drop zones.
found this component.
https://vuejsexamples.com/vuetify-draggable-v-treeview-component/
I didn't try it myself (because it has too few options), but it looks working well in demo.
Anyways, just to try

How to remove certain elements before taking screenshot?

I am able to take screenshot of the page using the example code below:
html2canvas(document.body, {
onrendered: function(canvas) {
document.body.appendChild(canvas);
}
});
Now there are certain div's i dont want to be part of the page when I take the screenshot?
How can i prevent them from being part of the screenshot.
One way I thought was to clone the element and then remove the elements, but taking a screenshot of the clone gives a white screen. Here is the code I used:
html2canvas($(document.body).clone()[0], {
onrendered: function(canvas) {
document.body.appendChild(canvas);
}
});
Add this attribute: data-html2canvas-ignore to any element you don't want to be taken when the screenshot is processed.
Hopefully this will help the next guy.
When I used this library I faced a problem that the lib download all the images in my application, that cause the application to run slowly. I resolved the problem using the ignoreElements option.
This is my code:
var DropAreaElement= document.getElementById("123");
var config= {
useCORS: true,
ignoreElements: function (element) {
if (element.contains(DropAreaElement) || element.parentElement.nodeName =="HTML" || element == DropAreaElement || element.parentNode == DropAreaElement) {
console.log("elements that should be taken: ", element)
return false;
}else {
return true;
}
}
};
html2canvas(DropAreaElement, config).then(function (canvas){
var imgBase64 = canvas.toDataURL('image/jpeg', 0.1);
console.log("imgBase64:", imgBase64);
var imgURL = "data:image/" + imgBase64;
var triggerDownload = $("<a>").attr("href", imgURL).attr("download", "layout_" + new Date().getTime() + ".jpeg").appendTo("body");
triggerDownload[0].click();
triggerDownload.remove();
}).catch(Delegate.create(this, function (e){
console.error("getLayoutImageBase64 Exception:", e);
});
If you don't want to use an attribute, html2canvas does provide a method to remove elements. For example:
html2canvas( document.body, {
ignoreElements: function( element ) {
/* Remove element with id="MyElementIdHere" */
if( 'MyElementIdHere' == element.id ) {
return true;
}
/* Remove all elements with class="MyClassNameHere" */
if( element.classList.contains( 'MyClassNameHere' ) ) {
return true;
}
}
} ).then( function( canvas ) {
document.body.appendChild( canvas );
} );
For more information, see html2canvas options.
You can create HOC for <Printable/> and <NonPrintable/> , you can wrap your component with <NonPrintable><YourCoolComponent/></NonPrintable>
those children components would be excluded.
import React from "react"
interface INonPrintable {
children: React.ReactChildren
}
/*
HOC - Printable which injects the printId to the React component
which gets us Printable Context to html2canvas => jsPDF
eg:
<Printable printId="about-you-print">
<PersonalInfo badEmail={badEmail} />
<IdentityInfo />
<AdditonalInfo />
<AddressInfo
serviceAddress={serviceAddress}
billingAddress={this.state.billingAddress}
setBillingAddress={this.setBillingAddress}
/>
</Printable>
*/
export default function Printable({ printId = "", children, ...restProps }) {
return <div print-id={printId} {...restProps}>{children}</div>
}
/*
HOC - NONPrintable which injects the data-html2canvas-ignore to the React component
which gets us Printable Context to html2canvas => jsPDF
eg:
<NonPrintable style={{display:"flex",justifyContent:'space-around'}}>
<Button
text="Print PDF using Own utility"
onClick={this.handlePrintPdf}
/>
<Button
text="Print PDF using html2canvas + jsPDF"
onClick={this.handlePrintwithPDFjs}
/>
</NonPrintable>
*/
export const NonPrintable = ({ children, ...restProps }) => {
return <div data-html2canvas-ignore {...restProps}>{children}</div>
}

Splitter control in SAPUI5

I am trying to implement SAPUI5 splitter button/control that accepts one Label and one button like Linked in. Like linked in when you add your skills, text display along with delete button. If you want to delete the text then simple click on delete button, it will delete (this is what happens in linked in).
I am also want to implement same thing using SAP splitter control but i am facing some layout issue. I have tried a lot to fix this issue but no luck.
Here is my code
In code there three splitters in total. Main splitter called oSplitterH that saves 0.....n sub-sublitters in its addFirstPaneContent.
The problem is it always display split button in vertical alignment rather than horizontal like linked in. I also changed the layout into Horizontal but still displaying in vertical alignment.
Any suggestion?
var splitterLabel = new Label({
text : 'Splitter ',
width: '80px'
});
var oSplitterH = new sap.ui.commons.Splitter("splitterH");
oSplitterH.setSplitterOrientation(sap.ui.commons.Orientation.Horizontal);
oSplitterH.setSplitterPosition("200%%");
oSplitterH.setMinSizeFirstPane("20%");
oSplitterH.setMinSizeSecondPane("30%");
oSplitterH.setWidth("200%");
//adding Labels to both panes
var oSplitter2 = new sap.ui.commons.Splitter("splitterH12");
oSplitter2.setSplitterOrientation(sap.ui.commons.Orientation.Vertical);
oSplitter2.setSplitterPosition("10%");
oSplitter2.setMinSizeFirstPane("10%");
oSplitter2.setMinSizeSecondPane("10%");
oSplitter2.setWidth("20%");
var oLabel2 = new sap.ui.commons.Label({text: "Part1"});
oSplitter2.addFirstPaneContent(oLabel2);
var oLabel2 = new sap.ui.commons.Label({text: "Part2"});
oSplitter2.addFirstPaneContent(oLabel2);
var oSplitter3 = new sap.ui.commons.Splitter("splitterH13");
oSplitter3.setSplitterOrientation(sap.ui.commons.Orientation.Vertical);
oSplitter3.setSplitterPosition("10%");
oSplitter3.setMinSizeFirstPane("10%");
oSplitter3.setMinSizeSecondPane("10%");
oSplitter3.setWidth("20%");
var oLabe123 = new sap.ui.commons.Label({text: "Part3"});
oSplitter3.addFirstPaneContent(oLabe123);
var oLabe1234 = new sap.ui.commons.Label({text: "Part4"});
oSplitter3.addFirstPaneContent(oLabe1234);
oSplitterH.addFirstPaneContent(oSplitter2);
oSplitterH.addFirstPaneContent(oSplitter3);
createProfileMatrix.createRow(splitterLabel, oSplitterH, null, null);
The following code may help you.
index.html
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="stylesheet" href="main.css"/>
<script src="resources/sap-ui-core.js"
id="sap-ui-bootstrap"
data-sap-ui-libs="sap.ui.commons"
data-sap-ui-theme="sap_goldreflection">
</script>
<!-- add sap.ui.table,sap.ui.ux3 and/or other libraries to 'data-sap-ui-libs' if required -->
<script>
sap.ui.localResources("sapui5samples");
var view = sap.ui.view({id:"idlinkedIn-label1", viewName:"sapui5samples.linkedIn-label", type:sap.ui.core.mvc.ViewType.JS});
view.placeAt("content");
</script>
</head>
<body class="sapUiBody" role="application">
<div id="content"></div>
<div id="list"></div>
</body>
</html>
main.css
.tech-area{
border:1px solid gray;
border-radius: 5px;
width:500px;
height:300px;
left:0;
top:50;
position:relative;
overflow:scroll;
}
SAPUI5 view file (didn't used controller file)
var oLayout;
sap.ui.jsview("sapui5samples.linkedIn-label", {
getControllerName : function() {
return "sapui5samples.linkedIn-label";
},
createContent : function(oController) {
// create a simple SearchField with suggestion list (list expander
// visible)
var oSearch = new sap.ui.commons.SearchField("suggestSearch1", {
enableListSuggest : true,
startSuggestion : 1,
search : function(oEvent) {
var techName = oEvent.getParameter("query");
addTechnology(techName);
},
suggest : doSuggest
});
// Button for adding the technology if it is not listed in the available
// technologies
var oButton = new sap.ui.commons.Button({
text : "Add",
tooltip : "Add Technology",
press : function() {
var tech = sap.ui.getCore().byId("suggestSearch1").getValue();
addTechnology(tech);
}
});
// create a simple horizontal layout
var oLayout = new sap.ui.commons.layout.HorizontalLayout({
content : [ oSearch, oButton ]
});
// attach it to some element in the page
oLayout.placeAt("content");
oLayout = new sap.ui.commons.layout.HorizontalLayout("target");
oLayout.addStyleClass("tech-area");
// attach it to some element in the page
oLayout.placeAt("list");
}
});
// Help function to handle the suggest events of the search field
var doSuggest = function(oEvent) {
var sVal = oEvent.getParameter("value");
var aSuggestions = filterTechnologies(sVal); // Find the technologies
var oSearchControl = sap.ui.getCore().byId(oEvent.getParameter("id"));
oSearchControl.suggest(sVal, aSuggestions); // Set the found suggestions on
// the search control
};
var technologies = [ "Java", ".Net", "PHP", "SAPUI5", "JQuery", "HTML5", "" ];
technologies.sort();
jQuery.sap.require("jquery.sap.strings"); // Load the plugin to use
// 'jQuery.sap.startsWithIgnoreCase'
// Help function to filter the technologies according to the given prefix
var filterTechnologies = function(sPrefix) {
var aResult = [];
for (var i = 0; i < technologies.length; i++) {
if (!sPrefix || sPrefix.length == 0
|| jQuery.sap.startsWithIgnoreCase(technologies[i], sPrefix)) {
aResult.push(technologies[i]);
}
}
return aResult;
};
var count = 0;
var arr = [];
// function for add the item to horizontal layout
var addTechnology = function(techName) {
var elementIndex = arr.indexOf(techName);
// conditional statement for adding the tech to the list
if (elementIndex === -1) {
count++;
// create a horizontal Splitter
var oSplitterV = new sap.ui.commons.Splitter({
width : "120px",
height : "30px",
showScrollBars : false,
splitterBarVisible : false
});
oSplitterV.setSplitterOrientation(sap.ui.commons.Orientation.vertical);
oSplitterV.setSplitterPosition("60%");
oSplitterV.setMinSizeFirstPane("60%");
oSplitterV.setMinSizeSecondPane("40%");
// label with dynamic Id
var oLabel1 = new sap.ui.commons.Label("tCount" + count, {
text : techName,
tooltip : techName
});
oSplitterV.addFirstPaneContent(oLabel1);
var oLabel2 = new sap.ui.commons.Button({
icon : "img/delete.png",
press : function() {
removeElement(techName);
oSplitterV.destroy();
}
});
oSplitterV.addSecondPaneContent(oLabel2);
sap.ui.getCore().byId("target").addContent(oSplitterV);
// Adding the tech to the parent array
arr.push(techName);
// Emptying the search box
sap.ui.getCore().byId("suggestSearch1").setValue("");
} else {
sap.ui.commons.MessageBox.alert(techName
+ " is already added to the list");
}
}
// function for removing removed element from parent array
var removeElement = function(addedTech) {
// Find and remove item from an array
var i = arr.indexOf(addedTech);
if (i != -1) {
arr.splice(i, 1);
}
}
Please make a note that I concentrated more on functionality rather than look and feel
Thanks,
prodeveloper

HTML5 Geolocation data loaded in a form to send towards database

i'm busy with a school project and I have to build a web app. One function that I want to use is Google Maps and HTML5 Geo Location to pin point what the location of the mobile user is.
I have found this HTML5 Geo Location function on http://merged.ca/iphone/html5-geolocation and works very well for me. However, I want the adress data to be placed into a form so that I can submit it to my database when a mobile user Geo locates his position. This causes the marker to be saved and can be viewed on a global website.
Who know how to get the "Your address:" data loaded into a input field of a form?
Below you can find my Html file. Maybe somebody got a better suggestion perhaps?
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<title>HTML 5 Geolocation</title>
<style>
#map {
height:300px;
width:300px;
}
</style>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">google.load("jquery", "1"); google.load("jqueryui", "1");</script>
<script src="http://maps.google.com/maps?file=api&v=2&sensor=false&key=ABQIAAAAiUzO1s6QWHuyzxx-JVN7ABSUL8-Cfeleqd6F6deqY-Cw1iTxhxQkovZkaxsxgKCdn1OCYaq7Ubz3SQ" type="text/javascript"></script>
<script type="text/javascript" src="http://api.maps.yahoo.com/ajaxymap?v=3.8&appid=n2wY9mzV34Hsdslq6TJoeoJDLmAfzeBamSwJX7jBGLnjM7oDX7fU.Oe91KwUbOwqzvc-"></script>
<script type="text/javascript">
// Geolocation with HTML 5 and Google Maps API based on example from maxheapsize: http://maxheapsize.com/2009/04/11/getting-the-browsers-geolocation-with-html-5/
//
// This script is by Merge Database and Design, http://merged.ca/ -- if you use some, all, or any of this code, please offer a return link.
var map;
var mapCenter
var geocoder;
var fakeLatitude;
var fakeLongitude;
function initialize()
{
if (navigator.geolocation)
{
navigator.geolocation.getCurrentPosition( function (position) {
// Did we get the position correctly?
// alert (position.coords.latitude);
// To see everything available in the position.coords array:
// for (key in position.coords) {alert(key)}
mapServiceProvider(position.coords.latitude,position.coords.longitude);
}, // next function is the error callback
function (error)
{
switch(error.code)
{
case error.TIMEOUT:
alert ('Timeout');
break;
case error.POSITION_UNAVAILABLE:
alert ('Position unavailable');
break;
case error.PERMISSION_DENIED:
alert ('Permission denied');
break;
case error.UNKNOWN_ERROR:
alert ('Unknown error');
break;
}
}
);
}
else
{
alert("I'm sorry, but geolocation services are not supported by your browser or you do not have a GPS device in your computer. I will use a sample location to produce the map instead.");
fakeLatitude = 49.273677;
fakeLongitude = -123.114420;
//alert(fakeLatitude+', '+fakeLongitude);
mapServiceProvider(fakeLatitude,fakeLongitude);
}
}
function mapServiceProvider(latitude,longitude)
{
if (window.location.querystring['serviceProvider']=='Yahoo')
{
mapThisYahoo(latitude,longitude);
}
else
{
mapThisGoogle(latitude,longitude);
}
}
function mapThisYahoo(latitude,longitude)
{
var map = new YMap(document.getElementById('map'));
map.addTypeControl();
map.setMapType(YAHOO_MAP_REG);
map.drawZoomAndCenter(latitude+','+longitude, 3);
// add marker
var currentGeoPoint = new YGeoPoint( latitude, longitude );
map.addMarker(currentGeoPoint);
// Start up a new reverse geocoder for addresses?
// YAHOO Ajax/JS/Rest API does not yet support reverse geocoding (though they do support it via Actionscript... lame)
// So we'll have to use Google for the reverse geocoding anyway, though I've left this part of the script just in case Yahoo! does support it and I'm not aware of it yet
geocoder = new GClientGeocoder();
geocoder.getLocations(latitude+','+longitude, addAddressToMap);
}
function mapThisGoogle(latitude,longitude)
{
var mapCenter = new GLatLng(latitude,longitude);
map = new GMap2(document.getElementById("map"));
map.setCenter(mapCenter, 15);
map.addOverlay(new GMarker(mapCenter));
// Start up a new reverse geocoder for addresses?
geocoder = new GClientGeocoder();
geocoder.getLocations(latitude+','+longitude, addAddressToMap);
}
function addAddressToMap(response)
{
if (!response || response.Status.code != 200) {
alert("Sorry, we were unable to geocode that address");
} else {
place = response.Placemark[0];
$('#address').html('Your address: '+place.address);
}
}
window.location.querystring = (function() {
// by Chris O'Brien, prettycode.org
var collection = {};
var querystring = window.location.search;
if (!querystring) {
return { toString: function() { return ""; } };
}
querystring = decodeURI(querystring.substring(1));
var pairs = querystring.split("&");
for (var i = 0; i < pairs.length; i++) {
if (!pairs[i]) {
continue;
}
var seperatorPosition = pairs[i].indexOf("=");
if (seperatorPosition == -1) {
collection[pairs[i]] = "";
}
else {
collection[pairs[i].substring(0, seperatorPosition)]
= pairs[i].substr(seperatorPosition + 1);
}
}
collection.toString = function() {
return "?" + querystring;
};
return collection;
})();
</script>
</head>
<body onLoad="initialize()">
<div id="content">
<div id="map"></div>
<p id="address"></p>
<form id="ContactForm" action="">
<p>
<label>Topic</label>
<input id="event" name="event" maxlength="120" type="text" autocomplete="off"/>
</p>
<p>
<label>Address</label>
<input id="address" name="address" maxlength="120" type="text" autocomplete="off"/>
</p>
<input id="send" type="button" value="Send"/>
<input id="newcontact" name="newcontact" type="hidden" value="1"></input>
</form>
</div>
</body>
</html>
You have to use JavaScript to set the value of address input field, this way
1- Add name attribute to the form and input.
2- document.formName.inputName.value=place.address;
Good Luck