ion-content method scrollToPoint not working on Ionic 5 - ionic-framework

I am following this ionic5 and github documentation in order to programmatically scroll my page to a point. Following is the code
getContent() {
return document.querySelector('ion-content');
}
scrollPage() {
this.getContent().scrollToPoint(100,100);
}
Method scrollToPoint() is not doing anything. Is there another way of calling this method?

You can not apply methods at item obtained by selector. You must be select this ion-content with #ViewChild and can use methods:
#ViewChild(IonContent) content: IonContent;
content.scrollToPoint(100,100);

In case somebody is having trouble with this using VueJS + Ionic 6. I got it working by storing the $ref in my data() on mounted(). Don't forget to add the ref attribute like so: <ion-content ref="myContent">.
data() {
return {
myCustomContent: null
};
}
In your mounted()
mounted() {
this.myCustomContent = this.$refs.myContent.$el;
}
Your method:
scrollFunction() {
this.myCustomContent.scrollToBottom(500);
}

Related

Detect a click outside of an element

There is some components in Ionic that do not provide an event that is emitted when focus is lost.
For example ion-input provides ionBlur. On the other hand there is other elements like ion-content where I need to detect an outside click, but without knowing which event to use.
Is there a way to achieve that without being limited to the proposed events in the documentation?
I found this article that shows a way to use a custom directive to detect an outside click:
import {Directive, ElementRef, Output, EventEmitter, HostListener} from '#angular/core';
#Directive({
selector: '[clickOutside]'
})
export class ClickOutsideDirective {
constructor(private _elementRef : ElementRef) {
}
#Output()
public clickOutside = new EventEmitter();
#HostListener('document:click', ['$event.target'])
public onClick(targetElement) {
const clickedInside = this._elementRef.nativeElement.contains(targetElement);
if (!clickedInside) {
this.clickOutside.emit(null);
}
}
}
The directive can then be used this way, after declaring it in the concerned module:
<!-- HTML Template -->
<ion-content (clickOutside)="handleOutsideClick()"><!-- ... --></ion-content>
<!-- Typescript code -->
handleOutsideClick() {
//Handle My outside Click
}
Yeah, It's been 7 months since asked.
Stucked with the same issue; this solved the issue
TS
#ViewChild('content') content: ElementRef
#HostListener('document:click', ['$event'])
andClickEvent(event) {
if (!this.content.nativeElement.contains(event.target)) {
if (!this.navCtrl.isTransitioning() && this.navCtrl.getActive()) {
this.close()
}
}
}
HTML
<ion-content #content>

VideoJS 5 plugin add button

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()

Using search feature in Ionic framework

