Added proper form validation to printer profile editor to the UI
Closes #809
This commit is contained in:
parent
5cadfb5a09
commit
91b9fb3e3f
2 changed files with 88 additions and 11 deletions
|
|
@ -31,6 +31,8 @@ $(function() {
|
|||
}
|
||||
};
|
||||
|
||||
self.requestInProgress = ko.observable(false);
|
||||
|
||||
self.profiles = new ItemListHelper(
|
||||
"printerProfiles",
|
||||
{
|
||||
|
|
@ -57,6 +59,7 @@ $(function() {
|
|||
self.editorName = ko.observable();
|
||||
self.editorColor = ko.observable();
|
||||
self.editorIdentifier = ko.observable();
|
||||
self.editorIdentifierPlaceholder = ko.observable();
|
||||
self.editorModel = ko.observable();
|
||||
|
||||
self.editorVolumeWidth = ko.observable();
|
||||
|
|
@ -110,6 +113,46 @@ $(function() {
|
|||
return extruderOffsets.slice(0, numExtruders);
|
||||
});
|
||||
|
||||
self.editorNameInvalid = ko.computed(function() {
|
||||
return !self.editorName();
|
||||
});
|
||||
|
||||
self.editorIdentifierInvalid = ko.computed(function() {
|
||||
var identifier = self.editorIdentifier();
|
||||
var placeholder = self.editorIdentifierPlaceholder();
|
||||
var data = identifier;
|
||||
if (!identifier) {
|
||||
data = placeholder;
|
||||
}
|
||||
|
||||
var validCharacters = (data && (data == self._sanitize(data)));
|
||||
|
||||
var existingProfile = self.profiles.getItem(function(item) {return item.id == data});
|
||||
return !data || !validCharacters || (self.editorNew() && existingProfile != undefined);
|
||||
});
|
||||
|
||||
self.editorIdentifierInvalidText = ko.computed(function() {
|
||||
if (!self.editorIdentifierInvalid()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (!self.editorIdentifier() && !self.editorIdentifierPlaceholder()) {
|
||||
return gettext("Identifier must be set");
|
||||
} else if (self.editorIdentifier() != self._sanitize(self.editorIdentifier())) {
|
||||
return gettext("Invalid characters, only a-z, A-Z, 0-9, -, ., _, ( and ) are allowed")
|
||||
} else {
|
||||
return gettext("A profile with such an identifier already exists");
|
||||
}
|
||||
});
|
||||
|
||||
self.enableEditorSubmitButton = ko.computed(function() {
|
||||
return !self.editorNameInvalid() && !self.editorIdentifierInvalid() && !self.requestInProgress();
|
||||
});
|
||||
|
||||
self.editorName.subscribe(function() {
|
||||
self.editorIdentifierPlaceholder(self._sanitize(self.editorName()).toLowerCase());
|
||||
});
|
||||
|
||||
self.makeDefault = function(data) {
|
||||
var profile = {
|
||||
id: data.id,
|
||||
|
|
@ -153,6 +196,7 @@ $(function() {
|
|||
|
||||
self.addProfile = function(callback) {
|
||||
var profile = self._editorData();
|
||||
self.requestInProgress(true);
|
||||
$.ajax({
|
||||
url: API_BASEURL + "printerprofiles",
|
||||
type: "POST",
|
||||
|
|
@ -160,23 +204,35 @@ $(function() {
|
|||
contentType: "application/json; charset=UTF-8",
|
||||
data: JSON.stringify({profile: profile}),
|
||||
success: function() {
|
||||
self.requestInProgress(false);
|
||||
if (callback !== undefined) {
|
||||
callback();
|
||||
}
|
||||
self.requestData();
|
||||
},
|
||||
error: function(jqXHR) {
|
||||
alert(jqXHR.responseText);
|
||||
error: function() {
|
||||
self.requestInProgress(false);
|
||||
var text = gettext("There was unexpected error while saving the printer profile, please consult the logs.");
|
||||
new PNotify({title: gettext("Saving failed"), text: text, type: "error", hide: false});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
self.removeProfile = function(data) {
|
||||
self.requestInProgress(true);
|
||||
$.ajax({
|
||||
url: data.resource,
|
||||
type: "DELETE",
|
||||
dataType: "json",
|
||||
success: self.requestData
|
||||
success: function() {
|
||||
self.requestInProgress(false);
|
||||
self.requestData();
|
||||
},
|
||||
error: function() {
|
||||
self.requestInProgress(false);
|
||||
var text = gettext("There was unexpected error while removing the printer profile, please consult the logs.");
|
||||
new PNotify({title: gettext("Saving failed"), text: text, type: "error", hide: false});
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
|
|
@ -185,6 +241,8 @@ $(function() {
|
|||
profile = self._editorData();
|
||||
}
|
||||
|
||||
self.requestInProgress(true);
|
||||
|
||||
$.ajax({
|
||||
url: API_BASEURL + "printerprofiles/" + profile.id,
|
||||
type: "PATCH",
|
||||
|
|
@ -192,10 +250,16 @@ $(function() {
|
|||
contentType: "application/json; charset=UTF-8",
|
||||
data: JSON.stringify({profile: profile}),
|
||||
success: function() {
|
||||
self.requestInProgress(false);
|
||||
if (callback !== undefined) {
|
||||
callback();
|
||||
}
|
||||
self.requestData();
|
||||
},
|
||||
error: function() {
|
||||
self.requestInProgress(false);
|
||||
var text = gettext("There was unexpected error while updating the printer profile, please consult the logs.");
|
||||
new PNotify({title: gettext("Saving failed"), text: text, type: "error", hide: false});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
@ -248,7 +312,9 @@ $(function() {
|
|||
dialogTitle.text(add ? gettext("Add Printer Profile") : _.sprintf(gettext("Edit Printer Profile \"%(name)s\""), {name: data.name}));
|
||||
confirmButton.unbind("click");
|
||||
confirmButton.bind("click", function() {
|
||||
self.confirmEditProfile(add);
|
||||
if (self.enableEditorSubmitButton()) {
|
||||
self.confirmEditProfile(add);
|
||||
}
|
||||
});
|
||||
editDialog.modal("show");
|
||||
};
|
||||
|
|
@ -266,8 +332,13 @@ $(function() {
|
|||
};
|
||||
|
||||
self._editorData = function() {
|
||||
var identifier = self.editorIdentifier();
|
||||
if (!identifier) {
|
||||
identifier = self.editorIdentifierPlaceholder();
|
||||
}
|
||||
|
||||
var profile = {
|
||||
id: self.editorIdentifier(),
|
||||
id: identifier,
|
||||
name: self.editorName(),
|
||||
color: self.editorColor(),
|
||||
model: self.editorModel(),
|
||||
|
|
@ -314,6 +385,10 @@ $(function() {
|
|||
return profile;
|
||||
};
|
||||
|
||||
self._sanitize = function(name) {
|
||||
return name.replace(/[^a-zA-Z0-9\-_\.\(\) ]/g, "").replace(/ /g, "_");
|
||||
};
|
||||
|
||||
self.onSettingsShown = self.requestData;
|
||||
self.onStartup = self.requestData;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
<td class="settings_printerProfiles_profiles_name"><span class="icon-star" data-bind="invisible: !isdefault()"></span> <span data-bind="text: name"></span></td>
|
||||
<td class="settings_printerProfiles_profiles_model" data-bind="text: model"></td>
|
||||
<td class="settings_printerProfiles_profiles_action">
|
||||
<a href="#" class="icon-star" title="{{ _('Set as default profile') }}" data-bind="click: function() { $root.printerProfiles.makeDefault($data); }"></a> | <a href="#" class="icon-pencil" title="{{ _('Edit Profile') }}" data-bind="click: function() { $root.printerProfiles.showEditProfileDialog($data); }"></a> | <a href="#" class="icon-trash" title="{{ _('Delete Profile') }}" data-bind="click: function() { $root.printerProfiles.removeProfile($data); }"></a>
|
||||
<a href="#" class="icon-star" title="{{ _('Set as default profile') }}" data-bind="click: function() { $root.printerProfiles.makeDefault($data); }, css: {disabled: $root.printerProfiles.requestInProgress()}, enabled: !$root.printerProfiles.requestInProgress()"></a> | <a href="#" class="icon-pencil" title="{{ _('Edit Profile') }}" data-bind="click: function() { $root.printerProfiles.showEditProfileDialog($data); }, css: {disabled: $root.printerProfiles.requestInProgress()}, enabled: !$root.printerProfiles.requestInProgress()"></a> | <a href="#" class="icon-trash" title="{{ _('Delete Profile') }}" data-bind="click: function() { $root.printerProfiles.removeProfile($data); }, css: {disabled: $root.printerProfiles.requestInProgress()}, enabled: !$root.printerProfiles.requestInProgress()"></a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
@ -40,16 +40,18 @@
|
|||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="form-horizontal">
|
||||
<div class="control-group">
|
||||
<div class="control-group" data-bind="css: {error: printerProfiles.editorNameInvalid()}">
|
||||
<label class="control-label">{{ _('Name') }}</label>
|
||||
<div class="controls">
|
||||
<input type="text" data-bind="value: printerProfiles.editorName">
|
||||
<input type="text" data-bind="value: printerProfiles.editorName, valueUpdate: 'afterkeydown'">
|
||||
<span data-bind="visible: printerProfiles.editorNameInvalid()"><br><span class="help-inline">{{ _('Name must be set') }}</span></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<div class="control-group" data-bind="css: {error: printerProfiles.editorIdentifierInvalid()}">
|
||||
<label class="control-label">{{ _('Identifier') }}</label>
|
||||
<div class="controls">
|
||||
<input type="text" data-bind="value: printerProfiles.editorIdentifier, enable: $root.printerProfiles.editorNew, css: {disabled: !$root.printerProfiles.editorNew()}">
|
||||
<input type="text" data-bind="value: printerProfiles.editorIdentifier, valueUpdate: 'afterkeydown', enable: printerProfiles.editorNew, css: {disabled: !printerProfiles.editorNew()}, attr: {placeholder: printerProfiles.editorIdentifierPlaceholder}">
|
||||
<span data-bind="visible: printerProfiles.editorIdentifierInvalid()"><br><span class="help-inline" data-bind="text: printerProfiles.editorIdentifierInvalidText()"></span></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
|
|
@ -180,6 +182,6 @@
|
|||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal" aria-hidden="true">{{ _('Abort') }}</button>
|
||||
<button class="btn btn-primary btn-confirm">{{ _('Confirm') }}</button>
|
||||
<button class="btn btn-primary btn-confirm" data-bind="enabled: printerProfiles.enableEditorSubmitButton, css: {disabled: !printerProfiles.enableEditorSubmitButton()}"><i class="icon-spinner icon-spin" data-bind="visible: printerProfiles.requestInProgress()"></i> {{ _('Confirm') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in a new issue