I want to use form2js to convert a form's info to json to post. The problem is, the framework I am using uses require.js and it seems like I am not linking the form2js file with the requirejs config properly. I am getting an
Uncaught ReferenceError: form2js is not defined
error.
form2js is a function within the form2js.js file.
Here is the config file:
require.config({
baseUrl: "assets/js/lib/"
, shim: {
'backbone': {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
'underscore': {
exports: '_'
},
'bootstrap': {
deps: ['jquery'],
exports: '$.fn.popover'
},
'form2js': {
exports: 'form2js'
}
}
, paths: {
app : ".."
, collections : "../collections"
, data : "../data"
, models : "../models"
, helper : "../helper"
, templates : "../templates"
, views : "../views"
}
});
require([ 'app/app'], function(app){
app.initialize();
});
And in the main html page I run this:
<script data-main="assets/js/main.js" src="assets/js/lib/require.js" ></script>
Any guidance to the right resources would be very appreciated!
Including form2js in require.config just tells it where to find the form2js module (and other information, like it's dependencies, etc.)
To actually load form2.js you have (and hence define the form2js global), you have to list it as a dependency in the module where you are using it.
For example assuming your initialize() function uses it, your last statement would be
require([ 'app/app', 'form2js' ], function(app){
app.initialize();
});
Note - if app/app.js uses form2js, you have to include it in the define for that module. You might also want to check (in your browser developer tools network tab if form2.js was actually loaded, once you list it as a dependency somewhere)
Related
Require.js loads every module on every page, so I get JavaScript errors on pages that don't need the loaded scripts. Specifically, the news-filter.js is loading on my search page, and causing the error:
jquery-1.12.3.min.js:2 Uncaught Error: Syntax error, unrecognized expression: "li." from this line in the news-filter.js
$("ul.mediaListing").children("li."+chosenYear).filter("."+chosenCategory).each(function(c) {
Am I missing somthing about how reqire.js determines what scripts are needed on each page?
My main.js file is:
requirejs.config({
baseUrl: [system-view:internal]"/render/file.act?path=/assets/scripts/"[/system-view:internal] [system-view:external]"/assets/scripts/"[/system-view:external],
paths: {
"jquery": "libs/jquery/jquery-1.12.3.min",
"velocity": "libs/velocity/velocity",
"bgstretch": "plugins/background-stretch/background-stretch",
"campus-map": "modules/campus-map",
"velocity-ui": "libs/velocity/velocity.ui",
"slick": "plugins/slick/slick",
"iscroll": "plugins/iscroll/iscroll",
"dotdotdot": "plugins/dotdotdot/jquery.dotdotdot.min.umd",
"select": "plugins/select/select",
"accordion": "modules/accordion",
"news-filter": "modules/news-filter",
"codebird": "modules/codebird",
"social-feed": "modules/social-feed"
},
shim: {
"slick": ["jquery"],
"select": ["jquery"],
"bgstretch": {
deps: ["jquery"]
},
"accordion": ["jquery"],
"codebird": ["jquery"],
"social-feed": {
dep: ["jquery", "codebird"],
exports: "displayFeed"
},
"campus-map": {
deps: [ "jquery" ]
},
"velocity": {
deps: [ "jquery" ]
},
"velocity-ui": {
deps: [ "velocity" ]
}
},
map: {
'*': {
'jQuery': 'jquery'
}
}
});
requirejs(
['jquery', 'modules/utils', 'modules/custom.ui', 'libs/jquery/paginga.jquery', "modules/social-feed", "modules/news-filter"],
function ($, utils, ui, paga, social, news) {
ui();
$(".paginate").paginga({
// use default options
});
});
I like a very modular approach and RequireJS has a lot of different ways to use it. I'll share how I typically have it set up which accomplishes what you are looking for, is streamlined and makes it easy to implement and understand.
I avoid having anything require in my main js completely. First I will create a bundle that includes both the base require.js and a JS file I create called config.js. I will have this bundle loaded in my layout page so it's always available. If you aren't using MVC, the idea is just to make sure Require and my custom config file are always loaded together and always available so do what you need to for that.
Config.js is very simple, in your case just taking your code it will look like this:
var require = {
baseUrl: [system-view:internal]"/render/file.act?path=/assets/scripts/"
[/system-view:internal] [system-view:external]"/assets/scripts/"[/system-
view:external],
paths: {
"jquery": "libs/jquery/jquery-1.12.3.min",
"velocity": "libs/velocity/velocity",
"bgstretch": "plugins/background-stretch/background-stretch",
"campus-map": "modules/campus-map",
"velocity-ui": "libs/velocity/velocity.ui",
"slick": "plugins/slick/slick",
"iscroll": "plugins/iscroll/iscroll",
"dotdotdot": "plugins/dotdotdot/jquery.dotdotdot.min.umd",
"select": "plugins/select/select",
"accordion": "modules/accordion",
"news-filter": "modules/news-filter",
"codebird": "modules/codebird",
"social-feed": "modules/social-feed"
},
shim: {
"slick": ["jquery"],
"select": ["jquery"],
"bgstretch": {
deps: ["jquery"]
},
"accordion": ["jquery"],
"codebird": ["jquery"],
"social-feed": {
dep: ["jquery", "codebird"],
exports: "displayFeed"
},
"campus-map": {
deps: [ "jquery" ]
},
"velocity": {
deps: [ "jquery" ]
},
"velocity-ui": {
deps: [ "velocity" ]
}
},
map: {
'*': {
'jQuery': 'jquery'
}
}
};
That's it. I tend to have all of my javascript files associated to each HTML page separated, so in the paths section of the set up I'll have the view name and then the location in my source of the corresponding javascript file. Then in my HTML page when I'm adding in scripts, I'll simply state
<script> require(['sign-in']); </script>
This will grab the script file I have defined in the require variable for my view. Then in each script file, sign-in.js for example for this one, I will wrap all of the scrip in a define statement, so at the top of each JS file you can clearly see what dependencies you will load and use in that page. It's clean, it's a framework, it works wonderfully, and it keeps you from loading things you don't need.
In the self contained JS file you would do:
define(['jquery', 'lodash', 'bootstrap'], function ($, _) {
//All JS code here
}):
I will have all my libraries that need a selector defined first and then everything else after. That's it, hopefully a real example will help you.
Am I missing somthing about how reqire.js determines what scripts are needed on each page?
Sure looks like you are. You show a main.js file that has this (reformatted to help readability):
requirejs(['jquery', 'modules/utils', 'modules/custom.ui',
'libs/jquery/paginga.jquery', "modules/social-feed",
"modules/news-filter"],
If you use this main.js on all your pages, then all the modules you list there are going to be loaded, which means that modules/news-filter is going to be loaded on all pages. This, irrespective of whether any code actually uses it.
The way RequireJS works, any dependency listed in a require call is loaded. And for each module loaded, any dependency they list in their define call or in a shim set for them in your configuration is also loaded. It does not matter one bit if something is listed but not actually used by your code.
Tangential remark about your configuration. In your paths you have:
"news-filter": "modules/news-filter"
But then you refer to it as modules/news-filter in your require call instead of news-filters. You should use news-filter or remove the mapping you've set in paths. RequireJS does now allow referring to the same JavaScript file through two different module names in the same context. If you load your module as modules/news-filter in one place and as news-filter somewhere else, you're going to run into problems.
If you need to use two different names to access the same JavaScript file, you use map. What map does is tell RequireJS "when you get a request for module X, load module Y instead". So RequireJS replaces the module name requested with a different one.
I'm trying to load textext.js jquery plugin, with one of it's plugins, textext tags. On my project, I'm using require.js in order to load all scripts with it's dependencies.
As used for other scripts, I'm using a shim config on my main.js file:
main.js
require.config({
shin: {
jquery: {
exports: '$'
},
'textext': {
deps: ['jquery'],
exports: '$.fn.textext'
},
'textext_tags': {
deps: ['jquery', 'textext'],
}
},
paths: {
jquery: 'lib/jquery-min',
textext: 'lib/textext/textext.core',
textext_tags: 'lib/textext/textext.plugin.tags',
}
});
On the page that I use it, I call it as above:
file-app.js
define([
'jquery',
'textext',
'textext_tags',
], function($, Textext, TextextTags) {
// do stuff
});
The code is loading and working correctly on firefox, but on Chromium, sometimes (about 2/3 of the times), at the first time that I load the page, I've receive the following error, that broke the functioning of the page:
TypeError: Cannot set property 'TextExtTags' of undefined
#3 localhost/js/lib/textext/textext.plugin.tags.js:23:27
Inside the file textext.plugins.tags.js, we have at line 23 (the failure line):
$.fn.textext.TextExtTags = TextExtTags;
So, inspecting it with Firebug, I realize that Jquery is not loaded, so $ and $.fn is undefined.
My question is: why this schema of require.js is working with other jQuery plugins on the same project (like jquery cookie and others), but not with this, a jquery plugin with it's subplugins?
As Vishwanath said, only changing from "shin" to "shim" worked, like above:
require.config({
shim: {
jquery: {
exports: '$'
},
...
Thanks!
I am learning backbone.js and use require.js to make a modular app.
I've got it working on every browser except IE8 where I get some major errors and a blank, white page.
Here is the link to the app, open it in IE8 and see the error.
I have no idea what to do, I have searched and searched and I need help in making it work.
Any ideas?
Here are the errors:
SCRIPT445: Object doesn't support this action
jquery.min.js, line 4 character 29137
SCRIPT5007: Object expected
backbone-min.js, line 1 character 17010
And here is my main.js file:
// file: main.js
require.config({
paths: {
"jquery" : "http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min",
"underscore" : "http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min",
"backbone" : "http://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.0/backbone-min",
"text" : "http://cdnjs.cloudflare.com/ajax/libs/require-text/2.0.10/text"
},
shim: {
underscore: {
exports: '_'
},
backbone: {
deps: ["underscore", "jquery"],
exports: "Backbone"
},
text : {
exports : 'text'
}
}
});
require(['app'], function (App) {
App.initialize();
});
You're using jQuery 2.x, which does not support IE8. Try using jQuery 1.10 instead. Details on jquery..com
I'm having a lot of troubles with RequireJS, I get errors simply by using a define module.
Let's assume I have this configuration:
require.config({
baseUrl: "js/",
paths: {
jquery: "libs/jquery/jquery-2.0.2.min",
handlebars: "libs/backbone/template/handlebars",
lodash: "libs/backbone/template/lodash.min",
backbone: "libs/backbone/backbone-1.0.0.min",
helper:"app/helper",
jquery_cookie:"libs/jquery/plugin/jquery.cookie",
text:"libs/require/text-2.0.7"
},
shim: {
"lodash": {
exports: '_'
},
"handlebars": {
deps:["jquery"],
exports: 'Handlebars'
},
"backbone": {
deps: ["helper", "lodash", "handlebars", "jquery"],
exports: "Backbone"
}
},
urlArgs: "bust=" + (new Date()).getTime()
});
define(["jquery"], function ($) {
console.log('define "jquery" on config.js');
return $;
});
console.log("end config.js");
First, I've tried the classic way, I've loaded a config file where I have all the dependances of my JavaScript files, I'm using jQuery, Backbone and other libs.
<script type="text/javascript" data-main="config" src="js/libs/require/require-2.1.6.min.js"></script>
<script type="text/javascript">
require(["jquery"], function ($) {
console.log("jquery loaded");
});
</script>
With this configuration, i get these errors and logs sequence:
Uncaught Error: Mismatched anonymous define() module: function (){return r}
> http://requirejs.org/docs/errors.html#mismatch
end config.js
define "jquery" on config.js
It seems the error is referred to the function require.config(...);
I thought it was a load problem, so I've tried to use the var require as described in RequireJS site without solving it.
The absurd thing is I'm working on a fullscreen app built in Backbone with the same configuration without getting any problem, here I need to work more with different views and I cannot start, basically the whole difference is here I'm using CakePHP.
Why this won't work, where I'm wrong?
The jQuery version you are using already has AMD support. So you don't have to use shim for it. You can directly give the path and start using it.
Since the module is already defined in the jQuery library, it throws errors when you try to redefine it. The following code tries to define an anonymous module.
define(["jquery"], function ($) {
console.log('define "jquery" on config.js');
return $;
});
remove the above code and should work fine. The following code uses require method to load the jquery module.
require(["jquery"], function ($) {
console.log($(document));
});
Hopefully this works.
My application use require.js, I have a random bug (happens 1 time for 50 reload)
Require.js write in the console :
Failed to load resource: the server responded with a status of 404 (Not Found)
Indeed, require.js try to include jquery from a wrong directory...
I don't know why, most of the time the application works fine...
My config is pretty simple :
require.config({
shim: {
underscore: {
exports: '_'
},
backbone: {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
animate_from_to: {
deps: ['jquery']
},
bootstrap: {
deps: ['jquery']
},
zoom: {
deps: ['jquery']
},
shop_util: {
deps: ['jquery']
},
pricer: {
deps: ['jquery']
},
filter: {
deps: ['jquery']
},
paginator: {
deps: ['jquery']
},
},
paths: {
bootstrap: 'lib/bootstrap',
jquery: 'lib/jquery-1.9.1',
zoom: 'lib/jquery.zoom.min',
animate_from_to: 'lib/jquery.animate_from_to-1.0.min',
backbone: 'lib/backbone.min',
underscore: 'lib/underscore.min',
text: 'lib/require-text',
shop_util: 'lib/shop_util',
pricer: 'lib/pricer',
filter: 'lib/filter',
paginator: 'lib/paginator',
}
});
Thank you
It seems you have another entry point into your application somewhere other than your data-main script (js/main.js). Even if it's a subsequent script in the same page, you cannot depend on your data-main script being completed before the next script runs, since it's loaded with async attribute.
<script data-main="js/main" src="js/lib/require.js"></script>
<!-- foo.js might run before js/main.js !!! -->
<script src="js/foo.js"></script>
You can prove this by adding a console.log statement at the end of js/main.js and one in foo.js (or whatever). Normally you will see the one from js/main.js and then foo.js , but in that 1 out of 50 case you'll see them happen in the other order.
There are several strategies to deal with this:
1 - Do all your app initiation and subsequent require's from your data-main script
Applies to single-page apps, of course. All in one file:
require.config({
// snip
});
require(['mymodule'], function( mymodule ) {
// do stuff
});
2 - Use an inline script right after the require.js script tag
Instead of having the above script inside a separate file referenced by data-main, just have a 2nd script tag right below. This is the first example listed in the docs.
Applies mostly to single-page-apps
3 - Load your require config into global variable prior to the require.js script tag
Second example listed in the docs.
<script>
var require = {
paths: { // define them}
shim: { // define them }
};
</script>
<script src="scripts/require.js"></script>
Applies mostly to single-page-apps
4 - Nest your require calls to load the the config first
This works best for multi-page apps and is the one recommended in the multi-page shim app example
<script src="js/lib/require.js"></script>
<script>
//Load common code that includes config, then load the app
//logic for this page. Do the require calls here instead of
//a separate file so after a build there are only 2 HTTP
//requests instead of three.
require(['./js/common'], function (common) {
//js/common sets the baseUrl to be js/ so
//can just ask for 'app/main1' here instead
//of 'js/app/main1'
require(['app/main1']);
});
</script>
Related questions here, here, and here