Use existing buttons in datatables - datatables

I am trying to trigger an onClick event when click on next or previous buttons in data tables. I checked the IDs of the buttons and they are auto generated. couldn't use those IDs. Is this possible ?

You have a page.dt event, fired each time the paging is updated :
table.on('page.dt', function() {
var info = table.page.info();
console.log('Showing page: '+info.page+' of '+info.pages);
});
If you want to target click on the previous / next buttons you can easily do that. To my experience dataTables seems to "eat" the click event simply by updating the view immediately - but you can stay upfront in the chain by listening on the mousedown event instead :
$('.dataTables_wrapper').on('mousedown', '.previous', function() {
console.log('previous clicked')
})
$('.dataTables_wrapper').on('mousedown', '.next', function() {
console.log('next clicked')
})
You need to use a delegated event handler because the dataTable controls is recreated each time the dataTable is redrawn. .dataTables_wrapper, .next and .previous is common for all dataTables.
demo -> http://jsfiddle.net/6jpbyvd4/

Related

Mithriljs does not update DOM on change in data

I read somewhere, the DOM is updated every time an event occurs and there is changes in data which are bound to DOM. So I wished to learn more about it. I tried the code below but the DOM is not updated when data in textarea changes but its updated whenever I click or press tab key.
var app = {
controller: function () {
var self = this;
this.model = {};
this.model.errors = [];
this.break_data = function (value) {
self.model.errors = value.split(' ');
m.redraw();
}
},
view: function (ctrl) {
return m('.content', [
m('textarea', {onchange: m.withAttr('value', ctrl.break_data)}),
ctrl.model.errors.map(function (error) {
return m('.error', error);
})
]);
}
}
m.mount(document.getElementById('app'), app);
I even tried m.startComputaion(), m.stopComputation() and m.redraw() non of them works.
The redrawing timing is described here: https://stackoverflow.com/a/30728976/70894
As for your example, the problem is not Mithril but the event. You need to use oninput instead of onchange to look for immediate changes. As the Mozilla docs for the "change" event states:
The change event is fired for input, select, and textarea
elements when a change to the element's value is committed by the
user. Unlike the input event, the change event is not necessarily
fired for each change to an element's value.
Here's a fiddle with your code that uses oninput: http://jsfiddle.net/ciscoheat/LuLcra77/
Note that you don't need m.redraw in the event handler anymore now when the correct event is used, since Mithril redraws automatically after every event defined in a call to m().

How to catch opened event on a ComboBox with Dojo?

I want to know whether a combo box has been opened and call a function that displays an progress bar while it loads the data from a store. I've check the API but no I didn't find any suitable event for what I'm doing.
EDIT
What I want to do is start a progress bar while the combobox is populated from the store. I've created a widget with the combobox and the progress bar (a custom class) and "decorate" openDropDown function with aspect.before. This is the code I've written:
postCreate: function() {
this.inherited(arguments);
aspect.before(
this.comboBox, 'openDropDown',
lang.hitch(this, function(){
this.progressBar.increase();
})
);
on(
this.comboBox,
'search',
lang.hitch(this.progressBar, 'decrease')
);
}
But it seems is not using the right progressBar object.
It sounds like you are looking for something like an "onOpen" event. as of Dojo 1.10 The Dijit/Combobox widget does not support an event like the one you are describing, however it does support a number of other events that might meet your requirements.
I recommend looking into the api for a list of possible events: http://dojotoolkit.org/api/
However the following code will create a custom "onOpen" event like what you are describing. I've provided a jsfiddle which demos this new event
http://jsfiddle.net/kagant15/z4nvzy44/
var comboBox = new ComboBox({
id: "stateSelect",
name: "state",
value: "California",
store: stateStore,
searchAttr: "name"
}, "stateSelect")
// grab the existing openDropDown method
var openDropDownFunction = comboBox.openDropDown;
newFunction = function(){
topic.publish("openDropDown") // add the custom "openDropDown" event trigger
return openDropDownFunction.apply(this);
}
// replace the old comBox method will our new function
comboBox.openDropDown = newFunction;
// Subscribe to the custom openDropDown event and do something when it fires
topic.subscribe("openDropDown", function(){
console.log("Open Drop Down even trigger");
});

.dataTable() pagination breaks class .click responsiveness

