I have a nearly-vanilla Phoenix setup in which I want to use select2[1]. I have bootstrap and jquery configured by means of bower. The front-end is bootstrap 4 and it all works great, so that's covered. See my bower config below.
The steps I tried are the following.
I have created a minimal working example in HTML from the website of select2, and included the js and css via a CDN. This all worked.
I have installed select2 via npm using npm install --save select2.
I have verified that the select2 data is present in my http://localhost:8000/js/app.js.
I have added the script needed to execute select2 on the option list (see below). I have added this below my import of app.js.
When I navigate to the page I have the minimal working example on (the homepage), I see this error in the console:
jQuery.Deferred exception: $(...).select2 is not a function #http://0.0.0.0:4000/:85:9
mightThrow#http://0.0.0.0:4000/js/app.js:7638:21
resolve/</process<#http://0.0.0.0:4000/js/app.js:7706:12
undefined jquery.js:3822
[Show/hide message details.] TypeError: $(...).select2 is not a function[Learn More]
I admit, I have no clue how this all works, as my knowledge is all focussed on backend related tasks. The entire codebase is on github as well [2].
Any help would be appreciated.
Relevant part of app.html.eex
<script src="<%= static_path(#conn, "/js/app.js") %>"></script>
<script>
$(document).ready(function() {
$('.js-example-basic-single').select2();
});
</script>
Html added to layout.html.eex
<select class="js-example-basic-single" name="state">
<option value="AL">Alabama</option>
<option value="WY">Wyoming</option>
</select>
brunch-config.js
exports.config = {
// See http://brunch.io/#documentation for docs.
files: {
javascripts: {
joinTo: "js/app.js"
},
stylesheets: {
joinTo: "css/app.css",
order: {
after: ["css/app.css"] // concat app.css last
}
},
templates: {
joinTo: "js/app.js"
}
},
conventions: {
assets: /^(static)/
},
// Phoenix paths configuration
paths: {
// Dependencies and current project directories to watch
watched: ["static", "css", "js", "vendor", "scss", "fonts"],
// Where to compile files to
public: "../priv/static"
},
// Configure your plugins
plugins: {
babel: {
// Do not use ES6 compiler in vendor code
ignore: [/vendor/]
},
sass: {
native: true,
options: {
includePaths: ["node_modules/bootstrap/scss", "node_modules/font-awesome/scss"], // Tell sass-brunch where to look for files to #import
precision: 8 // Minimum precision required by bootstrap-sass
}
},
copycat: {
"fonts" : ["static/fonts", "node_modules/font-awesome/fonts"],
verbose : false, //shows each file that is copied to the destination directory
onlyChanged: true //only copy a file if it's modified time has changed (only effective when using brunch watch)
}
},
modules: {
autoRequire: {
"js/app.js": ["js/app"]
}
},
npm: {
enabled: true,
globals: {
select2: 'select2',
$: 'jquery',
jQuery: 'jquery',
Tether: 'tether',
Popper: "popper.js",
bootstrap: 'bootstrap'
}
}
};
[1] https://select2.org/
[2] https://github.com/m1dnight/gymlog/tree/frontend_crap
Related
I updated my phoenix 1.2 to 1.3 follwing the phoenix upgrade description.
Now assets/js/app.js can't be loaded:
Uncaught Error: Cannot find module 'js/app' from '/'
After debugging the problem, I found that the expected module is app not js/app.
When I change the module name in the brunch-config.js autoRequire modules to ["app"] instead of ["js/app"] it works. I don't understand what is the problem or what I did in my app, that the default settings don't work.
Here my assets/brunch-config.js
exports.config = {
// See http://brunch.io/#documentation for docs.
files: {
javascripts: {
joinTo: "js/app.js"
},
stylesheets: {
joinTo: "css/app.css",
order: {
after: ["../priv/static/css/app.css"] // concat app.css last
}
},
templates: {
joinTo: "js/app.js"
}
},
conventions: {
assets: /^(static)/
},
// Phoenix paths configuration
paths: {
// Dependencies and current project directories to watch
watched: ["static", "css", "js", "vendor"],
// Where to compile files to
public: "../priv/static"
},
// Configure your plugins
plugins: {
babel: {
// Do not use ES6 compiler in vendor code
ignore: [/vendor/]
},
copycat: {
"fonts": ["node_modules/font-awesome/fonts"] // copy node_modules/font-awesome/fonts/* to priv/static/fonts/
},
sass: {
options: {
includePaths: [
"node_modules/bootstrap-sass/assets/stylesheets",
"node_modules/font-awesome/scss"
], // tell sass-brunch where to look for files to #import
precision: 8 // minimum precision required by bootstrap-sass
}
}
//sass: {
// mode: "native" // This is the important part!
// },
},
modules: {
autoRequire: {
"js/app.js": ["js/app"]
}
},
npm: {
enabled: true,
globals: {
$: 'jquery',
jQuery: 'jquery'
}
}
};
And my assets/js/app.js is here:
import "phoenix_html"
import "./datetimepicker"
thanks for any help, tipps or ideas to understand/solve the problem.
The problem is related to the brunch version.
updating brunch to:
brunch#2.10.10
solved the problem.
I am try use Ember 2.0 and have next files
config.js
System.config({
"baseURL": "/static/js",
"transpiler": "traceur",
"paths": {
"*": "*.js",
"github:*": "jspm_packages/github/*.js"
}
});
System.config({
"map": {
"ember": "github:components/ember#2.0.0",
"traceur": "github:jmcriffey/bower-traceur#0.0.88",
"traceur-runtime": "github:jmcriffey/bower-traceur-runtime#0.0.88",
"github:components/ember#2.0.0": {
"jquery": "github:components/jquery#2.1.4",
"handlebars": "github:components/handlebars#1.3.0"
}
}
});
app.js
import Ember from "ember";
let App = Ember.Application.create({
LOG_TRANSITIONS: true,
LOG_TRANSITIONS_INTERNAL: true,
});
and index.html
<script src="{% static "js/jspm_packages/system.js" %}"></script>
<script src="{% static "js/config.js" %}"></script>
<script>
System.import('app');
</script>
aftre load i have next error
Uncaught (in promise) Error: Cannot read property 'Ember' of undefined
Error loading http://localhost:9090/static/js/app.js
at http://localhost:9090/static/js/jspm_packages/github/components/ember#2.0.0/ember.js!transpiled:16:38
at http://localhost:9090/static/js/jspm_packages/github/components/ember#2.0.0/ember.js!transpiled:97:11
at execute (http://localhost:9090/static/js/jspm_packages/github/components/ember#2.0.0/ember.js!transpiled:25603:9)
at m (http://localhost:9090/static/js/jspm_packages/system.js:4:20821)
at m (http://localhost:9090/static/js/jspm_packages/system.js:4:20756)
at m (http://localhost:9090/static/js/jspm_packages/system.js:4:20756)
at Object.Promise.all.then.execute (http://localhost:9090/static/js/jspm_packages/system.js:4:23421)
at b (http://localhost:9090/static/js/jspm_packages/system.js:4:7874)
at S (http://localhost:9090/static/js/jspm_packages/system.js:4:8253)
at p (http://localhost:9090/static/js/jspm_packages/system.js:4:6131)
if load scripts without systemjs and jspm always work. but want use jspm and systemjs :)
Before i use ember 1.13 and with config worked. I think problem with config jquery
It looks like the package for Ember is not always jspm-compatible. I always use the following override in my package.json:
"jspm": {
"overrides": {
"github:components/ember#2.0.0": {
"main": "ember.debug",
"files": [
"ember.prod.js",
"ember.debug.js"
],
"dependencies": {
"jquery": "github:components/jquery#^2.1.3"
},
"shim": {
"ember.prod": {
"deps": [
"jquery"
],
"exports": "Ember"
},
"ember.debug": {
"deps": [
"jquery"
],
"exports": "Ember"
}
}
}
}
}
It dictates jspm to install only prod and debug versions of Ember and describes all dependencies and exports properly. If you use it, you need to run jspm install again after you added it to your package.json.
You may encounter another problem with htmlbars templates. I have got a plugin to solve that: https://github.com/n-fuse/plugin-ember-hbs:
jspm install hbs=github:n-fuse/plugin-ember-hbs#2.0.0
should allow importing hbs templates w/o the need to add a compiler in dependencies.
See also a starter project I created: https://github.com/OrKoN/jspm-ember-playground
I'm working on a project using requirejs and I'm trying to optimize my javascript into two files: vendor libraries and app code. Unfortunately, I can't seem to get it to work.
Folder structure:
backbone_components/
app/
less/
js/
component1/
component2/
layouts/
dashboard/
about/
lib/
config.js
main.js
index.html
dist/
Gruntfile.js
config.js:
require.config({
baseUrl: '../js/',
paths: {
jquery: '../../bower_components/jquery/dist/jquery',
underscore: '../../bower_components/lodash/dist/lodash',
backbone: '../../bower_components/backbone/backbone',
text: '../../bower_components/requirejs-text/text'
},
enforeceDefine: true
});
define(['backbone', 'main'], function(Backbone, app) {
});
Gruntfile.js:
requirejs: {
options: {
dir: 'dist/js/',
mainConfigFile: 'app/js/config.js',
optimize: 'none',
normalizeDirDefines: 'all',
skipDirOptimize: true
},
dist: {
options: {
modules: [
{
name: 'vendor',
include: ['jquery', 'underscore', 'backbone', 'text'],
},
{
name: 'app',
exclude: ['vendor']
}
]
}
}
});
When I run grunt, I get the following error: "Error: Error: ERROR: module path does not exist: /path/to/project/app/js/app/js/vendor.js for module named: vendor."
Why is it looking for "vendor" when it doesn't exist yet?
I take it that you have no module named vendor in the source you want to optimize. If this is correct, then the error you are getting is because r.js is looking for a module named vendor. You have to tell it to create it with the create option:
modules: [
{
name: 'vendor',
create: true, // <--- Add this option!
include: ['jquery', 'underscore', 'backbone', 'text']
},
{
name: 'app',
exclude: ['vendor']
}
]
Without the option r.js understands you to be effectively saying "take the vendor module and include with it jquery, etc." With the option, you are telling it to create vendor from scratch.
The create option is documented in this file.
Is there a way to generate pages from json/yaml if you provide a layout? I thought this was possible, but can't find in docs.
This is currently being tracked here in GitHub: http://webb.li/QjTX
Since the options.pages feature has been implemented, you can add pages like this:
options: {
pages: {
"about": {
"data": {
"title": "About"
},
"content": "Content for {{title}}"
},
...
}
}
We aren't supporting automatic loading of a json/yml file, but you can do this inside your Gruntfile and add the object to options.pages that way...
module.exports = function(grunt) {
grunt.initConfig({
// package.json
pkg: grunt.file.readJSON('package.json'),
assemble: {
options: {
flatten: true,
layoutdir: 'src/layouts',
assets: 'dest/assets'
},
blog: {
options: {
engine: 'handlebars',
layout: 'post.hbs',
site: {
title: 'This is my Blog'
},
pages: grunt.file.readJSON('pages.json')
},
files: { 'dest/': ['src/index.hbs'] }
}
}
});
// Load npm plugins to provide necessary tasks.
grunt.loadNpmTasks('assemble');
// Default task.
grunt.registerTask('default', ['assemble']);
};
This example uses the post.hbs file as the layout for any pages defined in the pages.json file. It will also build a page for the index.hbs specified in the files src array. Right now, the files dest/src is required so Assemble knows where to write the files, but I think we'll add that to the options, or the page object so it can be run without the files object.
I'm trying to optimize RequireJS using GruntJS, using the grunt-contrib-requirejs plugin.
The problem is my code works fine before optimizing it, and then after optimizing it, on the console it says Uncaught ReferenceError: define is not defined.
Here's the Gruntfile.js
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-contrib-requirejs');
grunt.initConfig({
requirejs: {
compile : {
options : {
name : 'main',
baseUrl : ".",
mainConfigFile : "./main.js",
out : "./optimized.js",
preserveLicenseComments: false
}
}
}
})
grunt.registerTask('default', 'requirejs');
}
Adding the require.js file as an "include" option should work.
requirejs: {
compile : {
options : {
name : 'main',
baseUrl : ".",
mainConfigFile : "./main.js",
out : "./optimized.js",
preserveLicenseComments: false,
include: ['path/to/require.js']
}
}
}
As define is a requireJs function it seems you miss to load requireJs or any other AMD loader. If you dont need to load any other AMD module then your complied once, you can use a light weight loader shim like almond.
As pointed out before the requirejs-script is missing.
This is the way the official requirejs-page suggests you do it (ripped from my gruntfile):
requirejs: {
compile: {
options: {
baseUrl: "src/js",
mainConfigFile: 'src/js/require.config.js',
paths: {
requireLib: "vendor/require/require"
},
include: "requireLib",
name: "require.config",
out: "dist/js/bundle.js"
}
}
},
Observe the options paths and include, those are vital for the require to be defined.
Just point the requireLib-option to your require.js-file.
See the official answer here: http://requirejs.org/docs/optimization.html#onejs
It seems that the grunt-contrib-requirejs doesn't compile requirejs in by default. You could use concat to re-add requirejs back in.
concat : {
dist : {
src : ['./optimized.js', 'path/to/requirejs.js'],
dest : './optimized.js'
},
}
grunt.loadNpmTasks('grunt-contrib-concat');