Datepicker jqueryui not works with require.js and backbone.js - jquery-ui

Jquery ui datepicker not works on click on input.
main.js
require.config({
baseUrl: "js",
paths: {
html5shiv: "libs/html5shiv",
jquery: "http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min",
jqueryui: "http://code.jquery.com/ui/1.10.3/jquery-ui",
tablesorter: "libs/jquery.tablesorter.min",
script: "script",
underscore: "libs/underscore.min",
backbone: "libs/backbone.min",
utils: "utils",
collectorModel: "models/collectorModel",
collectorCollection: "collections/collectorCollection",
tollectorRouter: "routers/tollectorRouter",
edit: "views/collector/tollector_edit",
index: "views/collector/collector_index",
neww: "views/collector/collector_new",
row: "views/collector/collector_row",
show: "views/collector/collector_show",
'templates': 'templates'
},
shim: {
jqueryui: {
deps: ["jquery"],
exports: "Jqueryui"
},
tablesorter: {
deps: ["jquery"],
exports: "TableSorter"
},
script: {
deps: ["jquery", "jqueryui", "tablesorter"],
exports: "Script"
},
jqueryui: {
deps: ["jquery"]
},
underscore: {
exports: "_"
},
backbone: {
deps: ["underscore", "jquery"],
exports: "Backbone"
}
}
});
require(["backbone", "underscore", "collectorCollection", "collectorRouter", "script"],
function (Backbone, _, CollectorCollection, CollectorRouter) {
var collectors = new CollectorCollection();
var router = new CollectorRouter({collectors: collectors});
Backbone.history.start();
});
Template: collector_edit.html
input type="text" class="inputs dateInput" name="endDate" placeholder="End date" value="<%= endDate %>
scripts.js
$(document).ready(function () {
$(".dateInput").datepicker({dateFormat: "dd/mm/yy"});
});
it worked before using backbone and RequireJS

When using requireJS your dependencies do not exist in the global scope anymore but only inside modulde that requires them. Try changing your script JS to:
define(['jqueryui'], function( jqueryui ) {
$(document).ready(function () {
$(".dateInput").datepicker({dateFormat: "dd/mm/yy"});
});
})

Related

Angular component not executing with Webpack

Short Version:
I'm building an app with Angular2 and Webpack. I have the bundles building successfully, but when I include them on my page, the angular components loading. No errors are showing up.
webpack.config.js
"use strict";
let webpack = require('webpack');
let ExtractTextPlugin = require('extract-text-webpack-plugin');
let helpers = require('./webpack.helpers.js');
let HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
'app': helpers.root('/Modules/Shared/Main.ts'),
'vendor': helpers.root('/External/Vendor.ts'),
'polyfills': helpers.root('/External/Polyfill.ts')
},
devtool: 'source-map',
resolve: {
extensions: ['.ts', '.js', '.json', '.css', '.scss', '.html']
},
output: {
path: helpers.root('/wwwroot/scripts'),
filename: '[name].js'
},
module: {
rules: [
{
test: /\.ts$/,
loaders: [
{ loader: 'awesome-typescript-loader', options: { tsConfig: 'tsconfig.json' } },
'angular-router-loader',
'angular2-template-loader',
'source-map-loader',
'tslint-loader'
]
},
{
test: /\.(png|jpg|gif|woff|woff2|ttf|svg|eot)$/,
loader: 'file-loader?name=assets/[name]-[hash:6].[ext]'
},
{
test: /favicon.ico$/,
loader: 'file-loader?name=/[name].[ext]'
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract({
fallbackLoader: "style-loader",
loader: "css-loader"
})
},
{
test: /\.scss$/,
exclude: /node_modules/,
loaders: ['style-loader', 'css-loader', 'sass-loader']
},
{
test: /\.html$/,
loader: 'raw-loader'
}
]
},
plugins: [
new ExtractTextPlugin('css/[name].bundle.css'),
new webpack.NoEmitOnErrorsPlugin(),
// Workaround for angular/angular#11580
new webpack.ContextReplacementPlugin(
// The (\\|\/) piece accounts for path separators in *nix and Windows
/angular(\\|\/)core(\\|\/)#angular/,
'Modules/', // location of your src
{} // a map of your routes
),
new webpack.optimize.CommonsChunkPlugin({
name: ['app', 'vendor', 'polyfills']
}),
new webpack.ProvidePlugin({
jQuery: 'jquery',
$: 'jquery',
jquery: 'jquery',
}),
new HtmlWebpackPlugin()
]
};
tsconfig.json
{
"compilerOptions": {
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"module": "commonjs",
"moduleResolution": "node",
"noEmitOnError": true,
"noImplicitAny": true,
"removeComments": true,
"skipLibCheck": true,
"sourceMap": true,
"target": "es5"
},
"exclude": [
"node_modules",
"wwwroot"
],
"compileOnSave": true
}
The files are being generated correctly:
http://imgur.com/a/xzw0E
_Layout.cshtml
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>#ViewData["Title"]</title>
<base href="/" />
</head>
<body style="background-color: #333;">
#RenderBody()
<script type="text/javascript" src="/scripts/polyfills.js"></script>
<script type="text/javascript" src="/scripts/vendor.js"></script>
#RenderSection("scripts", required: false)
</body>
</html>
index.cshtml
#using System.Threading.Tasks
#{
ViewData["Title"] = "Home Page";
}
<div style="height: 100%;">
<app-component>Loading...</app-component>
</div>
#section Scripts{
<script type="text/javascript" src="/scripts/app.js"></script>
}
The component I'm expecting to see looks like this:
import { Component } from '#angular/core';
#Component({
selector: 'app-component'
})
export class AppComponent {
constructor() {
console.log('I\'m running !!!!');
}
}
But when I generate the page, it looks like this:
http://imgur.com/a/YrPJf
with no errors in the console:
http://imgur.com/a/Xepl2
Any help is greatly appreciated
Seems you forgot about bootstrapping your application via
platformBrowserDynamic().bootstrapModule(AppModule);

