Phonegap App not Running javascript elements - javascript

So I have a code that runs the css and html fine in phonegap, but the javascript items do not function. For example I'm making a To Do app, but the button will not save my new item, or click to delete.
css code
body
{
font-family: Verdana, Arial;
font-size: 18px;
background-color:#D4D0B4;
}
h1
{
background-color:#626b5e;
font-size:1em;
color:#F5F6F5;
line-height:2em;
text-align:center;
}
#newTaskInput, #addNewTask
{
display:block;
width:98%;
margin-top:5px;
margin-left:auto;
margin-right:auto;
background-color:#757769;
border:0;
height;2em;
font-size:1em;
color:#F5F6F5;
}
#taskList
{
margin-top:10px;
}
#taskList > li
{
background: -webkit-linear-gradient(#FFF, #F6F6F7);
background: -o-linear-gradient(#FFF, #F6F6F7);
background: -moz-linear-gradient(#FFF, #F6F6F7);
background: linear-gradient(#FFF, #F6F6F7);
border:1px solid #BBB6AF
line-height:2em;
color:#929292;
margin-top:2px;
}
#taskList span
{
margin-left:5px;
}
.done
{
text-decoration:line-through;
opacity:0.5;
}
HTML
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" type="type/css" href="css/reset.css">
<link rel="stylesheet" type="text/css" href="css/index.css" />
<title>Todo List</title>
</head>
<body>
<h1>Todo List</h1>
<div id="newTaskSection">
<input type="text" id="newTaskInput" placeholder="New Task">
<button id="addNewTask">Add</button>
</div>
<ul id="taskList">
</ul>
<script type="text/javascript" src="js/jquery-2.1.4.min.js"></script>
<script type="text/javascript" src="js/index.js"></script>
</body>
</html>
javascript
var taskList = new Array();
$( document ).ready(function(){
var $newTaskInput = $('#newTaskInput');
var $taskList = $('#taskList');
var taskTouchStart;
var taskTouchEnd;
var taskTouchStartX;
var taskTouchEndX;
if( window.localStorage )
{
taskList = JSON.parse(window.localStorage.getItem('taskList'));
}
if(null !== taskList)
{
for(i=0;i<taskList.length;i++)
{
var newTask = '<li data-key="' + taskList[1].key + '"><span>' + taskList[i].task + '</span></li>';
$taskList.append(newTask);
}
}
else
{
taskList = new Array();
}
$('#addNewTask').on('click', function(){
var key = Date.now();
var newTask = '<li data-key="' + key + '"><span>' + $newTaskInput.val() + '</span></li>';
$taskList.append( newTask );
taskList.push({key:key, task:$newTaskInput.val(), done:false});
if(window.localStorage)
{
window.localStorage.setItem('taskList', JSON.stringify(taskList));
}
$newTaskInput.val('');
});
$taskList.on('touchstart', 'li', function(e){
var start = document.elementFromPoint( e.originalEvent.touches[0].pageX, e.originalEvent.touches[0].pageY);
taskTouchStart = $(start).attr('data-key');
taskTouchStartX = e.originalEvent.touches[0].pageX;
});
$taskList.on('touchend', 'li', function(e){
var $end;
var $this = $(this);
var end = document.elementFromPoint( e.originalEvent.touches[0].pageX, e.originalEvent.touches[0].pageY);
$end = $(end);
taskTouchEnd = $end.attr('data-key');
taskTouchEndX = e.originalEvent.touches[0].pageX;
if(taskTouchStart == taskTouchEnd)
{
if(taskTouchStartX < taskTouchEndX)
{
if($this.hasClass('done'))
{
$this.removeClass('done');
}
else
{
$this.addClass('done');
}
}
else
{
taskList = $.grep(taskList, function(e){ return e.key != taskTouchEnd;});
if(window.localStorage)
{
window.localStorage.setItem('taskList', JSON.stringify(taskList));
}
$end.remove();
}
}
});
});

Simplified form of the done/not done handler in the code below, which would replace your current on('touchstart.. and on('touchend... blocks and remove a lot of complexity:
Additionally, you have a 1 where there should be an i in your display block (unless I mistook the purpose), and you're not setting the done class for tasks from localStorage which are marked such.
Changes commented in the code below, which would replace the JS you posed above.
Also, apologies, but I've mixed jQuery and vanilla JS, and only went so far as to get a working example, you'll have to work further on validation on what not, hopefully this gets you going.
$( document ).ready(function(){
var $newTaskInput = $('#newTaskInput');
var $taskList = $('#taskList');
if( window.localStorage ){
taskList = JSON.parse(window.localStorage.getItem('taskList'));
}
if(null !== taskList){
for(i=0;i<taskList.length;i++){
// Should we add the 'done' class to these items?
var newTaskClass = (taskList[i].done)? 'done': '';
// taskList[1].key to taskList[i].key ??? or am I missing something?
var newTask = '<li data-key="' + taskList[i].key + '" class="' + newTaskClass + '"><span>' + taskList[i].task + '</span></li>';
$taskList.append(newTask);
}
}
else {
taskList = new Array();
}
$('#addNewTask').on('click', function(){
var key = Date.now();
var newTask = '<li data-key="' + key + '"><span>' + $newTaskInput.val() + '</span></li>';
$taskList.append( newTask );
taskList.push({key:key, task:$newTaskInput.val(), done:false});
if(window.localStorage)
{
window.localStorage.setItem('taskList', JSON.stringify(taskList));
}
$newTaskInput.val('');
});
// Replaces the 'touchstart/end' handlers
$(document).on('click', '#taskList li', function(e){
var task = $(this);
// Update the li class
if (task.hasClass('done')){
task.removeClass('done');
} else {
task.addClass('done');
}
// Find the item by its key property (assumes key exists / no duplicates)
var itemToUpdate = taskList.filter(function(item){
return item.key === task.data('key');
})[0];
// If true, make false, if false, make ture
itemToUpdate.done = !itemToUpdate.done;
// Over-write the task list in local storage
window.localStorage.setItem('taskList', JSON.stringify(taskList));
});
});

Related

Why RTCMultiConnection Event Type is always 'local'?

I'm trying to create a basic video chat using RTCMultiConnection Webrtc.
The code works fine in Safari browser but it always fails to show the joiners videos in a simple ios phonegap app. so basically no one can see others videos.
I added iosrtc plugin to my app as well...
Spent days trying to find the issue and I think I am getting close.
I found out that the event.type is always local for everyone.
So, the event.type is never remote for anyone that uses the app.
But when i test the same code in safari browser, the first joiner event.type is local and the rest of the joiners event.type is remote and thats why it works fine in the browser.
Now that I found the issue (sort of), I need to know why this is happening in the phonegap app and how to eradicate it.
This is my entire code, you can run this code directly in your browser as is and it will work fine:
Javascript:
// ......................................................
// .......................UI Code........................
// ......................................................
document.getElementById('open-room').onclick = function() {
disableInputButtons();
connection.open(document.getElementById('room-id').value, function(isRoomOpened, roomid, error) {
if(isRoomOpened === true) {
showRoomURL(connection.sessionid);
}
else {
disableInputButtons(true);
if(error === 'Room not available') {
alert('Someone already created this room. Please either join or create a separate room.');
return;
}
alert(error);
}
});
};
document.getElementById('join-room').onclick = function() {
disableInputButtons();
connection.join(document.getElementById('room-id').value, function(isJoinedRoom, roomid, error) {
if (error) {
disableInputButtons(true);
if(error === 'Room not available') {
alert('This room does not exist. Please either create it or wait for moderator to enter in the room.');
return;
}
alert(error);
}
});
};
document.getElementById('open-or-join-room').onclick = function() {
disableInputButtons();
connection.openOrJoin(document.getElementById('room-id').value, function(isRoomExist, roomid, error) {
if(error) {
disableInputButtons(true);
alert(error);
}
else if (connection.isInitiator === true) {
// if room doesn't exist, it means that current user will create the room
showRoomURL(roomid);
}
});
};
// ......................................................
// ..................RTCMultiConnection Code.............
// ......................................................
var connection = new RTCMultiConnection();
// by default, socket.io server is assumed to be deployed on your own URL
//connection.socketURL = '/';
// comment-out below line if you do not have your own socket.io server
connection.socketURL = 'https://rtcmulticonnection.herokuapp.com:443/';
connection.socketMessageEvent = 'video-conference-demo';
connection.session = {
audio: true,
video: true
};
connection.sdpConstraints.mandatory = {
OfferToReceiveAudio: true,
OfferToReceiveVideo: true
};
connection.videosContainer = document.getElementById('videos-container');
connection.onstream = function(event) {
var video = document.createElement('video');
if(event.type === 'local') {
video.setAttribute('class', 'myvideo');
//$('.yourVideo').attr('src', event.stream);
//$('.yourVideo').attr('id', event.streamid);
//alert('local');
/*video.volume = 0;
try {
video.setAttributeNode(document.createAttribute('muted'));
} catch (e) {
video.setAttribute('muted', true);
}*/
}
if (event.type === 'remote') {
alert('remote');
video.setAttribute('class', 'othersvideo');
}
//video.src = URL.createObjectURL(event.stream);
setTimeout(function() {
var existing = document.getElementById(event.streamid);
if(existing && existing.parentNode) {
existing.parentNode.removeChild(existing);
}
event.mediaElement.removeAttribute('src');
event.mediaElement.removeAttribute('srcObject');
event.mediaElement.muted = true;
event.mediaElement.volume = 0;
try {
video.setAttributeNode(document.createAttribute('autoplay'));
video.setAttributeNode(document.createAttribute('playsinline'));
} catch (e) {
video.setAttribute('autoplay', true);
video.setAttribute('playsinline', true);
}
console.log(JSON.stringify(event));
video.srcObject = event.stream;
var width = parseInt(connection.videosContainer.clientWidth / 3) - 20;
var width = $(document).width();
var height = $(document).height();
var mediaElement = getHTMLMediaElement(video, {
/*title: event.userid,*/
buttons: ['full-screen'],
width: width,
showOnMouseEnter: false
});
connection.videosContainer.appendChild(mediaElement);
mediaElement.media.play();
var isInitiator = connection.isInitiator;
if (isInitiator === true && event.type === 'local') {
// initiator's own stream
alert('you are initiator');
}else{
alert('you are remote');
}
mediaElement.id = event.streamid;
//video.play();
}, 5000);
};
var recordingStatus = document.getElementById('recording-status');
var chkRecordConference = document.getElementById('record-entire-conference');
var btnStopRecording = document.getElementById('btn-stop-recording');
btnStopRecording.onclick = function() {
var recorder = connection.recorder;
if(!recorder) return alert('No recorder found.');
recorder.stopRecording(function() {
var blob = recorder.getBlob();
invokeSaveAsDialog(blob);
connection.recorder = null;
btnStopRecording.style.display = 'none';
recordingStatus.style.display = 'none';
chkRecordConference.parentNode.style.display = 'inline-block';
});
};
connection.onstreamended = function(event) {
var mediaElement = document.getElementById(event.streamid);
if (mediaElement) {
mediaElement.parentNode.removeChild(mediaElement);
}
};
connection.onMediaError = function(e) {
if (e.message === 'Concurrent mic process limit.') {
if (DetectRTC.audioInputDevices.length <= 1) {
alert('Please select external microphone. Check github issue number 483.');
return;
}
var secondaryMic = DetectRTC.audioInputDevices[1].deviceId;
connection.mediaConstraints.audio = {
deviceId: secondaryMic
};
connection.join(connection.sessionid);
}
};
// ..................................
// ALL below scripts are redundant!!!
// ..................................
function disableInputButtons(enable) {
document.getElementById('room-id').onkeyup();
document.getElementById('open-or-join-room').disabled = !enable;
document.getElementById('open-room').disabled = !enable;
document.getElementById('join-room').disabled = !enable;
document.getElementById('room-id').disabled = !enable;
}
// ......................................................
// ......................Handling Room-ID................
// ......................................................
function showRoomURL(roomid) {
var roomHashURL = '#' + roomid;
var roomQueryStringURL = '?roomid=' + roomid;
var html = '<h2>Unique URL for your room:</h2><br>';
html += 'Hash URL: ' + roomHashURL + '';
html += '<br>';
html += 'QueryString URL: ' + roomQueryStringURL + '';
var roomURLsDiv = document.getElementById('room-urls');
roomURLsDiv.innerHTML = html;
roomURLsDiv.style.display = 'block';
}
(function() {
var params = {},
r = /([^&=]+)=?([^&]*)/g;
function d(s) {
return decodeURIComponent(s.replace(/\+/g, ' '));
}
var match, search = window.location.search;
while (match = r.exec(search.substring(1)))
params[d(match[1])] = d(match[2]);
window.params = params;
})();
var roomid = '';
if (localStorage.getItem(connection.socketMessageEvent)) {
roomid = localStorage.getItem(connection.socketMessageEvent);
} else {
roomid = connection.token();
}
var txtRoomId = document.getElementById('room-id');
txtRoomId.value = roomid;
txtRoomId.onkeyup = txtRoomId.oninput = txtRoomId.onpaste = function() {
localStorage.setItem(connection.socketMessageEvent, document.getElementById('room-id').value);
};
var hashString = location.hash.replace('#', '');
if (hashString.length && hashString.indexOf('comment-') == 0) {
hashString = '';
}
var roomid = params.roomid;
if (!roomid && hashString.length) {
roomid = hashString;
}
if (roomid && roomid.length) {
document.getElementById('room-id').value = roomid;
localStorage.setItem(connection.socketMessageEvent, roomid);
// auto-join-room
(function reCheckRoomPresence() {
connection.checkPresence(roomid, function(isRoomExist) {
if (isRoomExist) {
connection.join(roomid);
return;
}
setTimeout(reCheckRoomPresence, 5000);
});
})();
disableInputButtons();
}
// detect 2G
if(navigator.connection &&
navigator.connection.type === 'cellular' &&
navigator.connection.downlinkMax <= 0.115) {
alert('2G is not supported. Please use a better internet service.');
}
$(document).on('click', '.mybtn', function() {
window.cordova.InAppBrowser.open(" https://vps267717.ovh.net/webrtc", "_blank", "location=no,toolbar=yes");
});
HTML:
<!-- Demo version: 2019.01.09 -->
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Video Conferencing using RTCMultiConnection</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
<script>
setTimeout(function() {
navigator.splashscreen.hide();
}, 4000);
// alert dialog dismissed
function alertDismissed() {
}
</script>
<link rel="stylesheet" href="https://rtcmulticonnection.herokuapp.com/demos/stylesheet.css">
<script src="https://rtcmulticonnection.herokuapp.com/demos/menu.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://rtcmulticonnection.herokuapp.com/dist/RTCMultiConnection.min.js"></script>
<script src="https://rtcmulticonnection.herokuapp.com/node_modules/webrtc-adapter/out/adapter.js"></script>
<script src="https://rtcmulticonnection.herokuapp.com/socket.io/socket.io.js"></script>
<!-- custom layout for HTML5 audio/video elements -->
<link rel="stylesheet" href="https://rtcmulticonnection.herokuapp.com/dev/getHTMLMediaElement.css">
<script src="https://rtcmulticonnection.herokuapp.com/dev/getHTMLMediaElement.js"></script>
<script src="https://rtcmulticonnection.herokuapp.com/node_modules/recordrtc/RecordRTC.js"></script>
<script src="cordova.js"></script>
<script src="ios-websocket-hack.js"></script>
<style>
/* .myvideo{
width:100px !important;
height:100px !important;
background:#ccc;
position:absolute;
top:0;
left:0;
z-index:10;
}
.othersvideo{
width:100% !important;
height:100% !important;
background:#ccc;
position:absolute;
top:0;
left:0;
z-index:0;
}*/
* {
word-wrap:break-word;
}
video {
object-fit: fill;
width: 30%;
}
button,
input,
select {
font-weight: normal;
padding: 2px 4px;
text-decoration: none;
display: inline-block;
text-shadow: none;
font-size: 16px;
outline: none;
}
.make-center {
text-align: center;
padding: 5px 10px;
}
img, input, textarea {
max-width: 100%
}
#media all and (max-width: 500px) {
.fork-left, .fork-right, .github-stargazers {
display: none;
}
}
</style>
</head>
<body>
<button class="mybtn" >click me now</button>
<section class="make-center">
<div>
<label><input type="checkbox" id="record-entire-conference"> Record Entire Conference In The Browser?</label>
<span id="recording-status" style="display: none;"></span>
<button id="btn-stop-recording" style="display: none;">Stop Recording</button>
<br><br>
<input type="text" id="room-id" value="abcdef" autocorrect=off autocapitalize=off size=20>
<button id="open-room">Open Room</button>
<button id="join-room">Join Room</button>
<button id="open-or-join-room">Auto Open Or Join Room</button>
</div>
<div id="videos-container" style="margin: 20px 0;"></div>
<div id="room-urls" style="text-align: center;display: none;background: #F1EDED;margin: 15px -10px;border: 1px solid rgb(189, 189, 189);border-left: 0;border-right: 0;"></div>
</section>
<script src="https://cdn.webrtc-experiment.com/common.js"></script>
</body>
</html>
Any help would be greately appreciated.
Thanks in advance.

Storing a checkbox value in local storage

Im working on a checklist chrome app for myself and would love your help. Basically, I cant figure out how to save a checkbox status. If I check a box and refresh the page, I would like it to stay checked. But I cant seem to code that. Any ideas how to do that? Thank you!!
Edit: I added the html, it gives me the message that my post is mostly code and that I need to add some text, so here I am just writing some more to fulfil this requirement. There is no need reading this. Thanks for the help and sorry for the late edit
function get_todos() {
var todos = new Array;
var todos_str = localStorage.getItem('todo');
if (todos_str !== null) {
todos = JSON.parse(todos_str);
}
return todos;
}
function add() {
var task = document.getElementById('task').value;
var todos = get_todos();
todos.push(task);
localStorage.setItem('todo', JSON.stringify(todos));
show();
return false;
}
function remove() {
var id = this.getAttribute('id');
var todos = get_todos();
todos.splice(id, 1);
localStorage.setItem('todo', JSON.stringify(todos));
show();
return false;
}
function show() {
var todos = get_todos();
var html = '<ul>';
for(var i=0; i<todos.length; i++) {
html += '<li>' + '<input type="checkbox" id="checkbox">' + todos[i] + '<button class="remove" id="' + i + '">delete</button></li>' ;
};
html += '</ul>';
document.getElementById('todos').innerHTML = html;
var buttons = document.getElementsByClassName('remove');
for (var i=0; i < buttons.length; i++) {
buttons[i].addEventListener('click', remove);
};
}
document.getElementById('add').addEventListener('click', add);
show();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
</head>
<body>
<style>
html,body,h1,h3,h4,h6 {font-family: "Roboto";font-size: 24px; sans-serif}
h2 {font-family: "Roboto";font-size: 36px; sans-serif}
h5 {font-family: "Roboto";font-size: 28px; sans-serif}
</style>
<input id="task"><button id="add">Add</button>
<hr>
<div id="todos"></div>
<script src="todo.js"></script>
</body>
</html>
Seeing as no one else has provided an answer, I thought I'd throw in my potential solution, I went with a functional style because why not, it's simple, easy to read, etc...
PS
I included the fallback variable because on Stack Overflow, you can't access local storage when running a snippet.
let fallback = [];
const $e = query => document.querySelector(query);
// Return a todo list.
const getToDoList = () => {
let data = null;
try {
data = JSON.parse(localStorage.getItem('todo'));
} catch (e) {
data = fallback;
}
return data == null || Array.isArray(data) == false ? [] : data;
};
// Set the todo list.
const setToDoList = (data) => {
try {
localStorage.setItem('todo', JSON.stringify(data));
} catch (e) {
fallback = data;
}
};
// Add a task to the todo list.
const addToDo = () => {
const array = getToDoList();
array.push({value: $e("#task").value, checked: false});
setToDoList(array);
};
// Remove a task from the todo list.
const removeToDo = index => {
const array = getToDoList();
array.splice(index, 1);
setToDoList(array);
};
// Allow for the ability to remove an item from the todo list & other stuff..
const dispatchListEvents = () => {
document.querySelectorAll('#app ul li span').forEach(span => {
span.onclick = () => {
removeToDo(span.parentElement.getAttribute('data-index'));
render();
}
});
document.querySelectorAll('#app ul li input').forEach(input => {
input.onclick = () => {
const array = getToDoList();
const object = array[input.parentElement.getAttribute('data-index')];
object.checked = ! object.checked;
setToDoList(array);
render();
}
});
};
// Render the todo list.
const render = () => {
let index = 0;
const template = item => `<li data-index="${index++}">` +
`<input type="checkbox" ${item.checked ? 'checked' : ''} />` +
`${item.value} <span>X</span></li>`;
const re = new RegExp('</li>,', 'g'), replacement = '</li>';
const html = `<ul>${getToDoList().map(i => template(i))}</ul>`;
$e("#app").innerHTML = `${html.replace(re, replacement)}`;
dispatchListEvents();
};
// Allow the user to add a task to the todo list.
const addToListClickHandler = () => {
let result = $e("#task").value.replace(/\ /g, '').length > 0 ? addToDo() : null;
$e("#task").value = null; // Always null as addToDo returns null.
render();
};
// The function that will be fired when the DOM is ready.
const ready = () => {
render(); // Initial render.
$e("#addToList").addEventListener('click', addToListClickHandler);
};
// An insanely lazy implementation of $(document).ready.
const delay = 250;
const fakeOnReady = setTimeout(ready, delay);
body {
font-family: Arial, Helvetica, sans-serif;
}
#app ul li {
max-width: 150px;
}
#app ul li span {
float: right;
color: red;
}
#app ul li span:hover {
cursor: pointer;
}
<h1>To Do List</h1>
<section>
<h2>Add Task</h2>
<input id="task" placeholder="Task..."/>
<input type="button" id="addToList" value="Add"/>
</section>
<hr/>
<section>
<h2>Tasks</h2>
<div id="app">
<!-- Area for the DHTML. -->
</div>
</section>

using jQuery to append div's and each div has a different ID

So I'm trying to to use jQuery to append a div which will generate a card using the assigned class. The problem is I need to create a different ID each time so I can put random number on the card. I'm sure there's an easier way to do this. So i'm posing two questions. how to make the code where it put the random number on the card go endlessly. and how to append divs with unique ID's. Sorry if my code isn't the best. It's my first project.
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
<title></title>
<style>
.cardLook {
border: 1px solid black;
width: 120px;
height: 220px;
border-radius: 5px;
float: left;
margin: 20px;
padding: 5px;
background-color: #fff;
}
#card1,#card2,#card3,#card4,#card5 {
transform:rotate(180deg);
}
#cardTable {
background-color: green;
height: 270px
}
.reset {
clear: both;
}
</style>
<script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
</head>
<body>
<button id="deal">Deal</button>
<button id="hit">hit</button>
<button id="stand">Stand</button>
<button id="hi">hi</button>
<div id="number"></div>
<div id="arrayOutput"></div>
<div id="someId"></div>
<div id="out2"></div>
<div id="cardTable">
</div>
<div class="reset"></div>
<script>
var what;
//Services helper functon
document.getElementById('deal').onclick = function deal() {
var score1 = Math.floor(Math.random() *10 + 1);
var score2 = Math.floor(Math.random() *10 + 1);
var firstCard = score1;
var secondCard = score2;
//myNumberArray.push(firstCard, score2);
//card1.innerHTML = myNumberArray[0];
//card2.innerHTML = myNumberArray[1];
$("#deal").click(function(){
$("#cardTable").append("<div class='cardLook' id='card1'></div>");
});
console.log(score2, score1)
}
var myNumberArray = [];
$("#hit").click(function(){
$("#cardTable").append("<div class='cardLook' id="uniqueIdNumberOne"></div>");
if (myNumberArray > 1) {
#cardTable
}
var card = Math.floor(Math.random() * 10) + 1;
document.getElementById('number').innerHTML=card;
myNumberArray.push(card);
var number = myNumberArray.value;
var arrayOutput = document.getElementById('number');
var someId = document.getElementById('someId');
someId.innerHTML = myNumberArray;
card1.innerHTML = myNumberArray[0];
card2.innerHTML = myNumberArray[1];
card3.innerHTML = myNumberArray[2];
card4.innerHTML = myNumberArray[3];
card5.innerHTML = myNumberArray[4];
// console.log("myNumberArray: ", myNumberArray);
what = calcTotal(myNumberArray);
showMe(calcTotal(myNumberArray));
});
//var output = myNumberArray = calcTotal(list);
function calcTotal(myNumberArray) {
var total = 0;
for(var i = 0; i < myNumberArray.length; i++){
total += myNumberArray[i];
}
return total;
}
//document.getElementById('out2').innerHTML = out2;
console.log("myNumberArray: ", myNumberArray);
function showMe(VAL) {
var parent = document.getElementById('out2');
parent.innerHTML = VAL;
if (calcTotal(myNumberArray) > 21) {
alert('you lose');
}
};
document.getElementById('stand').onclick = function stand() {
var compterDeal1 = Math.floor(Math.random() *10 + 1);
var computerCards = compterDeal1;
console.log(computerCards);
computerArray.push(computerCards);
if (computerCards < 21) {
stand();
}
}
var computerArray = [];
</script>
</body>
</html>
Use an unique class with all of then, and call then by class
Add a global integer:
var cardNumber = 0;
A function to generate an id:
function newCardId() {
cardNumber ++;
return 'uniqueCardId' + cardNumber.toString();
}
And use:
var newId = newCardId();
$("#cardTable").append("<div class=\"cardLook\" id=\"" + newId + "\"></div>");
Finally to access your new div:
$('#' + newId).
Note: Escape quotes within a string using backslash!

