VideoJS 5 plugin add button - plugins

I looked everywhere on the internet but I couldn't find any clear documentation or some examples to create my verySimplePlugin for videoJS 5 (Since it uses ES6).
I just want to add a button next to the big play button... Can someone help me?
Thanks...
PS: I'm using it in angularJS but I guess this can not a problem

This is how you can add download button to the end of control bar without any plugins or other complicated code:
var vjsButtonComponent = videojs.getComponent('Button');
videojs.registerComponent('DownloadButton', videojs.extend(vjsButtonComponent, {
constructor: function () {
vjsButtonComponent.apply(this, arguments);
},
handleClick: function () {
document.location = '/path/to/your/video.mp4'; //< there are many variants here so it is up to you how to get video url
},
buildCSSClass: function () {
return 'vjs-control vjs-download-button';
},
createControlTextEl: function (button) {
return $(button).html($('<span class="glyphicon glyphicon-download-alt"></span>').attr('title', 'Download'));
}
}));
videojs(
'player-id',
{fluid: true},
function () {
this.getChild('controlBar').addChild('DownloadButton', {});
}
);
I used 'glyphicon glyphicon-download-alt' icon and a title for it so it fits to the player control bar styling.
How it works:
We registering a new component called 'DownloadButton' that extends built-in 'Button' component of video.js lib
In constructor we're calling constructor of the 'Button' component (it is quite complicated for me to understand it 100% but it is similar as calling parent::__construct() in php)
buildCSSClass - set button classes ('vjs-control' is must have!)
createControlTextEl - adds content to the button (in this case - an icon and title for it)
handleClick - does something when user presses this button
After player was initialized we're adding 'DownloadButton' to 'controlBar'
Note: there also should be a way to place your button anywhere within 'controlBar' but I haven't figured out how because download button is ok in the end of the control bar

