Youtube javascript api, pjax, how to reload onYouTubeIframeAPIReady(); - youtube-javascript-api

I have a problem with the youtube javascript player api.
I call this js code :
function onYouTubeIframeAPIReady() {
var podcast = document.getElementById('podcast')
var player = new YT.Player( document.getElementById('podcast'));
player.addEventListener('onStateChange', function(e) {
if (e.data === 1) {
alert("play");
}
});
};
with this html code :
<iframe id="podcast" type="text/html" width="720" height="405"
src="https://www.youtube.com/embed/XXXXXX?cc_load_policy=1&enablejsapi=1&theme=light"
frameborder="0" allowfullscreen>
The problem is that I use the pjax system, so the global javascript code is not reloaded when I navigate.
So, I reload some part of my javascript code when pjax:success. I tried something like this :
$(document).on('pjax:success', function() {
onYouTubeIframeAPIReady();
}
but it doesn't work. My question is how to reload onYouTubeIframeAPIReady(); when it must to be defined globally as it is said there onYouTubeIframeAPIReady function is not calling

When my player is defined I don't use onYoutubePlayerAPIReady. It's the best solution I find, and it works.
var player = {
playVideo: function(container, videoId) {
if (typeof(YT) == 'undefined' || typeof(YT.Player) == 'undefined') {
window.onYouTubePlayerAPIReady = function() {
player.loadPlayer(container, videoId);
};
$.getScript('//www.youtube.com/player_api');
} else {
player.loadPlayer(container, videoId);
}
},
loadPlayer: function(container, videoId) {
window.myPlayer = new YT.Player(container,
height: 200,
width: 200,
videoId: videoId,
});
}
};
var containerId = 'podcast';
var videoId = '<%= #youtube_id %>';
player.playVideo(containerId, videoId);

Related

VueJS Leaflet 'moveend' fires multiple times

Ask for help from the community. For two weeks I can not overcome the problem with repeated firing of 'mooveend' in the project. I have tried all the advice given here. Here's what I've read and researched already, but it didn't work for me.
This is one of the tips:
moveend event fired many times when page is load with Leaflet
<template>
<div id="map"></div>
</template>
<script>
export default {
name: "ObjectMapView",
props: ['coordinate'],
data: function () {
return {
map: null,
addressPoints: null,
markers: null,
}
},
mounted: function() {
this.initializedMap();
},
watch: {
coordinate: function (val) {
this.run();
}
},
methods: {
initializedMap: function () {
this.map = L.map('map').setView([52.5073390000,5.4742833000], 13);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(this.map);
this.markers = L.markerClusterGroup();
},
run: function () {
var map = this.map;
var markers = this.markers;
var getAllObjects = this.coordinate;
var getBoundsMarkers;
//Clearing Layers When Switching a Filter
markers.clearLayers();
this.addressPoints = getAllObjects.map(function (latlng){
return [latlng.latitude, latlng.longitude, latlng.zip, latlng.object_id, latlng.archived];
});
map.addLayer(markers);
//We give to the map only those coordinates that are in the zone of visibility of the map during the first
getBoundsMarkers = getAllObjects.filter((coord) => {
if(!coord.latitude && !coord.longitude){
return false;
}
return map.getBounds().contains(L.latLng(coord.latitude, coord.longitude));
});
/*
Responds to changing the boundaries of the map visibility zone and
transmits a list of coordinates that are in the visibility zone
*/
console.log('getAllObjects_1', getAllObjects);
map.on('moveend', function() {
console.log('moveend');
console.log('getAllObjects_2', getAllObjects);
getBoundsMarkers = getAllObjects.filter((coord) => {
if(!coord.latitude && !coord.longitude){
return false;
}
return map.getBounds().contains(L.latLng(coord.latitude, coord.longitude));
});
eventHub.$emit('sendMarkers', getBoundsMarkers);
});
// In the loop, we iterate over the coordinates and give them to the map
for (var i = 0; i < this.addressPoints.length; i++) {
var a = this.addressPoints[i];
var title = '' + a[2] + ''; //bubble
var marker = L.marker(new L.LatLng(a[0], a[1]), {
title: title
});
marker.bindPopup(title);
markers.addLayer(marker);
}
eventHub.$emit('sendMarkers', getBoundsMarkers);
}
}
}
</script>
<style scoped>
#map {
width: 97%;
height: 100%;
}
</style>
I figured it out myself.
The 'zoomend' and 'dragend' option didn't work for me. I searched a lot for a suitable option and realized that the "moveend" event fires several times because this event is created every time you move the map. Therefore it is necessary to stop this event. I got out of the situation in this way. Immediately after the map was initialized, I wrote:
map.off('moveend');
and for me it worked. Now it works fine. I will be very happy if this is useful to someone.