I am a UI person and very new to ionic framework.. I wanted to add search feature in my android app built using Ionic framework. After a research i found that I will need to use this plugin https://github.com/djett41/ionic-filter-bar. but there is no detail documentation available. Can anyone please guide how to use this plugin working. I have made all setup but stuck with actual code.
First of all you must install the plugin. You can use bower for that:
bower install ionic-filter-bar --save
and it will copy all the javascript and css needed in the lib folder inside www.
Then you must add the references to the css to your index.html:
<link href="lib/ionic-filter-bar/dist/ionic.filter.bar.css" rel="stylesheet">
same thing for the javascript:
<script src="lib/ionic-filter-bar/dist/ionic.filter.bar.js"></script>
You have to inject the module jett.ionic.filter.bar you your main module:
var app = angular.module('app', [
'ionic',
'jett.ionic.filter.bar'
]);
and you must reference the service $ionicFilterBar in your controller:
angular.module('app')
.controller('home', function($scope, $ionicFilterBar){
});
Now you can start using it.
In my sample I want to trigger the search-box when the user clicks/taps on a icon in the header. I would add this HTML to the view:
<ion-nav-buttons side="secondary">
<button class="button button-icon icon ion-ios-search-strong" ng-click="showFilterBar()">
</button>
</ion-nav-buttons>
The action trigger an event in my controller showFilterBar:
$scope.showFilterBar = function () {
var filterBarInstance = $ionicFilterBar.show({
cancelText: "<i class='ion-ios-close-outline'></i>",
items: $scope.places,
update: function (filteredItems, filterText) {
$scope.places = filteredItems;
}
});
};
which creates the $ionicFilterBar and shows it.
As you can see here I am using an array of objects $scope.places
$scope.places = [{name:'New York'}, {name: 'London'}, {name: 'Milan'}, {name:'Paris'}];
which I have linked to the items member of my $ionicFilterBar. The update method will give me in filteredItems the items (places) filtered.
You can play with this plunker.
Another option is to use the plugin to actually fetch some data remotely through $http.
If we want to achieve this we can use the update function again.
Now we don't need to bind the items to our array of objects cause we won't need the filtered elements.
We will use the filterText to perform some action:
$scope.showFilterBar = function () {
var filterBarInstance = $ionicFilterBar.show({
cancelText: "<i class='ion-ios-close-outline'></i>",
// items: $scope.places,
update: function (filteredItems, filterText) {
if (filterText) {
console.log(filterText);
$scope.fetchPlaces(filterText);
}
}
});
};
We will call another function which will, maybe, call $http and return some data which we can bind to our array of objects:
$scope.fetchPlaces = function(searchText)
{
$scope.places = <result of $http call>;
}
Another plunker here.
PS:
If you want to configure it using some sort of customization you must do it in your configuration using the provider $ionicFilterBarConfigProvider:
angular.module('app')
.config(function($ionicFilterBarConfigProvider){
$ionicFilterBarConfigProvider.clear('ion-ios-close-empty');
})
PPS:
In my plunker I've included the css and the script directly copying it from the source.
UPDATE:
Someone asked not to replace the list with the updated one.
My cheap and dirty solution is to check if the filterText contains some values. If it's empty (no searches) we go throught each element an set a property found = false otherwise we compare the places array we the filteredItems array.
Matching elements will be marked as found.
function allNotFound(filteredItems) {
angular.forEach($scope.places, function(item){
item.found = false;
});
}
function matchingItems(filteredItems) {
angular.forEach($scope.places, function(item){
var found = $filter('filter')(filteredItems, {name: item.name});
if (found && found.length > 0) {
console.log('found', item.name);
item.found = true;
} else {
item.found = false;
console.log('not found', item.name);
}
});
and now we can integrate the filter bar this way:
$scope.showFilterBar = function () {
var filterBarInstance = $ionicFilterBar.show({
cancelText: "<i class='ion-ios-close-outline'></i>",
items: $scope.places,
update: function (filteredItems, filterText) {
if (!filterText) {
allNotFound();
} else {
matchingItems(filteredItems);
}
}
});
};
We can use the found attribute of the object to change the style of the element.
As always, a Plunker to show how it works.
Ionic uses Angular, and Angular include an atributte filter very useful. Look this: https://docs.angularjs.org/api/ng/filter/filter and the example there. Regards

GwtQuery - fadeIn one after another

I want to add fade-in animation for couple of widgets one after another.
I reviewed the doc, but it only does first fade-in.
$(myWidget1).fadeIn(new Function(){
public boolean f(Event e){
//tried to add the second fade-in for myWidget2, but no result
return true;
}
});
How do I achieve fade-in one after another in this way or, is there another way to do it?
Thanks!
Try this, using jQuery:
$(document).ready(function(){
var widgets = $('.widget');
var fader = function(widget_n){
if (widget_n < widgets.length) {
$(widgets.get(widget_n)).fadeIn('slow', function(){
fader(widget_n +1);
});
}
};
if (widgets.length > 0) {
fader(0);
}
});
Check my example here : http://gwtquery-plugins.googlecode.com/svn/branches/droppable_1_0/demo/DraughtsSample/DraughtsSample.html
I use the fadeIn GQuery method method to fade in each piece of the board. You can find the code there : http://code.google.com/p/gwtquery-plugins/source/browse/trunk/droppable/sample/src/main/java/gwtquery/plugins/droppable/client/draughtssample/CheckerBoard.java#116
Why dont you use the .each() function to loop through your "widgets".
var map = {
'mywidget1': '#mywidget1',
'mywidget2': '#mywidget2'
};
$.each(map, function(key, value) {
$(value).fadeIn(...);
});
or if they all have a something in common (i.e. class of tag combination etc.) this would be even easier.
See .each() jQuery API
You are overriding an incorrect method: f(Event) is used for events, change it by f():
$(myWidget1).fadeIn(new Function(){
public void f() {
$(myOtherWidget).fadeIn();
}
});

jQuery get object moused over

I have this code:
$('*').mouseover(function() {
$('#log').text($('*').id);
});
When you mouse over any element on the page, I want #log to have the id of that element. Obviously the code above doesn't work... How do I do this?
$('*').mouseover(function() {
console.log($(this).attr('id'))
});
In almost all jQuery callbacks, "this" is the object on which the callback is being executed.
$('*').mouseover(function() {
$('#log').text($(this).attr('id'));
});
You can also use event.target
var $log = $("#log");
$('*').mouseover(function(event) {
$log.text($(event.target).attr('id'));
event.stopPropagation();
});