I'm trying to write a javascript file which will be able to cast images to a chromecast. There will be multiple buttons on an html page. Depending on the button the user clicks, a url will be sent to the chromecast. I have the names of the files stored in a JSON file called videoNames.json, which I loop over to get the names. At the moment all the files to be casted are images. When I run the code the screen remains blank and no buttons show up. Here is my code:
<!doctype html>
<html>
<head>
<title>Casting</title>
<script type="text/javascript" src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
</head>
<body>
<SCRIPT language= "Javascript">
var session = null;
$( document ).ready(function(){
var loadCastInterval = setInterval(function(){
if (chrome.cast.isAvailable) {
console.log('Cast has loaded.');
clearInterval(loadCastInterval);
initializeCastApi();
} else {
console.log('Unavailable');
}
}, 1000);
});
function initializeCastApi() {
var applicationID = chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID;
var sessionRequest = new chrome.cast.SessionRequest(applicationID);
var apiConfig = new chrome.cast.ApiConfig(sessionRequest,
sessionListener,
receiverListener);
chrome.cast.initialize(apiConfig, onInitSuccess, onInitError);
};
function sessionListener(e) {
session = e;
console.log('New session');
if (session.media.length != 0) {
console.log('Found ' + session.media.length + ' sessions.');
}
}
function receiverListener(e) {
if( e === 'available' ) {
console.log("Chromecast was found on the network.");
}
else {
console.log("There are no Chromecasts available.");
}
}
function onInitSuccess() {
console.log("Initialization succeeded");
}
function onInitError() {
console.log("Initialization failed");
}
function getArray(){
return $.getJSON('./videoNames.json');
}
getArray().done( function(json) {
//console.log(json); // show the json data in console
//var len = json.length;
var fixture;
//loop through json and match today's date with match-date
for (var i in json) {
fixture = json[i];
document.write(fixture.name);
var butt = document.createElement("button");
var text = document.createTextNode("Click to cast");
butt.appendChild(text);
butt.id = i;
var nameArray[i] = fixture.name;
document.body.appendChild(butt);
}
});
$(#i).click(function(nameArray[i]){
launchApp(nameArray[i]);
});
function getFileNameExtension(filename){
return filename.split('.').pop();
}
function launchApp(nameArray[i]) {
console.log("Launching the Chromecast App...");
chrome.cast.requestSession(onRequestSessionSuccess(nameArray[i]), onLaunchError);
}
function onRequestSessionSuccess(e) {
console.log("Successfully created session: " + e.sessionId);
session = e;
}
function onLaunchError() {
console.log("Error connecting to the Chromecast.");
}
function onRequestSessionSuccess(e, nameArray[i]) {
console.log("Successfully created session: " + e.sessionId);
session = e;
loadMedia(nameArray[i]);
}
function loadMedia(nameArray[i]) {
if (!session) {
console.log("No session.");
return;
}
var mediaInfo = new
chrome.cast.media.MediaInfo('http://52.60.153.189/video_files/' + nameArray[i]);
mediaInfo.contentType = 'image/' + getFileNameExtension(nameArray[i]);
var request = new chrome.cast.media.LoadRequest(mediaInfo);
request.autoplay = true;
session.loadMedia(request, onLoadSuccess, onLoadError);
}
function onLoadSuccess() {
console.log('Successfully loaded image.');
}
function onLoadError() {
console.log('Failed to load image.');
}
$('#stop').click(function(){
stopApp();
});
function stopApp() {
session.stop(onStopAppSuccess, onStopAppError);
}
function onStopAppSuccess() {
console.log('Successfully stopped app.');
}
function onStopAppError() {
console.log('Error stopping app.');
}
</SCRIPT>
</body>
</html>
Any help is appreciated. Thanks!
Related
I'm using the TomTom FuzzySearch/Autocomplete API, to allow users to search for an address on a form and then the address input fields will prepopulate (with the address values), when the user selects an address.
My API call works absolutely fine and the input fields display the correct values.
The problem I have, is the input fields remain untouched, despite the fields having a value. (If I type document.getElementById("house-number-textbox").value, a value is returned).
How can I turned the input fields to be touched, when the input values are applied?
I noticed, if I type something in the input field, after my input values have been added, only then does the form register my inputs as valid/touched.
PS - The reason I am injecting my scripts is because I'm using an AB Testing tool. So despite the form/application being AngularJS, I can only manipulate the form via the AB Testing tool, (on top of the compiled codebase - hence why I'm using vanilla JS).
Here's my code:
function waitForElement(className, callBack){
window.setTimeout(function(){
var element = document.getElementById(className);
if(element) {
callBack(className, element);
} else {
waitForElement(className, callBack);
}
},2000)
};
// LOAD API SCRIPTS
function loadScript(scriptUrl) {
const script = document.createElement('script');
script.src = scriptUrl;
document.body.appendChild(script);
return new Promise((res, rej) => {
script.onload = function() {
res();
}
script.onerror = function () {
rej();
}
});
};
// RESULTS MANAGER
function appendParentSelector(parentSelector, selector) {
return parentSelector ? parentSelector + ' ' + selector : selector;
}
function ResultsManager(resultsElementSelector) {
this.resultsElement = document.querySelector(appendParentSelector(resultsElementSelector, '.js-results'));
this.resultsPlaceholder =
document.querySelector(appendParentSelector(resultsElementSelector, '.js-results-placeholder'));
this.resultsLoader = document.querySelector(appendParentSelector(resultsElementSelector, '.js-results-loader'));
}
ResultsManager.prototype.loading = function() {
this.resultsLoader.removeAttribute('hidden');
this.resultsElement.setAttribute('hidden', 'hidden');
this.resultsPlaceholder.setAttribute('hidden', 'hidden');
this.resultsElement.innerHTML = '';
};
ResultsManager.prototype.success = function() {
this.resultsLoader.setAttribute('hidden', 'hidden');
this.resultsElement.removeAttribute('hidden');
};
ResultsManager.prototype.resultsNotFound = function() {
this.resultsElement.setAttribute('hidden', 'hidden');
this.resultsLoader.setAttribute('hidden', 'hidden');
this.resultsPlaceholder.removeAttribute('hidden');
};
ResultsManager.prototype.append = function(element) {
this.resultsElement.appendChild(element);
};
ResultsManager.prototype.clear = function() {
for (var i = 0; i < this.resultsElement.children.length; i++) {
this.resultsElement.removeChild(this.resultsElement.children[i]);
}
};
waitForElement("house-number-textbox",function(){
console.log("WAIT FOR ELEMENT DONE");
window.ResultsManager = window.ResultsManager || ResultsManager;
console.log("document.getElementById(component)", document.getElementById("house-number-textbox") );
// use
loadScript('https://api.tomtom.com/maps-sdk-for-web/cdn/plugins/SearchBox/2.24.2//SearchBox-web.js')
.then(() => {
console.log('Script loaded!');
})
.catch(() => {
console.error('Script loading failed! Handle this error');
});
// use
loadScript('https://api.tomtom.com/maps-sdk-for-web/cdn/5.x/5.64.0/services/services-web.min.js')
.then(() => {
console.log('Script loaded!');
// HANDLE RESULTS
tt.setProductInfo('ABTest', '1');
// Options for the fuzzySearch service
var searchOptions = {
key: 'XXX',
language: 'en-Gb',
limit: 10,
countrySet: "GB"
};
var searchBoxOptions = {
minNumberOfCharacters: 1,
searchOptions: searchOptions
// autocompleteOptions: autocompleteOptions
};
var ttSearchBox = new tt.plugins.SearchBox(tt.services, searchBoxOptions);
document.querySelector('.tt-side-panel__header').appendChild(ttSearchBox.getSearchBoxHTML());
let componentForm = {
// streetName: "house-number-textbox",
municipalitySubdivision: "street-name-textbox",
localName: "town-city-textbox",
extendedPostalCode: "postcode-textbox"
};
function SidePanel(selector) {
// this.map = map;
this.element = document.querySelector(selector);
}
new SidePanel('.tt-side-panel');
var resultsManager = new ResultsManager();
ttSearchBox.on('tomtom.searchbox.resultscleared', handleResultsCleared);
ttSearchBox.on('tomtom.searchbox.resultsfound', handleResultsFound);
ttSearchBox.on('tomtom.searchbox.resultfocused', handleResultSelection);
ttSearchBox.on('tomtom.searchbox.resultselected', handleResultSelection);
function handleResultsCleared() {
resultsManager.clear();
}
// HANDLE RESULST
function handleResultsFound(event) {
// Display fuzzySearch results if request was triggered by pressing enter
if (event.data.results && event.data.results.fuzzySearch && event.data.metadata.triggeredBy === 'submit') {
var results = event.data.results.fuzzySearch.results;
if (results.length === 0) {
handleNoResults();
}
resultsManager.success();
console.log("results", results);
}
if (event.data.errors) {
console("event.data.errors", event.data.errors);
}
}
// RESPONSE
function handleResultSelection(event) {
if (isFuzzySearchResult(event)) {
// Display selected result on the map
var result = event.data.result;
console.log("THIS result", result);
;
resultsManager.success();
for (const component in componentForm) {
console.log("componentForm", componentForm);
document.getElementById(componentForm[component]).value = result.address[component];
document.getElementById(componentForm[component]).disabled = false;
console.log('component', componentForm[component]);
if (document.getElementById(componentForm[component]).value === 'undefined') {
document.getElementById(componentForm[component]).value = "";
}
};
if (result.address.streetNumber) {
document.getElementById("house-number-textbox").value = result.address.streetNumber + " " + result.address.streetName;
} else {
document.getElementById("house-number-textbox").value = result.address.streetName;
};
};
}
function isFuzzySearchResult(event) {
return !('matches' in event.data.result);
}
function handleNoResults() {
resultsManager.clear();
resultsManager.resultsNotFound();
searchMarkersManager.clear();
infoHint.setMessage(
'No results for "' +
ttSearchBox.getValue() +
'" found nearby. Try changing the viewport.'
);
};
document.querySelector(".tt-search-box-input").setAttribute("placeholder", "Enter your address...");
})
.catch(() => {
console.error('Script loading failed! Handle this error');
});
});
I currently have a chrome packaged app that we have also ported to iPad, but I want to make it install-able using node-webkit (nw.js) and I need to abstract the chrome packaged app API for use with chrome.fileSystem. The code I am currently using to save is as follows.
var downloadFile = function (readUrl, next) {
var xhr = new XMLHttpRequest();
xhr.open('GET', readUrl);
xhr.responseType = 'arraybuffer';
xhr.onload = function (e) {
if (this.status == 200) {
var response = this.response;
var params = {
type : 'saveFile',
suggestedName : fileNameNoExtension,
//my code will inject the extension but in this case i just put in txt
accepts : [{
extensions : ['.txt']
}
]
}
chrome.fileSystem.chooseEntry(params, function (writableFileEntry) {
debugger;
writableFileEntry.createWriter(function (writer) {
debugger;
writer.onwriteend = function (e) {
return next(null)
};
writer.onerror = function (e) {};
writer.write(new Blob([response], {
type : 'application/octet-stream'
}));
});
});
} else {
//alert
}
};
xhr.onprogress = function (evt) {
if (evt.lengthComputable) {
console.log('progress: ' + Math.round(evt.loaded * 100 / evt.total));
}
}
xhr.addEventListener("error", function () {
return next('error')
}, false);
xhr.addEventListener("abort", function () {
return next('abort')
}, false);
xhr.send();
}
I have created a file that I am calling interop.js I load this script into my index.html and it will handle all of the chrome packaged app API calls for fileStorage if it's a nw.js project. If it's a chrome packaged app, then chrome will handle it's own API.
//if process is undefined then it is not an nw.js project and we can ignore the rest of the code;
if (typeof process == 'undefined') {}
//this is a nw.js project, spoof the chrome packaged app API
else {
var fs = require('fs')
chrome = new function () {
var fileSystem = {
//callback return readableFileEntry, which has a
chooseEntry : function (params, callback) {
if (params.type == 'openFile') {
//open file choose
chooseFile(params, function (files) {
//this is technically an html5 "filelist" we need to turn it into an array if there is more
//than one, and just return the single file if there isn't
if (!files) {
return callback(null)
}
async.map(files, function (file, cb) {
//normally chrome provides a 'readablefileentry' that will only give you the file
//asynchronously using the file() function
file.file = function (next) {
return next(this);
}
cb(null, file)
}, function (err, files) {
if (files.length > 1) {
return callback(files);
} else {
return callback(files[0]);
}
})
})
} else if (params.type == 'saveFile') {
chooseFile(params, function (files) {
var file = files[0];
debugger;
file.createWriter = function (next) {
var writer = {
write : function (blob) {
debugger;
var reader = new FileReader()
reader.readAsArrayBuffer(blob)
reader.addEventListener('loadend', function (e) {
var binary = new Uint8Array(reader.result)
debugger;
fs.writeFile(file.path, new Buffer(binary), function (err) {
//if the on error and writeend has been defined then callback, otherwise throw the error and log success
if (err && writer.onerror) {
writer.onerror(err)
} else if (err) {
throw err
} else if (writer.onwriteend) {
writer.onwriteend()
} else {
console.log('file was written but no callback was defined')
}
})
});
}
}
return next(writer)
}
return callback(file)
})
}
function chooseFile(params, next) {
var fileHtml = '<input type="file"'
debugger;
if (params.acceptsMultiple)
fileHtml += ' multiple';
if (params.accepts && params.accepts.length > 0 && params.accepts[0].extensions) {
fileHtml += ' accept="'
for (var i = 0; i < params.accepts[0].extensions.length; i++) {
if (i != 0)
fileHtml += ','
fileHtml += '.' + params.accepts[0].extensions[i]
}
fileHtml += '"'
}
if (params.suggestedName) {
fileHtml += ' nwsaveas="' + params.suggestedName + '"'
}
fileHtml += '>'
var chooser = $(fileHtml);
chooser.change(function (evt) {
debugger;
return next(chooser[0].files)
});
chooser.click();
}
}
}
return {
fileSystem : fileSystem,
}
};
}
I got the example from this link to work fine, trying to make it a little more dynamic where I would have multiple buttons and pass the button text or id to function doHelloWorld()
here is my attempt
<!doctype html>
<html>
<head>
<script src="https://www.dropbox.com/static/api/dropbox-datastores-1.0-latest.js"></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<center>
<button id="writeButton1"><font size="12">text one</font></button><br>
<button id="writeButton2"><font size="12">text two</font></button><br>
<button id="writeButton3"><font size="12">text three</font></button>
</center>
<script>
var client = new Dropbox.Client({ key: 'YOUR-APP-KEY-HERE' });
// Try to complete OAuth flow.
client.authenticate({ interactive: false }, function (error, client) {
if (error) {
alert('Error: ' + error);
}
});
for (var i = 1; i <= 3; i++){
document.getElementById('writeButton' + i).onclick = function () {
client.authenticate(function (error, client) {
if (error) {
alert('Error: ' + error);
} else {
doHelloWorld(this.id);
}
});
}
}
function doHelloWorld(i) {
client.writeFile('hello.txt', 'Hello, World!' + i, function (error) {
if (error) {
alert('Error: ' + error);
} else {
alert('File written successfully!');
}
});
}
</script>
The execution context inside authenticate callback function is not button object anymore. The simplest fix is to save reference proper this in local variable and use it like this:
for (var i = 1; i <= 3; i++) {
document.getElementById('writeButton' + i).onclick = function () {
var button = this;
client.authenticate(function (error, client) {
if (error) {
alert('Error: ' + error);
} else {
doHelloWorld(button.id);
}
});
}
}
i have call the below function in my application
function workerCall() {
debugger;
if (typeof (Worker) !== "undefined") {
var worker = new Worker("Scripts/worker.js");
worker.onmessage = workerResultReceiver;
worker.onerror = workerErrorReceiver;
worker.postMessage({ 'username': Username });
function workerResultReceiver(e) {
$('.NotificationCount').html(e.data);
if (parseInt(e.data) != 0 && currentPage == "Alert") {
StateFlag = false;
$('.Notification').show();
$('.Drildown').each(function () {
var temp = this.id;
if ($('#' + temp).attr('expand') == "true") {
currentTab = temp;
StateFlag = true;
}
});
currentScrollPosition = $('body').scrollTop();
GetAlerts();
} else {
$('.Notification').hide();
}
}
function workerErrorReceiver(e) {
console.log("there was a problem with the WebWorker within " + e);
}
}
else {
}
}
the method will execute in IE,Chrome but when comes to Mozilla i got an error ReferenceError: workerResultReceiver is not defined.How can i resolve this error?
This happens because you are making reference to function that is not created yet. You need to put this:
worker.onmessage = workerResultReceiver;
worker.onerror = workerErrorReceiver;
Above
function workerErrorReceiver
line or at the end of the scope.
So, I have created a simple chat system which consists of nodeJS and mongodb. I currently 'host' it on apache, and it works perfectly on my computer, but if someone else connects to my site on the local network, then the chat doesnt work as intended. The send message and show message function breaks.
Ps: The code is from phpacademy, so cudos to them.
Here's the code I used:
HTML:
<!DOCTYPE html>
<html>
<head>
<title>ChattSystem</title>
<link rel="stylesheet" href="css/main.css">
</head>
<body>
<div class="chat">
<input type="text" class="chat-name" placeholder="Enter your name">
<div class="chat-messages"></div>
<textarea placeholder="Type your message"></textarea>
<div class="chat-status">Status: <span>Idle</span></div>
</div>
<script src="http://127.0.0.1:8080/socket.io/socket.io.js"></script>
<script>
(function() {
var getNode = function(s) {
return document.querySelector(s);
},
// Get required nodes
status = getNode('.chat-status span'),
messages = getNode('.chat-messages'),
textarea = getNode('.chat textarea'),
chatName = getNode('.chat-name');
statusDefault = status.textContent,
setStatus = function(s) {
status.textContent = s;
if(s !== statusDefault) {
var delay = setTimeout(function() {
setStatus(statusDefault);
clearInterval(delay);
}, 3000);
}
};
try {
var socket = io.connect('http://127.0.0.1:8080');
} catch(e) {
// Set status to warn user
}
if(socket !== undefined) {
// Listen for output
socket.on('output', function(data) {
if(data.length) {
// Loop through results
for(var x = 0; x < data.length; x = x + 1) {
var message = document.createElement('div');
message.setAttribute('class', 'chat-message');
message.textContent = data[x].name + ': ' + data[x].message;
// Append
messages.appendChild(message);
messages.insertBefore(message, messages.firstChild);
}
}
});
// Listen for a status
socket.on('status', function(data) {
setStatus((typeof data === 'object') ? data.message : data);
if(data.clear === true) {
textarea.value = '';
}
});
// Listen for keydown
textarea.addEventListener('keydown', function(event) {
var self = this,
name = chatName.value;
if(event.which);if(event.which == 13 && event.shiftKey === false) {
socket.emit('input', {
name: name,
message: self.value
});
event.preventDefault();
}
});
}
})();
</script>
</body>
</html>
Server.js
var mongo = require('mongodb').MongoClient,
client = require('socket.io').listen(8080).sockets;
mongo.connect('mongodb://127.0.0.1/chat', function(err, db) {
if(err) throw err;
client.on('connection', function(socket) {
var col = db.collection('messages'),
sendStatus = function(s) {
socket.emit('status', s);
};
// Emit all messages
col.find().limit(100).sort({_id: 1}).toArray(function(err, res) {
if(err) throw err;
socket.emit('output', res);
});
// Wait for input
socket.on('input', function(data) {
var name = data.name,
message = data.message,
whitespacePattern = /^\s*$/;
if(whitespacePattern.test(name) || whitespacePattern.test(message)) {
sendStatus('Name and message is required.');
} else {
col.insert({name: name, message: message}, function() {
// Emit latest message to ALL qclients
client.emit('output', [data]);
sendStatus({
message: "Message sent",
clear: true
});
});
}
});
});
});
In your JS from client side, change the IP to your server IP..
You script has currently the same local IP, thats mean what is always in localhost...
Find your IP and put it:
HTML (JS client side)
try {
var socket = io.connect('http://192.168.x.x:8080');
} catch(e) {
// Set status to warn user
}