requirejs - shim configuration

I am using Almond and the r.js optimizer to combine all my scripts in a single file for a Backbone.js-based Single Page Application.
My build file:
({
name: '../bower_components/almond/almond',
include: ['main'],
insertRequire: ['main'],
baseUrl: 'src',
optimize: 'uglify2',
mainConfigFile: 'src/main.js',
out: 'javascripts/scripts.js',
preserveLicenseComments: false,
paths: {
jquery: '../bower_components/jquery/dist/jquery',
underscore: '../bower_components/underscore/underscore',
backbone: '../bower_components/backbone/backbone',
kineticjs: '../bower_components/kineticjs/kineticjs',
'jquery-ui': '../bower_components/jquery-ui/ui',
'jquery.layout': '../bower_components/jquery.layout/dist/jquery.layout-latest'
},
shim: {
'jquery.layout': {
deps: [
'jquery-ui/core',
'jquery-ui/draggable',
'jquery-ui/effect',
'jquery-ui/effect-slide'
],
exports: 'jQuery.fn.layout'
}
}
})
In my Backbone view I initialize the jquery-layout plugin:
define(['backbone', 'underscore', 'jquery.layout'], function(Backbone, _) {
'use strict'
return Backbone.View.extend({
el: $('#application'),
initialize: function() {
this.$el.layout({
west: {
size: '50%',
closable: false,
slidable: false,
resizable: true
}
});
}
});
});
The panes show up correctly, however I cannot resize any of them. I found that $.fn.draggable (JQuery UI Draggable widget) is not being initialized at the time when the jquery-layout plugin is declared.
This indicates that probably the widget is not being loaded. So I checked the combined source file and noticed that the JQuery UI Draggable widget code appears before the jquery-layout plugin code, which means the dependencies are inserted in the correct order. Printing $.fn.draggable in the Firebug console also shows that the widget is available, at least after the document is ready.
jQuery, underscore, backbone, jQuery UI are all AMD modules. jquery-layout has no AMD compatibility, hence the shim config. It depends on JQuery UI's ui.core and ui.draggable per their docs.
For all of this to not sound too abstract, here is a demo of the jquery-layout plugin.
I have "wasted" over 8 hours trying to figure this out in vain, any help on how to fix this would save my day. Most probably this would involve only some fix of my shim config in the build file.
I solved the problem by making the non AMD-aware jquery-layout plugin AMD-compatible. I used the onBuildWrite hook of the r.js optimizer in the build file. This way the jQuery UI dependency ui.draggable is initialized before the code of the non AMD-aware plugin loads:
({
name: '../bower_components/almond/almond',
include: ['main'],
insertRequire: ['main'],
baseUrl: 'src',
optimize: 'uglify2',
mainConfigFile: 'src/main.js',
out: 'javascripts/scripts.js',
preserveLicenseComments: false,
paths: {
jquery: '../bower_components/jquery/dist/jquery',
underscore: '../bower_components/underscore/underscore',
backbone: '../bower_components/backbone/backbone',
kineticjs: '../bower_components/kineticjs/kineticjs',
'jquery-ui': '../bower_components/jquery-ui/ui',
'jquery.layout': '../bower_components/jquery.layout/dist/jquery.layout-latest'
},
shim: {
'jquery.layout': {
deps: ['jquery', 'jquery-ui/draggable', 'jquery-ui/effect', 'jquery-ui/effect-slide'],
exports: 'jQuery.fn.layout'
}
},
onBuildWrite: function(moduleName, path, contents) {
if (moduleName == 'jquery.layout') {
contents = "define('jquery.layout', ['jquery', 'jquery-ui/draggable', 'jquery-ui/effect', 'jquery-ui/effect-slide'], function(jQuery) {" + contents + "});";
}
return contents;
}
})
Following the answer from #Genti and using latest jquery-ui, following shim worked for me.
shim: {
'jquery.layout': {
deps: ['jquery', 'jquery-ui/core', 'jquery-ui/widgets/draggable', 'jquery-ui/effect', 'jquery-ui/effects/effect-slide', 'jquery-ui/effects/effect-drop', 'jquery-ui/effects/effect-scale'],
exports: 'jQuery.fn.layout'
}
}

