JQuery UI Widget Inheritance / class method call - jquery-ui

I'm trying to write a custom widget in JQuery UI (v 1.9 m8): http://pastebin.com/zua4HgjR
From my site I call it like this: var D = new $.ui.mail({}); Basically it works.
Is there a better method to call doSend on button click?
The question is how to access object instance from function handler?
"this" returns entire html window.
Tried with $.proxy doesn't work: click: $.proxy(this.doSend, this);
Thanks in advice!

Unfortunately if you setup the buttons by using the options member you'll have no reference to the element that you need in order to call doSend. One workaround I was able to come up with is to assign the handler in the _create method where you have the appropriate reference.
_create: function() {
this.options.buttons = [
{
text: 'Send',
click: function(self) {
return function() {
$(self.element).mail('doSend');
};
}(this)
},
{
text: 'Cancel',
click: function() { $(this).remove() }
}
];
this._super(arguments);
}
Live Example - http://jsfiddle.net/hhscm/2/

Spending this weekend finally I finished my plugin: http://agrimarket-blacksea.com/jsc/jquery-mail.js
I decided to call "class function" in classical way: $(this).mail('doSend'), until I'll find something better.
Thanks!

Related

How to access a Stimulus JS controller method from inside a nested function?

I have a Stimulus controller inside which I have a setSegments function and then this code in the connect() method:
connect() {
const options = {
overview: {
container: document.getElementById('overview-container'),
waveformColor: 'blue',
},
mediaElement: document.querySelector('audio'),
dataUri: {
arraybuffer: document.getElementById('normal-audio-button').dataset.waveform
},
emitCueEvents: true,
};
Peaks.init(options, function (err, peaks) {
window.instance = peaks;
window.speed = "normal";
setSegments()
instance.on('segments.enter', function (segment) {
const segmentCard = document.getElementById(segment.id)
segmentCard.focus({preventScroll: true})
window.currentSegment = segment
});
});
}
setSegments() {
alert("segment set up)
}
I'm tryng to call setSegments() inside the Peaks.init function but it doesn't work because of the function's scope. I'm just not sure how to get around this. I tried calling this.setSegments() instead but it doesn't help.
What's the correct way of accessing the function in this case?
Thanks
The problem is that this is a bit confusing when working with JavaScript, however a way to think about it that it is the current context.
For example, when your code is running in the browser console or not in another function this is the global window object. When you are directly in the controller's connect method this is the controller's instance.
However, when you pass a function to Peaks.init that function creates it's own new context where this is the function's context and no longer the controller instance.
There are three common workarounds to calling this.setSegments;
1. Set a variable that is outside the function scope
As per your solution, const setSegments = this.setSegments; works because you are creating a reference outside the function scope and functions have access to this.
connect() {
const options = {}: // ... Options
// this is the controller's instance
const setSegments = this setSegments;
Peaks.init(options, function (err, peaks) {
// this is the peaks init handler context
window.instance = peaks;
// this.setSegments(): - will not work
setSegments();
instance.on('segments.enter', function (segment) {
// this is the event (usually)
});
});
}
2. Use bind to override the function'sthis
You can pull your function out to a variable and then add .bind(this) to it so that when the function is called it will use the this from the controller instance instead.
connect() {
const options = {}: // ... Options
// this is the controller's instance
const myFunction = function (err, peaks) {
// this is the BOUND this provided by the bind command and will be the controller's instance
window.instance = peaks;
this.setSegments():
instance.on('segments.enter', function (segment) {
// this is the event (usually)
});
};
myFunction.bind(this);
Peaks.init(options, myFunction);
}
3. Use an arrow function (easiest)
You should be able to use an arrow function in modern browsers or if you have a build tool running it may transpiled this for older browsers.
Instead of function() {} you use () => {} and it grabs the this from the parent function context instead.
connect() {
const options = {}: // ... Options
// this is the controller's instance
Peaks.init(options, (err, peaks) => {
// this is now the controller's instance and NOT the peak handler context
window.instance = peaks;
this.setSegments():
instance.on('segments.enter', function (segment) {
// this is the event (usually) and is NOT the controller instance as arrow function not used here.
});
});
}
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this for more details
I don't know if it's the best way to do it but adding the following right after the beginning of the connect method did the trick:
let setSegments = this.setSegments

ExtJS - disable Quick Tip on Ext.window.Window close button

I have a view that extends Ext.window.Window:
Ext.define('MyApp.view.help.Module', {
extend: 'Ext.window.Window',
initComponent: function () {
var me = this,
me.callParent(arguments);
}
});
Ext.QuickTips.init() is run when the application first starts up. Later on, when I create an instance of MyApp.view.help.Module as follows:
var module = Ext.create('MyApp.view.help.Module');
module.show()
A quick tip "Close Dialog" is shown over the 'X' button in the window. How can I disable the quicktip?
I know I can run Ext.QuickTip.disable(), however that disables the quick tips globally when I just want the quick tip over the 'X' button to be disabled.
Any help is appreciated!
You can define the closeToolText property as an empty string as follows:
Ext.define('MyApp.view.help.Module', {
extend: 'Ext.window.Window',
closeToolText: '',
initComponent: function () {
var me = this,
me.callParent(arguments);
}
});
You can just define the closeToolText property as an empty string as Kevin Lee said or null as follows:
Ext.define('MyApp.view.help.Module', {
extend: 'Ext.window.Window',
closeToolText: null,
initComponent: function () {
var me = this,
me.callParent(arguments);
}
});

this reference in a jQuery UI Custom widget

I have built a custom widget that contains lots of other widgets.
The problem I am getting is the this. reference when a widget inside my custom widget calls a function in my custom widget. For example:
$(function() {
$.widget("custom.my_widget",
{
_create: function() {
this.variable = "HI";
var that=this;
// A Custom widget
this.button = $("<button>", {html:"PRESS"})
.button()
.click(this.do_it) // I know I can do a function(){ that.do_it() }) but that is not the point
.appendTo(this.element);
},
do_it: function() {
// With the setup like this, how do I get the correct this. reference
// As it stands, this = the button object
alert("TEST: "+ this.variable);
}
})
});
The problem is that the this in the do_it function does not point to my_custom widget, instead it points to the button widget.
Above is symbolic, please don't point out a bug as my actual widget is over 3000 lines of code and has many references like this. I need to get the my_widget instance inside functions like this when other widgets call my widget's functions.
I have tried putting in another parameter, but with some callbacks in some third party widgets this is not possible.
There must be an easy way to get the correct base this value for my_widget.
jsFiddle for reference : http://jsfiddle.net/jplevene/6e7m2q6h/3/
You can either use bind(), instead of click(), specifying the "context", or just reference a local variable and call the function (e.g. self below):
$.widget("custom.my_widget",
{
// the constructor
_create: function() {
var self = this;
this.variable = "HI";
// A Custom widget
this.button = $("<button>").button().click(function(){
self.do_it();
});
},
do_it: function(e) {
alert(this.variable);
}
JSFiddle: http://jsfiddle.net/ewpgv3mt/1/
The only way I found to do it is as follows:
$(function() {
$.widget("custom.my_widget",
{
_create: function() {
this.variable = "HI";
// A Custom widget
this.button = $("<button>", {html:"PRESS"})
.button()
.click(this.do_it) // I know I can do a function(){ that.do_it() }) but that is not the point
.data("widget", this) // <---- New line here
.appendTo(this.element);
},
do_it: function() {
// Get the parent widget
var that = $(this).data("widget");
alert("TEST: "+ that.variable);
}
})
});
What I did was pass the "this" value to a data value of the object. There must be a better way than this.
I have tried $(this).closest(".my_widget_class"), but I then need the widget from the object

How to use each function, this from jquery to Dart Language?

I have a function in jquery as below
function findMax(){
$( ".elements" ).each(function( ) {
if($(this).css('z-index')>max1)
max1=$(this).css('z-index');
max1=parseInt(max1);
});
}
I have to implement this function in Dart Language. Facing problems with syntaxes in using .each function and 'this' function.
The equivalent of jQuery :
$(".elements").each(function( ) {
// do something with this being one of elements with a 'elements' class
// you can access the current element with $(this)
});
is in Dart :
querySelectorAll('.elements').forEach((Element e) {
// do something with e being one of elements with a 'elements' class
// you can access the current element with e
});

how do I add custom function to zepto?

New to zepto (and honestly, far from a jQuery-whiz),
I want to add a custom function.
This is my attempts so far:
//define..
$.fn.doSearch = function() {
alert(this.parentNode.html());
//now xhr..
}
//assign..
$('#resetBtn').click( function (e) {$(this).doSearch()});
and
//define
<script type="text/ja..
function doSearch(obj) {
alert('Ugly way but here I am');
}
//assign..
$('#resetBtn').click( function (e) {window.doSearch()});
And neither works.. I'd rather go the first route, aware that .fn isn't listed in the zepto-docs.
regards,
//t
ok, now I have
//define
var myFunc = {
doSearch: function(obj) {
//just check obj is ok.
alert($(obj.parentNode).html());
}
}
//correct way to extend zepto?
$.extend($,myFunc);
//assign...
$('#searchBtn').click( function (e) {$(this).doSearch(this)});
is this the way to go?
As mentioned in the documents,
(function($){
$.extend($.fn, {
foo: function(){
// `this` refers to the current Zepto collection.
// When possible, return the Zepto collection to allow chaining.
return this.html('bar')
}
})
})(Zepto)

Resources