I am writing a jqueryui widget, and I want to get at some widget data when the widget changes (using _trigger). I am using the widget as follows:
$("#myDiv").myWidget({
change: function(e) {
alert($("#filter").myWidget('getWidgetData'));
// do something with the widget data.
}
});
This code works (the alert fires and show the widget data when the widget calls _trigger). However, is this the correct/best way to get at the widget data inside the change callback ? For isntance, I can't seem to call this.getWidgetData, or e.getWidgetData.
You can attached your data to the change event you triggered. You should have something like :
this._trigger('change', e);
and could use :
this._trigger('change', e, { widgetData: this.getWidgetData() });
The _trigger function accepts A hash of data associated with the event. as its third arg as decribed in the documentation.
And your code will become :
$("#myDiv").myWidget({
change: function(e, data) {
alert(data.widgetData);
// do something with the widget data.
}
});
Related
I'm building a file uploader plugin for studying purposes, and I'm struggling trying to get my callback working the way I want to. Briefly, this widget opperates on an input field with the type file. A little of code to explain better:
$.widget('ultimatum.uploadify', {
create: function() {
// Irrelevant code here
},
_onChange: function(event) {
// Private function that is fired when an "change" event
// is triggered by the input.
var files = event.target.files;
var fileInfo = {};
// When the file processing finish, I want to trigger this custom event:
this._trigger("fileready", null, fileInfo);
}
});
Ok, doing this way, I can handle the callback like so:
$('#upload-files').uploadify({
fileready: function(event, file) {
// My code here
}
});
The problem is that I want to handle this event like so:
$('#upload-files').uploadify();
$('.upload-files').on('fileready', function(event, file) {
// My code here.
});
Although the former way works perfectly well, the latter doesn't. Is it possible to handle custom jQuery events this way, using "on"?
From http://api.jqueryui.com/jQuery.widget/
Events
All widgets have events associated with their various behaviors to notify you when the state is changing. For most widgets, when the events are triggered, the names are prefixed with the widget name and lowercased. For example, we can bind to progressbar's change event which is triggered whenever the value changes.
$( "#elem" ).bind( "progressbarchange", function() {`
alert( "The value has changed!" );
});
Each event has a corresponding callback, which is exposed as an option. We can hook into progressbar's change callback instead of binding to the progressbarchange event, if we want to.
$( "#elem" ).progressbar({
change: function() {
alert( "The value has changed!" );
}
});
All widgets have a create event which is triggered upon instantiation.
So for your widget, this would look like:
$('#upload-files').uploadify();
$('#upload-files').on('uploadifyfileready', function(event, file) {
// My code here.
});
As I mentioned in the comment, I think that $('.upload-files') may be a typo, and that the proper selector is $('#upload-files').
I made a reusable table view which takes a table definition (JSON array) and data (JSON) and renders the table using javascript. I made the table using an mvc pattern like here updated for es6.
I have hard coded events in the view which work great within instances of my model, view and controller. These events are things like "addRowClicked" and "modelChanged" which then calls a callback function to operate.
For example On the view I created the event:
this.addRowClicked = new CIEvent(this);
On the Controller I attach the callback:
this.view.addRowClicked.attach(
function() {
self.addRow()
}
);
Then when creating the view I can pass a button array with an event name which creates the button and attaches the notify method of the event when clicked
element.onclick = function () {
self[button.event_name].notify();
}
So that all works perfect and is pretty awesome!!
Now I am trying to add custom events without luck. A Custom event would be something like "updateQuantity" which is unique to an instance of the table. updateQuantity would get fired from an input element when changing and would sum up specified cells and put that sum in a different cell.
I thought I would be able to simply create the event on the view, attach the callback on the controller, then attach the event notification to onchange or onkeyup... etc
But that is not working.
Here is some extracted code of the entire process....
To build the table I do this:
let model = new TableModel(table_definition, data);
let view = new DataTableView(model, div, buttons);
let controller = new DataTableController(model, view);
Now I add the event 'updateQuantity' on the view and the callback on the controller:
view.updateQuantity = new CIEvent(view);
controller.view.updateQuantity.attach(
function() {
console.log('update the quantity row')
}
);
If I then call the event from the within same file it works fine:
view.updateQuantity.notify(); // works fine
However, if I try to attach this to an an element onclick, onkeyup, etc, the event will not fire... the commented code attaches dynamically however I just hardwired it to try to get it working. I tried using events like onkeyup directly and using addEventListener
let self = this;
// element[index] = this[event[index]].notify();
// element.onkeyup = this.updateQuantity.notify();
element.addEventListener("onkeyup", function(){
// self[event[index]].notify();
self.updateQuantity.notify();
});
When modifying the element I get no response.
I hope I am missing something elementary. thanks all!
element.addEventListener("onkeyup", function(){
// self[event[index]].notify();
self.updateQuantity.notify();
});
Should be
element.addEventListener("keyup", function(){
// self[event[index]].notify();
self.updateQuantity.notify();
});
onkeyup should have been keyup
I want to catch the create event from the jsTree context menu so i can do whatever i want after i right-click on the node and choose "Create".
For example i want to enter into another page after i click "Create" and to disable the default behavior of the create button.
Which event i should use from the library documentation ?
I'm trying something like this to try catch the event but it doesnt work.
$(".jstree").bind("create.jstree", function(event,data)
{
alert("hello");
});
Search for jstree.js js library inside your code. If you are using CDN link, than download the js file in your system and search for the following line:
$.jstree.defaults.contextmenu = {
Inside this function you get code like:
items : function (o, cb) { // Could be an object directly
return {
"create" : {}
// This is the create function block which is called when create is clicked. You can change it accordingly.
I am trying to get access and modify this function (second one) in jqueryUI. I have tried everything. What I want to do is to add something in the function. I know it is possible and I need to do something like this :
var snapIt = $.ui.draggable.prototype.drag;
$.ui.draggable.prototype.drag = function() {
console.log("hello"); // exemple of a thing I want to add
// Now go back to jQuery's original function()
return snapIt.apply(this, arguments);
};
On top it will get the function add in console "hello" and then continue normally with the rest of the jQuery function. But I just can't find this function. I know this doesn't work: $.ui.draggable.prototype.start and dozens of others I tried.
$.ui.plugin.add("draggable", "snap", {
start: function( event, ui, i ) {
click.x2 = event.clientX;
click.y2 = event.clientY;
var o = i.options;
i.snapElements = [];
$(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
var $t = $(this),
$o = $t.offset();
if (this !== i.element[0]) {
//...........
I don't want the drag: function(event, ui) {..... I need to modify the function because I use ui.position = {left..... and it make the snap method not work. The only way was to change the drag method. I know it work because I tried manualy. But changing the library might be problematic for futur dev.
Don't know if I am clear but basically I want the path to $.ui.plugin.add("draggable", "snap", {//stuff}); in jqueryUI library
Thx in advance
There are 3 different sources of behaviors that are called on the different events in jquery-ui, each with its own structure.
First you have the "private" functions, that are defined on the prototype and that are called directly on native events. These are on $.ui.draggable.prototype and begin with a _ character. For example you have $.ui.draggable.prototype._mouseDrag function.
These are called directly and are the ones triggering the events. They are not directly accessible from the options.
Then you have the plugins functions. These are the ones that are added using add. Basically what add does is that it sets functions to be called on the events that are accessible via the options. And these plugins callbacks are called if their corresponding option is true. The structure goes like this:
Each plugin is an object that defines a callback for different
events. The events available are the same that are accessible in the options. For draggable, you have start, drag and stop.
These callbacks are pushed in arrays contained by
$.ui.draggable.plugins object, in which each property is one of the available event.
A function goes through the event array and validates if the plugin
should be ran based on the option set.
Once the plugins are done, the options callbacks are called. These are the ones that you set in the options.
So depending what ou want to modify, you can either change the prototype:
$.ui.draggable.prototype._mouseDrag
Or you can add a plugin. Like this:
$.ui.plugin.add( "draggable", "customPlugin", {
drag: function(event, ui, draggable){
console.log("I'm the custom plugin");
});
Or you can modify snap plugin. This one is a bit more complicated, and much less reliable since the functions are stored in arrays and not in an object, and they are added. The structure goes like this:
Each property key is an event, and every property is an array of
arrays.
Each of the array first element is the name of the option associated
with the callback, that is the second element of the array.
So the drag callback associated to snap is $.ui.draggable.prototype.plugins.drag[2], because it's the third callback that's been added to drag event. $.ui.draggable.prototype.plugins.drag[2][0] is the string "snap", which is used to check if the option was set to true. And the callback is $.ui.draggable.prototype.plugins.drag[2][1]. So you can modify it like this:
$.ui.draggable.prototype.plugins.drag[2][1] = function(){
console.log("I'm the modified plugin");
}
If you want a better control, you can iterate through $.ui.draggable.prototype.plugins.drag array and check the first element to make sure you modify the proper plugin.
Obviously, as you tried, you need to store the original callback if you want the behavior to work.
See here how this goes:
$.ui.plugin.add("draggable", "customPlugin", {
drag: function() {
console.log("%c I'm a custom plugin", 'color: blue');
}
});
var _temp = $.ui.draggable.prototype.plugins.drag[2][1];
$.ui.draggable.prototype.plugins.drag[2][1] = function() {
console.log("%c I'm the modified snap plugin drag callback", 'color: red');
_temp.apply(this, arguments);
}
$('div').draggable({
snap: true,
customPlugin: true,
drag: function() {
console.log("%c I'm the options callback", 'color: green');
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript" src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<div>Drag me</div>
<div>Or me</div>
I'm trying to change the "change" event of a Kendo UI Dropdownlist, but unfortunately I haven't had any luck. Here's the code I've tried so far: http://trykendoui.telerik.com/ukeV
Specifically, here's my dropdownlist initializer:
var onChange = function(e)
{
alert("something changed");
};
// create DropDownList from input HTML element
$("#dropdown").kendoDropDownList({
dataTextField: "text",
dataValueField: "value",
dataSource: data,
index: 0,
change: onChange
});
And this is my attempt to change that function later:
onChange = function(e){alert("attempt 1");};
var dropDownData = $("#dropdown").data("kendoDropDownList");
dropDownData.options.change = function(e){alert("attempt 2");}
dropDownData.refresh();
Specifically, I first tried just changing the onChange function, and then (when that didn't work), I tried changing the options.change function directly. While the options.change function did change (when I examined it in chrome debugger), the dropdownlist's actual functionality remained unchanged. I think I need to refresh the dropdownlist or something to make my edits actually take effect. Does anyone know how I can actually get the kendo grid to refresh and display my data?
I see you've already found a work-around, but I thought I'd add some more explanations.
The reason why changing it like this
onChange = function(e){alert("attempt 1");};
doesn't work is that you're passing a function to the widget, and the widget calls that function at appropriate times. You're not passing a reference to the variable onChange. So changing the variable won't affect the widget.
The reason why
dropDownData.options.change = function(e){alert("attempt 2");}
doesn't work is that Kendo stores handlers in its own structure (which is necessary since you can bind multiple handlers for the same event!), so it doesn't call whatever is in options.change at any given moment in time.
However, there is a setOptions method, and with that you could've made your second approach work:
dropDownData.setOptions({
change: function (e) {
alert("attempt 2");
}
});
I ended up using a simple work-around. When I put in the line
change: onChange
Kendo actually hardcoded in the function body into the dropDownData.options.change function, rather than referencing my named javascript function. It looked like this in the debugger:
function(e)
{
alert("something changed");
};
So my workaround was simply to use an anonymous function in the Kendo call. So I changed change: to
change: function(e) { onChange(e) };
Then when I changed onChange later, kendo referenced the named javascript function and called my updated version. Here's the working demo: http://trykendoui.telerik.com/AkIW/2