Why does using requirejs 2 stop my backbone / jQuery mobile app working?

I have a very simple proof of concept app built with jQuery Mobile, Backbone.js, and require.js.
I am using Backbone's router, and I have jQuery Mobile's routing disabled. It works perfectly.
I am using require.js 1.04. However: when I use requirejs 2.1.14, then I can't seem to disable jQuery Mobile's routing, and hence Backbone's routing stops working. Can't figure it out.
The following code works if I remove jQuery mobile, but stops working if I put jQuery mobile back in. Similarly, it will work with Require.js 1.0.4, but not with require.js 2.1.14:
index.html:
<html>
<body>
Click Here
<script data-main="main" src="require.js"></script>
</body>
</html>
main.js
require.config({
paths : {
backbone : 'libraries/backbone/backbone',
underscore : 'libraries/underscore/underscore',
jquery : 'libraries/jquery/jquery-1.7.1',
jqm : 'libraries/jquery.mobile/jquery.mobile',
router: 'router'
},
shim: {
jqm: {
exports: 'jqm',
deps: ['jquery']
},
underscore: {
exports: 'underscore'
},
backbone: {
exports: 'backbone',
deps: ['jquery', 'underscore']
}
}
});
require(
['jquery', 'jqm', 'underscore', 'backbone', 'router'],
function ($, $$, underscore, Backbone, router) {
$.mobile.ajaxEnabled = false;
$.mobile.linkBindingEnabled = false;
$.mobile.hashListeningEnabled = false;
$.mobile.pushStateEnabled = false;
$.mobile.changePage.defaults.changeHash = false;
router.init();
});
router.js
define(['jquery', 'jqm', 'underscore', 'backbone'],
function($, $$, _, Backbone) {
var init = function () {
$.mobile.ajaxEnabled = false;
$.mobile.linkBindingEnabled = false;
$.mobile.hashListeningEnabled = false;
$.mobile.pushStateEnabled = false;
$.mobile.changePage.defaults.changeHash = false;
var AppRouter = Backbone.Router.extend({
routes: {
"posts/:id" : "getSomePost",
"*action": "defaultRoute"
},
getSomePost: function(id) {
alert( "Get post number " + id );
},
defaultRoute: function( actions ){
console.log('Action: ' + actions );
}
});
// Instantiate the backbone router
var app_router = new AppRouter();
// Start Backbone history
Backbone.history.start();
};
return { init : init };
});
This problem is seriously baking my noodle!!
When I load up the app, I see a link saying "Click here". When the app uses requirejs-1.0.4 (or without jquery mobile) it works, I get an alert saying "get post number 1", and the URL looks like:
http://myapp.dev/src/#posts/1
but when using requirejs-2.1.14 and jQuery Mobile, I the URL quickly changes to this:
http://myapp.dev/src/posts/1
and nothing happens.
Help!
I finally found the answer to this problem. The issue is the timing of jQuery Mobile configuration. According to the jQuery Mobile docs:
Because the mobileinit event is triggered immediately, you'll need to
bind your event handler before jQuery Mobile is loaded
So I rewrote main.js like so:
require.config({
paths : {
backbone : 'libraries/backbone/backbone',
underscore : 'libraries/underscore/underscore',
jquery : 'libraries/jquery/jquery-1.7.1',
jqmconfig : 'jquerymobile.config',
jqm : 'libraries/jquery.mobile/jquery.mobile',
router: 'router'
},
shim: {
jqm: {
exports: 'jqm',
deps: ['jquery', 'jqmconfig']
},
underscore: {
exports: 'underscore'
},
backbone: {
exports: 'backbone',
deps: ['jquery', 'jqm', 'underscore']
}
}
});
require(
['jquery', 'backbone', 'jqmconfig', 'jqm', 'router'],
function ($, Backbone, jqmconfig, $$, router) {
router.init();
});
And added a new file called jquerymobile.config.js:
define(['jquery'], function ($) {
$(document).on('mobileinit', function () {
// Prevents all anchor click handling
$.mobile.linkBindingEnabled = false
// Disabling this will prevent jQuery Mobile from handling hash changes
$.mobile.hashListeningEnabled = false
$.mobile.ajaxEnabled = false;
$.mobile.pushStateEnabled = false;
});
});
This code fires after jQuery has loaded, but BEFORE jQuery Mobile has loaded, which is the key!
For reference, this is the blog post that helped me figure it out:
http://www.justinmccandless.com/blog/Yeoman%2C+Requirejs%2C+jQuery+Mobile%2C+Backbone%2C+and+a+Lot+of+Config+Problems

