jQuery unbind listener - events

I have issue to unbind one listeners that listen one of shared emitter:
// this is emitter. Fire always in a.b.c namespace but with different parameters
$(document).trigger("a.b.c", {
p: 1,
p2: ...
});
// listener 1
$(document).bind("a.b.c", function(e, object) {
if (object.myParam) {
....
}
});
// listener 2
$(document).bind("a.b.c", function(e, object) {
if (object.anotherParam) {
....
}
});
How to unbind listener 2, so listeners 1 still continue work?

Save a reference to the handler so that you can later unbind it:
var listener = function(e, object) {
if (object.anotherParam) {
....
}
};
$(document).bind("a.b.c", listener);
// sometime later:
$(document).unbind("a.b.c", listener);

I found better solution Namespaced Events
// this is emitter. Fire always in a.b.c namespace but with different parameters
$(document).trigger("a.b.c", {
p: 1,
p2: ...
});
// listener 1
$(document).bind("a.b.c.listener1", function(e, object) {
if (object.myParam) {
....
}
});
// listener 2
$(document).bind("a.b.c.listener2", function(e, object) {
if (object.anotherParam) {
....
}
});
Now trigging a.b.c will trigger with listener1 and listener2.
And to unbind - just unbind with specific listener, like:
$(document).unbind("a.b.c.listener1");
In that case listener2 will be preserved, and will be able to invoked via namespace a.b.c

Related

How to change enter behaviour in summernote