This is how I created a simple button plugin for videojs 5:
(function() {
var vsComponent = videojs.getComponent('Button');
// Create the button
videojs.SampleButton = videojs.extend(vsComponent, {
constructor: function() {
vsComponent.call(this, videojs, null);
}
});
// Set the text for the button
videojs.SampleButton.prototype.buttonText = 'Mute Icon';
// These are the defaults for this class.
videojs.SampleButton.prototype.options_ = {};
// videojs.Button uses this function to build the class name.
videojs.SampleButton.prototype.buildCSSClass = function() {
// Add our className to the returned className
return 'vjs-mute-button ' + vsComponent.prototype.buildCSSClass.call(this);
};
// videojs.Button already sets up the onclick event handler, we just need to overwrite the function
videojs.SampleButton.prototype.handleClick = function( e ) {
// Add specific click actions here.
console.log('clicked');
};
videojs.SampleButton.prototype.createEl = function(type, properties, attributes) {
return videojs.createEl('button', {}, {class: 'vjs-mute-btn'});
};
var pluginFn = function(options) {
var SampleButton = new videojs.SampleButton(this, options);
this.addChild(SampleButton);
return SampleButton;
};
videojs.plugin('sampleButton', pluginFn);
})();
You can use it this way:
var properties = { "plugins": { "muteBtn": {} } }
var player = videojs('really-cool-video', properties , function() { //do something cool here });
Or this way:
player.sampleButton()

Related

Leaflet - How to add click event to button inside marker pop up in ionic app?

I am trying to add a click listener to a button in a leaftlet popup in my ionic app.
Here I am creating the map & displaying markers, also the method I want called when the header tag is clicked is also below:
makeCapitalMarkers(map: L.map): void {
let eventHandlerAssigned = false;
this.http.get(this.capitals).subscribe((res: any) => {
for (const c of res.features) {
const lat = c.geometry.coordinates[0];
const lon = c.geometry.coordinates[1];
let marker = L.marker([lon, lat]).bindPopup(`
<h4 class="link">Click me!</h4>
`);
marker.addTo(map);
}
});
map.on('popupopen', function () {
console.log('Popup Open')
if (!eventHandlerAssigned && document.querySelector('.link')) {
console.log('Inside if')
const link = document.querySelector('.link')
link.addEventListener('click', this.buttonClicked())
eventHandlerAssigned = true
}
})
}
buttonClicked(event) {
console.log('EXECUTED');
}
When I click this header, Popup Open & Inside if are printed in the console, so I know I'm getting inside the If statement, but for some reason the buttonClicked() function isn't being executed.
Can someone please tell me why this is the current behaviour?
I just ran into this issue like 2 hours ago. I'm not familiar with ionic, but hopefully this will help.
Create a variable that keeps track of whether or not the content of your popup has an event handler attached to it already. Then you can add an event listener to the map to listen for a popup to open with map.on('popupopen', function(){}). When that happens, the DOM content in the popup is rendered and available to grab with a querySelector or getElementById. So you can target that, and add an event listener to it. You'll have to also create an event for map.on('popupclose', () => {}), and inside that, remove the event listener from the dom node that you had attached it to.
You'd need to do this for every unique popup you create whose content you want to add an event listener to. But perhaps you can build a function that will do that for you. Here's an example:
const someMarker = L.marker(map.getCenter()).bindPopup(`
<h4 class="norwayLink">To Norway!</h4>
`)
someMarker.addTo(map)
function flyToNorway(){
map.flyTo([
47.57652571374621,
-27.333984375
],3,{animate: true, duration: 5})
someMarker.closePopup()
}
let eventHandlerAssigned = false
map.on('popupopen', function(){
if (!eventHandlerAssigned && document.querySelector('.norwayLink')){
const link = document.querySelector('.norwayLink')
link.addEventListener('click', flyToNorway)
eventHandlerAssigned = true
}
})
map.on('popupclose', function(){
document.querySelector('.norwayLink').removeEventListener('click', flyToNorway)
eventHandlerAssigned = false
})
This is how I targeted the popup content and added a link to it in the demo for my plugin.
So yes you can't do (click) event binding by just adding static HTML. One way to achieve what you want can be by adding listeners after this new dom element is added, see pseudo-code below:
makeCapitalMarkers(map: L.map): void {
marker.bindPopup(this.popUpService.makeCapitalPopup(c));
marker.addTo(map);
addListener();
}
makeCapitalPopup(data: any): string {
return `` +
`<div>Name: John</div>` +
`<div>Address: 5 ....</div>` +
`<br/><button id="myButton" type="button" class="btn btn-primary" >Click me!</button>`
}
addListener() {
document.getElementById('myButton').addEventListener('click', onClickMethod
}
Ideally with Angular, we should not directly be working with DOM, so if this approach above works you can refactor adding event listener via Renderer.
Also I am not familiar with Leaflet library - but for the above approach to work you need to account for any async methods (if any), so that you were calling getElementById only after such DOM element was successfully added to the DOM.

Event for view leave

I declared a controller for a view in my SAPUI5 application. Now I want to perform tasks when the view is left by the user.
There is already a possibility to add a callback function to attachRoutePatternMatched to perform tasks when the view is navigated by the user now I need a equivalent function to handle a leave of the view. I use a SplitContainer as parent container
onInit: function() {
this._oRouter = this.getOwnerComponent().getRouter();
this._oRouter.attachRoutePatternMatched(this._routePatternMatched, this);
},
_routePatternMatched: function(oEvent) {
var that = this;
var sRouteTargetName = oEvent.getParameter("name");
if (sRouteTargetName === "myView") {
// perform tasks if the view is opened by the user
}
},
You can try if this works:
navAway: function(viewName, callback) {
this._oRouter.navTo(viewName);
if(callback && typeof(callback) === "function") {
callback();
}
}
e.g. this.navAway("myView", function() { //doStuff });
Presume you mean navigating backwards? If you have a back button, which presumably you must, put your actions in that function. E.g your detail/master has a navBack button in the toolbar, so put your logic in the button's event handler...
You can achieve this with BeforeHide delegate on the NavContainer child which is often the view:
onInit: function() {
this._navDelegate = { onBeforeHide: this.onBeforeLeave };
this.getView()/*<-- navContainerChild*/.addEventDelegate(this._navDelegate, this);
},
onBeforeLeaving: function(event) {
// ... do something
},
onExit: function() {
// detach events, delegates, and references to avoid memory leak
this.getView().removeEventDelegate(this._navDelegate);
this._navDelegate = null;
},
Example: https://embed.plnkr.co/wp6yes?show=controller%2FNext.controller.js,preview%23next
API reference: NavContainerChild
API reference: sap.ui.core.Element#addEventDelegate
For other navigation related events, see documentation topics mentioned in https://stackoverflow.com/a/55649563

Uncaught TypeError: Cannot read property 'setVisible' of undefined

Im fairly new to SAPUI5 and when I click on button I get the error in the title
what I did in Is I used the SAP web IDE to create new MVC project .
in the main view JS I put
createContent : function(oController) {
var btn = new sap.m.Button({
id:"myBtn",
text : "Content Button"
});
return new sap.m.Page({
title: "TitleT",
content: [ btn ]
});
}
in the Main controller JS I put the following code
onInit: function() {
var that = this;
window.setTimeout(function() {
that.byId("myBtn").setVisible(true);
}, Math.random() * 10000);
},
onPress: function() {
this.byId("pressMeButton").setText("I got pressed");
}
When I run it I see the button but when I click on it I get the error in the on Init,
what am I doing wrong here?
The actual problem with your code is that you create a static id in your javascript view, but the controller will search the id with a prefix like "__jsview0--myBtn" if you call that.byId("myBtn").
Therefore you either have to use createId("myBtn") in your javascript view for defining the id or sap.ui.getCore().byId("myBtn") in the controller and it will work fine. The first approach is recommended though to avoid name clashes.
PS:
i did not really get the use case, it seems like you want to display the button only after a certain (random) timeframe. But the visible flag by default is already true, so the button will always be visible.
Use the standard timeout and byId function from SAPUI5 like this:
onInit: function() {
setTimeout(function() {
sap.ui.getCore().byId("myBtn").setVisible(true);
}, Math.random() * 10000);
},

jquery file upload - how to process entire queue on "basic plus" demo

Given the following demo:
jQuery File Upload Basic Plus demo
I have this working in a project as per the demo, but I'd like to remove the "Upload" button on each image and just add an "Upload All" button at the top. For the life of me I can't work out how to do it and the documentation is pretty thin...
I've tried to create a handle to the fileupload object e.g. var fileUpload = $('#fileupload').fileupload({ and call something like fileUpload.send(); but I just get "object doesn't contain a method 'send'"
The working solution is here: Start Upload all in jquery file upload blueimp
The key is unbinding the click event in the "done" option and not in the "add" option as other articles here suggest.
done: function (e, data) {
$("#uploadBtn").off('click')
$.each(data.result, function (index, file) {
$('<p/>').text(file.name).appendTo(document.body);
});
},
add: function (e, data) {
$("#uploadBtn").on('click',function () {
data.submit();
});
}
Another option is to give the individual upload buttons a class, hide them from view by setting their css display to none and then binding their click to the upload_all click:
//Put this button code next to your button (or span mimicking button) that adds files to the queue.
<button id="upload_all" type="submit" class="btn btn-primary start">
<i class="glyphicon glyphicon-upload"></i>
<span>Start upload</span>
</button>
//Give your buttons a class and set their display to none.
var uploadButton = $('<button/>', {
class:"upload",
style:"display:none"
})
.on('click', function () {
var $this = $(this),
data = $this.data();
data.submit().always(function () {
$this.remove();
});
});
//Bind their click to the click of your upload_all button.
$('#upload_all').on('click', function() {
$('.upload').click();
});
You can push all the data into an array and have your external button call a function that loops through the array and call .submit() on each.
var fileDataArray = [];
// Inside "add" event
fileDataArray.push(data);
// Inside your onClick function for your button
for (var i = 0; i < fileDataArray.length; i++) {
var data = fileDataArray[i];
data.submit();
}

TinyMCE4 How to toggle selfcreated Buttons

I have created a Button with the Tiny Method addButton().
How is it possible to toggle the State of the Button ?
In my first simple case I have a Button with Fullscreen
(Different Functionality than the built-in function)
and want to hide it after getting the Fullscreen State
and replace it with an "End Fullscreen" Button.
But I have not found the right way to show or hide them.
I know that the button will get an ID, but I dont know which one ...
If you add the button with:
editor.addButton('customFullscreen', {
tooltip: 'Fullscreen',
shortcut: 'Ctrl+Alt+F',
onClick: toggleCustomFullscreen,
onPostRender: function() {
var self = this;
editor.on('CustomFullscreenStateChanged', function(e) {
if (e.state) {
self.name('Close fullscreen');
//self.active(e.state); // uncomment for "pressed" look
} else {
self.name('Fullscreen');
}
});
}
});
and handle the event with
var customFullscreenState = false;
function toggleFullscreen() {
customFullscreenState = !customFullscreenState;
if (customFullscreenState) {
// do something, we are active
} else {
// do something else, we're unactive
}
editor.fire('CustomFullscreenStateChanged', {state: fullscreenState});
}
You should be able to have it look like wo different button and do two different things depending on state, but it will still just be one button that changes action and text.