Backbone + JQuery Mobile + RequireJS

I am having a big proglem with RequireJS. This configuration works randomly. I dont know why, once it works and once it doesn't:
requirejs.config({
baseUrl: 'js',
urlArgs: "bust=" + (new Date()).getTime(),
paths: {
jquery: 'libs/jquery/jquery-1.10.2.min',
underscore: 'libs/underscore/underscore-min',
backbone: 'libs/backbone/backbone-min',
marionette: 'libs/marionette/backbone.marionette',
cordova: 'libs/cordova/cordova-1.9.0',
jquerym: 'libs/jquery-mobile/jquery.mobile-1.4.0'
},
shim: {
'jquery': {
deps: []
},
'jquerym': {
deps: ['jquery'],
exports: 'jquery'
},
'underscore': {
deps: [],
exports: "_"
},
'backbone': {
deps: ['jquery', 'underscore'],
exports: 'Backbone'
},
'marionette': {
deps: ['jquery', 'underscore', 'backbone']
}
},
priority: ['jquery', 'jquerym']
});
require(['app', 'jquery', 'jquerym'], function (App) {
$(document).bind("mobileinit", function () {
$.mobile.ajaxEnabled = false;
$.mobile.linkBindingEnabled = false;
$.mobile.hashListeningEnabled = false;
$.mobile.pushStateEnabled = false;
// Remove page from DOM when it's being replaced
$('div[data-role="page"]').live('pagehide', function (event, ui) {
$(event.currentTarget).remove();
});
});
console.log('jQuery version ' + $().jquery + ' installed');
App.initialize();
});
The Mobile-Init-Event has to be bound before jQuery Mobile is loaded for it to be triggered correctly.
Try using something like this:
require(["jquery"], function( $ ){
$( document ).one( "mobileinit", function() {
//Set your configuration and event binding
$.mobile.ajaxEnabled = false;
$.mobile.linkBindingEnabled = false;
$.mobile.hashListeningEnabled = false;
$.mobile.pushStateEnabled = false;
// Remove page from DOM when it's being replaced
$('div[data-role="page"]').live('pagehide', function (event, ui) {
$(event.currentTarget).remove();
});
});
require( [ "App", "jquerym" ], function( App, jqm ) {
/* Do Stuff with jqm here if you want like jqm.initializePage() if turned off */
App.initialize();
});
});