Using dropzone.js in vue, calling function with image file name

I'm having a hard time getting anything to work with this the way I need it, but I have a working dropzone instance in my Vue project.
I can upload the image and call functions within the dropzone code, however, I need to call a function directly from the form in the html in order to send the 'card' object.
All I need to do is call a function when a file is added through the dropzone form, with the filename.
My code:
<div class="uk-width-3-10">
<form v-on:change="imageChange(card)" method="post" action="{{url('product/parts/upload/store')}}" enctype="multipart/form-data"
class="dropzone" v-bind:id="'dropzone-'+i">
</form>
</div>
...
imageChange(Card){
console.log('working');
},
addCard(){
Vue.nextTick(function () {
new Dropzone("#dropzone-"+cardIndex, {
maxFilesize: 12,
renameFile: function (file) {
var dt = new Date();
var time = dt.getTime();
return time + file.name;
},
acceptedFiles: ".jpeg,.jpg,.png,.gif",
addRemoveLinks: true,
timeout: 50000,
removedfile: function (file) {
console.log(file.upload.filename);
var name = file.upload.filename;
var fileRef;
return (fileRef = file.previewElement) != null ?
fileRef.parentNode.removeChild(file.previewElement) : void 0;
},
init: function() {
this.on("addedfile",
function(file) {
instance.imageZoneNames.push({name: file.upload.filename});
console.log(file);
console.log(instance.imageZoneNames);
});
}
});
});
}
Dropzone has many events, You used removedfile() event! there is another event called addedfile() and executes when a file is added to the dropzone list
imageChange(card) {
console.log(card)
},
addCard() {
Vue.nextTick(() => {
new Dropzone('#dropzone-` + cardIndex, {
addedfile(file) {
this.imageChange(file);
}
}
}
}

Record Audio for Android and iOS using Appcelerator Titanium

I'm having problems trying to record audio into a file. I'm trying to run the sample code (with the required permissions in the tiapp.xml) but i'm always getting errors (like "+[NSBlock boundBridge:withKrollObject:]: unrecognized selector sent to class 0x1b5549500"; at the stop() action).
I can't find a module for audio recording (i've used the tutorial.audiorecord but it doesn't work in newest versions of SDK)
This is the sample code from the appcelerator documentation page https://docs.appcelerator.com/platform/latest/#!/api/Titanium.Media.AudioRecorder
I try everything but doesn't work.
Someone have a working example or a module for Appcelerator SDK 7?
var window = Ti.UI.createWindow({
backgroundColor: '#fff'
});
var recordStart = Ti.UI.createButton({
title: 'Start',
top: 10
});
var recordPause = Ti.UI.createButton({
title: 'Pause',
top: 60
});
var recordStop = Ti.UI.createButton({
title: 'Stop',
top: 110
});
var recordPlay = Ti.UI.createButton({
title: 'Play',
top: 160
});
var audioRecorder = Ti.Media.createAudioRecorder();
var record;
var audioPlayer;
window.addEventListener('open', function(e) {
if (!Ti.Media.hasAudioRecorderPermissions()) {
Ti.Media.requestAudioRecorderPermissions(function(e) {
if (e.success) {
window.add(recordStart);
}
});
} else {
window.add(recordStart);
}
});
recordStart.addEventListener('click', function(e) {
audioRecorder.start();
});
recordPause.addEventListener('click', function(e) {
if (audioRecorder.getPaused()) {
recordPause.setTitle('Pause');
audioRecorder.resume();
} else {
recordPause.setTitle('Resume');
audioRecorder.pause();
}
});
recordStop.addEventListener('click', function(e) {
record = audioRecorder.stop();
Ti.API.info(record.getNativePath());
});
recordPlay.addEventListener('click', function(e) {
audioPlayer = Ti.Media.createAudioPlayer({
url: record.getNativePath()
});
audioPlayer.start();
});
window.add(recordPause);
window.add(recordStop);
window.add(recordPlay);
window.open();
Thanks in advance
This is an example using Titanium's Hyperloop: https://gist.github.com/dinahgarcia/119ac00c91334d3951601cf347bad8d4
To be able to use it you need to enable Hyperloop: https://docs.appcelerator.com/platform/latest/#!/guide/Enabling_Hyperloop

Using Youtube Javascript API for multiple videos

I am trying to find a way to use Youtube API to have multiple videos with each in its own hidden div where each one is called up by their corresponding thumbnails. I am having a hard time finding out how to get the close button of the once hidden div to also stop that particular video. I can only get one to do it right and the other will not. My code below:
// 2. This code loads the IFrame Player API code asynchronously.
var tag = document.createElement('script');
tag.src = "//www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player1 = new YT.Player('popupVid1', {
height: '408',
width: '725',
videoId: '6Bp1c3-AeXQ',
playerVars: {
wmode: "opaque"
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
player2 = new YT.Player('popupVid2', {
height: '408',
width: '725',
videoId: '6Bp1c3-AeXQ',
playerVars: {
wmode: "opaque"
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
event.target.playVideo();
}
// 5. The API calls this function when the player's state changes.
// The function indicates that when playing a video (state=1),
// the player should play for six seconds and then stop.
var done = false;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo,loop);
done = true;
}
}
function stopVideo1() {
player1.stopVideo();
}
function stopVideo2() {
player2.stopVideo();
}

How to refilter a dojo DataGrid?

I have a DataGrid that I already filtered using grid.filter(query, rerender). If I add another item, after calling save() I see the new item in the grid even though it shouldn't display because of the filter. I'm thinking "ok, I'll just filter it again when the store finishes saving. But after calling grid.filter with the same query all the rows disappear. Any ideas what I might be doing wrong?
Code to filter the grid:
var filterQuery = dijit.byId("filterTextbox").attr("value");
var grid = dijit.byId("grid");
var queryValue = "*";
if(filterQuery != ""){
queryValue += filterQuery + "*";
}
grid.filter({name: queryValue}, true);
Code to add new items to the grid
function addItemToGrid(newItemName){
var newItem = {name: newItemName};
var grid = dijit.byId("grid");
var store = grid.store;
store.addItem(newItem);
store.save();
}
Try to use:
store.newItem(newItem);
instead of store.addItem(newItem);
(addItem is not a standard method to add items into store)
Inside of your addItemToGrid function, try adding an onComplete listener to your save method and sort or filter the grid in the onComplete function
store.save({onComplete: function() {
grid.filter({name: queryValue}, true);
}
});
I had the same problem and only managed to fix it by running the grid filter periodically in the background with the help of some jQuery. Here is some sample code; hope this helps someone else having problems with this.
// ADD JQUERY
<script src="http://code.jquery.com/jquery-latest.js"></script>
.
// PUT THIS IN THE <HEAD> OF THE PAGE
<script type="text/javascript">
$(document).ready(function() {
function filterTheDataGrid() {
if (dijit.byId("grid") != undefined) {
dijit.byId("grid").filter({color: "Red"});
}
}
// RUN THE filterTheDataGrid FUNCTION EVERY ONE SECOND (1000 MILLISECONDS) //
// LOWER '1000' FOR FASTER REFRESHING, MAYBE TO 500 FOR EVERY 0.5 SECOND REFRESHES //
var refreshDataGrid = setInterval(function() { filterTheDataGrid(); }, 1000);
}
</script>
.
// PUT THIS IN THE <HEAD> OF THE PAGE
<script type="text/javascript">
// SETUP THE LAYOUT FOR THE DATA //
var layoutItems = [[
{
field: "id",
name: "ID",
width: '5px',
hidden: true
},
{
field: "color",
name: "Color",
width: '80px'
}
]];
// Create an empty datastore //
var storeData = {
identifier: 'id',
label: 'id',
items: []
}
var store3 = new dojo.data.ItemFileWriteStore( {data : storeData} );
</script>
.
// PUT THIS IN THE <HTML> OF THE PAGE
<div id="grid" dojoType="dojox.grid.DataGrid" jsId="grid5" store="store3" structure="layoutItems" query="{ type: '*' }" clientSort="true" rowsPerPage="40"></div>
.
<script type="text/javascript">
function addItemToGrid(formdata) {
// THIS FUNCTION IS CALLED BY A DIALOG BOX AND GETS FORM DATA PASSED TO IT //
var jsonobj = eval("(" + dojo.toJson(formData, true) + ")");
var myNewItem = {
id: transactionItemID,
color: jsonobj.color
};
// Insert the new item into the store:
store3.newItem(myNewItem);
store3.save({onComplete: savecomplete, onError: saveerror});
}
</script>