diff options
author | Benaka <benakamoorthi@fastmail.fm> | 2014-10-08 00:07:39 +0400 |
---|---|---|
committer | Benaka <benakamoorthi@fastmail.fm> | 2014-10-08 00:07:39 +0400 |
commit | ef2e3422e6fa36a0200ebfed2ec709534ff79935 (patch) | |
tree | a4805bd7e16eb5c4ccdcb2eefb629ee058aff0c7 /plugins | |
parent | 51cf6ecc5542e463facb43f430cdc7c10f2aad98 (diff) | |
parent | 32fc31678e2273e52e2eaa1c1add65d5cf7c9a05 (diff) |
Merge pull request #6399 from piwik/angular_forms
Added angular directive that automates logic for AJAX forms.
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/CoreHome/CoreHome.php | 4 | ||||
-rw-r--r-- | plugins/CoreHome/angularjs/ajax-form/ajax-form.controller.js | 75 | ||||
-rw-r--r-- | plugins/CoreHome/angularjs/ajax-form/ajax-form.directive.js | 120 |
3 files changed, 199 insertions, 0 deletions
diff --git a/plugins/CoreHome/CoreHome.php b/plugins/CoreHome/CoreHome.php index f833b1e5cc..e06e8cf0ac 100644 --- a/plugins/CoreHome/CoreHome.php +++ b/plugins/CoreHome/CoreHome.php @@ -153,6 +153,9 @@ class CoreHome extends \Piwik\Plugin $jsFiles[] = "plugins/CoreHome/angularjs/notification/notification.controller.js"; $jsFiles[] = "plugins/CoreHome/angularjs/notification/notification.directive.js"; + + $jsFiles[] = "plugins/CoreHome/angularjs/ajax-form/ajax-form.controller.js"; + $jsFiles[] = "plugins/CoreHome/angularjs/ajax-form/ajax-form.directive.js"; } public function getClientSideTranslationKeys(&$translationKeys) @@ -243,6 +246,7 @@ class CoreHome extends \Piwik\Plugin $translationKeys[] = 'General_Default'; $translationKeys[] = 'General_LoadingData'; $translationKeys[] = 'General_ErrorRequest'; + $translationKeys[] = 'General_YourChangesHaveBeenSaved'; $translationKeys[] = 'CoreHome_UndoPivotBySubtable'; $translationKeys[] = 'CoreHome_PivotBySubtable'; } diff --git a/plugins/CoreHome/angularjs/ajax-form/ajax-form.controller.js b/plugins/CoreHome/angularjs/ajax-form/ajax-form.controller.js new file mode 100644 index 0000000000..13d88f3991 --- /dev/null +++ b/plugins/CoreHome/angularjs/ajax-form/ajax-form.controller.js @@ -0,0 +1,75 @@ +/*! + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ +(function () { + angular.module('piwikApp').controller('AjaxFormController', AjaxFormController); + + AjaxFormController.$inject = ['piwikApi', '$filter']; + + function AjaxFormController(piwikApi, $filter) { + var vm = this; + + /** + * Set to non-null when a form submit request returns successfully. When successful, it will + * be the entire JSON parsed response of the request. + * + * @type {null|string} + */ + vm.successfulPostResponse = null; + + /** + * Set to non-null when a form submit request results in an error. When an error occurs, + * it will be set to the string error message. + * + * @type {null|string} + */ + vm.errorPostResponse = null; + + vm.submitForm = submitForm; + + /** + * Sends a POST to the configured API method. + */ + function submitForm() { + var postParams; + + vm.successfulPostResponse = null; + vm.errorPostResponse = null; + + if (vm.sendJsonPayload) { + postParams = {data: JSON.stringify(vm.data)}; + } else { + postParams = vm.data; + } + + piwikApi.post( + { // GET params + module: 'API', + method: vm.submitApiMethod + }, + postParams, + { // request options + createErrorNotification: !vm.noErrorNotification + } + ).then(function (response) { + vm.successResponse = response; + + if (!vm.noSuccessNotification) { + var UI = require('piwik/UI'); + var notification = new UI.Notification(); + notification.show($filter('translate')('General_YourChangesHaveBeenSaved'), { + context: 'success', + type: 'toast', + id: 'ajaxHelper' + }); + notification.scrollToNotification(); + } + }).catch(function (errorMessage) { + vm.errorPostResponse = errorMessage; + }); + } + } +})();
\ No newline at end of file diff --git a/plugins/CoreHome/angularjs/ajax-form/ajax-form.directive.js b/plugins/CoreHome/angularjs/ajax-form/ajax-form.directive.js new file mode 100644 index 0000000000..4f2242135f --- /dev/null +++ b/plugins/CoreHome/angularjs/ajax-form/ajax-form.directive.js @@ -0,0 +1,120 @@ +/*! + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +/** + * AngularJS directive that manages an AJAX form. + * + * This directive will detect inputs & selects defined within an element and when a + * submit button is clicked, will post data from the inputs & selects to a Piwik API method. + * + * When the POST request is finished the result will, by default, be displayed as a + * notification. + * + * This directive accepts the following attributes: + * + * - **save-api-method**: **required** The Piwik API method that handles the POST request. + * - **send-json-payload**: Whether to send the data as a form encoded URL or to send it as JSON. + * If sending as JSON, the payload will still be a form encoded value, + * but will contain a JSON object like `{data: {...form data...}}`. + * + * This is for forms with lots of fields where having the same number + * of parameters in an API method would not be desired. + * - **no-error-notification**: If true, does not display an error notification if the AJAX post + * fails. + * - **no-success-notification**: If true, does not display an error notification if the AJAX + * results in success. + * + * **Custom Success/Error Handling** + * + * On success/failure, the response will be stored in controller scope. Child elements of a + * piwik-ajax-form element can access this data, and thus, can customize what happens when + * a form submit succeeds/fails. + * + * See the ajax-form.controller.js file for more info. + * + * Usage: + * + * <div piwik-ajax-form + * save-api-method="MyPlugin.myFormSaveMethod" + * send-json-payload="true" + * ng-model="myFormData"> + * + * <h2>My Form</h2> + * <input name="myOption" value="myDefaultValue" type="text" /> + * <input name="myOtherOption" type="checkbox" checked="checked" /> + * <input type="submit" value="Submit" /> + * + * <div piwik-notification context='error' ng-show="errorPostResponse">ERROR!</div> + * </div> + */ +(function () { + angular.module('piwikApp').directive('piwikAjaxForm', piwikAjaxForm); + + piwikAjaxForm.$inject = []; + + function piwikAjaxForm() { + return { + restrict: 'A', + scope: { + submitApiMethod: '=', + sendJsonPayload: '=', + noErrorNotification: '=', + noSuccessNotification: '=' + }, + require: '?ngModel', + controller: 'AjaxFormController', + controllerAs: 'ajaxForm', + compile: function (element, attrs) { + if (!attrs.submitApiMethod) { + throw new Error("submitApiMethod is required"); + } + + attrs.noErrorNotification = !! attrs.noErrorNotification; + + return function (scope, element, attrs, ngModel) { + scope.ajaxForm.submitApiMethod = scope.submitApiMethod; + scope.ajaxForm.sendJsonPayload = scope.sendJsonPayload; + scope.ajaxForm.noErrorNotification = scope.noErrorNotification; + scope.ajaxForm.noSuccessNotification = scope.noSuccessNotification; + + scope.ajaxForm.data = (ngModel ? ngModel.$modelValue : {}) || {}; + + var $inputs = element.find('input:not([type=submit]),select'); + + // initialize form data to input values (include <select>s + $inputs.each(function () { + setFormValueFromInput(this); + }); + + // on change of any input, change appropriate value in ngModel + element.on('change', 'input,select', function () { + setFormValueFromInput(this); + }); + + // on submit call controller submit method + element.on('click', 'input[type=submit]', function () { + scope.ajaxForm.submitForm(); + }); + + function setFormValueFromInput(inputElement) { + var $ = angular.element, + name = $(inputElement).attr('name'), + val; + + if ($(this).attr('type') == 'checked') { + val = $(inputElement).is(':checked'); + } else { + val = $(inputElement).val(); + } + + scope.ajaxForm.data[name] = val; + } + }; + } + }; + } +})();
\ No newline at end of file |