I'm using Webpack Encore with Symfony 3.4 (part of migration to Symfony 4).
I have Datatables (installed via NPM to node_modules) working with jQuery but the api
functions such as .columns
are returning: .column is not a function at
Package Versions:
- jQuery
2.14.4
- Datatables
1.10.19
- Webpack Encore
0.27.0
Webpack app.js:
global.$ = global.jQuery = require('jquery');
require('bootstrap');
global.moment = require('moment');
require('datatables-dt');
$.fn.dataTable = $.fn.DataTable = global.DataTable = require('datatables');
webpack.config.js:
var Encore = require('@symfony/webpack-encore');
Encore
// directory where piled assets will be stored
.setOutputPath('code/web/build/')
// public path used by the web server to access the output path
.setPublicPath('/build')
// only needed for CDN's or sub-directory deploy
//.setManifestKeyPrefix('build/')
.addEntry('site', './assets/js/site/app.js')
// will require an extra script tag for runtime.js
// but, you probably want this, unless you're building a single-page app
.enableSingleRuntimeChunk()
.cleanupOutputBeforeBuild()
.enableSourceMaps(!Encore.isProduction())
// enables hashed filenames (e.g. app.abc123.css)
.enableVersioning(Encore.isProduction())
// unment if you use TypeScript
//.enableTypeScriptLoader()
// unment if you use Sass/SCSS files
//.enableSassLoader()
// unment if you're having problems with a jQuery plugin
//.autoProvidejQuery()
;
module.exports = Encore.getWebpackConfig();
Javascript example in template.html.twig (extends base html file):
{{ encore_entry_script_tags('site') }}
<script type="text/javascript">
$(document).ready(function() {
var $dtable;
$dtable = $('#simpleTable')
.DataTable({
data: data,
deferRender: true,
scrollX: false,
searching: true,
paging: true,
pageLength: 25});
console.log($dtable);
// Error occurs here
var column = $dtable.column(index);
});
</script>
A console log of $dtable
immediately after instantiation outputs the following which seems to confirm an Api instance isn't created?
Is it possible this is related to the DataTable loader that uses the AMD
method due to Webpack?
jquery.dataTables.js:
(function( factory ) {
"use strict";
if ( typeof define === 'function' && define.amd ) {
define( ['jquery'], function ( $ ) {
return factory( $, window, document );
} );
}
else if ( typeof exports === 'object' ) {
module.exports = function (root, $) {
if ( ! root ) {
// CommonJS environments without a window global must pass a
// root. This will give an error otherwise
root = window;
}
if ( ! $ ) {
$ = typeof window !== 'undefined' ? // jQuery's factory checks for a global window
require('jquery') :
require('jquery')( root );
}
return factory( $, root, root.document );
};
}
else {
factory( jQuery, window, document );
}
}
I'm using Webpack Encore with Symfony 3.4 (part of migration to Symfony 4).
I have Datatables (installed via NPM to node_modules) working with jQuery but the api
functions such as .columns
are returning: .column is not a function at
Package Versions:
- jQuery
2.14.4
- Datatables
1.10.19
- Webpack Encore
0.27.0
Webpack app.js:
global.$ = global.jQuery = require('jquery');
require('bootstrap');
global.moment = require('moment');
require('datatables-dt');
$.fn.dataTable = $.fn.DataTable = global.DataTable = require('datatables');
webpack.config.js:
var Encore = require('@symfony/webpack-encore');
Encore
// directory where piled assets will be stored
.setOutputPath('code/web/build/')
// public path used by the web server to access the output path
.setPublicPath('/build')
// only needed for CDN's or sub-directory deploy
//.setManifestKeyPrefix('build/')
.addEntry('site', './assets/js/site/app.js')
// will require an extra script tag for runtime.js
// but, you probably want this, unless you're building a single-page app
.enableSingleRuntimeChunk()
.cleanupOutputBeforeBuild()
.enableSourceMaps(!Encore.isProduction())
// enables hashed filenames (e.g. app.abc123.css)
.enableVersioning(Encore.isProduction())
// unment if you use TypeScript
//.enableTypeScriptLoader()
// unment if you use Sass/SCSS files
//.enableSassLoader()
// unment if you're having problems with a jQuery plugin
//.autoProvidejQuery()
;
module.exports = Encore.getWebpackConfig();
Javascript example in template.html.twig (extends base html file):
{{ encore_entry_script_tags('site') }}
<script type="text/javascript">
$(document).ready(function() {
var $dtable;
$dtable = $('#simpleTable')
.DataTable({
data: data,
deferRender: true,
scrollX: false,
searching: true,
paging: true,
pageLength: 25});
console.log($dtable);
// Error occurs here
var column = $dtable.column(index);
});
</script>
A console log of $dtable
immediately after instantiation outputs the following which seems to confirm an Api instance isn't created?
Is it possible this is related to the DataTable loader that uses the AMD
method due to Webpack?
jquery.dataTables.js:
(function( factory ) {
"use strict";
if ( typeof define === 'function' && define.amd ) {
define( ['jquery'], function ( $ ) {
return factory( $, window, document );
} );
}
else if ( typeof exports === 'object' ) {
module.exports = function (root, $) {
if ( ! root ) {
// CommonJS environments without a window global must pass a
// root. This will give an error otherwise
root = window;
}
if ( ! $ ) {
$ = typeof window !== 'undefined' ? // jQuery's factory checks for a global window
require('jquery') :
require('jquery')( root );
}
return factory( $, root, root.document );
};
}
else {
factory( jQuery, window, document );
}
}
Share
Improve this question
asked Apr 15, 2019 at 10:15
DanDan
12.1k14 gold badges55 silver badges117 bronze badges
0
4 Answers
Reset to default 5 +100The AMD loader may be a problem here,
Can you try to disable AMD Loader it to see if it work :
var config = Encore.getWebpackConfig();
config.module.rules.unshift({
parser: {
amd: false,
}
});
module.exports = config;
Otherwise you could try to make it work with AMD Loader : First install DataTables :
npm install datatables
Then DataTables style (bootstrap) :
npm install datatables-bs
Then the imports-loader plugin
Modify your webpack.config.js to make an exception for datatables:
module: {
loaders: [
{
test: /datatables\.*/,
loader: 'imports?define=>false'
}
]
}
Now you should be able to use DataTables :
import 'datatables';
import dt from 'datatables-bs';
dt(window, $);
//And now use it
$('#exampleDatatable').DataTable();
The issue I see is with line:
$.fn.dataTable = $.fn.DataTable = global.DataTable = require('datatables');
dataTable()
and DataTable()
are not equivalent.
The correct functions will be added to Jquery by the factory, no need to set these. Actually, if I can guess, the above code will overwrite DataTable()
with dataTable()
.
Change to:
require('datatables');
It should work.
Maybe it's a stupid idea ... but what is the data
value in your template-defined call $('#simpleTable').DataTable({data:data, ...})
call?
According to docs (3rd paragraph) setting the data
option (even with an empty value) will override the data from the table. If your value data
is undefined, this might turn your data-rich table into a vegetable in the eyes of DataTable
.
I assume that your table is fine, the module is loaded fine, ... so the data might be the problem ...
If, however, it does contain useful data, would you mind posting some example of it? ;o)
The DataTables documentation for using with NPM show that the export is a function that returns the DataTable API.
var dt = require( 'datatables' )(); // N.b. the extra parenthesis.
So it's likely you'd need to alter your global assignment; something like this might work:
$.fn.dataTable = $.fn.DataTable = global.DataTable = require('datatables')(); // N.b. the extra parentheses.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745064729a4609186.html
评论列表(0条)