I have get this old code
// myenter.js, enter key is binded to insertParagraph command.
$.summernote.addPlugin({
name : 'myenter',
events : {
// redefine insertParagraph
'insertParagraph' : function(event, editor, layoutInfo) {
//you can use summernote enter
//layoutInfo.holder().summernote('insertParagraph');
// also you can use your enter key
layoutInfo.holder().summernote('insertNode', document.createTextNode("\r\n"));
// to stop enter key
//e.preventDefault();
}
}
});
$('.summernote').summernote({ height : 300 });
but now method of add plugin has changed and i want this functionality with new version by this code
$.extend($.summernote.plugins, {
'myenter': function (context) {
console.log('myenter');
}
});
but it is not called at all
I had tried to get same functionality by
summernote.onEnter
and
summernote.keyPress
but it gives error..
$.extend($.summernote.plugins, {
'brenter': function (context) {
this.events = {
'summernote.enter': function (we, e) {
// insert 2 br tags (if only one br tag is inserted the cursor won't go to the next line)
document.execCommand('insertHTML', false, '<br><br>');
e.preventDefault();
}
};
}
}
I managed to fix it like this:
$('#summernote').summernote('destroy');
$.extend($.summernote.plugins, {
'brenter': function (context) {
this.events = {
'summernote.enter': function (we, e) {
//get hold of the enter event and trigger a shift+enter keypress
e.trigger($.Event("keydown", {
keyCode: 13, // ENTER
shiftKey: true
}));
//stop the normal event from happening
e.preventDefault();
}
};
}
});
// then do summernote as normal...
$('#summernote').summernote({

Extending behaviors when extending views

The task is:
MyViewX uses BehaviorA and B
MyViewY extends MyViewX,
and uses all behaviors in MyViewX, plus BehaviorC
// The following code works
//
var MyViewX = Marionette.ItemView.extend({
behaviors: {
BehaviorA: {},
BehaviorB: {}
}
});
var MyViewY = MyViewX.extend({
behaviors: {
BehaviorA: {},
BehaviorB: {},
BehaviorC: {}
}
});
The question: how to make use of the behaviors definition in X, so that in Y I do not need to repeat A and B?
// this is not good. It overrides X. Y has only C
var MyViewY = MyX.extend({
behaviors: {
BehaviorC: {}
}
});
// maybe something like this?
// but how exactly to get X's behaviors here?
var MyViewY = MyViewX.extend({
behaviors: _.extend{
BEHAVIORS_OF_THE_SUPER_OF_THE_CURRENT_CLASS,
{ BehaviorC: {} }
}
});
// this gives no errors,
// but A and B do not behave, as if they are not used.
//
var MyViewY = MyViewX.extend({
behaviors: { BehaviorC: {} },
initialize: function () {
var b = this.behaviors;
this.behaviors = _.extend(
MyViewY.__super__.behaviors,
b
);
}
});
You can get MyViewX's behaviors by accessing it's prototype. Using your ideal solution the following should work:
var MyViewY = MyViewX.extend({
behaviors: _.extend({},
MyViewX.prototype.behaviors,
{ BehaviorC: {} }
);
});
The reason the last example doesn't work is because Marionette Behaviors are added to a view in the Marionette.View constructor which takes place before the Backbone.View constructor which calls initialize at the end.

Using Inheritance Patterns to Organize Large jQuery Applications - how to extend the plugin?

I found this working example of Inheritance Patterns that separates business logic and framework code. I'm tempted to use it as a boilerplate, but since it is an inheritance Pattern, then how can I extend the business logic (the methods in var Speaker)?
For instance, how can I extend a walk: method into it?
/**
* Object Speaker
* An object representing a person who speaks.
*/
var Speaker = {
init: function(options, elem) {
// Mix in the passed in options with the default options
this.options = $.extend({},this.options,options);
// Save the element reference, both as a jQuery
// reference and a normal reference
this.elem = elem;
this.$elem = $(elem);
// Build the dom initial structure
this._build();
// return this so we can chain/use the bridge with less code.
return this;
},
options: {
name: "No name"
},
_build: function(){
this.$elem.html('<h1>'+this.options.name+'</h1>');
},
speak: function(msg){
// You have direct access to the associated and cached jQuery element
this.$elem.append('<p>'+msg+'</p>');
}
};
// Make sure Object.create is available in the browser (for our prototypal inheritance)
// Courtesy of Papa Crockford
// Note this is not entirely equal to native Object.create, but compatible with our use-case
if (typeof Object.create !== 'function') {
Object.create = function (o) {
function F() {} // optionally move this outside the declaration and into a closure if you need more speed.
F.prototype = o;
return new F();
};
}
$.plugin = function(name, object) {
$.fn[name] = function(options) {
// optionally, you could test if options was a string
// and use it to call a method name on the plugin instance.
return this.each(function() {
if ( ! $.data(this, name) ) {
$.data(this, name, Object.create(object).init(options, this));
}
});
};
};
// With the Speaker object, we could essentially do this:
$.plugin('speaker', Speaker);
Any ideas?
How about simply using JavaScript's regular prototype inheritance?
Consider this:
function Speaker(options, elem) {
this.elem = $(elem)[0];
this.options = $.extend(this.defaults, options);
this.build();
}
Speaker.prototype = {
defaults: {
name: "No name"
},
build: function () {
$('<h1>', {text: this.options.name}).appendTo(this.elem);
return this;
},
speak: function(message) {
$('<p>', {text: message}).appendTo(this.elem);
return this;
}
};
Now you can do:
var pp = new Speaker({name: "Porky Pig"}, $("<div>").appendTo("body"));
pp.speak("That's all folks!");
Speaker.prototype.walk = function (destination) {
$('<p>', {
text: this.options.name + " walks " + destination + ".",
css: { color: "red" }
}).appendTo(this.elem);
return this;
}
pp.walk("off the stage");
Runnable version:
function Speaker(options, elem) {
this.elem = $(elem)[0];
this.options = $.extend(this.defaults, options);
this.build();
}
Speaker.prototype = {
defaults: {
name: "No name"
},
build: function () {
$('<h1>', {text: this.options.name}).appendTo(this.elem);
return this;
},
speak: function(message) {
$('<p>', {text: message}).appendTo(this.elem);
return this;
}
};
var pp = new Speaker({name: "Porky Pig"}, $("<div>").appendTo("body"));
pp.speak("That's all folks!");
Speaker.prototype.walk = function (destination) {
$('<p>', {
text: this.options.name + " walks " + destination + ".",
css: { color: "red" }
}).appendTo(this.elem);
return this;
}
pp.walk("off the stage");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>

TypeScript kendoTreeView change / select class method callback

I've been searching around to find why Kendo callbacks are not working with TypeScript but I couldn't find something useful.
So my question is how can kendo use class method as a callback?
Ex:
$("#ipt_tree").kendoTreeView(
{
dataSpriteCssClassField: "sprite",
dataSource: data,
template: "<span data-oid='#= item.oid#'>#= item.text#</span>",
//change: this.Tree_Item_Selected, //doens't get even called
//change: ( item: any ): void => //'this' is not 'this' of the class
//{
// this.Tree_Item_Selected( item );
//}
change: function( item: any ) //using compiler this variable
{
_this.Tree_Item_Selected( item );
}
});
The only solution I've found is to use the _this variable that compiler makes.
Now for the jquery the method callbacks work perfectly.
$( "#ipb_aci_button_edit" ).show().on( "click", this.Info_OnClick_Edit );
private Info_OnClick_Edit = (): void =>
{
//'this' is correct
}
If using the current version of TypeScript (1.0RC), you create a class:
class Demo {
private Tree_Item_Selected(item:any) { }
public Create_Tree(data:any) {
var kendoSettings = {
dataSpriteCssClassField: "sprite",
dataSource: data,
template: "<span>#= item.text#</span>",
change: ( item: any ): void =>
{
this.Tree_Item_Selected( item );
},
change2: function( item: any )
{
_this.Tree_Item_Selected( item );
}
};
}
}
And compile that to JavaScript, the functions change and change2 in the example code both produce the exact same code block:
change: function (item) {
_this.Tree_Item_Selected(item);
},
change2: function (item) {
_this.Tree_Item_Selected(item);
}
The only difference is that the second one produces an error that _this is not found.
In the second example, it's working because it's captured the this correctly. However, you might want to consider a different syntax:
$( "#ipb_aci_button_edit" ).show().on( "click",
(e:JQueryEventObject) => { this.Handle_Info_OnClick_Edit(e) } );
private Handle_Info_OnClick_Edit(e:JQueryEventObject): void
{
// 'this' is correct as it was captured by the event handler code
}

Change switch position with draggable/droppable and save the new position in db

Got a nice solution for my project on stack but I test now some days for a solution to save data after switch in db.
The original post: change switch position behavior
$(function()
{
$(".swapable").
draggable({ revert: true }).
droppable(
{
drop:function(event,ui)
{
swapNodes($(this).get(0),$(ui.draggable).get(0));
}
});
});
function swapNodes(a, b)
{
var aparent= a.parentNode;
var asibling= a.nextSibling===b? a : a.nextSibling;
b.parentNode.insertBefore(a, b);
aparent.insertBefore(b, asibling);
}
http://jsfiddle.net/keGuN/1/
Now I want use the stop to save something after drop.
$(function() {
$(".swapable").
draggable(
{
revert: true,
stop:function()
{
// put new div combination in db
}
}).
droppable(
{
drop:function(event,ui)
{
swapNodes($(this).get(0),$(ui.draggable).get(0));
}
});
});
function swapNodes(a, b)
{
var aparent= a.parentNode;
var asibling= a.nextSibling===b? a : a.nextSibling;
b.parentNode.insertBefore(a, b);
aparent.insertBefore(b, asibling);
}
How to find a way to put new div combination put in database?
My problem is how to get the right way to show new div combination.

Resources