Angular UI slider with Require JS fires before jQuery UI

I am building an AngularJS application using RequireJs, AngularUI and jQuery UI.
I occasionally get the following error when using the slider:
TypeError: Object [object Object] has no method 'slider'
at init (http://example.com/Assets/js/lib/angular-ui/slider.js?v=635137928871837150:18:29)
at ngModel.$render (http://example.com/Assets/js/lib/angular-ui/slider.js?v=635137928871837150:55:25)
at Object. (http://example.com/Assets/js/lib/angular-1.0.7/angular.min.js?v=635137928871837150:140:131)
at Object.e.$digest (http://example.com/Assets/js/lib/angular-1.0.7/angular.min.js?v=635137928871837150:86:286)
at Object.e.$apply (http://example.com/Assets/js/lib/angular-1.0.7/angular.min.js?v=635137928871837150:88:506)
at e (http://example.com/Assets/js/lib/angular-1.0.7/angular.min.js?v=635137928871837150:95:38)
at p (http://example.com/Assets/js/lib/angular-1.0.7/angular.min.js?v=635137928871837150:98:123)
at XMLHttpRequest.t.onreadystatechange (http://example.com/Assets/js/lib/angular-1.0.7/angular.min.js?v=635137928871837150:99:259)
angular.min.js?v=635137928871837150:62
(anonymous function) angular.min.js?v=635137928871837150:62
(anonymous function) angular.min.js?v=635137928871837150:52
e.$digest angular.min.js?v=635137928871837150:87
e.$apply angular.min.js?v=635137928871837150:88
e angular.min.js?v=635137928871837150:95
p angular.min.js?v=635137928871837150:98
t.onreadystatechange angular.min.js?v=635137928871837150:99
If I refresh the page the error goes away and it only happens occasionally anyway.
I am using:
Require version 2.1.8.js
Current version of Angular Ui Slider (https://github.com/angular-ui/ui-slider/blob/master/src/slider.js)
The relevant parts of my Require Config are:
require.config({
shim: {
jqueryui: {
deps: ['jquery']
},
'angular': { 'exports': 'angular' },
angularResource: { deps: ['angular'] },
angularMocks: { deps: ['angular'] },
angularSortable: { deps: ['angular', 'jquery', 'jqueryui'] },
angularSlider: { deps: ['angular', 'jquery', 'jqueryui'] }
},
paths: {
angular: '/Assets/js/lib/angular-1.0.7/angular.min',
angularResource: '/Assets/js/lib/angular-1.0.7/angular-resource.min',
angularMocks: '/Assets/js/lib/angular-1.0.7/angular-mocks',
angularSortable: '/Assets/js/lib/angular-ui/sortable',
angularSlider: '/Assets/js/lib/angular-ui/slider',
jquery: '/Assets/js/lib/jquery-1.9.1.min',
jqueryui: '/Assets/js/lib/jquery-ui-1.10.0'
}
});
I am bootstrapping my application like so:
require(['require', 'jquery', 'jqueryui', 'angular', 'angularResource', 'angularSortable', 'angularSlider'],
function (require, $, jqueryui, angular) {
'use strict';
var contentApp = angular.module('testApp', ['ngResource', 'ui.sortable', 'ui.slider']);
require(['TestController'],
function () {
$(document).ready(function () {
var $angularRootElement = $('#wrapper');
angular.bootstrap($angularRootElement, [contentApp['name']]);
$angularRootElement.addClass('ng-app');
});
});
}
);
I presume the problem is that occasionally jQuery UI hasn't loaded before the Angular UI slider code runs. Although, I can see in the network tab in Chrome that jQuery UI was downloaded before the slider.
Can anyone give me some ideas on how to debug this?
Thanks

Resources