I have an backbone.js application who work with require.js and i want implement this following jquery plugin:
https://github.com/blueimp/jQuery-File-Upload
I have following this processus:
https://github.com/blueimp/jQuery-File-Upload/wiki/Basic-plugin
If anybody can send me an example of backbone app work with this plugin or can help me with other recommandations.
Before you can read my code:
Require.js config :
require.config({
paths: {
'jquery' : 'common/vendors/jquery_2.1.0',
'underscore' : 'common/vendors/underscore_1.6.0',
'backbone' : 'common/vendors/backbone_1.1.2',
'layoutmanager' : 'common/vendors/backbone.layoutmanager_0.9.5',
'jquery.iframe-transport' : 'common/vendors/jquery.iframe.transport_1.0',
'jquery.ui.widget' : 'common/vendors/jquery.ui.widget_1.10.4',
'jquery.fileupload.ui' : 'common/vendors/jquery_fileupload/jquery.fileupload.ui_9.6.0',
'jquery.fileupload' : 'common/vendors/jquery_fileupload/jquery.fileupload_5.40.3'
},
shim: {
'jquery': {
exports: '$'
},
'underscore': {
exports: '_'
},
'backbone' : {
deps: ["jquery", "underscore"],
exports: "Backbone"
},
'layoutmanager' : {
deps: ["backbone"]
}
}
});
My Backbone View :
var define, selector, console;
define([
'jquery',
'underscore',
'backbone',
'layoutmanager',
'../../../../common/models/global/model_picture',
'jquery.ui.widget',
'jquery.iframe-transport',
'jquery.fileupload'
],
function (
$,
_,
Backbone,
LayoutManager,
PictureModel
) {
"use strict";
return Backbone.Layout.extend({
__class__ : "adPostPictureRow",
initialize: function () {
this.template = _.template($('#adpost_picture_row_template').html());
},
events: {
"change .adpost_picture_input_file" : "handleImageUpload"
},
handleImageUpload: function () {
selector = this.$('.adpost_picture_input_file')[0];
this.uploadProgress = 0;
this.model = new PictureModel({ files : selector.files[0] });
var test = $('#adpost_picture_fileupload', this.el).fileupload({
dataType: 'json',
autoUpload: true,
singleFileUploads: true,
url: '../upload/adpost/img',
done: function (data) {
console.log('upload done');
_.each(data.result, function (index, file) {
console.log(file.name);
});
},
add: function () {
// How can access to this function for see the console.log result
console.log('test upload ');
}
});
console.log(test);
}
});
});
Thanks
I'm using this plugin in my backbone Apps.
It works for me using the Jquery plugin inside my render method. Here a sample of my code.
Html File.
<form id="Anything" action="the api url" method='post' encrtype="multipart/form-data">
<input type='file'/ accept='.txt'>
</form>
Backbone View
render: function(){
this.$el.html(this.template);
$("#Anything").fileupload({
dataType:'json',
add : this.AddFile,
fail: this.AddFileFail
});
AddFile : function(data){
return data.submit();
}
}
Related
I have this code:
define(['plugins/dialog', 'knockout', 'backend', 'durandal/app', 'datepicker', 'datepicker_ko'], function (dialog, ko, backend, app, datepicker, datepicker_ko) {
var ApplicationForm = function(config) {
this.config = ko.observableArray(config);
};
ApplicationForm.prototype.submit = function() {
backend.setFormConfig(this.config()).then(function(response){
dialog.close(this);
});
};
ApplicationForm.show = function(config){
return dialog.show(new ApplicationForm(config));
};
return ApplicationForm;
});
congig in the mainfile main.js:
requirejs.config({
paths: {
'text': '../lib/require/text',
'durandal':'../lib/durandal/js',
'plugins' : '../lib/durandal/js/plugins',
'transitions' : '../lib/durandal/js/transitions',
'knockout': '../lib/knockout/knockout-3.1.0',
'validation_ko': '../lib/knockout/knockout-validation',
'bootstrap': '../lib/bootstrap/js/bootstrap',
'jquery': '../lib/jquery/jquery-1.9.1',
'underscore': '../lib/underscore/underscore-min',
'datepicker': '../lib/datepicker/bootstrap-datepicker',
'datepicker_ko': '../lib/datepicker/datepicker_ko'
},
shim: {
'bootstrap': {
deps: ['jquery'],
exports: 'jQuery'
}
}
});
And my Problem is, that I get the error:
TypeError: this.config is not a function
I do this many times in my project ans with observables works it fine but not with observableArrays. What do I wrong?
define(['plugins/dialog',
'knockout',
'backend',
'durandal/app',
'datepicker',
'datepicker_ko'], function (dialog, ko, backend, app, datepicker, datepicker_ko) {
var config = ko.observableArray([]);
var submit = function(){
var request = config();
backend.setFormConfig(request).then(function(response){
dialog.close(viewmodel);
});
}
var show = function(config){
dialog.show(viewmodel, config);
}
var activate = function(config){
config(config);
}
var viewmodel =
{
config: config,
submit: submit,
show: show,
activate: activate
};
return viewmodel;});
I'm trying to get Masonry loaded into my app using RequireJS, but it keeps causing backbone to spit out a "object is not a function" error anytime I add it.
Edit: possibly related to this issue.
main.js
require.config({
paths: {
jquery: 'lib/jquery-1.9.1',
underscore: 'lib/underscore-1.5.2',
backbone: 'lib/backbone-1.0.0',
masonry: 'lib/masonry.pkgd'
},
shim: {
backbone: {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
underscore: {
exports: '_'
}
}
});
require(['app'], function(App){
App.initialize();
});
app.js
define([
'jquery',
'underscore',
'backbone',
'masonry',
'collections/ideas',
], function($, _, Backbone, Masonry, IdeasCollection) {
var IdeasView = Backbone.View.extend({
el: $('#container'),
initialize: function() {
...
},
render: function(){
...
}
});
return IdeasView;
});
To use Masonry as a jQuery plugin with RequireJS, you’ll need to run jQuery bridget.
Check the documentation:
http://masonry.desandro.com/appendix.html#requirejs
You can download bridget here:
https://github.com/desandro/jquery-bridget
Then you can include an run bridget and it should work fine
define([
'jquery'
, 'underscore'
, 'backbone'
, 'config'
, 'app'
, 'jquery.masonry'
, 'jquery.bridget'
], function ($, _, Backbone, Config, App, Masonry, bridget) {
initialize : function () {
bridget('masonry', Masonry);
}
});
Hope it helps!
This is one way you can run it without bridget:
requirejs-config.js:
var config = {
paths: {
"lib-masonry": "Module/js/lib/masonry.pkgd.min"
},
shim: {
"lib-masonry": {
deps: ['jquery', 'jquery/ui']
}
}
}
and then in another module where you want to use it:
define([
'jquery',
'lib-masonry'
], function ($, Masonry) {
$.widget('ModuleNamespace.containerMasonry', {
options: {
},
_create: function() {
var msnry = new Masonry('.grid', {
itemSelector: '.grid__item',
columnWidth: 200
});
// .. code
}
});
return $.ModuleNamespace.containerMasonry;
});
I am trying to use the backbone-ui library but cannot figure out the require.js configuration to get the modules loaded.
main.js:
requirejs.config({
baseUrl: '/static/js/facebook_report_app/js',
paths: {
backbone: 'lib/backbone'
, underscore: 'lib/underscore'
, jquery: 'lib/jquery'
, laconic: 'lib/laconic'
, moment: 'lib/moment'
, backboneUI: 'lib/backbone-ui/js/backbone_ui'
, menuUI: 'lib/backbone-ui/js/menu'
, textUI: 'lib/backbone-ui/js/text_field'
, text: 'lib/text'
},
shim: {
'lib/underscore': {
exports: '_'
},
'laconic': {
deps: ["jquery"],
exports: "$.el"
},
'lib/backbone': {
deps: ['lib/underscore']
, exports: 'Backbone'
},
'backboneUI': {
deps: ['lib/backbone', 'laconic', 'jquery']
, exports: 'Backbone.UI'
},
'textUI': {
deps: ['jquery', 'lib/backbone', 'backboneUI', 'laconic']
, exports: 'Backbone.UI.TextField'
},
'menuUI': {
deps: ['lib/backbone', 'backboneUI', 'laconic', 'textUI']
, exports: 'Backbone.UI.Menu'
},
'lib/backgrid': {
deps: ['lib/underscore', 'lib/backbone']
, exports: 'Backgrid'
},
'report_app': {
deps: ['lib/underscore', 'lib/backbone', 'lib/backgrid', 'backboneUI']
}
}
});
require([
'facebook_report_app'
],
function(FacebookReportApp) {
window.fbReport = new FacebookReportApp();
});
menu_user.js
define(['jquery', 'lib/backbone', 'backboneUI', 'menuUI', 'laconic'], function(AccountPickerView) {
var AccountPickerView = Backbone.UI.Menu.extend({
el: '.left-nav',
});
return AccountPickerView;
});
When I load this in dev, the console reports "Object [object Object] has no method 'input' ", on line 44 of the text_field.js of the Backbone-UI library.
I suppose my configuration approach is broken to begin with -- I added the menu.js and text_field.js files bc I was getting errors 'Backbone.UI.Menu' and Backbone.UI.TextField' (a requirement of Menu) weren't defined. But there must be a cleaner way to bring in the various files of backbone-ui.
So how do I get rid of the 'no method input' error? Or better configure to use Backbone UI? Or should I be using jQuery UI in the first place? In which case, where do I go to figure out configuration of that?
I got it working, after much fiddling with the following setup:
js/main.js
requirejs.config({
baseURL: 'js',
urlArgs: "bust=" + (new Date()).getTime(),
shim: {
underscore: {
exports: '_'
},
jquery: {
exports: '$'
},
backbone: {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
laconic: {
exports: '$.el'
},
backbone_ui: {
deps: ['underscore', 'jquery', 'backbone', 'laconic', 'moment'],
exports: 'Backbone.UI'
}
},
paths: {
jquery: 'http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min',
moment: './lib/moment.min',
laconic: './lib/laconic',
underscore: 'http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min',
backbone: 'http://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min',
backbone_ui: './lib/backbone-ui',
crypto: 'http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/md5',
templates: '../templates',
collections: './collections',
models: './models',
}
});
js/views/json.js
define(['jquery','underscore', 'backbone', 'backbone_ui'],
function($,_,Backbone, BBUI){
var JsonView = Backbone.View.extend({
className: "json-item",
initialize: function(data){
var self = this;
this.app = data.app;
this.model = data.model;
this.listenTo(this.model, "change", function(){
console.log("model changed", self.model);
});
this.model.fetch({
success: function(){
self.render();
}
});
},
render: function(){
var self = this;
$(this.el).empty();
for (key in this.model.attributes){
this.el.appendChild(new Backbone.UI.Label({content:key}).render().el);
this.el.appendChild(new Backbone.UI.TextField({model: this.model, content:key}).render().el);
}
this.el.appendChild(new Backbone.UI.Button({content:"save", onClick: function(){self.model.save()}}).render().el);
return this;
}
});
return JsonView;
});
Please note that I import backbone-ui as BBUI and never reference it that way. BBUI.TextField() is a defined function and using it would work as well, but the way Backbone-ui is set up it makes alterations to Backbone, Jquery, and Underscore when it loads. So I figured I just needed it to be run prior to the view getting loaded.
I'm relatively new to Backbone and RequireJS, so please bear with me. I'm getting an error when I do the following in my collection: _.range(0,10). It's giving me this error:
Uncaught TypeError: Cannot call method 'range' of undefined
Somehow the "_" is not getting resolved when my Collection is loaded. Here's my collection below:
define([
'jquery',
'underscore',
'backbone',
'collections/feed',
'text!/static/templates/shared/display_item.html'
], function($, _, Backbone, FeedCollection, DisplayItem){
debugger; // Added this to test the value of _
var FeedView = Backbone.View.extend({
el: '#below-nav',
initialize: function () {
this.feedCollection = new FeedCollection();
},
feed_row: '<div class="feed-row row">',
feed_span8: '<div class="feed-column-wide span8">',
feed_span4: '<div class="feed-column span4">',
render: function () {
this.loadResults();
},
loadResults: function () {
var that = this;
// we are starting a new load of results so set isLoading to true
this.isLoading = true;
this.feedCollection.fetch({
success: function (articles) {
var display_items = [];
// This line below is the problem...._ is undefined
var index_list = _.range(0, articles.length, 3);
_.each(articles, function(article, index, list) {
if(_.contain(index_list, index)) {
var $feed_row = $(that.feed_row),
$feed_span8 = $(that.feed_span8),
$feed_span4 = $(that.feed_span4);
$feed_span8.append(_.template(DisplayItem, {article: articles[index]}));
$feed_span4.append(_.template(DisplayItem, {article: articles[index+1]}));
$feed_span4.append(_.template(DisplayItem, {article: articles[index+2]}));
$feed_row.append($feed_span8, $feed_span4);
$(that.el).append($feed_row);
}
});
}
});
}
});
return FeedView;
});
I added the debugger line so that I could test the values of all the arguments. Everything loaded fine, except for _. Could this be something wrong with my config.js file?
require.config({
// Set base url for paths to reference
baseUrl: 'static/js',
// Initialize the application with the main application file.
deps: ['main'],
paths: {
jquery: 'libs/jquery/jquery.min',
require: 'libs/require/require.min',
bootstrap: 'libs/bootstrap/bootstrap.min',
text: 'libs/plugins/text',
underscore: 'libs/underscore/underscore',
backbone: 'libs/backbone/backbone',
json: 'libs/json/json2',
base: 'libs/base/base'
},
shim: {
'backbone': {
// These script dependencies should be loaded first before loading
// backbone
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
'bootstrap': {
deps: ['jquery'],
exports: 'Bootstrap'
}
}
})
Your help is greatly appreciated. My head is spinning as a result of this error.
Based off the project that I'm working on, you need a shim for underscore as well. Underscore isn't 'exported' per say, so use this instead:
shim: {
'backbone': {
// These script dependencies should be loaded first before loading
// backbone
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
'bootstrap': {
deps: ['jquery'],
exports: 'Bootstrap'
},
'underscore': {
exports: '_'
}
}
Seems this might also be 'duplicate' question of Loading Backbone and Underscore using RequireJS - one or two of the answers down the list there is a mention of this setup.
I building a project with requireJs my file structure is the following:
js/
lib/
noty/
layouts/
bottom.js
top.js
...
themes/
default.js
noty.jquery.js
jquery.js
jquery-ui.js
user/
user.js
app.js
And my configuration :
requirejs.config({
baseUrl: 'js/lib',
urlArgs: 'bust=' + (new Date()).getTime(), //only for dev : no-cache
paths: {
user: '../user'
},
shim: {
'jquery-ui': ['jquery'],
'jquery-tmpl': ['jquery'],
'gridy': ['jquery']
}
});
requirejs(['jquery', 'jquery-ui'], function($){
....
});
My concern is about to integrate noty which is a notification plugin that I may use in any modules. This plugin requires to load :
js/lib/noty/noty.jquery.js
js/lib/noty/layout/top.js
js/lib/noty/themes/bottom.js
I'm not sure what is the way to do that?
Concatenate the files ?
Load each file as a dependency? :
requirejs(['jquery', 'jquery-ui', 'noty/noty.jquery.js', 'noty/layout/top.js', etc. ]
Creates some kind of plugin/module for requireJs?
Thanks
or like this:
paths: {
'jquery': 'jquery/1.10.2/jquery',
'noty': 'noty/2.0/jquery.noty',
'noty.themes.default': 'noty/2.0/themes/default',
'noty.layouts.topCenter': 'noty/2.0/layouts/topCenter',
app: '../app',
util: '../util'
},
shim: {
'noty': ['jquery'],
'noty.themes.default': {
deps: ['jquery', 'noty'],
exports: 'jquery'
},
'noty.layouts.topCenter': {
deps: ['jquery', 'noty'],
exports: 'jquery'
}
}
Finally I managed to implement the 3rd solution: I've created a web module that wrap the library in a file named notiy.js :
define(['jquery',
'noty/layouts/topCenter',
'noty/layouts/bottomRight',
'noty/themes/default'],
function($){
$.noty.defaults.timeout = 20000;
return function(type, msg){
var topLayout = 'topCenter',
bottomLayout = 'bottomRight',
layout = {
'alert' : topLayout,
'info' : bottomLayout,
'confirm' : topLayout,
'success' : bottomLayout,
'error' : topLayout,
'warning' : topLayout
};
if(msg && type){
return noty({
text : msg,
layout: layout[type] || topLayout,
type : type
});
}
}
});
I've declared the dependencies in the shim config (to fix the dependency order) in my app.js :
requirejs.config({
baseUrl: 'js/lib',
urlArgs: 'bust=' + (new Date()).getTime(), //only for dev : no-cache
paths: {
user: '../user'
},
shim: {
'jquery-ui' : ['jquery'],
'jquery-tmpl' : ['jquery'],
'gridy' : ['jquery'],
'noty/jquery.noty' : ['jquery'],
'notify' : ['noty/jquery.noty']
}
});
requirejs(['jquery', 'jquery-ui', 'jquery-tmpl', 'notify'], function($, ui, tmpl, notify){
//...
});
Ans it works like a charm!