Related
I am uploading an image using drag n drop and cropping it using croppie plugin. Also, in case if the user has selected the wrong image and wants to change it then there is a browse again button to switch back to drag n drop state.
Everything was working fine while I was doing this with jquery code. However, I am trying to refactor my code to use Javascript Promise, it just runs for the first time only.
Promise code:
const dragDrop = (params, element) => {
return new Promise((resolve, reject) => {
$(element || '.drag-drop').on('dragover', (e) => {
e.preventDefault();
}).on('dragleave', (e) => {
e.preventDefault();
}).on('drop', (e) => {
e.preventDefault();
let fileList = e.originalEvent.dataTransfer.files;
let conditions = $.extend({}, {
files: 1,
fileSize: (1024 * 1024 * 5),
type: ["image/gif", "image/jpeg", "image/jpg", "image/png"],
extension: ["gif", "jpeg", "jpg", "png"]
}, (params || {}));
if (fileList.length > conditions.files)
{
reject('Please choose only ' + conditions.files + ' file(s)');
}
else if (fileList[0].size > (conditions.fileSize))
{
reject('File to large.!<br>Allowed: ' + (conditions.fileSize) + 'MB');
}
else
{
if (fileList[0].type == '')
{
let ext = (fileList[0].name).split('.');
if ($.inArray(ext[ext.length - 1], conditions.extension) < 0)
{
reject('File type not allowed');
}
}
else if ($.inArray(fileList[0].type, conditions.type) < 0)
{
reject('File type not allowed');
}
}
resolve(fileList);
});
})
};
Drag-Drop code:
dragDrop().then((files) => {
croppie({
url: 'url to upload',
data: {
token: "user identification token string"
}
}, files);
}).catch((message) => {
alert(message);
});
Croppie code:
function croppie(ajax, files, croppie, el)
{
// variables
let $image = $((el.image !== undefined) ? el.image : 'div.js-image');
let $button = $((el.button !== undefined) ? el.button : '.js-crop-button');
let $dragDrop = $((el.dragDrop !== undefined) ? el.dragDrop : '.drag-drop');
let $browseButton = $((el.browse !== undefined) ? el.browse : '.js-browse');
$imageCrop = $image.croppie($.extend(true, {
enableExif: true,
enableOrientation: true,
viewport: {
width: 200,
height: 200,
type: 'square'
},
boundary: {
height: 500
}
}, croppie)).removeClass('d-none');
var reader = new FileReader();
reader.onload = (event) => {
$imageCrop.croppie('bind', {
url: event.target.result
});
}
reader.readAsDataURL(files[0]);
$image.parent().removeClass('d-none');
$button.removeClass('d-none');
$dragDrop.addClass('d-none');
$('.js-rotate-left, .js-rotate-right').off('click').on('click', function (ev) {
$imageCrop.croppie('rotate', parseInt($(this).data('deg')));
});
$browseButton.off('click').on('click', function() {
$image.croppie('destroy');
$image.parent().addClass('d-none');
$button.addClass('d-none');
$dragDrop.removeClass('d-none');
});
$button.off('click').on('click', () => {
$imageCrop.croppie('result', {
type: 'canvas',
size: 'viewport'
}).then((response) => {
ajaxRequest($.extend(true, {
data: {
"image": response,
},
success: (data) => {
(data.success == true)
? window.parent.location.reload()
: alert(data.message);
}
}, ajax));
});
});
}
I am making a web app using yeoman and I'm stuck in creating a generator. The problem is that it won't copy files to the output folder.
Here's my code:
'use strict';
var fs = require('fs');
var path = require('path');
var yeoman = require('yeoman-generator');
var yosay = require('yosay');
var chalk = require('chalk');
var wiredep = require('wiredep');
module.exports=yeoman.extend({
scaffoldFolders: function(){
this.mkdir("app");
this.mkdir("app/css");
this.mkdir("app/sections");
this.mkdir("build");
},
initializing: function(){
this.pkg=require('../../package.json');
},
prompting: function() {
var done = this.async();
this.log(yosay(
'Welcome to the marvelous ' + chalk.red('generator-palmyra') + ' generator!'
));
var prompts = [{
type: 'checkbox',
name: 'mainframeworks',
message:'Would you like AngularJS or JQuery ?',
choices: [{
name: 'Angular',
value: 'includeAngular',
checked: true
}, {
name: 'JQuery',
value: 'includeJQuery',
checked: true
}]
},
{
type: 'checkbox',
name: 'features',
message:'What more front-end frameworks would you like ?',
choices: [{
name: 'Sass',
value: 'includeSass',
checked: true
}, {
name: 'Bootstrap',
value: 'includeBootstrap',
checked: true
}, {
name: 'Modernizr',
value: 'includeModernizr',
checked: true
}]
}
];
this.prompt(prompts, function (answers) {
var features = answers.features;
var mainframeworks = answers.mainframeworks;
var hasFeature = function (feat) {
return features.indexOf(feat) !== -1;
};
var hasMainframeworks = function (mainframework) {
return mainframeworks.indexOf(mainframework) !== -1;
};
// manually deal with the response, get back and store the results.
this.includeSass = hasFeature('includeSass');
this.includeBootstrap = hasFeature('includeBootstrap');
this.includeModernizr = hasFeature('includeModernizr');
this.includeAngular = hasMainframeworks('includeAngular');
this.includeJQuery = hasMainframeworks('includeJQuery');
done();
}.bind(this));
},
writing() {
gulpfile= function(){
this.fs.copy(
this.templatePath('gulpfile.js'),
this.destinationPath('gulpfile.js')
);
},
packageJSON= function () {
this.fs.copy(
this.templatePath('_package.json'),
this.destinationPath('package.json')
);
},
git= function () {
this.fs.copy(
this.templatePath('gitignore'),
this.destinationPath('.gitignore')
);
this.fs.copy(
this.templatePath('gitattributes'),
this.destinationPath('.gitattributes')
);
},
bower= function () {
var bower = {
name: this._.slugify(this.appname),
private: true,
dependencies: {}
};
if (this.includeBootstrap) {
var bs = 'bootstrap' + (this.includeSass ? '-sass' : '');
bower.dependencies[bs] = '~3.3.1';
}
if (this.includeModernizr) {
bower.dependencies.modernizr = '~2.8.1';
}
if (this.includeAngular) {
bower.dependencies.angular = '~1.3.15';
}
if (this.includeJQuery) {
bower.dependencies.jquery = '~2.1.1';
}
this.fs.copy(
this.templatePath('bowerrc'),
this.destinationPath('.bowerrc')
);
this.write('bower.json', JSON.stringify(bower, null, 2));
},
jshint= function () {
this.fs.copy(
this.templatePath('jshintrc'),
this.destinationPath('.jshintrc')
);
},
mainStylesheet= function () {
var css = 'main';
if (this.includeSass) {
css += '.scss';
} else {
css += '.css';
}
this.copy(css, 'app/styles/' + css);
},
writeIndex= function () {
this.indexFile = this.src.read('index.html');
this.indexFile = this.engine(this.indexFile, this);
// wire Bootstrap plugins
if (this.includeBootstrap) {
var bs = '/bower_components/';
if (this.includeSass) {
bs += 'bootstrap-sass/assets/javascripts/bootstrap/';
} else {
bs += 'bootstrap/js/';
}
this.indexFile = this.appendScripts(this.indexFile, 'scripts/plugins.js', [
bs + 'affix.js',
bs + 'alert.js',
bs + 'dropdown.js',
bs + 'tooltip.js',
bs + 'modal.js',
bs + 'transition.js',
bs + 'button.js',
bs + 'popover.js',
bs + 'carousel.js',
bs + 'scrollspy.js',
bs + 'collapse.js',
bs + 'tab.js'
]);
}
this.indexFile = this.appendFiles({
html: this.indexFile,
fileType: 'js',
optimizedPath: 'scripts/main.js',
sourceFileList: ['scripts/main.js']
});
this.write('app/index.html', this.indexFile);
},
app= function () {
this.copy('main.js', 'app/scripts/main.js');
}
},
install: function () {
var howToInstall =
'\nAfter running ' +
chalk.yellow.bold('npm install & bower install') +
', inject your' +
'\nfront end dependencies by running ' +
chalk.yellow.bold('gulp wiredep') +
'.';
if (this.options['skip-install']) {
this.log(howToInstall);
return;
}
this.installDependencies();
this.on('end', function () {
var bowerJson = this.dest.readJSON('bower.json');
// wire Bower packages to .html
wiredep({
bowerJson: bowerJson,
directory: 'bower_components',
exclude: ['bootstrap-sass', 'bootstrap.js'],
ignorePath: /^(\.\.\/)*\.\./,
src: 'app/index.html'
});
if (this.includeSass) {
// wire Bower packages to .scss
wiredep({
bowerJson: bowerJson,
directory: 'bower_components',
ignorePath: /^(\.\.\/)+/,
src: 'app/styles/*.scss'
});
}
}.bind(this));
}
});
I think the problem is in the writing method. I also wanted to ask where to go next? Or did I pass a fundamental step toward learning web dev
i removed the var done =async() and replaced "this.prompt" by "return this.prompt"
most of the files are copied ... but there is still more invalid code ::
if you format your code, you'll see the writing function isn't doing anything. It declares a bunch of sub-functions, but doesn't run anyone.
I think the issue is you want an object but instead wrote a function: writing() {} instead of writing: {}.
I did a quick fix of the code, but didn't test it out. So there might be further syntax issue, but it should roughly look like this:
'use strict';
var fs = require('fs');
var path = require('path');
var yeoman = require('yeoman-generator');
var yosay = require('yosay');
var chalk = require('chalk');
var wiredep = require('wiredep');
module.exports = yeoman.extend({
scaffoldFolders: function() {
this.mkdir('app');
this.mkdir('app/css');
this.mkdir('app/sections');
this.mkdir('build');
},
initializing: function() {
this.pkg = require('../../package.json');
},
prompting: function() {
var done = this.async();
this.log(
yosay(
'Welcome to the marvelous ' +
chalk.red('generator-palmyra') +
' generator!'
)
);
var prompts = [
{
type: 'checkbox',
name: 'mainframeworks',
message: 'Would you like AngularJS or JQuery ?',
choices: [
{
name: 'Angular',
value: 'includeAngular',
checked: true,
},
{
name: 'JQuery',
value: 'includeJQuery',
checked: true,
},
],
},
{
type: 'checkbox',
name: 'features',
message: 'What more front-end frameworks would you like ?',
choices: [
{
name: 'Sass',
value: 'includeSass',
checked: true,
},
{
name: 'Bootstrap',
value: 'includeBootstrap',
checked: true,
},
{
name: 'Modernizr',
value: 'includeModernizr',
checked: true,
},
],
},
];
this.prompt(
prompts,
function(answers) {
var features = answers.features;
var mainframeworks = answers.mainframeworks;
var hasFeature = function(feat) {
return features.indexOf(feat) !== -1;
};
var hasMainframeworks = function(mainframework) {
return mainframeworks.indexOf(mainframework) !== -1;
};
// manually deal with the response, get back and store the results.
this.includeSass = hasFeature('includeSass');
this.includeBootstrap = hasFeature('includeBootstrap');
this.includeModernizr = hasFeature('includeModernizr');
this.includeAngular = hasMainframeworks('includeAngular');
this.includeJQuery = hasMainframeworks('includeJQuery');
done();
}.bind(this)
);
},
writing: {
gulpfile: function() {
this.fs.copy(
this.templatePath('gulpfile.js'),
this.destinationPath('gulpfile.js')
);
},
packageJSON: function() {
this.fs.copy(
this.templatePath('_package.json'),
this.destinationPath('package.json')
);
},
git: function() {
this.fs.copy(
this.templatePath('gitignore'),
this.destinationPath('.gitignore')
);
this.fs.copy(
this.templatePath('gitattributes'),
this.destinationPath('.gitattributes')
);
},
bower: function() {
var bower = {
name: this._.slugify(this.appname),
private: true,
dependencies: {},
};
if (this.includeBootstrap) {
var bs = 'bootstrap' + (this.includeSass ? '-sass' : '');
bower.dependencies[bs] = '~3.3.1';
}
if (this.includeModernizr) {
bower.dependencies.modernizr = '~2.8.1';
}
if (this.includeAngular) {
bower.dependencies.angular = '~1.3.15';
}
if (this.includeJQuery) {
bower.dependencies.jquery = '~2.1.1';
}
this.fs.copy(this.templatePath('bowerrc'), this.destinationPath('.bowerrc'));
this.write('bower.json', JSON.stringify(bower, null, 2));
},
jshint: function() {
this.fs.copy(
this.templatePath('jshintrc'),
this.destinationPath('.jshintrc')
);
},
mainStylesheet: function() {
var css = 'main';
if (this.includeSass) {
css += '.scss';
} else {
css += '.css';
}
this.copy(css, 'app/styles/' + css);
},
writeIndex: function() {
this.indexFile = this.src.read('index.html');
this.indexFile = this.engine(this.indexFile, this);
// wire Bootstrap plugins
if (this.includeBootstrap) {
var bs = '/bower_components/';
if (this.includeSass) {
bs += 'bootstrap-sass/assets/javascripts/bootstrap/';
} else {
bs += 'bootstrap/js/';
}
this.indexFile = this.appendScripts(
this.indexFile,
'scripts/plugins.js',
[
bs + 'affix.js',
bs + 'alert.js',
bs + 'dropdown.js',
bs + 'tooltip.js',
bs + 'modal.js',
bs + 'transition.js',
bs + 'button.js',
bs + 'popover.js',
bs + 'carousel.js',
bs + 'scrollspy.js',
bs + 'collapse.js',
bs + 'tab.js',
]
);
}
this.indexFile = this.appendFiles({
html: this.indexFile,
fileType: 'js',
optimizedPath: 'scripts/main.js',
sourceFileList: ['scripts/main.js'],
});
this.write('app/index.html', this.indexFile);
},
app: function() {
this.copy('main.js', 'app/scripts/main.js');
},
},
install: function() {
var howToInstall =
'\nAfter running ' +
chalk.yellow.bold('npm install & bower install') +
', inject your' +
'\nfront end dependencies by running ' +
chalk.yellow.bold('gulp wiredep') +
'.';
if (this.options['skip-install']) {
this.log(howToInstall);
return;
}
this.installDependencies();
this.on(
'end',
function() {
var bowerJson = this.dest.readJSON('bower.json');
// wire Bower packages to .html
wiredep({
bowerJson: bowerJson,
directory: 'bower_components',
exclude: ['bootstrap-sass', 'bootstrap.js'],
ignorePath: /^(\.\.\/)*\.\./,
src: 'app/index.html',
});
if (this.includeSass) {
// wire Bower packages to .scss
wiredep({
bowerJson: bowerJson,
directory: 'bower_components',
ignorePath: /^(\.\.\/)+/,
src: 'app/styles/*.scss',
});
}
}.bind(this)
);
},
});
I have this app where I take picture with cordova camera then move it into file-system , save the imgpath for the image into sqlite db and display it, I'm trying to encrypt the imgPath for the image which is saved on ccordova.file.data directory , I tried cordova safe plugin https://github.com/disusered/cordova-safe ,
but I keep getting "Error with cryptographic operation".
Any help would be appreciated
var db = null;
angular.module('starter', ['ionic', 'ngCordova'])
.run(function($ionicPlatform, $cordovaSQLite) {
$ionicPlatform.ready(function() {
try {
db = $cordovaSQLite.openDB({
name: "my.db",
location: 'default'
});
$cordovaSQLite.execute(db,"CREATE TABLE IF NOT EXISTS imageTable " + "(id integer primary key, image text)");
} catch (e) {
alert(e);
} finally { }
if (window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
cordova.plugins.Keyboard.disableScroll(true);
}
if (window.StatusBar) {
StatusBar.styleDefault();
}
});
})
.controller('ImageCtrl', function($scope, $rootScope, $state, $stateParams, $cordovaDevice, $cordovaFile, $ionicActionSheet, $cordovaCamera, $cordovaFile, $cordovaDevice, $ionicPopup, $cordovaActionSheet, $cordovaSQLite, $interval) {
var imagesP = [];
//$scope.images = [];
$scope.showAlert = function(title, msg) {
var alertPopup = $ionicPopup.alert({
title: title,
template: msg
});
};
$scope.loadImage = function() {
var options = {
title: 'Select Receipts Image ',
buttonLabels: ['Gallery', 'Take photo', 'File System'],
addCancelButtonWithLabel: 'Cancel',
androidEnableCancelButton: true,
};
$cordovaActionSheet.show(options).then(function(btnIndex) {
var type = null;
if (btnIndex === 1) {
type = Camera.PictureSourceType.PHOTOLIBRARY;
} else if (btnIndex === 2) {
type = Camera.PictureSourceType.CAMERA;
}
if (type !== null) {
$scope.selectPicture(type);
}
});
}
// Take image with the camera or from library and store it inside the app folder
// Image will not be saved to users Library.
$scope.selectPicture = function(sourceType) {
var options = {
quality: 75,
destinationType: Camera.DestinationType.FILE_URI,
sourceType: sourceType,
allowEdit: true,
encodingType: Camera.EncodingType.JPEG,
correctOrientation: true,
targetWidth: 800,
targetHeight: 800,
popoverOptions: CameraPopoverOptions, // for IOS and IPAD
saveToPhotoAlbum: false
};
$cordovaCamera.getPicture(options).then(function(imagePath) {
// Grab the file name of the photo in the temporary directory
var currentName = imagePath.replace(/^.*[\\\/]/, '');
// alert(currentName);
//Create a new name for the photo to avoid duplication
var d = new Date(),
n = d.getTime(),
newFileName = n + ".jpg";
//alert(newFileName);
// If you are trying to load image from the gallery on Android we need special treatment!
if ($cordovaDevice.getPlatform() == 'Android' && sourceType === Camera.PictureSourceType.PHOTOLIBRARY) {
window.FilePath.resolveNativePath(imagePath, function(entry) {
window.resolveLocalFileSystemURL(entry, success, fail);
function fail(e) {
console.error('Error: ', e);
}
function success(fileEntry) {
var namePath = fileEntry.nativeURL.substr(0, fileEntry.nativeURL.lastIndexOf('/') + 1);
// Only copy because of access rights
$cordovaFile.copyFile(namePath, fileEntry.name, cordova.file.dataDirectory, newFileName).then(function(success) {
// $scope.image = newFileName;
var imgPath = cordova.file.dataDirectory + newFileName;
$scope.add(imgPath);
$scope.encryptFile(imgPath);
}, function(error) {
$scope.showAlert('Error', error.exception);
});
// alert( fileEntry.nativeURL);
};
});
} else {
var namePath = imagePath.substr(0, imagePath.lastIndexOf('/') + 1);
// Move the file to permanent storage
$cordovaFile.moveFile(namePath, currentName, cordova.file.dataDirectory, newFileName).then(function(success) {
// $scope.image = newFileName;
//$scope.images.push(newFileName);
var imgPath = cordova.file.dataDirectory + newFileName;
$scope.add(imgPath);
}, function(error) {
$scope.showAlert('Error', error.exception);
});
}
},
function(err) {
// Not always an error, maybe cancel was pressed...
})
};
$scope.add = function(path) {
if (imagesP != null) {
$cordovaSQLite.execute(db, "INSERT INTO imageTable (images) VALUES(?)", [path] );
}
alert("Inserted.");
},
function(e) {
alert(e);
};
$scope.encryptFile = function(file){
var safe = cordova.plugins.disusered.safe,
key = 'someKeyABC';
function success(encryptedFile) {
console.log('Encrypted file: ' + encryptedFile);
}
function error() {
console.log('Error with cryptographic operation');
}
safe.encrypt(file, key, success, error);
}
$scope.ShowAllData = function() {
$scope.images = [];
$cordovaSQLite.execute(db,"SELECT images FROM imageTable").then(function(res) {
if (res.rows.length > 0) {
for (var i = 0; i < res.rows.length; i++) {
$scope.images.push({
id: res.rows.item(i).id,
image: res.rows.item(i).images
});
}
}
}, function(error) {
alert(error);
} );
}
We have a CMS so I don't have access to the header of the HTML page which gets rendered for our extjs implementation. So I had to make a workaround which is like this:
Ext.local = {};
var lang = {
initLang: function (revisionNr) {
var local = localStorage.getItem('localLang')
if (!local) {
AjaxHandlerByClass('ajax/lang/webuser/init', {}, this.loadLangRemote);
} else {
local = JSON.parse(local);
if (local.revisionNr == config.revisionNr && local.lang == config.lang) {
console.log('loading local lang variables');
if (local.date < new Date().getTime() - (24 * 60 * 60 * 1000) * 2) {//2 day caching time before retry
delete window.localStorage.localLangBackup;
}
this.loadLangLocal(local);
} else {
delete window.localStorage.localLang;
AjaxHandlerByClass('ajax/lang/webuser/init', {}, this.loadLangRemote);
}
}
},
loadLangRemote: function (data) {
data.revisionNr = config.revisionNr;
data.lang = config.lang;
data.date = new Date().getTime();
lang.loadLangLocal(data);
localStorage.setItem('localLang', JSON.stringify(data));
},
loadLangLocal: function (data) {
var jsElm = document.createElement("script");
jsElm.type = "application/javascript";
jsElm.src = 'js/freetext-deploy.min.js?rev={/literal}{$revisionNr}{literal}';
document.getElementsByTagName('head')[0].appendChild(jsElm);
Ext.Date.defaultFormat = 'd-m-Y';
if (!debug) {
Ext.Loader.config.disableCaching = true;
}
Ext.application({
name: 'freetextOrder',
appFolder: 'modules/extjs/freetextOrder/app',
controllers: [
'Main'
],
launch: function () {
var freetextOrder = Ext.create('Ext.container.Container', {
renderTo: Ext.get('freetextOrderDiv'),
layout: 'fit',
id: 'catalogAdministrationDiv_ext',
height: 800,
cls: 'x-dig-override',
items: [Ext.create('freetextOrder.view.base.MainView', {})],
layout:'fit'
});
}
});
Ext.local = data;
}
};
lang.initLang();
The problem I'm having is that the minified version gets ignored completely. I see it load on the http request but extjs ignores them.... even though I can see the objects are being created after include (via console log)
Anyone any idea how I can achieve this?
as i see none found the answer so i post my own here wich i came up with.
Since i could for the love of god not load the damn thing i refactored the loader and exported it into a Js. file. wich i reqired and called later on in code.
exported lang.js file:
Ext.define('Lang', {
singleton: true,
ApplicationConf: null,
Launch: function (launchConfig) {
this.ApplicationConf = launchConfig;
var local = localStorage.getItem('localLang');
var me = this;
this.loadLangRemote = function (data) {
debugger;
data.revisionNr = config.revisionNr;
data.lang = config.lang;
data.date = new Date().getTime();
me.loadLangLocal(data);
localStorage.setItem('localLang', JSON.stringify(data));
};
this.loadLangLocal = function (data) {
Ext.local = data;
Ext.lang = function (langId) {
if (Ext.local[langId]) {
return Ext.local[langId];
}
delete window.localStorage.localLang;
localStorage.setItem('localLangBackup', true);
return langId;
}
Ext.application(me.ApplicationConf);
};
if (!local) {
Ext.Ajax.request({
url: 'ajax/lang/webuser/init',
params: {
sid: sid,
},
success: function (data) {
debugger;
me.loadLangRemote(Ext.JSON.decode(data.responseText));
}
})
} else {
local = JSON.parse(local);
if (local.revisionNr == config.revisionNr && local.lang == config.lang) {
console.log('loading local lang variables');
if (local.date < new Date().getTime() - (24 * 60 * 60 * 1000) * 2) {//2 day caching time before retry
delete window.localStorage.localLangBackup;
}
debugger;
me.loadLangLocal(local);
} else {
delete window.localStorage.localLang;
Ext.Ajax.request({
url: 'ajax/lang/webuser/init',
params: {
sid: sid,
},
success: function (data) {
me.loadLangRemote(Ext.JSON.decode(data.responseText));
}
})
}
}
},
})
And IMPORTANT was to add the
Ext.onReady(function () {
Lang.Launch({
name: 'catalogAdministration',
appFold....
To the call of the Launch function in code, bacause it would have been not defined at run time. i added the file to the minified file first and call the Lang.Launch instead Ext.Application.
Hope somone has use of my solution :)
I am creating a BackboneJS project. It works fine in Chrome and Safari, but in Firefox I get errors that stop my app from loading and I cannot work out why.
The error is in my jQuery file but it is obviously something in my app that is triggering it because the jQuery library is fine on its own.
It is throwing an error on the second line of the jQuery "createSafeFragment" method:
function createSafeFragment( document ) {
var list = nodeNames.split( "|" ),
safeFrag = document.createDocumentFragment();
if ( safeFrag.createElement ) {
while ( list.length ) {
safeFrag.createElement(
list.pop()
);
}
}
return safeFrag;
}
My main.js that runs the app:
Backbone.View.prototype.close = function () {
if (this.beforeClose) {
this.beforeClose();
}
this.remove();
this.unbind();
};
var AppRouter = Backbone.Router.extend({
routes: {
'': 'home',
'login' : 'login',
'register' : 'register',
'rosters' : 'rosters',
'workplaces' : 'workplaces',
'groups' : 'groups',
'shifts' : 'shifts',
'logout' : 'logout'
},
content : '#content',
initialize: function () {
window.headerView = new HeaderView();
$('.header').html(window.headerView.render().el);
},
home: function () {
window.homePage = window.homePage ? window.homePage : new HomePageView();
app.showView( content, window.homePage);
window.headerView.select('home');
},
register: function () {
window.registerPage = window.registerPage ? window.registerPage : new RegisterPageView();
app.showView( content, window.registerPage);
window.headerView.select('register');
},
login: function() {
app.showView( content, new LoginPageView());
window.headerView.select('login');
},
rosters: function () {
if(Utils.checkLoggedIn()){
app.showView( content, new RosterPageView());
window.headerView.select('rosters');
}
},
groups: function () {
if(Utils.checkLoggedIn()){
app.showView( content, new GroupsPageView());
window.headerView.select('groups');
}
},
shifts: function () {
if(Utils.checkLoggedIn()){
app.showView( content, new ShiftsPageView());
window.headerView.select('shifts');
}
},
workplaces: function () {
if(Utils.checkLoggedIn()){
app.showView( content, new WorkplacesPageView());
window.headerView.select('workplaces');
}
},
logout: function () {
window.headerView.toggleLogin(false);
this.login();
},
showView: function(selector, view) {
if (this.currentView)
this.currentView.close();
$(selector).html(view.render().el);
this.currentView = view;
return view;
}
});
Utils.loadTemplates(['HomePageView', 'HeaderView', 'LoginPageView', 'RegisterPageView',
'RostersPageView', 'GroupsPageView', 'ShiftsPageView', 'UserListView',
'GroupListView', 'ShiftListView', 'SearchedUserListView', 'SearchedGroupListView',
'GroupRosterView', 'RosterListView', 'WorkplacesPageView', 'WorkplaceListView',
'SearchedWorkplaceListView', 'RosterJoinListView', 'GroupUserListView',
'WorkplaceRosterView', 'WorkplaceUserListView', 'RosterShiftView'], function(){
app = new AppRouter();
Backbone.history.start();
});
And my Util.js:
Utils = {
//template stuff
templates: {},
loadTemplates: function(names, callback) {
var that = this;
var loadTemplate = function(index) {
var name = names[index];
$.get('tpl/' + name + '.html', function(data) {
that.templates[name] = data;
index++;
if (index < names.length) {
loadTemplate(index);
} else {
callback();
}
});
};
loadTemplate(0);
},
get: function(name) {
return this.templates[name];
},
//error stuff
showAlertMessage: function(message, type){
$('#error').html(message);
$('.alert').addClass(type);
$('.alert').show();
},
showErrors: function(errors) {
_.each(errors, function (error) {
var controlGroup = $('.' + error.name);
controlGroup.addClass('error');
controlGroup.find('.help-inline').text(error.message);
}, this);
},
hideErrors: function () {
$('.control-group').removeClass('error');
$('.help-inline').text('');
},
//validator stuff
validateModel: function(model, attrs){
Utils.hideErrors();
var valError = model.validate(attrs);
if(valError){
Utils.showErrors(valError);
return false;
}
return true;
},
//loading stuff
toggleLoading: function(toggle){
$('#loading').css('visibility', toggle ? 'visible' : 'hidden');
},
//login stuff
login: function(auth){
window.headerView.toggleLogin(true);
Backbone.history.navigate("", true);
},
checkLoggedIn: function(){
if(!window.userId){
window.headerView.toggleLogin(false);
Backbone.history.navigate("login", true);
return false;
}
return true;
},
//util methods
formatDate: function(date){
var formattedDate = '';
formattedDate += date.getFullYear() + '-';
formattedDate += date.getMonth()+1 + '-';
formattedDate += date.getDate();
return formattedDate;
},
formatDateForDisplay: function(date){
var formattedDate = '';
formattedDate += date.getDate() + '/';
formattedDate += date.getMonth()+1 + '/';
formattedDate += date.getFullYear() + ' - ';
formattedDate += ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'][date.getDay()];
return formattedDate;
},
formatDateForGroup: function(date){
var formattedDate = '';
formattedDate += date.getDate() + '/';
formattedDate += date.getMonth()+1;
return formattedDate;
},
showPopup: function(id, buttons, title, content){
var popup = $(id);
popup.dialog({
modal: true,
title: title,
buttons: buttons
});
popup.find('#popupContent').html(content);
}
};
Someone please help me as this is driving me crazy! Firefox only...
I was also experiencing this problem. You can reproduce this error by doing:
$(window).append('bla');
Mine was cause by a combination of this:
click
and
function doIt(){
var newElm = $('<span>hi</span>');
$(this).append(newElm);
//now this === window, and not what I was expecting the a-element
}
This all happened because I expected the click would have been binded in a proper more-jquery-ish way to the a element. But someone decided to use 1999 code ;p. I expected for the method to be bound like this:
$("a").click(doIt);
In which case this would have been bound to the a-element and not to the window.
benhowdle89 figured out that I was appending to content when I should have been appending to this.content.
It is also a good idea to always use JSFiddle I have realised, so other people can see your problem on their own.
Thanks to benhowdle89!