Skip to content
Snippets Groups Projects
Commit ccfcb961 authored by Allen Gilliland's avatar Allen Gilliland
Browse files

tidy up angular js form handling and streamline things a bit.

parent 23a63060
No related branches found
No related tags found
No related merge requests found
Showing
with 71 additions and 99 deletions
......@@ -44,14 +44,8 @@ DatabasesControllers.controller('DatabaseList', ['$scope', 'Metabase', function(
});
}]);
DatabasesControllers.controller('DatabaseEdit', ['$scope', '$routeParams', '$location', 'Metabase',
function($scope, $routeParams, $location, Metabase) {
var formFields = {
name: 'name',
engine: 'engine'
// details is handled manually
};
DatabasesControllers.controller('DatabaseEdit', ['$scope', '$routeParams', '$location', 'Metabase', 'MetabaseForm',
function($scope, $routeParams, $location, Metabase, MetabaseForm) {
// takes in our API form database details and parses them into a map of usable form field values
var parseDetails = function(engine, details) {
......@@ -86,38 +80,28 @@ DatabasesControllers.controller('DatabaseEdit', ['$scope', '$routeParams', '$loc
};
};
var parseFormErrors = function(error) {
// client side validation error
if (error.data.errors) {
// field validation error(s)
Object.keys(error.data.errors).forEach(function (key) {
if (formFields[key] !== 'undefined') {
// this simply takes the error message from our api response and
// applies it to the correct form field in our angular form object
$scope.form[formFields[key]].$error.message = error.data.errors[key];
}
});
} else if (error.data.message) {
// generic error not attributed to specific field
$scope.form.$error.message = error.data.message;
}
};
// update an existing Database
var update = function(database, details) {
MetabaseForm.clearFormErrors($scope.form);
database.details = buildDetails(database.engine, details);
Metabase.db_update(database, function (updated_database) {
$scope.database = updated_database;
}, parseFormErrors);
$scope.form.success = true;
}, function (error) {
MetabaseForm.parseFormErrors($scope.form, error);
});
};
// create a new Database
var create = function(database, details) {
MetabaseForm.clearFormErrors($scope.form);
database.org = $scope.currentOrg.id;
database.details = buildDetails(database.engine, details);
Metabase.db_create(database, function (new_database) {
$location.path('/' + $scope.currentOrg.slug + '/admin/databases/' + new_database.id);
}, parseFormErrors);
}, function (error) {
MetabaseForm.parseFormErrors($scope.form, error);
});
};
$scope.save = function(database, details) {
......
......@@ -10,8 +10,6 @@
<!-- form -->
<div class="Grid-cell Cell--2of3">
<form class="Form-new bordered rounded shadowed" name="form" novalidate>
<div class="FormError" ng-show="form.$error.message">{{form.$error.message}}</div>
<div class="Form-field" ng-class="{'Form--fieldError': form.engine.$error.message !== undefined}">
<mb-form-label form="form" display-name="Database type" field-name="engine"></mb-form-label>
<label class="Select Form-input Form-offset">
......@@ -59,9 +57,10 @@
</div>
<div class="Form-actions">
<button class="Button" ng-class="{'Button--primary': form.$valid}" ng-click="save(database)" ng-disabled="!form.$valid">
<button class="Button" ng-class="{'Button--primary': form.$valid}" ng-click="save(database, details)" ng-disabled="!form.$valid">
Save
</button>
<mb-form-message form="form" success-message="Successfully saved"></mb-form-message>
</div>
</form>
</div>
......
......@@ -96,15 +96,15 @@ EmailReportControllers.controller('EmailReportList', ['$scope', '$routeParams',
}
]);
EmailReportControllers.controller('EmailReportDetail', ['$scope', '$routeParams', '$location', 'EmailReport', 'EmailReportUtils', 'Metabase',
function($scope, $routeParams, $location, EmailReport, EmailReportUtils, Metabase) {
EmailReportControllers.controller('EmailReportDetail', ['$scope', '$routeParams', '$location', 'EmailReport', 'EmailReportUtils', 'Metabase', 'MetabaseForm',
function($scope, $routeParams, $location, EmailReport, EmailReportUtils, Metabase, MetabaseForm) {
// $scope.report
// $scope.success_message
// $scope.error_message
$scope.save = function(reportDetail) {
$scope.clearStatus();
MetabaseForm.clearFormErrors(form);
// we need to ensure our recipients list is properly set on the report
var recipients = [];
......@@ -115,14 +115,11 @@ EmailReportControllers.controller('EmailReportDetail', ['$scope', '$routeParams'
if ($scope.report.id) {
// if there is already an ID associated with the report then we are updating
EmailReport.update(reportDetail, function(result) {
EmailReport.update(reportDetail, function (result) {
$scope.report = result;
// alert
$scope.success_message = 'EmailReport saved successfully!';
}, function(error) {
$scope.error_message = 'Failed saving EmailReport!';
console.log('error updating email report', error);
$scope.form.success = true;
}, function (error) {
MetabaseForm.parseFormErrors($scope.form, error);
});
} else {
// otherwise we are creating a new report
......@@ -133,17 +130,14 @@ EmailReportControllers.controller('EmailReportDetail', ['$scope', '$routeParams'
// move the user over the the actual page for the new report
$location.path('/' + $scope.currentOrg.slug + '/admin/emailreport/' + result.id);
}, function(error) {
$scope.error_message = 'Failed saving EmailReport!';
console.log('error creating email report', error);
}, function (error) {
MetabaseForm.parseFormErrors($scope.form, error);
});
}
};
$scope.executeReport = function(reportId) {
$scope.clearStatus();
EmailReport.execute({
'reportId': reportId
}, function(result) {
......@@ -154,11 +148,6 @@ EmailReportControllers.controller('EmailReportDetail', ['$scope', '$routeParams'
});
};
$scope.clearStatus = function() {
$scope.success_message = undefined;
$scope.error_message = undefined;
};
$scope.refreshTableList = function(dbId) {
Metabase.db_tables({
'dbId': dbId
......
......@@ -98,8 +98,7 @@
<button class="Button" ng-class="{'Button--primary': form.$valid}" ng-click="save(report)" ng-disabled="!form.$valid || report.dataset_query.query.source_table == ''">
Save
</button>
<span class="FormError" ng-show="form.$error.message">{{form.$error.message}}</span>
<!-- TODO: success message -->
<mb-form-message form="form" success-message="Successfully saved"></mb-form-message>
</div>
</form>
</div>
......
......@@ -10,26 +10,20 @@ var OrganizationAdminControllers = angular.module('corvusadmin.organization.cont
OrganizationAdminControllers.controller('OrganizationSettings', ['$scope', 'Organization', 'MetabaseForm',
function($scope, Organization, MetabaseForm) {
var formFields = {
name: 'name',
description: 'description',
logo_url: 'logo_url'
};
$scope.save = function(organization) {
MetabaseForm.clearFormErrors($scope.form, formFields);
MetabaseForm.clearFormErrors($scope.form);
$scope.form.$setPristine();
//$scope.form.$setUntouched();
Organization.update(organization, function (org) {
$scope.currentOrg = org;
$scope.alertInfo('Organization settings updated!');
$scope.form.success = true;
// we need to trigger a refresh of $scope.user so that these changes propogate the UI
$scope.refreshCurrentUser();
}, function (error) {
MetabaseForm.parseFormErrors($scope.form, formFields, error);
MetabaseForm.parseFormErrors($scope.form, error);
});
};
......
......@@ -7,8 +7,6 @@
<!-- form -->
<div class="Grid-cell Cell--2of3">
<form class="Form-new bordered rounded shadowed" name="form" novalidate>
<div class="FormError" ng-show="form.$error.message">{{form.$error.message}}</div>
<div class="Form-field" ng-class="{'Form--fieldError': form.slug.$error.message !== undefined}">
<mb-form-label form="form" display-name="Slug" field-name="slug"></mb-form-label>
<input class="Form-input Form-offset full" name="slug" ng-model="currentOrg.slug" ng-disabled="true" />
......@@ -36,6 +34,7 @@
<button class="Button" ng-class="{'Button--primary': form.$valid}" ng-click="save(currentOrg)" ng-disabled="!form.$valid">
Save
</button>
<mb-form-message form="form" success-message="Successfully saved"></mb-form-message>
</div>
</form>
</div>
......
......@@ -95,14 +95,8 @@ PeopleControllers.controller('PeopleList', ['$scope', 'Organization',
PeopleControllers.controller('PeopleAdd', ['$scope', '$location', 'Organization', 'MetabaseForm',
function($scope, $location, Organization, MetabaseForm) {
var formFields = {
first_name: 'first_name',
last_name: 'last_name',
email: 'email'
};
$scope.save = function(newUser) {
MetabaseForm.clearFormErrors($scope.form, formFields);
MetabaseForm.clearFormErrors($scope.form);
newUser.orgId = $scope.currentOrg.id;
newUser.admin = false;
......@@ -110,7 +104,7 @@ PeopleControllers.controller('PeopleAdd', ['$scope', '$location', 'Organization'
// just go back to people listing page for now
$location.path('/'+$scope.currentOrg.slug+'/admin/people/');
}, function (error) {
MetabaseForm.parseFormErrors($scope.form, formFields, error);
MetabaseForm.parseFormErrors($scope.form, error);
});
};
}
......
......@@ -3,40 +3,49 @@
/*global _*/
/* Services */
var MetabaseForms = angular.module('metabase.forms', []);
var MetabaseForms = angular.module('metabase.forms', ['corvus.directives']);
MetabaseForms.service('MetabaseForm', function() {
// accepts an instance of angular form.FormController and a map of expected form fields and will simply
// clear any of our error messages from the form instance
this.clearFormErrors = function(form, formFields) {
Object.keys(formFields).forEach(function (key) {
form[formFields[key]].$error.message = undefined;
// accepts an instance of angular form.FormController and clears any of our error messages from the form
this.clearFormErrors = function(form) {
Object.keys(form).forEach(function (key) {
// we only care about attributes of the form which do NOT start with '$'
if (key.indexOf('$') === -1 &&
key in form &&
typeof(form[key]) === 'object' &&
form[key] !== null &&
'$error' in form[key]) {
form[key].$error.message = undefined;
}
});
form.$error.message = undefined;
};
// accepts an instance of angular form.FormController, a map of expected form fields, and the http errors
// from an $http call and will parse out any supplied error information and set it on the form
//
// the formFields should come as .. {'api_field_name': 'angularFormFieldName'}
this.parseFormErrors = function(form, formFields, httpErrors) {
// accepts an instance of angular form.FormController and the http errors from an $http call
// and will parse out any supplied error information and set it on the form
this.parseFormErrors = function(form, httpErrors) {
if (httpErrors.data.errors) {
// field validation error(s)
Object.keys(httpErrors.data.errors).forEach(function (key) {
if (formFields[key] !== 'undefined') {
if (form[key] !== 'undefined') {
// this simply takes the error message from our api response and
// applies it to the correct form field in our angular form object
form[formFields[key]].$error.message = httpErrors.data.errors[key];
form[key].$error.message = httpErrors.data.errors[key];
}
// NOTE: if we the above conditional fails that means we got an error for a field that our form
// does not seem to be interested in, so we simply skip over it and do nothing
});
} else if (httpErrors.data.message) {
// generic error not attributed to specific field
form.$error.message = httpErrors.data.message;
} else if (httpErrors.status === 500) {
// generic 500 without a specific message
form.$error.message = "Server error encountered";
}
};
});
......@@ -54,3 +63,17 @@ MetabaseForms.directive('mbFormLabel', [function () {
}
};
}]);
MetabaseForms.directive('mbFormMessage', [function () {
return {
restrict: 'E',
replace: true,
template: '<span><span class="FormError" ng-show="form.$error.message">{{form.$error.message}}</span>' +
'<span class="FormSuccess" ng-if="form.success" cv-delayed-call="form.success = undefined">{{successMessage}}</span></span>',
scope: {
form: '=',
successMessage: '@'
}
};
}]);
......@@ -34,12 +34,6 @@ OrganizationControllers.controller('OrganizationListController', ['$scope', 'Org
OrganizationControllers.controller('OrganizationDetailController', ['$scope', '$routeParams', '$location', 'Organization', 'MetabaseForm',
function($scope, $routeParams, $location, Organization, MetabaseForm) {
var formFields = {
slug: 'slug',
name: 'name',
description: 'description',
logo_url: 'logo_url'
};
$scope.organization = undefined;
......@@ -57,12 +51,12 @@ OrganizationControllers.controller('OrganizationDetailController', ['$scope', '$
// provide a relevant save() function
$scope.save = function(organization) {
MetabaseForm.clearFormErrors($scope.form, formFields);
MetabaseForm.clearFormErrors($scope.form);
Organization.update(organization, function (org) {
$scope.organization = org;
$scope.form.success = true;
}, function (error) {
MetabaseForm.parseFormErrors($scope.form, formFields, error);
MetabaseForm.parseFormErrors($scope.form, error);
});
};
......@@ -72,12 +66,12 @@ OrganizationControllers.controller('OrganizationDetailController', ['$scope', '$
// provide a relevant save() function
$scope.save = function(organization) {
MetabaseForm.clearFormErrors($scope.form, formFields);
MetabaseForm.clearFormErrors($scope.form);
Organization.create(organization, function (org) {
$scope.form.success = true;
$location.path('/superadmin/organization/' + org.id);
},function (error) {
MetabaseForm.parseFormErrors($scope.form, formFields, error);
}, function (error) {
MetabaseForm.parseFormErrors($scope.form, error);
});
};
}
......
......@@ -10,8 +10,6 @@
<!-- form -->
<div class="Grid-cell Cell--2of3">
<form class="Form-new bordered rounded shadowed" name="form" novalidate>
<div class="FormError" ng-show="form.$error.message">{{form.$error.message}}</div>
<div class="Form-field" ng-class="{'Form--fieldError': form.slug.$error.message !== undefined}">
<mb-form-label form="form" display-name="Slug" field-name="slug"></mb-form-label>
<input class="Form-input Form-offset full" name="slug" placeholder="A short name to go in URLs" ng-model="organization.slug" ng-disabled="organization.id" required />
......@@ -39,8 +37,7 @@
<button class="Button" ng-class="{'Button--primary': form.$valid}" ng-click="save(organization)" ng-disabled="!form.$valid">
Save
</button>
<span class="Form--fieldError" ng-show="form.$error.message">{{form.$error.message}}</span>
<span class="FormSuccess" ng-if="form.success" cv-delayed-call="form.success = undefined">Successfully saved</span>
<mb-form-message form="form" success-message="Successfully saved"></mb-form-message>
</div>
</form>
</div>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment