mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-12 04:23:19 +00:00
Split ListView by adding a CreateView
This commit is contained in:

committed by
Romain Neutron

parent
f886874f8d
commit
5c8cb9973e
@@ -22,12 +22,25 @@
|
|||||||
<script type="text/template" id="item_list_view_template">
|
<script type="text/template" id="item_list_view_template">
|
||||||
<div class="row-fluid">
|
<div class="row-fluid">
|
||||||
<div class="span12">
|
<div class="span12">
|
||||||
<div class="sidebar-block">
|
<div class="create-subview"></div>
|
||||||
<button type="button" class="btn btn-success btn-add-field"><i class="icon-plus icon-white"></i>{% trans %}Add new field{% endtrans %}</button>
|
<div class="sidebar-search-block">
|
||||||
</div>
|
|
||||||
<div class="sidebar-block">
|
|
||||||
<input class="input-block-level" type="text" id="live_search" placeholder="{% trans %}Live search{% endtrans %}"/>
|
<input class="input-block-level" type="text" id="live_search" placeholder="{% trans %}Live search{% endtrans %}"/>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row-fluid">
|
||||||
|
<div class="span12 list-block">
|
||||||
|
<ul id="collection-fields" class="unstyled"></ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/template" id="create_template">
|
||||||
|
<div class="row-fluid">
|
||||||
|
<div class="span12">
|
||||||
|
<div class="sidebar-add-block">
|
||||||
|
<button type="button" class="btn btn-success btn-add-field"><i class="icon-plus icon-white"></i>{% trans %}Add new field{% endtrans %}</button>
|
||||||
|
</div>
|
||||||
<div class="well well-small add-field-block" style="display:none">
|
<div class="well well-small add-field-block" style="display:none">
|
||||||
<h3>{% trans %}Add a new field{% endtrans %}</h3>
|
<h3>{% trans %}Add a new field{% endtrans %}</h3>
|
||||||
<form class="form-horizontal">
|
<form class="form-horizontal">
|
||||||
@@ -58,11 +71,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row-fluid">
|
|
||||||
<div class="span12 list-block">
|
|
||||||
<ul id="collection-fields" class="unstyled"></ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/template" id="edit_template">
|
<script type="text/template" id="edit_template">
|
||||||
|
24
www/scripts/apps/admin/fields/views.js
Normal file
24
www/scripts/apps/admin/fields/views.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
define([
|
||||||
|
"jquery",
|
||||||
|
"underscore",
|
||||||
|
"backbone"
|
||||||
|
], function($, _, Backbone) {
|
||||||
|
return {
|
||||||
|
MultiViews : {
|
||||||
|
// bind a subview to a DOM element
|
||||||
|
_assignView: function(selector, view) {
|
||||||
|
var selectors;
|
||||||
|
if (_.isObject(selector)) {
|
||||||
|
selectors = selector;
|
||||||
|
} else {
|
||||||
|
selectors = {};
|
||||||
|
selectors[selector] = view;
|
||||||
|
}
|
||||||
|
if (!selectors) return;
|
||||||
|
_.each(selectors, function(view, selector) {
|
||||||
|
view.setElement(this.$(selector)).render();
|
||||||
|
}, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
143
www/scripts/apps/admin/fields/views/create.js
Normal file
143
www/scripts/apps/admin/fields/views/create.js
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
define([
|
||||||
|
"jquery",
|
||||||
|
"underscore",
|
||||||
|
"backbone",
|
||||||
|
"i18n",
|
||||||
|
"bootstrap",
|
||||||
|
"apps/admin/fields/views/create",
|
||||||
|
"models/field"
|
||||||
|
], function($, _, Backbone, i18n, bootstrap, AlertView, FieldModel) {
|
||||||
|
var CreateView = Backbone.View.extend({
|
||||||
|
tagName: "div",
|
||||||
|
events: {
|
||||||
|
"click .btn-submit-field": "createAction",
|
||||||
|
"click .btn-add-field": "toggleCreateFormAction",
|
||||||
|
"click .btn-cancel-field": "toggleCreateFormAction"
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
var template = _.template($("#create_template").html());
|
||||||
|
|
||||||
|
this.$el.html(template);
|
||||||
|
|
||||||
|
$("#new-source", this.$el).autocomplete({
|
||||||
|
minLength: 2,
|
||||||
|
source: function(request, response) {
|
||||||
|
$.ajax({
|
||||||
|
url: "/admin/fields/tags/search",
|
||||||
|
dataType: "json",
|
||||||
|
data: {
|
||||||
|
term: request.term
|
||||||
|
},
|
||||||
|
success: function(data) {
|
||||||
|
response($.map(data, function(item) {
|
||||||
|
return {
|
||||||
|
label: item.label,
|
||||||
|
value: item.value
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).autocomplete("widget").addClass("ui-autocomplete-admin-field");
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
createAction: function(event) {
|
||||||
|
var self = this;
|
||||||
|
var formErrors = 0;
|
||||||
|
|
||||||
|
var fieldName = $("#new-name", this.$el);
|
||||||
|
var fieldNameValue = fieldName.val();
|
||||||
|
var fieldTag = $("#new-source", this.$el);
|
||||||
|
var fieldTagValue = fieldTag.val();
|
||||||
|
|
||||||
|
// check for empty field name
|
||||||
|
if ("" === fieldNameValue) {
|
||||||
|
fieldName
|
||||||
|
.closest(".control-group")
|
||||||
|
.addClass("error")
|
||||||
|
.find(".help-block")
|
||||||
|
.empty()
|
||||||
|
.append(i18n.t("validation_blank"));
|
||||||
|
|
||||||
|
formErrors++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for duplicate field name
|
||||||
|
if ("undefined" !== typeof AdminFieldApp.fieldsCollection.find(function(model){
|
||||||
|
return model.get("name").toLowerCase() === fieldNameValue.toLowerCase();
|
||||||
|
})) {
|
||||||
|
fieldName
|
||||||
|
.closest(".control-group")
|
||||||
|
.addClass("error")
|
||||||
|
.find(".help-block")
|
||||||
|
.empty()
|
||||||
|
.append(i18n.t("validation_name_exists"));
|
||||||
|
|
||||||
|
formErrors++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for format tag
|
||||||
|
if ("" !== fieldTagValue && false === /[a-z]+:[a-z0-9]+/i.test(fieldTagValue)) {
|
||||||
|
fieldTag
|
||||||
|
.closest(".control-group")
|
||||||
|
.addClass("error")
|
||||||
|
.find(".help-block")
|
||||||
|
.empty()
|
||||||
|
.append(i18n.t("validation_tag_invalid"));
|
||||||
|
|
||||||
|
formErrors++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formErrors > 0 ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var field = new FieldModel({
|
||||||
|
"sbas-id": AdminFieldApp.sbas_id,
|
||||||
|
"name": fieldNameValue,
|
||||||
|
"tag": fieldTagValue,
|
||||||
|
"multi": $("#new-multivalued", this.$el).is(":checked"),
|
||||||
|
"sorter": AdminFieldApp.fieldsCollection.max(function(model) {
|
||||||
|
return model.get("sorter");
|
||||||
|
}).get("sorter") + 1
|
||||||
|
});
|
||||||
|
|
||||||
|
field.save(null, {
|
||||||
|
success: function(field, response, options) {
|
||||||
|
if (response.success) {
|
||||||
|
AdminFieldApp.fieldsCollection.add(field);
|
||||||
|
_.last(self.itemViews).clickAction().animate();
|
||||||
|
}
|
||||||
|
|
||||||
|
new AlertView({
|
||||||
|
alert: response.success ? "success" : "error", message: response.message
|
||||||
|
}).render();
|
||||||
|
},
|
||||||
|
error: function(model, xhr, options) {
|
||||||
|
new AlertView({
|
||||||
|
alert: "error", message: i18n.t("something_wrong")}
|
||||||
|
).render();
|
||||||
|
|
||||||
|
self.toggleCreateFormAction();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
toggleCreateFormAction: function(event) {
|
||||||
|
var fieldBlock = $(".add-field-block", this.$el);
|
||||||
|
var addBtn = $(".btn-add-field", this.$el);
|
||||||
|
|
||||||
|
fieldBlock.is(":hidden") ? fieldBlock.show() : fieldBlock.hide();
|
||||||
|
|
||||||
|
addBtn.attr('disabled', !fieldBlock.is(":hidden"));
|
||||||
|
|
||||||
|
AdminFieldApp.resizeListBlock();
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return CreateView;
|
||||||
|
});
|
@@ -3,21 +3,18 @@ define([
|
|||||||
"underscore",
|
"underscore",
|
||||||
"backbone",
|
"backbone",
|
||||||
"i18n",
|
"i18n",
|
||||||
|
"apps/admin/fields/views",
|
||||||
"apps/admin/fields/views/alert",
|
"apps/admin/fields/views/alert",
|
||||||
"apps/admin/fields/views/modal",
|
"apps/admin/fields/views/modal",
|
||||||
"apps/admin/fields/views/dcField",
|
"apps/admin/fields/views/dcField",
|
||||||
"apps/admin/fields/errors/error"
|
"apps/admin/fields/errors/error"
|
||||||
], function($, _, Backbone, i18n, AlertView, ModalView, DcFieldView, Error) {
|
], function($, _, Backbone, i18n, ViewUtils, AlertView, ModalView, DcFieldView, Error) {
|
||||||
var FieldEditView = Backbone.View.extend({
|
// Add multiview methods
|
||||||
|
var FieldEditView = Backbone.View.extend(_.extend({}, ViewUtils.MultiViews, {
|
||||||
tagName: "div",
|
tagName: "div",
|
||||||
className: "field-edit",
|
className: "field-edit",
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
this.model.on("change", this._onModelChange, this);
|
this.model.on("change", this._onModelChange, this);
|
||||||
|
|
||||||
this.dcFieldsSubView = new DcFieldView({
|
|
||||||
collection: AdminFieldApp.dcFieldsCollection,
|
|
||||||
field: this.model
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
updateModel: function(model) {
|
updateModel: function(model) {
|
||||||
// unbind event to previous model
|
// unbind event to previous model
|
||||||
@@ -36,8 +33,11 @@ define([
|
|||||||
|
|
||||||
this.$el.empty().html(template);
|
this.$el.empty().html(template);
|
||||||
|
|
||||||
this._assign({
|
this._assignView({
|
||||||
".dc-fields-subview" : this.dcFieldsSubView
|
".dc-fields-subview" : new DcFieldView({
|
||||||
|
collection: AdminFieldApp.dcFieldsCollection,
|
||||||
|
field: this.model
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
var completer = $("#tag", this.$el).autocomplete({
|
var completer = $("#tag", this.$el).autocomplete({
|
||||||
@@ -220,20 +220,6 @@ define([
|
|||||||
|
|
||||||
this.render();
|
this.render();
|
||||||
},
|
},
|
||||||
// bind a subview to a DOM element
|
|
||||||
_assign: function(selector, view) {
|
|
||||||
var selectors;
|
|
||||||
if (_.isObject(selector)) {
|
|
||||||
selectors = selector;
|
|
||||||
} else {
|
|
||||||
selectors = {};
|
|
||||||
selectors[selector] = view;
|
|
||||||
}
|
|
||||||
if (!selectors) return;
|
|
||||||
_.each(selectors, function(view, selector) {
|
|
||||||
view.setElement(this.$(selector)).render();
|
|
||||||
}, this);
|
|
||||||
},
|
|
||||||
// select temView by index in itemList
|
// select temView by index in itemList
|
||||||
_selectModelView: function(index) {
|
_selectModelView: function(index) {
|
||||||
// select previous or next itemview
|
// select previous or next itemview
|
||||||
@@ -241,7 +227,7 @@ define([
|
|||||||
AdminFieldApp.fieldListView.itemViews[index].clickAction().animate();
|
AdminFieldApp.fieldListView.itemViews[index].clickAction().animate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
|
|
||||||
return FieldEditView;
|
return FieldEditView;
|
||||||
});
|
});
|
||||||
|
@@ -4,16 +4,13 @@ define([
|
|||||||
"underscore",
|
"underscore",
|
||||||
"backbone",
|
"backbone",
|
||||||
"i18n",
|
"i18n",
|
||||||
|
"apps/admin/fields/views",
|
||||||
"apps/admin/fields/views/listRow",
|
"apps/admin/fields/views/listRow",
|
||||||
"apps/admin/fields/views/alert",
|
"apps/admin/fields/views/create"
|
||||||
"models/field"
|
], function($, jqueryui, _, Backbone, i18n, ViewUtils, FieldListRowView, CreateView) {
|
||||||
], function($, jqueryui, _, Backbone, i18n, FieldListRowView, AlertView, FieldModel) {
|
var FieldListView = Backbone.View.extend(_.extend({}, ViewUtils.MultiViews, {
|
||||||
var FieldListView = Backbone.View.extend({
|
|
||||||
events: {
|
events: {
|
||||||
"keyup #live_search": "searchAction",
|
"keyup #live_search": "searchAction",
|
||||||
"click .btn-submit-field": "createAction",
|
|
||||||
"click .btn-add-field": "toggleCreateFormAction",
|
|
||||||
"click .btn-cancel-field": "toggleCreateFormAction",
|
|
||||||
"update-sort": "updateSortAction"
|
"update-sort": "updateSortAction"
|
||||||
},
|
},
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
@@ -56,26 +53,9 @@ define([
|
|||||||
|
|
||||||
this._renderList(this.collection);
|
this._renderList(this.collection);
|
||||||
|
|
||||||
$("#new-source", this.$el).autocomplete({
|
this._assignView({
|
||||||
minLength: 2,
|
".create-subview" : new CreateView()
|
||||||
source: function(request, response) {
|
});
|
||||||
$.ajax({
|
|
||||||
url: "/admin/fields/tags/search",
|
|
||||||
dataType: "json",
|
|
||||||
data: {
|
|
||||||
term: request.term
|
|
||||||
},
|
|
||||||
success: function(data) {
|
|
||||||
response($.map(data, function(item) {
|
|
||||||
return {
|
|
||||||
label: item.label,
|
|
||||||
value: item.value
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}).autocomplete("widget").addClass("ui-autocomplete-admin-field");
|
|
||||||
|
|
||||||
AdminFieldApp.resizeListBlock();
|
AdminFieldApp.resizeListBlock();
|
||||||
|
|
||||||
@@ -124,97 +104,6 @@ define([
|
|||||||
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
createAction: function(event) {
|
|
||||||
var self = this;
|
|
||||||
var formErrors = 0;
|
|
||||||
|
|
||||||
var fieldName = $("#new-name", this.$el);
|
|
||||||
var fieldNameValue = fieldName.val();
|
|
||||||
var fieldTag = $("#new-source", this.$el);
|
|
||||||
var fieldTagValue = fieldTag.val();
|
|
||||||
|
|
||||||
// check for empty field name
|
|
||||||
if ("" === fieldNameValue) {
|
|
||||||
fieldName
|
|
||||||
.closest(".control-group")
|
|
||||||
.addClass("error")
|
|
||||||
.find(".help-block")
|
|
||||||
.empty()
|
|
||||||
.append(i18n.t("validation_blank"));
|
|
||||||
|
|
||||||
formErrors++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for duplicate field name
|
|
||||||
if ("undefined" !== typeof this.collection.find(function(model){
|
|
||||||
return model.get("name").toLowerCase() === fieldNameValue.toLowerCase();
|
|
||||||
})) {
|
|
||||||
fieldName
|
|
||||||
.closest(".control-group")
|
|
||||||
.addClass("error")
|
|
||||||
.find(".help-block")
|
|
||||||
.empty()
|
|
||||||
.append(i18n.t("validation_name_exists"));
|
|
||||||
|
|
||||||
formErrors++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for format tag
|
|
||||||
if ("" !== fieldTagValue && false === /[a-z]+:[a-z0-9]+/i.test(fieldTagValue)) {
|
|
||||||
fieldTag
|
|
||||||
.closest(".control-group")
|
|
||||||
.addClass("error")
|
|
||||||
.find(".help-block")
|
|
||||||
.empty()
|
|
||||||
.append(i18n.t("validation_tag_invalid"));
|
|
||||||
|
|
||||||
formErrors++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (formErrors > 0 ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var field = new FieldModel({
|
|
||||||
"sbas-id": AdminFieldApp.sbas_id,
|
|
||||||
"name": fieldNameValue,
|
|
||||||
"tag": fieldTagValue,
|
|
||||||
"multi": $("#new-multivalued", this.$el).is(":checked"),
|
|
||||||
"sorter": this.collection.max(function(model) {
|
|
||||||
return model.get("sorter");
|
|
||||||
}).get("sorter") + 1
|
|
||||||
});
|
|
||||||
|
|
||||||
field.save(null, {
|
|
||||||
success: function(field, response, options) {
|
|
||||||
if (response.success) {
|
|
||||||
self.collection.add(field);
|
|
||||||
_.last(self.itemViews).clickAction().animate();
|
|
||||||
}
|
|
||||||
|
|
||||||
new AlertView({
|
|
||||||
alert: response.success ? "success" : "error", message: response.message
|
|
||||||
}).render();
|
|
||||||
},
|
|
||||||
error: function(model, xhr, options) {
|
|
||||||
new AlertView({
|
|
||||||
alert: "error", message: i18n.t("something_wrong")}
|
|
||||||
).render();
|
|
||||||
|
|
||||||
self.toggleCreateFormAction();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
toggleCreateFormAction: function(event) {
|
|
||||||
var fieldBlock = $(".add-field-block", this.$el);
|
|
||||||
|
|
||||||
fieldBlock.is(":hidden") ? fieldBlock.show() : fieldBlock.hide();
|
|
||||||
AdminFieldApp.resizeListBlock();
|
|
||||||
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
updateSortAction: function(event, model, ui) {
|
updateSortAction: function(event, model, ui) {
|
||||||
var position = ui.item.index();
|
var position = ui.item.index();
|
||||||
this.collection.remove(model, {silent: true});
|
this.collection.remove(model, {silent: true});
|
||||||
@@ -238,7 +127,7 @@ define([
|
|||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
|
|
||||||
return FieldListView;
|
return FieldListView;
|
||||||
});
|
});
|
||||||
|
@@ -22,12 +22,25 @@
|
|||||||
<script type="text/template" id="item_list_view_template">
|
<script type="text/template" id="item_list_view_template">
|
||||||
<div class="row-fluid">
|
<div class="row-fluid">
|
||||||
<div class="span12">
|
<div class="span12">
|
||||||
<div class="sidebar-block">
|
<div class="create-subview"></div>
|
||||||
<button type="button" class="btn btn-success btn-add-field"><i class="icon-plus icon-white"></i>{% trans %}Add new field{% endtrans %}</button>
|
<div class="sidebar-search-block">
|
||||||
</div>
|
|
||||||
<div class="sidebar-block">
|
|
||||||
<input class="input-block-level" type="text" id="live_search" placeholder="{% trans %}Live search{% endtrans %}"/>
|
<input class="input-block-level" type="text" id="live_search" placeholder="{% trans %}Live search{% endtrans %}"/>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row-fluid">
|
||||||
|
<div class="span12 list-block">
|
||||||
|
<ul id="collection-fields" class="unstyled"></ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/template" id="create_template">
|
||||||
|
<div class="row-fluid">
|
||||||
|
<div class="span12">
|
||||||
|
<div class="sidebar-add-block">
|
||||||
|
<button type="button" class="btn btn-success btn-add-field"><i class="icon-plus icon-white"></i>{% trans %}Add new field{% endtrans %}</button>
|
||||||
|
</div>
|
||||||
<div class="well well-small add-field-block" style="display:none">
|
<div class="well well-small add-field-block" style="display:none">
|
||||||
<h3>{% trans %}Add a new field{% endtrans %}</h3>
|
<h3>{% trans %}Add a new field{% endtrans %}</h3>
|
||||||
<form class="form-horizontal">
|
<form class="form-horizontal">
|
||||||
@@ -58,11 +71,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row-fluid">
|
|
||||||
<div class="span12 list-block">
|
|
||||||
<ul id="collection-fields" class="unstyled"></ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/template" id="edit_template">
|
<script type="text/template" id="edit_template">
|
||||||
|
@@ -114,6 +114,10 @@
|
|||||||
height: 70px;
|
height: 70px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#admin-field-app .add-field-block {
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
#admin-field-app .add-field-block .control-label {
|
#admin-field-app .add-field-block .control-label {
|
||||||
width: 80px;
|
width: 80px;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
@@ -131,7 +135,10 @@
|
|||||||
min-width: 220px;
|
min-width: 220px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#admin-field-app .sidebar-block {
|
#admin-field-app .sidebar-add-block {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
#admin-field-app .sidebar-search-block {
|
||||||
margin: 20px 0;
|
margin: 20px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user