});
Filex.File = OfflineModel.extend({
+ defaults: {
+ checked: false
+ },
+
isDir: function() {
return false;
},
isHidden: function() {
return this.get('name')[0] == '.';
+ },
+
+ toggle: function() {
+ this.set('checked', !this.get('checked'));
}
});
case 'file':
return new Filex.File(attrs, options);
default:
- console.log('Unknown model type:', attrs['type']);
+ console.error('Unknown model type:', attrs['type']);
}
},
model: Filex.PathBit,
initialize: function() {
- this.listenTo(this, 'reset', this.setActive);
- this.listenTo(this, 'add', this.setActive);
+ this.listenTo(this, 'reset add', this.setActive);
},
setActive: function() {
tagName: 'tr',
events: {
- 'click .link': 'selected'
+ 'click': 'click'
},
initialize: function(options) {
this.view = options.view;
+ this.listenTo(this.model, 'change', this.render);
this.listenTo(this.model, 'remove', this.remove);
this.listenTo(this.model, 'hidden', this.toggleHidden);
},
path: this.view.path.full(),
name: this.model.get('name')
});
+ data['cid'] = this.model.cid;
this.$el.html(this.template()(data));
this.toggleHidden();
this.$el.toggleClass('hidden', this.model.isHidden() && !this.view.showHidden());
},
- selected: function(e) {
- if (this.model.isDir()) {
- e.preventDefault();
- this.model.trigger('selected:dir', this.model);
+ click: function(e) {
+ if (e.target.className == 'link') {
+ if (this.model.isDir()) {
+ e.preventDefault();
+ this.model.trigger('selected:dir', this.model);
+ }
+
+ return;
}
+
+ this.model.toggle();
}
});
events: {
'change #show-hidden': 'toggleHidden',
- 'click #host-controls .view': 'hostEdit'
+ 'click #select-all': 'selectAll',
+ 'click #btn-refresh': 'reloadFiles',
+ 'click #btn-favorites': 'toggleFavorites',
+ 'click #btn-host': 'editHost'
},
initialize: function(options) {
this.$noItems = $('#no-items');
this.$error = $('#error');
this.$showHidden = $('#show-hidden');
- this.$host = $('#host-controls');
+ this.$selectAll = $('#select-all');
+ this.$favorites = $('#btn-favorites');
+ this.$host = $('#btn-host');
- this.host = options.host;
this.path = new Filex.Path();
this.files = new Filex.FileList();
this.listenTo(this.path, 'reset', this.resetPath);
- this.listenTo(this.path, 'add', this.reloadFiles);
this.listenTo(this.path, 'add', this.addPath);
+ this.listenTo(this.path, 'add reset', this.changedPath);
this.listenTo(this.path, 'selected', this.selectedPath);
this.listenTo(this.files, 'reset', this.resetFiles);
this.listenTo(this.files, 'selected:dir', this.selectedDir);
+ this.listenTo(this.files, 'change:checked', this.updateSelectAll);
// used in selectize callbacks
var view = this,
optionTemplate = _.template('<div><div><%= host %></div><div class="small text-muted"><%= path %></div></div>');
this.$('#host-selector').selectize({
- valueField: 'host',
+ optgroupField: 'group',
labelField: 'host',
searchField: ['host', 'path'],
sortField: [
{field: 'host', direction: 'asc'},
{field: 'path', direction: 'asc'}
],
- items: [this.host],
- options: options.hostOptions,
+ options: options.locations,
+ optgroups: [
+ {value: 'sys', label: 'Podstawowe'},
+ {value: 'usr', label: 'Użytkownika'}
+ ],
+ lockOptgroupOrder: true,
+ create: function(input, callback) {
+ var $form = $('#favorite-form'),
+ parts = input.split('/', 1),
+ callback_called = false;
+
+ $form.find('#id_host').val(parts[0]);
+
+ if (parts.length > 1)
+ $form.find('#id_path').val(parts[1]);
+
+ $form.on('submit', function(e) {
+ var $this = $(this),
+ $btn = $this.find('[type="submit"]');
+
+ e.preventDefault();
+ $btn.button('loading');
+
+ $.post($this.attr('action'), $this.serialize(), function(data) {
+ callback(data);
+ callback_called = true;
+
+ $this.modal('hide');
+ $btn.button('reset');
+ }, 'json').fail(function() {
+ console.error(arguments);
+ $btn.button('error');
+ });
+ });
+
+ $form.one('hide.bs.modal', function() {
+ if (!callback_called)
+ callback();
+ $form.off();
+ });
+
+ $form.modal();
+ },
render: {
option: function(item) {
return optionTemplate(item);
+ },
+ option_create : function(data, escape) {
+ return '<div class="create">Dodaj <em>' + escape(data.input) + '</em>…</div>';
}
},
- onDropdownClose: function() {
+ onItemAdd: function(value) {
+ view.load(value);
this.blur();
},
onBlur: function() {
- view.$host.toggleClass('editing');
-
- var value = this.getValue();
- if (!value) {
- this.addItem(view.host, true);
- return;
- }
-
- if (value != view.host) {
- var location = this.options[value];
-
- view.host = location.host;
- view.navigate(location.path);
- }
+ $('#host').removeClass('edit');
+ this.clear();
}
});
this.hostSelectize = this.$('#host-selector')[0].selectize;
this.render();
- this.navigate(this.hostSelectize.options[this.host].path);
},
render: function() {
- this.$host.find('.view').text(this.host);
- this.$noItems.toggle((this.showHidden() ? !Boolean(this.files.length) : !Boolean(this.files.visible().length)));
+ this.updateSelectAll();
+ this.updateFavorites();
+ this.$noItems.toggle(!Boolean(this.visibleFiles().length));
this.$error.hide();
},
- navigate: function(path) {
- var pathBits = [new Filex.PathBit({'text': '/', 'path': ''})];
-
- pathBits = pathBits.concat(_.map(path.replace(/(^\/+|\/+$)/g, '').split('/'), function(name) {
- return new Filex.PathBit({'text': name, 'path': name});
- }));
+ load: function(location) {
+ var path = location.replace(/(^\/+|\/+$)/g, '').split('/'),
+ host = path.shift(),
+ pathBits = [new Filex.PathBit({'text': '/', 'path': ''})].concat(_.map(path, function(name) {
+ return new Filex.PathBit({'text': name, 'path': name});
+ }));
+ this.host = host;
this.path.reset(pathBits);
+
+ this.$host.text(this.host);
},
reloadFiles: function() {
var msg = (response.responseJSON || {}).msg || 'Błąd serwera';
+ view.$noItems.hide();
view.$error.find('.msg').text(msg);
view.$error.show();
view.idle();
},
resetPath: function(models, options) {
- this.reloadFiles();
-
_.each(options.previousModels, function(model) {
model.trigger('remove');
});
},
selectedPath: function(bit) {
- var newPath = this.path.slice(0, this.path.indexOf(bit) + 1);
- this.path.set(newPath);
- this.reloadFiles();
+ this.path.reset(this.path.slice(0, this.path.indexOf(bit) + 1));
},
showHidden: function() {
return this.$showHidden[0].checked;
},
- hostEdit: function() {
- this.$host.toggleClass('editing');
- this.hostSelectize.focus();
- },
-
busy: function() {
this.$el.addClass('busy');
},
idle: function() {
this.$el.removeClass('busy');
+ },
+
+ visibleFiles: function() {
+ return this.showHidden() ? this.files.models : this.files.visible();
+ },
+
+ selectedFiles: function() {
+ return _.filter(this.visibleFiles(), function(item) {
+ return item.get('checked');
+ });
+ },
+
+ selectAll: function() {
+ var checked = this.$selectAll[0].checked;
+
+ _.each(this.visibleFiles(), function(item) {
+ item.set('checked', checked);
+ })
+ },
+
+ updateSelectAll: function() {
+ if (this.visibleFiles().length) {
+ this.$selectAll.prop('disabled', false);
+ this.$selectAll.prop('checked', this.selectedFiles().length == this.visibleFiles().length);
+ }
+ else {
+ this.$selectAll.prop('disabled', true);
+ this.$selectAll.prop('checked', false);
+ }
+ },
+
+ clearSelection: function() {
+ _.each(this.visibleFiles(), function(item) {
+ item.set('checked', false);
+ });
+ },
+
+ toggleFavorites: function() {
+ var $btn = this.$favorites,
+ locations = this.hostSelectize,
+ is_active = $btn.hasClass('active'),
+ url = is_active ? '/filex/fav/delete/' : '/filex/fav/add/',
+ data = {
+ host: this.host,
+ path: this.path.full()
+ };
+
+ $btn.button('loading');
+
+ $.post(url, data, 'json').done(function () {
+ $btn.button('reset');
+
+ if (is_active) {
+ locations.removeOption(data.host + data.path);
+ }
+ else {
+ locations.addOption({
+ group: 'usr',
+ host: data.host,
+ path: data.path,
+ value: data.host + data.path
+ });
+ }
+ }).fail(function() {
+ $btn.button('reset');
+ $btn.button('toggle');
+
+ console.error(arguments);
+ });
+ },
+
+ initialLoad: function() {
+ if (!this.host) {
+ var opts = this.hostSelectize.options;
+
+ this.load(opts[Object.keys(opts)[0]].value);
+ }
+ },
+
+ changedPath: function () {
+ this.reloadFiles();
+ this.updateFavorites();
+ },
+
+ updateFavorites: function() {
+ var loc = this.host + this.path.full(),
+ favorites = this.hostSelectize.options;
+
+ if (favorites.hasOwnProperty(loc)) {
+ if (favorites[loc].group == 'sys') {
+ this.$favorites.addClass('disabled').prop('disabled', true);
+ if (this.$favorites.hasClass('active'))
+ this.$favorites.button('toggle');
+ }
+ else {
+ this.$favorites.removeClass('disabled').prop('disabled', false);
+ if (!this.$favorites.hasClass('active'))
+ this.$favorites.button('toggle');
+ }
+ }
+ else {
+ this.$favorites.removeClass('disabled').prop('disabled', false);
+ if (this.$favorites.hasClass('active'))
+ this.$favorites.button('toggle');
+ }
+ },
+
+ editHost: function() {
+ $('#host').addClass('edit');
+ this.hostSelectize.focus();
}
});
});