When I construct a normal table and give each column a distinct class, the classes are responsive for all rows. However, when I call .dataTable() on my table, only page 1 of the paginated results is responsive. Page 2 and beyond are not responsive.
Example code:
var dataTableID = 'questionsTable';
var columns = {
questionID: "ID",
CategoryString: "Cat",
difficultyLevel: "Diff",
timesAsked: "Qty",
questionText: "Question Text"
};
// my own little function that builds the HTML table. <TD> classes are column names
//-- eg .questionID, .CategoryString, etc
var tableHTML = makeTable(questions, columns);
$('#' + dataTableID).html(tableHTML);
// dataTable works nicely except only page 1 .click is responsive!
$('#' + dataTableID).dataTable();
// works fine if I remove .dataTable() above. ONLY works for first page of results
// if I keep .dataTable()
$('.questionID').on("click", function() {
alert('Click called');
});
When using pagination, dataTables change the visible rows by moving <tr>'s back and forth the DOM. $('.questionID').on is processed for columns on the first page only, since those columns is the only visible (accessible) columns after initialization.
So you must assign the click handler (or whatever you want to attach) on page change rather than on initialization. Here by the use of the fnDrawCallback event :
function clickHandler() {
alert('Click called');
}
var dataTable = $('#example').dataTable({
fnDrawCallback : function() {
$('.questionID')
.off("click", clickHandler)
.on("click", clickHandler)
}
});
see demo -> http://jsfiddle.net/U9Jmg/
Notice the use of .off. dataTables actually moves the <tr>'s back and forth the DOM and a table in memory, including any attached events. If previous attached events is not released, we will end up in multiple alerts for each column.
Also note I have only used only one class .questionID for all the columns in the demo. The example is 1.10.x but this works in 1.9.x as well.
As you can see of the comments below, you could also use a delegated event instead of direct event binding. It changes the setup and perhaps it is not suitable for your needs, but anyway :
$('#example tbody').on('click', '.questionID', clickHandler);
see demo -> http://jsfiddle.net/L29Dq/
When using DataTables pagination feature (as you do), only the first page of your data is present in the dom when you attach the click event handler. That's why the handler is attached to the elements on the first page and only to those elements.
When going to another page, DataTables will redraw the table which in effect removes the attached event handler. You have to reattach the event handler after every table draw. The drawCallback option should be the right place for that:
$('#' + dataTableID).dataTable({
"drawCallback": function(settings){
$('.questionID').on("click", function(){
alert('Click called');
});
}
});
As #davidkonrad pointed out in his answer, the click handler should be removed (using off) to avoid handling the event multiple times.
The DataTables page has a section on this as well: Advanced Initialisation - DOM/jQuery events. The example there uses delegated events.

In backbone.js how do I bind a keyup to the document

I've been following along with a Railscast tutorial of backbone.js and I wanted to extend the functionality to include keyboard control. I added the following to my show view:
class Raffler.Views.EntryShow extends Backbone.View
template: JST['entries/show']
events:
'click .back': 'showListing'
'keyup': 'goBack'
showListing: ->
Backbone.history.navigate("/", trigger: true)
goBack: (e) ->
console.log e.type, e.keyCode
render: ->
$(#el).html(#template(entry: #model))
this
On my show template I have the following:
Back
<%= #entry.get('name') %></td>
If I select the back link using the tab key, then start hitting random keys I get output in my javascript console. However if I load the page and do not select the link and just start hitting keys I get no output in my console.
How do I bind the event to the document so that it will listen to any keys pressed when loading the screen?
You will need to work around backbone's scope for views.
when you are doing something like this:
events:
'click .back': 'showListing'
'keyup': 'goBack'
you are binding your goBack function to the keyup event raised on your container element of your view. (by default the div in which the view is rendered)
instead of doing that, if you want to bind to something outside your view (which doesn't have it's own view!(*))
Raffler.Views.EntryShow = Backbone.View.extend({
template: JST['entries/show'],
events: {
'click .back': 'showListing'
},
initialize: function () {
$('body').keyup(this.goBack);
},
showListing: function () {
Backbone.history.navigate("/", trigger: true);
},
goBack: function (e) {
console.log e.type, e.keyCode;
},
render: function () {
$(this.el).html(this.template(entry: #model));
return this;
}
});
(*)remark as marked above, you best do this only when the item you want to bind to does not have it's own view, if you have a view for your full page (an app view or something like that) you could bind the keyup in there, and just raise an event App.trigger('keypressed', e); for example.
you can then in your EntryShow view, bind to that App's keypressed event.
App.bind('keypressed', goBack);
keep in mind that you should do something as a delayed event or grouping keypresses together in some situations, as firing every keypress that happens in the body, might be a big performance hit. especially on older browsers.
Your events will be scoped to your view element #el. To capture events on the document, you have to roll that yourself:
initialize: ->
$(document).on "keyup", #goBack
remove: ->
$(document).off "keyup", #goBack
Should do the trick.

extjs 4 grid fireevent itemclick

How do you make a fireEvent itemclick after the store loads.
I have this but it doesn't work:
pcfstore.on('load', function(){
//auto select first row;
Ext.getCmp('pcf_grid').getSelectionModel().select(0); // this works
//fire itemclick event
var grid= Ext.getCmp('pcf_grid');
grid.fireEvent('itemclick', grid, 0); //this doesnt work
});
Here is my itemclick event in grid view:
viewConfig: {
listeners: {
itemclick: function(dv, record, item, index, e) {
alert(record.data.code);
}
}
}
Basically when the grid loads, it should fire the alert window of the selected first row
of the grid.
itemclick is event of View but not of Grid. Try to use:
grid.getview().fireEvent('itemclick', grid, 0);
And by the way why not use selectionchange instead.
UPDATE
If you have both itemcontextmenu and selectionchange handlers it can be a little bit confusing. In this case I recommend back to square one and use itemclick event.
But your code need to have some modifications:
Assign itemclick event to grid, NOT to it's view.
When firing itemclick pass actual record, NOT an index
like this:
grid.getSelectionModel().select(0);
grid.fireEvent('itemclick', grid, grid.getSelectionModel().getLastSelected());
And here is fiddle to demonstrate what I'm talking about.
After hours of search, I found a solution. It looks like there is an issue with ExtJs4 that make the following functions impossible to work for me:
grid.getSelectionModel().select(0);
or
grid.getView().select(0); // note that this function is deprecated in ExtJS4!!
In my controller, I use this code instead:
store.load({
callback: function (records, operation, success) {
var rowIndex = this.find('id', myRecord); //where 'id': the id field of your model. You can replace 'id' with your unique field.. And 'this' is your store.
grid.getView().select(rowIndex);
}
})
Where myRecord is the record to highlight and select.
It then worked like a charm. I got the row 0 highlighted and selected. However, the itemclick listeners were not fired when the row is select with this code.