I am developing a chrome app (on chromebook) and the javascript wont load. Is it the code, the fact that it is an app? Can someone help? Here is my code:
<!DOCTYPE html>
<html>
<body>
<h1>Cash Register</h1>
//inputs
<input type="text" id="myText1" value="Name">
<input type="text" id="myText2" value="Price">
//add button
<button onclick="add()">Add</button>
//The total goes here
<div id="div1"><h2 id="demo1"><h2 id="demo2"></h2></div>
<script>
//my function
function add() {
//variables
var x = 'Total:'
var y = document.getElementById("myText2").value;
var z = document.getElementById("myText1").value;
//writes the items you enter
//makes a separating line
var para = document.createElement("h4");
var node = document.createTextNode('_____');
para.appendChild(node);
var element = document.getElementById("div1");
element.appendChild(para);
//makes the item
var para = document.createElement("h4");
var node = document.createTextNode(z);
para.appendChild(node);
var element = document.getElementById("div1");
element.appendChild(para);
//makes the price
var para = document.createElement("p");
var node = document.createTextNode(y);
para.appendChild(node);
var element = document.getElementById("div1");
element.appendChild(para);
//writes "Total (total price)"
var w = document.getElementsByTagName("p"); // this gets all the P's as an object
// setup a total starting at 0
var total = 0;
for (var i = 0; i < w.length; i++) {
total += parseInt(w[i].innerText); // make the inner text an integer for addition.
}
document.getElementById("demo1").innerHTML = x;
document.getElementById("demo2").innerHTML = total; // replace w with total
}
</script>
</body>
</html>
Anything would help. If you have a solution, please shoe it to me! Thank you. By the way, I am new at this. When I put it through jshint, this is what I got:
(Image)
So, all I had to do was add
//my function
function add() {
//variables
var x = 'Total:';
var y = document.getElementById("myText2").value;
var z = document.getElementById("myText1").value;
//writes the items you enter
//makes a separating line
var para = document.createElement("h4");
var node = document.createTextNode('_____');
para.appendChild(node);
var element = document.getElementById("div1");
element.appendChild(para);
//makes the item
para = document.createElement("h4");
node = document.createTextNode(z);
para.appendChild(node);
element = document.getElementById("div1");
element.appendChild(para);
//makes the price
para = document.createElement("p");
node = document.createTextNode(y);
para.appendChild(node);
element = document.getElementById("div1");
element.appendChild(para);
//writes "Total (total price)"
var w = document.getElementsByTagName("p"); // this gets all the P's as an object
// setup a total starting at 0
var total = 0;
for (var i = 0; i < w.length; i++) {
total += parseInt(w[i].innerText); // make the inner text an integer for addition.
}
document.getElementById("demo1").innerHTML = x;
document.getElementById("demo2").innerHTML = total; // replace w with total
}
document.addEventListener('DOMContentLoaded', function() {
var link = document.getElementById('link');
// onClick's logic below:
link.addEventListener('click', function() {
add()
});
});
to a javascript file and change my script tag to
<script src="add.js"></script>
If anyone wants to use this, here is the code:
Manifest:
{
"name": "Cash register",
"description": "Use at garage sales",
"version": "0.1",
"manifest_version": 2,
"app": {
"background": {
"scripts": ["background.js"]
}
},
"icons": { "16": "calculator-16.png", "128": "calculator-128.png" }
}
background.js:
chrome.app.runtime.onLaunched.addListener(function() {
chrome.app.window.create('index.html', {
'outerBounds': {
'width': 400,
'height': 500
}
});
});
add.js:
//my function
function add() {
//variables
var x = 'Total:';
var y = document.getElementById("myText2").value;
var z = document.getElementById("myText1").value;
//writes the items you enter
//makes a separating line
var para = document.createElement("h4");
var node = document.createTextNode('_____');
para.appendChild(node);
var element = document.getElementById("div1");
element.appendChild(para);
//makes the item
para = document.createElement("h4");
node = document.createTextNode(z);
para.appendChild(node);
element = document.getElementById("div1");
element.appendChild(para);
//makes the price
para = document.createElement("p");
node = document.createTextNode(y);
para.appendChild(node);
element = document.getElementById("div1");
element.appendChild(para);
//writes "Total (total price)"
var w = document.getElementsByTagName("p"); // this gets all the P's as an object
// setup a total starting at 0
var total = 0;
for (var i = 0; i < w.length; i++) {
total += parseInt(w[i].innerText); // make the inner text an integer for addition.
}
document.getElementById("demo1").innerHTML = x;
document.getElementById("demo2").innerHTML = total; // replace w with total
}
document.addEventListener('DOMContentLoaded', function() {
var link = document.getElementById('link');
// onClick's logic below:
link.addEventListener('click', function() {
add()
index.html:
<html>
<head>
<script src="add.js"></script>
</head>
<body>
<h1>Cash Register</h1>
<input type="text" id="myText1" value="Name">
<input type="text" id="myText2" value="Price (numbers only)">
<a id="link">Add</a>
<div id="div1"><h2 id="demo1"></h2><h2 id="demo2"></h2></div>
</body></html>
Thanks Everyone!!!
Ok, you are creating the same elements with the same name three times and I don't see how you are using the additional tags and elements but that is most likely the reason an error is being thrown.
Try putting your code through http://jshint.com and you'll see your issues.
Related
Making a voice recorder visualizer and I'm just about finished but there's one thing, After I stop the recording, the values in mic.getLevel() do not go back to 0 but instead it seems like the last value that was recorded in mic.getLeve() is stored permanently and added to the height of my ellipse so the ellipse would then have a height of some value rather than 0 which it started with, is there anyway to fix this?
var recordAudio;
function setup() {
createCanvas(windowWidth, windowHeight);
recordAudio = new AudioFile()
}
function draw() {
background(0);
recordAudio.draw();
recordAudio.setup();
recordAudio.drawBorder();
recordAudio.drawNode();
}
function AudioFile() {
this.nodes = [];
var speed = 2;
var endBorder;
var mic = new p5.AudioIn();
var micLevel;
var level;
var recorder = new p5.SoundRecorder();
var soundFile = new p5.SoundFile();
var button = createButton('Start Recording');
var state = 0;
this.draw = function() {
background(0);
level = mic.getLevel();
micLevel = floor(map(level, 0, 0.6545, 0, 50));
}
this.drawNode = function() {
if (frameCount % 5 == 0) {
this.addNode()
}
for (var i = 0; i < this.nodes.length; i++) {
var node = this.nodes[i]
for (var j = 0; j < node.length; j++) {
fill(255);
node[j].x -= speed;
ellipse(node[j].x, node[j].y, node[j].width, node[j].height)
}
if (node[0].x < endBorder) {
this.nodes.splice(i, 1);
}
}
}
this.drawBorder = function() {
var x = windowWidth / 9;
var y = windowHeight / 10;
var width = (windowWidth / 9) * 7;
var height = windowHeight - y * 2;
stroke(255);
strokeWeight(2);
noFill();
rect(x, y, width, height);
}
this.addNode = function() {
this.nodes.push(
[{
x: ((windowWidth / 9) * 8) - 10,
y: windowHeight / 2,
width: 5,
height: 5 * micLevel
}])
}
this.setup = function() {
endBorder = windowWidth / 9 + 5;
mic.start();
recorder.setInput(mic);
button.position(windowWidth / 9, windowHeight / 10);
button.style('font-size', '18px');
button.mousePressed(this.recording)
}
this.recording = function() {
if (state === 0 && mic.enabled) {
button.html("Stop Recording");
getAudioContext().resume()
recorder.record(soundFile);
state++
} else if (state === 1) {
button.html("Start Recording");
getAudioContext().suspend();
recorder.stop();
state++;
} else if (state === 2) {
save(soundFile, 'Sound.wav');
state = 0;
}
}
}
<!DOCTYPE html>
<html>
<head>
<link href="style.css" rel="stylesheet">
<script src="p5.min.js"></script>
<script src="p5.dom.js"></script>
<script src="p5.sound.js"></script>
<script src="sketch.js"></script>
<!--<link rel="stylesheet" type="text/css" href="style.css">-->
<style>
body {
padding: 0;
margin: 0;
}
</style>
</head>
<body>
<div id="Button">
</div>
</body>
</html>
I ended up making a global variable called listening and used that in an if statement in draw to set the level to either mic.getLevel() or 0 based on if listening is true or false.
I am building a Framework7 MVC app and found myself in a dead end alley. I have a form which I need to evaluate. This form contains selects. I am using localStorage to store the form values and everything works OK in that sense, I mean everything is stored correctly. ¿What is the issue? When I fill the form I answer some questions on textareas inputs, select inputs and inputs. everything goes fine until I try to reedit the form, then everything is display correctly on the form, including the score i got from my previous answers, but, the selects appears as if I have never touch them. Their previously selected value is stored but not display on the form. I have found that the issue is caused by the fact that I have set numerical values to the options values but what the form show is "yes" or "no". If I change the option values to "yes" or "no" then the form displays correctly but I need to set "5" or "0" because I need to evaluate the user's answers.
This is my code
The form
<li style="margin-top:-10px;">
<input style="visibility:hidden;height:1px;" value="0" name="choice" onchange="checkTotal()"/>
<input style="visibility:hidden;height:1px;" value="1" type="checkbox" name="choice" onchange="checkTotal()" checked="on">
</li>
<li><div class="item-content">1. ¿Sueles quejarte de sentirte mal?</div>
<div class="item-content">
<div class="item-inner">
<div class="item-input">
<select name="pr1" id="pr1" onchange="checkTotal()">
<option class="item-inner" value="5">No</option>
<option class="item-inner" value="0">Si</option>
</select>
</div>
</div>
</div>
<div class="item-content">En tal caso,</div>
<div class="item-content">
<div class="item-inner">
<div class="item-input">
<textarea class="resizable" id="pr1notes" placeholder="¿cuál es la causa?">{{model.pr1notes}}</textarea>
</div>
</div>
</div>
</li>
The functions on the editController
function init(query){
var protections = JSON.parse(localStorage.getItem("f7Protections"));
if (query && query.id) {
protection = new Protection(_.find(protections, { id: query.id }));
state.isNew = false;
}
else {
protection = new Protection({ isFavorite: query.isFavorite });
state.isNew = true;
}
View.render({ model: protection, bindings: bindings, state: state, doneCallback: saveProtection });
showSelectedValues();
}
function showSelectedValues(){
var fieldNames = protection.getSelectFields();
for (var i = 0, len = fieldNames.length; i < len; i++) {
var itemname = fieldNames[i];
var selectObj = document.getElementById(itemname);
if (selectObj!=null) {
var objOptions = selectObj.options;
var selIndex=0;
for (var j = 0, len2 = objOptions.length; j < len2; j++) {
if ((objOptions[j].label).localeCompare(protection[itemname])==0){
selIndex=j;
}
}
selectObj.options[selIndex].setAttribute("selected","selected");
}else{
}
}
}
and the model
Protection.prototype.setValues = function(inputValues, extras) {
for (var i = 0, len = inputValues.length; i < len; i++) {
var item = inputValues[i];
if (item.type === 'checkbox') {
this[item.id] = item.checked;
}
else {
this[item.id] = item.value;
}
}
for (var i = 0, len = extras[0].length; i < len; i++) {
var item = extras[0][i];
if((item.id).localeCompare("pr1notes")==0) {this[item.id] = item.value;}
}
console.log('starting loop for extras 3...');
for (var i = 0, len = extras[2].length; i < len; i++) {
var item = extras[2][i];
this[item.name] = item.value;
}
};
Protection.prototype.validate = function() {
var result = true;
if (_.isEmpty(this.prdate)
) {result = false;}
return result;
};
Protection.prototype.getSelectFields = function() {
return ['pr1'];
}
What should I change in order to keep my "5" or "0" values on the select options while the form options still show "yes" or "no" to the user just like this: <select name="pr1" id="pr1" onchange="checkTotal()"><option class="item-inner" value="5">No</option><option class="item-inner" value="0">Si</option></select>?
need anything else to help you understand the issue?
The simplest solution
function init(query){
var protections = JSON.parse(localStorage.getItem("f7Protections"));
if (query && query.id) {
protection = new Protection(_.find(protections, { id: query.id }));
state.isNew = false;
}
else {
protection = new Protection({ isFavorite: query.isFavorite });
state.isNew = true;
}
View.render({ model: protection, bindings: bindings, state: state, doneCallback: saveProtection });
showSelectedValues();
}
function showSelectedValues(){
var fieldNames = protection.getSelectFields();
for (var i = 0, len = fieldNames.length; i < len; i++) {
var itemname = fieldNames[i];
var selectObj = document.getElementById(itemname);
if (selectObj!=null) {
var objOptions = selectObj.options;
var selIndex=0;
for (var j = 0, len2 = objOptions.length; j < len2; j++) {
if ((objOptions[j].value).localeCompare(protection[itemname])==0){
selIndex=j;
}
}
selectObj.options[selIndex].setAttribute("selected","selected");
}else{
}
}
}
Just changed this line
if ((objOptions[j].label).localeCompare(protection[itemname])==0){
selIndex=j;
and changed .label for .value.
There is a similar thread here but the answer isn't clear and there is no clear example to follow.
I need to dynamically add series to a Google Charts graph. Suppose each successive click of a button should add a new series from my array. Right now it just replaces it. What should I do?
// Init
google.charts.load('current', {'packages':['corechart']});
var currentclick = 0;
// My Data
var titles = ['Year1','Year2','Year3','Year4'];
var nums = [ [44,12,33,22], [33,11,7,8], [2,1,65,44] ];
$('#addSeries').click(function() {
if (currentclick < 3) {
draw(nums, currentclick);
}
currentclick++;
});
function draw(arr, seriesnum) {
var chartData = new google.visualization.DataTable();
chartData.addColumn('string', 'Year');
chartData.addColumn('number', 'Value');
var chartRowArray = $.makeArray();
for (var i = 0; i < 4; i++) {
chartRowArray.push( [ titles[i], arr[seriesnum][i] ] );
}
chartData.addRows(chartRowArray);
var chart = new google.visualization.LineChart(document.getElementById('chartarea'));
chart.draw(chartData, null);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="addSeries">Add Next Series</button>
<div id="chartarea">
</div>
You want to add a line chart from the data of nums every time when you clicked "Add Next Series" button.
If my understanding is correct, how about this modification? I think that there are several answers for your situation. So please think of this as just one of several answers.
Modification point:
In this modification, chartRowArray is declared as a global variable. When the button is clicked, the data is added to chartRowArray. By this, the line chars are added to the existing chart.
Modified script:
// Init
google.charts.load('current', {'packages':['corechart']});
var currentclick = 0;
// My Data
var titles = ['Year1','Year2','Year3','Year4'];
var nums = [ [44,12,33,22], [33,11,7,8], [2,1,65,44] ];
$('#addSeries').click(function() {
if (currentclick < 3) {
draw(nums, currentclick);
}
currentclick++;
});
// Below script was modified.
var chartRowArray = $.makeArray(); // Added
function draw(arr, seriesnum) {
var chartData = new google.visualization.DataTable();
chartData.addColumn('string', 'Year');
for (var i = 0; i < seriesnum + 1; i++) { // Added
chartData.addColumn('number', 'Value');
}
if (seriesnum === 0) { // Added
for (var i = 0; i < 4; i++) {
chartRowArray.push( [ titles[i], arr[seriesnum][i] ] );
}
} else { // Added
for (var i = 0; i < 4; i++) {
chartRowArray[i].push(arr[seriesnum][i]);
}
}
chartData.addRows(chartRowArray);
var chart = new google.visualization.LineChart(document.getElementById('chartarea'));
chart.draw(chartData, null);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="addSeries">Add Next Series</button>
<div id="chartarea"></div>
If I misunderstood your question and this was not the result you want, I apologize.
The key thing is the final structure of the data.
The Column Array should be
0: Year
1: Value
2: Value
etc.
The Column array is added 1-by-1 as chartData.addColumn(type, name).
The data's Row Array should be
0:
0: Year1
1: 44
2: 33
1:
0: Year2
1: 12
2: 11
etc.
The Row Array is added in one shot as chartData.addRows(rowArray).
Knowing this, I made both RowArray / ColArray global variables that get modified on the fly (thanks for the idea Tainake) and for the initial conditions when the arrays are empty, I construct or initialize them for the first time.
Working example below. Thanks again for the help!
// Init
google.charts.load('current', {'packages':['corechart']});
var currentclick = 0;
// My Data
var titles = ['Year1','Year2','Year3','Year4'];
var nums = [ [44,12,33,22], [33,11,7,8], [2,1,65,44] ];
var chartColArray = $.makeArray(); // Global var
var chartRowArray = $.makeArray(); // Global var
$('#addSeries').click(function() {
if (currentclick < 3) {
draw(nums, currentclick);
}
currentclick++;
});
function draw(arr, seriesnum) {
var chartData = new google.visualization.DataTable();
// For initial Column, push 'Year'; otherwise, push 'Value'
if (chartColArray.length == 0) {
chartColArray.push('Year');
}
chartColArray.push('Value');
// addColumn() has to be 1-by-1-by-1, there is no addColumns(colarray)
$.each(chartColArray, function(index, item) {
(index == 0 ? chartData.addColumn('string', item) : chartData.addColumn('number', item));
});
for (var i = 0; i < 4; i++) {
// For initial Row subarray, create subarray and push 'Year Series';
// otherwise, push actual 'Series' value
if (chartRowArray[i] == undefined) {
chartRowArray[i] = $.makeArray();
chartRowArray[i].push(titles[seriesnum]);
}
chartRowArray[i].push(nums[seriesnum][i]);
}
chartData.addRows(chartRowArray);
// Instantiate and draw the chart.
var chart = new google.visualization.LineChart(document.getElementById('chartarea'));
chart.draw(chartData, null);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="addSeries">Add Next Series</button>
<div id="chartarea">
</div>
I'm not really sure why the GeoLocation works on my PC, but not my iPhone ... I've got sensor=true within the script call to the API, but apart from that, I'm at a loss. Here's the entire script:
<div id="info"></div>
<div id="map_canvas" style="width:908px; height:420px"></div>
<input type="text" id="addressInput" size="10"/>
<select id="radiusSelect">
<option value="5" selected>5mi</option>
<option value="15" selected>15mi</option>
<option value="25" selected>25mi</option>
<option value="100">100mi</option>
<option value="200">200mi</option>
<option value="4000">4000mi</option>
</select>
<input type="button" value="Search" onclick="searchLocations();">
<div><select id="locationSelect" style="width:100%;visibility:hidden"></select></div>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key=AIzaSyCe49sI29q0AVNo9iVvQ-lDlDwZpFZuA4o&sensor=true"></script>
<script type="text/javascript" src="http://gmaps-samples-v3.googlecode.com/svn/trunk/geolocate/geometa.js"></script>
<script type="text/javascript">
var map;
var markers = [];
var infoWindow;
var locationSelect;
function load() {
map = new google.maps.Map(document.getElementById("map_canvas"), {
center: new google.maps.LatLng(40, -100),
zoom: 4,
mapTypeId: 'roadmap',
mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU}
});
infoWindow = new google.maps.InfoWindow();
locationSelect = document.getElementById("locationSelect");
locationSelect.onchange = function() {
var markerNum = locationSelect.options[locationSelect.selectedIndex].value;
if (markerNum != "none") {
google.maps.event.trigger(markers[markerNum], 'click');
}
};
// geolocation
prepareGeolocation();
doGeolocation();
}
function doGeolocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(positionSuccess, positionError);
} else {
positionError(-1);
}
}
function positionError(err) {
var msg;
switch(err.code) {
case err.UNKNOWN_ERROR:
msg = "Unable to find your location";
break;
case err.PERMISSION_DENINED:
msg = "Permission denied in finding your location";
break;
case err.POSITION_UNAVAILABLE:
msg = "Your location is currently unknown";
break;
case err.BREAK:
msg = "Attempt to find location took too long";
break;
default:
msg = "Location detection not supported in browser";
}
document.getElementById('info').innerHTML = msg;
}
function positionSuccess(position) {
// Centre the map on the new location
var coords = position.coords || position.coordinate || position;
var latLng = new google.maps.LatLng(coords.latitude, coords.longitude);
map.setCenter(latLng);
map.setZoom(15);
var marker = new google.maps.Marker({
map: map,
position: latLng,
title: 'Why, there you are!'
});
document.getElementById('info').innerHTML = 'Looking for <b>' +
coords.latitude + ', ' + coords.longitude + '</b>...';
// And reverse geocode.
(new google.maps.Geocoder()).geocode({latLng: latLng}, function(resp) {
var place = "You're around here somewhere!";
if (resp[0]) {
var bits = [];
for (var i = 0, I = resp[0].address_components.length; i < I; ++i) {
var component = resp[0].address_components[i];
if (contains(component.types, 'political')) {
bits.push('<b>' + component.long_name + '</b>');
}
}
if (bits.length) {
place = bits.join(' > ');
}
marker.setTitle(resp[0].formatted_address);
}
document.getElementById('info').innerHTML = place;
});
}
function contains(array, item) {
for (var i = 0, I = array.length; i < I; ++i) {
if (array[i] == item) return true;
}
return false;
}
function searchLocations() {
console.log("searching locations...");
var address = document.getElementById("addressInput").value;
var geocoder = new google.maps.Geocoder();
geocoder.geocode({address: address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
searchLocationsNear(results[0].geometry.location);
} else {
alert(address + ' not found');
}
});
}
function clearLocations() {
//infoWindow.close();
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
markers.length = 0;
locationSelect.innerHTML = "";
var option = document.createElement("option");
option.value = "none";
option.innerHTML = "See all results:";
locationSelect.appendChild(option);
locationSelect.style.visibility = "visible";
}
function searchLocationsNear(center) {
clearLocations();
var radius = document.getElementById('radiusSelect').value;
/* var searchUrl = 'phpsqlajax_search.php?lat=' + center.lat() + '&lng=' + center.lng() + '&radius=' + radius; */
var searchUrl = 'http://dev-imac.local/phpsqlajax_search.php?lat=' + center.lat() + '&lng=' + center.lng() + '&radius=' + radius;
console.log(searchUrl);
downloadUrl(searchUrl, function(data) {
var xml = parseXml(data);
var markerNodes = xml.documentElement.getElementsByTagName("marker");
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < markerNodes.length; i++) {
var name = markerNodes[i].getAttribute("name");
var address = markerNodes[i].getAttribute("address");
var distance = parseFloat(markerNodes[i].getAttribute("distance"));
var latlng = new google.maps.LatLng(
parseFloat(markerNodes[i].getAttribute("lat")),
parseFloat(markerNodes[i].getAttribute("lng")));
createOption(name, distance, i);
createMarker(latlng, name, address);
bounds.extend(latlng);
}
map.fitBounds(bounds);
});
}
function createMarker(latlng, name, address) {
var html = "<b>" + name + "</b> <br/>" + address;
var marker = new google.maps.Marker({
map: map,
position: latlng
});
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent(html);
infoWindow.open(map, marker);
});
markers.push(marker);
}
function createOption(name, distance, num) {
var option = document.createElement("option");
option.value = num;
option.innerHTML = name + "(" + distance.toFixed(1) + ")";
locationSelect.appendChild(option);
}
function downloadUrl(url, callback) {
var request = window.ActiveXObject ?
new ActiveXObject('Microsoft.XMLHTTP') :
new XMLHttpRequest;
request.onreadystatechange = function() {
if (request.readyState == 4) {
request.onreadystatechange = doNothing;
callback(request.responseText, request.status);
}
};
request.open('GET', url, true);
request.send(null);
}
function parseXml(str) {
if (window.ActiveXObject) {
var doc = new ActiveXObject('Microsoft.XMLDOM');
doc.loadXML(str);
return doc;
} else if (window.DOMParser) {
return (new DOMParser).parseFromString(str, 'text/xml');
}
}
function doNothing() {}
window.onload = load();
</script>
First of all,
mapTypeId: 'roadmap',
should be:
mapTypeId: google.maps.MapTypeId.ROADMAP,
but that should cause it to fail in your PC as well.
Other than that, your <script> section should be in the <head> section of the document and not in the <body>. Maybe the iPhone browser is more strict about this than the browser on your PC. What browser(s) are you using in each system? (I'm guessing you're using IE on the PC. Have you tried other browsers?)
I am trying to implement Autocomplete in a text area (similar to http://www.pengoworks.com/workshop/jquery/autocomplete.htm).
What I am trying to do is when a user enters a specific set of characters (say insert:) they will get an AJAX filled div with possible selectable matches.
In a regular text box, this is of course simple, but in a text area I need to be able to popup the div in the correct location on the screen based on the cursor.
Can anyone provide any direction?
Thanks,
-M
You can get the caret using document.selection.createRange(), and then examining it to reveal all the information you need (such as position). See those examples for more details.
Implementing an autocomplete in a text area is not that easy. I implemented a jquery plugin that does that, and i had to create a clone of the texarea to guess where the cursor is positioned inside the textarea.
Its working, but its not perfect.
You can check it out here: http://www.amirharel.com/2011/03/07/implementing-autocomplete-jquery-plugin-for-textarea/
I hope it helps.
function getCursor(nBox){
var cursorPos = 0;
if (document.selection){
nBox.focus();
var tmpRange = document.selection.createRange();
tmpRange.moveStart('character',-nBox.value.length);
cursorPos = tmpRange.text.length;
}
else{
if (nBox.selectionStart || nBox.selectionStart == '0'){
cursorPos = nBox.selectionStart;
}
}
return cursorPos;
}
function detectLine(nBox,lines){
var cursorPos = getCursor(nBox);
var z = 0; //Sum of characters in lines
var lineNumber = 1;
for (var i=1; i<=lines.length; i++){
z = sumLines(i)+i; // +i because cursorPos is taking in account endcharacters of each line.
if (z >= cursorPos){
lineNumber = i;
break;
}
}
return lineNumber;
function sumLines(arrayLevel){
sumLine = 0;
for (var k=0; k<arrayLevel; k++){
sumLine += lines[k].length;
}
return sumLine;
}
}
function detectWord(lineString, area, currentLine, linijeKoda){
function sumWords(arrayLevel){
var sumLine = 0;
for (var k=0; k<arrayLevel; k++){
sumLine += words[k].length;
}
return sumLine;
}
var cursorPos = getCursor(area);
var sumOfPrevChars =0;
for (var i=1; i<currentLine; i++){
sumOfPrevChars += linijeKoda[i].length;
}
var cursorLinePos = cursorPos - sumOfPrevChars;
var words = lineString.split(" ");
var word;
var y = 0;
for(var i=1; i<=words.length; i++){
y = sumWords(i) + i;
if(y >= cursorLinePos){
word = i;
break;
}
}
return word;
}
var area = document.getElementById("area");
var linijeKoda = area.value.split("\n");
var currentLine = detectLine(area,linijeKoda);
var lineString = linijeKoda[currentLine-1];
var activeWord = detectWord(lineString, area, currentLine, linijeKoda);
var words = lineString.split(" ");
if(words.length > 1){
var possibleString = words[activeWord-1];
}
else{
var possibleString = words[0];
}
That would do it ... :)
an ugly solution:
for ie: use document.selection...
for ff: use a pre behind textarea, paste text before cursor into it, put a marker html element after it (cursorPos), and get the cursor position via that marker element
Notes: | code is ugly, sorry for that | pre and textarea font must be the same | opacity is utilized for visualization | there is no autocomplete, just a cursor following div here (as you type inside textarea) (modify it based on your need)
<html>
<style>
pre.studentCodeColor{
position:absolute;
margin:0;
padding:0;
border:1px solid blue;
z-index:2;
}
textarea.studentCode{
position:relative;
margin:0;
padding:0;
border:1px solid silver;
z-index:3;
overflow:visible;
opacity:0.5;
filter:alpha(opacity=50);
}
</style>
hello world<br/>
how are you<br/>
<pre class="studentCodeColor" id="preBehindMyTextarea">
</pre>
<textarea id="myTextarea" class="studentCode" cols="100" rows="30" onkeyup="document.selection?ieTaKeyUp():taKeyUp();">
</textarea>
<div
style="width:100px;height:60px;position:absolute;border:1px solid red;background-color:yellow"
id="autoCompleteSelector">
autocomplete contents
</div>
<script>
var myTextarea = document.getElementById('myTextarea');
var preBehindMyTextarea = document.getElementById('preBehindMyTextarea');
var autoCompleteSelector = document.getElementById('autoCompleteSelector');
function ieTaKeyUp(){
var r = document.selection.createRange();
autoCompleteSelector.style.top = r.offsetTop;
autoCompleteSelector.style.left = r.offsetLeft;
}
function taKeyUp(){
taSelectionStart = myTextarea.selectionStart;
preBehindMyTextarea.innerHTML = myTextarea.value.substr(0,taSelectionStart)+'<span id="cursorPos">';
cp = document.getElementById('cursorPos');
leftTop = findPos(cp);
autoCompleteSelector.style.top = leftTop[1];
autoCompleteSelector.style.left = leftTop[0];
}
function findPos(obj) {
var curleft = curtop = 0;
if (obj.offsetParent) {
do {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
} while (obj = obj.offsetParent);
}
return [curleft,curtop];
}
//myTextarea.selectionStart
</script>
</html>