Change settings in modern jQuery DataTables after initialization - jquery-plugins

I'm using new version of DataTables ( www.datatables.net, not a legacy.datatables.net ). I have initial scrollY value, and want to change it on some events.
I tried all approaches I can imagine, but none of them worked (please check out this jsFiddle):
var dt = $('#example').DataTable({
scrollY: "200px",
});
$('#resize').click(function() {
// Doesn't affect anything
dt.settings({
scrollY: "100px",
});
// TypeError: Cannot read property 'sY' of undefined
dt.settings().oScroll.sY = "100px";
// TypeError: undefined is not a function
// http://datatables.net/reference/api/ doesn't work as described :(
dt.Api();
// To redraw table after
dt.draw();
});
There are two very confusing things:
First: Api object can't be created, as it described in documentation:
$('#example').DataTable().Api(); // undefined is not a function
Second: I can see needed field in designer, but can't access it by name (other fields in first request were cropped by me):
I don't know, how it is even possible.

Related

Getting window.checkout.quoteData or store code are undefined error when cart item count updated using ajax

I have created a custom page with free text ordering functionality and called custom add to cart API to add items to the cart.
Once the item is added I need to update the cart item count with updated quantity. I tried to use
require([
'jquery',
'Magento_Checkout/js/action/get-totals'
], function ($, getTotalsAction) {
'use strict';
var deferred = $.Deferred();
getTotalsAction([], deferred);
});
But It is throwing error:
Uncaught TypeError: Cannot read property 'quoteData' of undefined at quote.js:34
And
url-builder.js:12 Uncaught TypeError: Cannot read property 'storeCode' of undefined at url-builder.js:12
Anything missing here?
I referred https://magento.stackexchange.com/questions/210517/error-javascript-define-magento2-window-checkout-quotedata-or-store-code-are-u which doesn't have any working solutions.
The issue is that quoteData lives in window.checkoutConfig - this data will only be set on the checkout pages, you won't have many of required js the modules loaded on a custom page that set this data correctly.
this may be a useful read: https://www.yireo.com/blog/2017-08-20-do-not-depend-on-window-checkoutconfig
I was able to achieve this for my scenario using the below code. It might help someone
require([
'Magento_Customer/js/customer-data'
], function (customerData) {
var sections = ['cart'];
customerData.invalidate(sections);
customerData.reload(sections, true);
});

BackboneJS calling a views render function from an event bound to a collection

