Split ListView by adding a CreateView

This commit is contained in:
Nicolas Le Goff
2013-05-23 21:16:53 +02:00
committed by Romain Neutron
parent f886874f8d
commit 5c8cb9973e
7 changed files with 227 additions and 162 deletions

View File

@@ -22,12 +22,25 @@
<script type="text/template" id="item_list_view_template">
<div class="row-fluid">
<div class="span12">
<div class="sidebar-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="sidebar-block">
<div class="create-subview"></div>
<div class="sidebar-search-block">
<input class="input-block-level" type="text" id="live_search" placeholder="{% trans %}Live search{% endtrans %}"/>
</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">
<h3>{% trans %}Add a new field{% endtrans %}</h3>
<form class="form-horizontal">
@@ -58,11 +71,6 @@
</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="edit_template">

View 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);
}
}
};
});

View 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;
});

View File

@@ -3,21 +3,18 @@ define([
"underscore",
"backbone",
"i18n",
"apps/admin/fields/views",
"apps/admin/fields/views/alert",
"apps/admin/fields/views/modal",
"apps/admin/fields/views/dcField",
"apps/admin/fields/errors/error"
], function($, _, Backbone, i18n, AlertView, ModalView, DcFieldView, Error) {
var FieldEditView = Backbone.View.extend({
], function($, _, Backbone, i18n, ViewUtils, AlertView, ModalView, DcFieldView, Error) {
// Add multiview methods
var FieldEditView = Backbone.View.extend(_.extend({}, ViewUtils.MultiViews, {
tagName: "div",
className: "field-edit",
initialize: function() {
this.model.on("change", this._onModelChange, this);
this.dcFieldsSubView = new DcFieldView({
collection: AdminFieldApp.dcFieldsCollection,
field: this.model
});
},
updateModel: function(model) {
// unbind event to previous model
@@ -36,8 +33,11 @@ define([
this.$el.empty().html(template);
this._assign({
".dc-fields-subview" : this.dcFieldsSubView
this._assignView({
".dc-fields-subview" : new DcFieldView({
collection: AdminFieldApp.dcFieldsCollection,
field: this.model
})
});
var completer = $("#tag", this.$el).autocomplete({
@@ -220,20 +220,6 @@ define([
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
_selectModelView: function(index) {
// select previous or next itemview
@@ -241,7 +227,7 @@ define([
AdminFieldApp.fieldListView.itemViews[index].clickAction().animate();
}
}
});
}));
return FieldEditView;
});

View File

@@ -4,16 +4,13 @@ define([
"underscore",
"backbone",
"i18n",
"apps/admin/fields/views",
"apps/admin/fields/views/listRow",
"apps/admin/fields/views/alert",
"models/field"
], function($, jqueryui, _, Backbone, i18n, FieldListRowView, AlertView, FieldModel) {
var FieldListView = Backbone.View.extend({
"apps/admin/fields/views/create"
], function($, jqueryui, _, Backbone, i18n, ViewUtils, FieldListRowView, CreateView) {
var FieldListView = Backbone.View.extend(_.extend({}, ViewUtils.MultiViews, {
events: {
"keyup #live_search": "searchAction",
"click .btn-submit-field": "createAction",
"click .btn-add-field": "toggleCreateFormAction",
"click .btn-cancel-field": "toggleCreateFormAction",
"update-sort": "updateSortAction"
},
initialize: function() {
@@ -56,26 +53,9 @@ define([
this._renderList(this.collection);
$("#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
};
}));
}
this._assignView({
".create-subview" : new CreateView()
});
}
}).autocomplete("widget").addClass("ui-autocomplete-admin-field");
AdminFieldApp.resizeListBlock();
@@ -124,97 +104,6 @@ define([
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) {
var position = ui.item.index();
this.collection.remove(model, {silent: true});
@@ -238,7 +127,7 @@ define([
return this;
}
});
}));
return FieldListView;
});

View File

@@ -22,12 +22,25 @@
<script type="text/template" id="item_list_view_template">
<div class="row-fluid">
<div class="span12">
<div class="sidebar-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="sidebar-block">
<div class="create-subview"></div>
<div class="sidebar-search-block">
<input class="input-block-level" type="text" id="live_search" placeholder="{% trans %}Live search{% endtrans %}"/>
</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">
<h3>{% trans %}Add a new field{% endtrans %}</h3>
<form class="form-horizontal">
@@ -58,11 +71,6 @@
</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="edit_template">

View File

@@ -114,6 +114,10 @@
height: 70px;
}
#admin-field-app .add-field-block {
margin-bottom: 0px;
}
#admin-field-app .add-field-block .control-label {
width: 80px;
text-align: left;
@@ -131,7 +135,10 @@
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;
}