jquery autocomplete not working on dynamically added input boxes

Here is something i am trying to do. I want to add jquery autocomplete to all the input boxes. Initially i have only 2 boxes, user can dynamically add multiple boxes. Autocomplete works in first two boxes but fails in the dynamically added buttons.
hers the fiddle for the code : http://jsfiddle.net/HG2hP/
code:
HTML:
<!doctype html>
<html>
<head>
<title>TakeMeHome</title>
<!-- <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> -->
<!--<script type="text/javascript" src="js/jquery-1.9.0.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.10.0.custom.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.10.0.custom.min.js"></script>-->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.1/jquery-ui.min.js"></script>
<script type="text/javascript" src="js/app.js"></script>
<link type="text/css" rel="stylesheet" href="css/design.css"/>
</head>
<body>
<center>
Your Place:<input class="address" id="source" type="text"/><br/>
<div id= "div1">Friend1:<input class="address" id="friend1" type="text"/></div><br/>
<pre>
<div id="button">Add!</div> <div id="button2">Remove</div></br>
</pre>
<div id="sumbit_button">GO!</div>
<div id="map" style = "width: 500px; height: 500px"></div>
</center>
</body>
</html>
JS
$(document).ready(function() {
var geocoder;
var map;
var marker;
var friends_cnt = 1;
var friends = [];
var distance = [];
$('#button').click(function() {
if (friends_cnt < 11) {
$('<div id = div' + (friends_cnt + 1) + '>Friend' + (friends_cnt + 1) + ':<input type="text" class="address" id="friend' + (friends_cnt + 1) + '"/></div>').insertAfter('#div' + friends_cnt);
friends_cnt++;
} else {
console.log("Limit reached");
}
});
$('#button2').click(function() {
if (friends_cnt > 1) {
$('#friend' + friends_cnt).remove();
$('#div' + friends_cnt).remove();
friends_cnt--;
}
});
geocoder = new google.maps.Geocoder();
$(function() {
$(".address").autocomplete({
source : function(request, response) {
geocoder.geocode({
'address' : request.term
}, function(results, status) {
response($.map(results, function(item) {
return {
label : item.formatted_address,
value : item.formatted_address,
latitude : item.geometry.location.lat(),
longitude : item.geometry.location.lng()
}
}));
})
},
});
});
$('#sumbit_button').on("click", function() {
console.log("button clicked");
var a = [];
a.push($("#source").val());
for ( i = 1; i <= friends_cnt; i++) {
a.push($("#friend" + i).val());
}
console.log("a :");
console.log(a);
var gurl = "http://maps.googleapis.com/maps/api/distancematrix/json";
console.log("gurl :" + gurl);
$.ajax({
url : gurl,
data : {
origins : a.join('|').replace(/ /g, '+'),
destinations : a.join('|').replace(/ /g, '+'),
sensor : false
},
success : function(response) {
console.log("response type :");
console.log( typeof response);
if ( typeof response == "string") {
response = JSON.parse(response);
}
var rows = response.rows;
for (var i = 0; i < rows.length; i++) {
distance[i] = [];
for (var j = 0; j < rows[i].elements.length; j++) {
distance[i][j] = rows[i].elements[j].distance.value;
}
}
}
});
console.log("No.of friends is " + friends_cnt);
console.log(distance);
});
});
CSS
input {
margin: 10px 4px;
}
#button, #button2 {
width: 70%;
margin: 0 auto;
}
.ui-autocomplete {
background-color: white;
width: 300px;
border: 1px solid #cfcfcf;
list-style-type: none;
padding-left: 0px;
}
.ui-helper-hidden-accessible {
display: none;
}
As I am using classes concept to add auto-complete, I should get the results.
Can you please let me know where I am wrong?
In your click event:
$('#button').click(function ()...
You should set your autocomplete on newly added input field, something like:
$('#button').click(function () {
if (friends_cnt < 11) {
$('<div id = div'+(friends_cnt+1)+'>Friend' + (friends_cnt+1) + ':<input type="text" class="address" id="friend' + (friends_cnt+1) + '"/></div>').insertAfter('#div'+friends_cnt);
$('div#div'+(friends_cnt+1)).autocomplete(...);
friends_cnt++;
}
else {
console.log("Limit reached");
}
});
As your autocomplete attachs to current DOM only, not the dynamically added one.
you must either re apply the auto complete to each element like Kapo suggested
$('div#div'+(friends_cnt+1)).autocomplete(...);
or use liveuery (see this thread for more details on that)
On pageload your autocomplete attaches to fields with class .address, however on page load you do not have any .address field, so nothing gets attached.
You need to run
$(".address").autocomplete({
Right after you add your new field to the dom, or better still, make the input an object, and you can attach events straight to it like:
$input = $('input')
.attr('type', 'text')
.attr('class', 'address')
.attr('id', 'friend')
.autocomplete({ etc
As i got the answers, this change in the code worked for me :
Adding this in the $('#button').click(function () { function
$(function() {
$("#friend"+(friends_cnt+1)).autocomplete({
source: function(request, response) { . .. . .
This will add autocomplete to all the boxes whenever made.

Offline storage in firefox 3.5 for file://

I was trying out the code for offline storage in firefox 3.5, taken from http://starkravingfinkle.org/blog/2008/05/firefox-3-offline-app-demo-part-2/.
When the page loads i get a dialog prompting me that the application is asking for storing data, but when i press Allow, the dialog does not go away . The app works fine at the online demo given on the website.
The source file containing the javascript is as follows :
todo.html
<!--
Simple task list application used to illusrate Firefox's offline/DOMStorage capabilities
Author: Mark Finkle
-->
<html manifest="todo.manifest">
<head>
<title>TODO - Offline Demo</title>
<script type="text/javascript" src="json.js"></script>
<script language="javascript">
var taskStorage = "[]";
var storageDomain = location.hostname;
if (storageDomain == "localhost")
storageDomain += ".localdomain";
function loaded() {
updateOnlineStatus("load", false);
document.body.addEventListener("offline", function () { updateOnlineStatus("offline", true) }, false);
document.body.addEventListener("online", function () { updateOnlineStatus("online", true) }, false);
if (typeof globalStorage != "undefined") {
var storage = globalStorage[storageDomain];
if (storage && storage.taskStorage) {
taskStorage = storage.taskStorage;
}
}
fetchList();
}
function updateOnlineStatus(msg, allowUpdate) {
var status = document.getElementById("status");
status.innerHTML = (navigator.onLine ? "[online]" : "[offline]");
var log = document.getElementById("log");
log.appendChild(document.createTextNode("Event: " + msg + "\n"));
if (navigator.onLine && allowUpdate) {
update();
log.appendChild(document.createTextNode("Updated server\n"));
}
}
function httpRequest(type, data, callback) {
var httpreq = new XMLHttpRequest();
httpreq.onreadystatechange = function() { if (httpreq.readyState == 4) callback(httpreq.readyState, httpreq.status, httpreq.responseText); };
httpreq.open(type, "todo-server.php", true);
if (type == "POST") {
httpreq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
}
httpreq.send(data);
}
function loadList(readyState, status, responseText) {
if (readyState == 4) {
if (status == 200) {
taskStorage = responseText;
var tasks = eval("(" + taskStorage + ")");
var html = "";
for (var i=0; i<tasks.length; i++) {
html += "<input type='checkbox' id='" + tasks[i].name + "'/><label for='" + tasks[i].name + "'>" + tasks[i].data + "</label><br/>";
}
document.getElementById("tasklist").innerHTML = html;
if (typeof globalStorage != "undefined") {
globalStorage[storageDomain].taskStorage = taskStorage;
}
}
}
}
function fetchList() {
if (navigator.onLine) {
httpRequest("GET", null, loadList);
}
else {
loadList(4, 200, taskStorage);
}
}
function addItem() {
var data = document.getElementById("data").value;
document.getElementById("data").value = "";
var tasks = eval("(" + taskStorage + ")");
tasks.push({"name": Date.now(), "data": data });
taskStorage = tasks.toJSONString();
update();
}
function removeItems() {
var tasks = eval("(" + taskStorage + ")");
var newTasks = [];
var items = document.getElementById("tasklist").getElementsByTagName("input");
for (var i=0; i<items.length; i++) {
if (items[i].checked == false) {
newTasks.push(tasks[i]);
}
}
taskStorage = newTasks.toJSONString();
update();
}
function completeItems() {
var tasks = eval("(" + taskStorage + ")");
var items = document.getElementById("tasklist").getElementsByTagName("input");
for (var i=0; i<items.length; i++) {
if (items[i].checked) {
var task = tasks[i].data;
if (task.indexOf("<strike>") != -1) {
task = task.replace("<strike>", "");
task = task.replace("</strike>", "");
}
else {
task = "<strike>" + task + "</strike>";
}
tasks[i].data = task;
}
}
taskStorage = tasks.toJSONString();
update();
}
function update() {
if (navigator.onLine) {
var post = "action=update&data=";
post += encodeURIComponent(taskStorage);
httpRequest("POST", post, function(readyState, status, json) { fetchList(); });
}
else {
loadList(4, 200, taskStorage);
}
}
</script>
<style type="text/css">
body { font-family: verdana,tahoma, arial; }
div#container { width: 300px; }
div#title { font-size: 120%; }
div#subtitle { font-size: 80%; }
div#tasklist { margin-bottom: .5em; }
div#log { font-size: 90%; background-color: lightgray; margin-top: 1em; white-space: pre; }
</style>
</head>
<body onload="loaded();">
<div id="container">
<div id="title">Task Helper - <span id="status">ONLINE</span></div>
<div id="subtitle">simple online/offline demo application</div>
<hr />
<div id="tasklist">
</div>
<input type="text" id="data" size="35" />
<input type="button" value="Add" onclick="addItem();"/>
<hr />
<input type="button" value="Remove" onclick="removeItems();"/>
<input type="button" value="Complete" onclick="completeItems();"/>
<div id="log"><strong>Event Log</strong>
</div>
</div>
</body>
</html>
I believe that the localStorage api is replacing globalStorage in FF 3.5. You can read more about it here: https://developer.mozilla.org/en/DOM/Storage
I think the api is very similar, so you could try something like this:
var storage;
if (typeof localStorage != "undefined") {
storage = localStorage;
}
else if (typeof globalStorage != "undefined") {
storage = globalStorage[storageDomain];
}
if (storage && storage.taskStorage) {
taskStorage = storage.taskStorage;
}
Hope that helps!
EDIT: Anywhere you use globalStorage, you'll have to check for localStorage as well. Or promote the storage variable up in scope and detect it once.
So after reading the question twice, I think I understood the question: you're asking about using globalStorage in file:/// documents.
globalStorage (as well as localStorage) doesn't work very well in file:/// documents as of Firefox 3.5. I didn't see the specific bug report about this issue, but since globalStorage is deprecated in favor of localStorage, it doesn't really matter.
If you're just testing it out, install some kind of web server locally, it's not complicated at all.

Categories