RoomsDGView = Backbone.View.extend({
collection: roomcollection,
initialize: function(){
var template = _.template( $("#search_template").html(), {} );
this.$el.html( template );
this.collection.bind('add', this.modeladded);
this.collection.bind('remove', this.modelremoved);
this.collection.bind('change', this.collectionchanged);
console.log(this);
this.render();
},
render: function(){
// Compile the template using underscore
console.log("running the render function...");
//renderrender();
/*$("#roomsList").jqGrid('clearGridData');
roomcollection.each(function (room,i){
var temp = jQuery.parseJSON(JSON.stringify(room));
$("#roomsList").jqGrid('addRowData', i,{idrooms: temp["idrooms"], roomname: temp["roomname"],
occupants: temp["occupants"]});
});*/
},
events: {
"click input[type=button]": "doSearch"
},
doSearch: function(){
// Button clicked
console.log(this);
},
modeladded: function() {
console.log("room added...");
$("#roomsList").jqGrid('clearGridData');
//My intent is to call the views render function
//her. I tried using this.render() and also
//this.collection.bind('add', this.modeladded(this));
//modeladded: function(view) {
// view.render();
console.log(this);
},
modelremoved: function() {
console.log("room removed...");
$("#roomsList").jqGrid('clearGridData');
},
collectionchanged: function() {
console.log("room changed...");
$("#roomsList").jqGrid('clearGridData');
}
});
I have tried many different ways to call the views render: method from inside the code for modeladded:. Use of this.render inside model added shows that the this object at that point has no render function. I also tried passing the view in something like:
this.collection.bind('add', this.modeladded(this));
modeladded: function(view) {
view.render();
which also leads to a console error that no render() can be found. Does anyone know how to call the views render: from inside modeladded?
For the time being I moved the render function out of the views render: and into a JavaScript function declared renderGlobal() declared in global scope and I know it does work that way but I don't think that is really the backbone.js way.
This is the error that is coming out of the console:
Uncaught TypeError: Object [object Object] has no method 'render'
Thank you for posting....
You're binding your event handler using bind (AKA on):
this.collection.bind('add', this.modeladded);
But, as usual with JavaScript, the value of this inside a function depends on how the function is called, not how it is defined (ignoring bound functions of course). You're not specifying a specific this for your function anywhere so you're not getting any particular this when it is called. If you give bind the third context argument:
this.collection.bind('add', this.modeladded, this);
// ------------------------------------------^^^^
then Backbone will call modeladded with the specific this and you'll find that this inside modeladded will be your view.
You could also use _.bind, Function.prototype.bind, or $.proxy to produce a bound version of your callback:
this.collection.bind('add', _(this.modeladded).bind(this));
this.collection.bind('add', this.modeladded.bind(this));
this.collection.bind('add', $.proxy(this.modeladded, this));
All of those produce new functions so you won't be able to unbind them without stashing the bound functions somewhere. You'll usually avoid using these when you have the option to specify the context (AKA this) explicitly.
There's also listenTo:
listenTo object.listenTo(other, event, callback)
Tell an object to listen to a particular event on an other object. The advantage of using this form, instead of other.on(event, callback, object), is that listenTo allows the object to keep track of the events, and they can be removed all at once later on. The callback will always be called with object as context.
So you can (and should) say this:
this.listenTo(this.collection, 'add', this.modeladded);
That will take care of giving you the desired this and makes it easier to clean up your event handlers when you're done with them. Similarly for the other event handlers you're using.

Backbone Marionette - Uncaught TypeError: Cannot call method 'show' of undefined

I know that the error is generated by jQuery. Is there any way I can structure a backbone.marionette application to avoid the below error?
Uncaught TypeError: Cannot call method 'show' of undefined
The error occurs because I create a Layout, which has regions. In the onRender function I load a collection and execute fetch. When the fetch is complete, I populate the region. If I switch to a different view, the error is triggered because of self.content.show which no longer exists.
var view = Marionette.Layout.extend({
template: _.template(tplPage),
className: 'customers-view',
regions:{
content: '.customers-content'
},
onRender: function(){
var self = this,
colCustomers = new ColCustomers();
colCustomers.fetch({success: function(){
self.content.show(new ViewCustomersList({collection: colCustomers}));
}});
}
});
NOTE: At the moment I wrap self.content.show() in a try catch and its working. Ideally I avoid that.
Modify the onRender function and listen for the fetch differently.
onRender: function(){
var colCustomers = new ColCustomers();
this.listenTo(colCustomers, "sync", function () {
this.content.show(new ViewCustomersList({collection: colCustomers}));
});
colCustomers.fetch();
}
What I did was change the approach to binding the event listener. By using the listenTo function from Backbone.Events, you get handlers that are cleaned up for free when the listener object dies.

"Cannot call method 'getColumns' of undefined " on FiltersFeature of LiveSearchGridPanel ExtJS

im getting the Uncaught TypeError: Cannot call method 'getColumns' of undefined when clicking on the header toolbar of a Live Serach Grid Panel on ExtJS. Im implementing filters with the Filters Feature.
Heres some of my code:
Ext.require([
'Ext.grid.*',
'Ext.ux.grid.FiltersFeature',
'Ext.ux.LiveSearchGridPanel'
...
]);
var filters = {
ftype: 'filters',
encode: false,
local: true
};
var grid = new Ext.create('Ext.ux.LiveSearchGridPanel', {
selType: 'cellmodel',
store: store,
columns:[
{
header: "Evento",
width: 90,
sortable: true,
filterable: true,
dataIndex: 'RH_DESCRIPCION',
filter: {
type: 'string'
}
}],
features: [filters]
...
This is the block of code where the exception occurs:
Ext.Array.each(grid.columnManager.getColumns(), function (column) {
//Uncaught TypeError: Cannot call method 'getColumns' of undefined
if (column.filterable === false) {
filters.removeAtKey(column.dataIndex);
} else {
add(column.dataIndex, column.filter, column.filterable);
}
});
Any help will be appriciated!
After doing heavier debugging it seems that grid.columnManager isn't very well supported on version 4.2. For any others with the same issue you should use:
grid.down('headercontainer').getGridColumns();
or
grid.down('headercontainer').getVisibleGridColumns();
to get a hold of columns on your grid. I believe this won't work with grouped columns, I've not tested it though.
Ext.Array.each(grid.columnManager.getColumns(), function (column) ...
change to
Ext.Array.each(grid.columns, function (column) {
it works well :)
grid.columns is not a supported/public property. It might not contain, for example, columns added with reconfigure. It will contain them if you use 4.2.0, but not in 4.2.1/4.2.2. This will happen even if you add Ext.selection.CheckboxModel, the checkbox column will not be included there in 4.2.2 and you will end up with "index mismatch" if you get the index from, lets say cellClick event.
Unfortunately, grid.columnManager or grid.getColumnManager() is new in 4.2.1/4.2.2 and it is a private property/method. Shortly speaking, either of those might stop working with next releases of ExtJS, and "columns" property is not reliable in all cases.
See some discussion here:
http://www.sencha.com/forum/showthread.php?277525
I haven't found any officially supported solution yet. I can't add comments, so I had to publish this as a full answer, thanks S.O.!
As others already posted, you should not use the columnManager property. Check Sencha's note about it:
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.grid.ColumnManager
This is a private utility class for internal use by the framework.
Don't rely on its existence.
I think the best option is to use this for all columns:
grid.headerCt.getGridColumns()
And this if you only need the visible columns:
grid.headerCt.getVisibleGridColumns()

prototype get inner html of multiple classes

I am new to prototype and finding it a lot more difficult than jquery. All i want to do is get the inner html of various classes.
$$('.book').each(function() {
var msg = this.down(".information");
alert(msg.innerHTML);
//new Tip(this, msg.innerHTML, {stem: 'topLeft', hook: { tip: 'topLeft', mouse: true }, offset: { x: 14, y: 14 }});
});
I'm trying to create tooltips for multiple items, but I'm not even getting the alert.
I think you can probably prevent the extra dom work of down() like this:
$$('.book .information').each(function(book) {
alert(book.innerHTML);
});
remember you also have the ability to use advanced CSS2 and CSS3 selectors in prototype like this for example:
$$('.book a[rel]').each(function(el) {
alert(el.rel);
});
see the bottom of this page for more examples http://www.prototypejs.org/api/utility/dollar-dollar
The this variable is not pointing to the element you're iterating over in Prototype, you have to explicitly use a parameter:
$$('.book').each(function(book) {
var msg = book.down(".information");
alert(msg.innerHTML);
});

Resources