From e50321d900e9c03754c1cabfb09e075118be2a36 Mon Sep 17 00:00:00 2001 From: buttflattery Date: Wed, 15 Jan 2020 14:37:39 +0500 Subject: [PATCH 1/2] Added editMode feature --- src/FormWizard.php | 25 +++++++++++-- src/assets/js/formwizard.js | 57 +++++++++++++++++++++++------ src/assets/js/jquery.smartWizard.js | 24 ++++++++++-- 3 files changed, 87 insertions(+), 19 deletions(-) diff --git a/src/FormWizard.php b/src/FormWizard.php index dca46be..d06022e 100644 --- a/src/FormWizard.php +++ b/src/FormWizard.php @@ -116,6 +116,23 @@ class FormWizard extends Widget */ public $steps = []; + /** + * Enable Edit mode for a saved record, it will enable all the steps + * and user can jump to any steps by just clicking on the step anchor + * so that if any single information needs to be changed in any step + * he/she wont have to go through every step serially. + * + * @var mixed + */ + public $editMode = false; + + /** + * The array of steps that have errors + * + * @var array + */ + public $errorSteps = []; + /** * The Options for the ActiveForm see the * https://www.yiiframework.com/doc/api/2.0/yii-widgets-activeform @@ -483,6 +500,7 @@ public function getPluginOptions() 'keyNavigation' => false, 'autoAdjustHeight' => $this->autoAdjustHeight, 'disabledSteps' => $this->disabledSteps, + 'errorSteps' => $this->errorSteps, 'backButtonSupport' => false, 'theme' => $this->theme, 'transitionEffect' => $this->transitionEffect, @@ -494,8 +512,8 @@ public function getPluginOptions() 'toolbarExtraButtons' => $this->toolbarExtraButtons, ], 'anchorSettings' => [ - 'anchorClickable' => false, - 'enableAllAnchors' => false, + 'anchorClickable' => $this->editMode, + 'enableAllAnchors' => $this->editMode, 'markDoneStep' => $this->markDoneStep, 'markAllPreviousStepsAsDone' => $this->markAllPreviousStepsAsDone, 'removeDoneStepOnNavigateBack' => $this->removeDoneStepOnNavigateBack, @@ -981,7 +999,7 @@ public function registerScripts($pluginOptions, $isBs3, $jsOptionsPersistence) //bind Yii ActiveForm event afterValidate to check //only current steps fields for validation and allow to next step if($('#{$this->formOptions["id"]}').yiiActiveForm('data').attributes.length){ - $.formwizard.validation.bindAfterValidate('#{$this->formOptions["id"]}'); + $.formwizard.formValidation.bindAfterValidate('#{$this->formOptions["id"]}'); } //fields list @@ -1001,6 +1019,7 @@ classNext:'{$this->classNext}', classPrev:'{$this->classPrev}', classFinish:'{$this->classFinish}', enablePreview:'{$this->enablePreview}', + editMode:'{$this->editMode}', bsVersion:'{$this->_bsVersion}', classListGroup:'{$this->classListGroup}', classListGroupHeading:'{$this->classListGroupHeading}', diff --git a/src/assets/js/formwizard.js b/src/assets/js/formwizard.js index c40342c..370b469 100644 --- a/src/assets/js/formwizard.js +++ b/src/assets/js/formwizard.js @@ -111,7 +111,7 @@ $.formwizard = { setTimeout( function () { if ($(form).yiiActiveForm("data").attributes.length) { - return $.formwizard.validation.run(form, e); + return $.formwizard.formValidation.run(form, e); } if ($(e.target).hasClass("formwizard_finish")) { $(form).yiiActiveForm("submitForm"); @@ -238,7 +238,7 @@ $.formwizard = { `; } }, - validation: { + formValidation: { run: function (form, event) { $.formwizard.resetCurrentTarget = false; @@ -295,14 +295,14 @@ $.formwizard = { } }, }; - - if(inputTypes.hasOwnProperty(input.type)){ - if(inputTypes[input.type].call(this,input)===false){ - allEmpty=false; + + if (inputTypes.hasOwnProperty(input.type)) { + if (inputTypes[input.type].call(this, input) === false) { + allEmpty = false; return false; } } - + }); //if skippable step and all the inputs are empty then @@ -322,21 +322,54 @@ $.formwizard = { event.preventDefault(); + //form name let formName = $(this).attr("id"); + //current step index let currentIndex = $.formwizard.helper.currentIndex(form); + //is last step const isLastStep = currentIndex == $(form + " .step-anchor").find("li").length - 1; - const isPreviewEnabled = $.formwizard.options[formName].enablePreview && isLastStep; + //is preview step + const isPreviewStep = $.formwizard.options[formName].enablePreview && isLastStep; + //is skipable step const isSkippableStep = $("#step-" + currentIndex).data('step').skipable; - + let res; //check if the preview step OR skippable step then skip validation messages check - if (isPreviewEnabled || isSkippableStep) { + if (isPreviewStep || isSkippableStep) { res = 0; } else { res = $.formwizard.fields[formName][currentIndex].diff(messages); } + //if edit mode then highlight error steps + if ($.formwizard.options[formName].editMode) { + //get all fields + let allFields = $.formwizard.fields[formName]; + let errorSteps = []; + + //iterate all the fields + $.each(allFields, function (index, stepFields) { + //if the step is skipable + let isSkippable = $("#step-" + index).data('step').skipable; + + //if not skipable and has errors + if (!isSkippable && stepFields.diff(messages).length) { + //push the step index to the errorsteps array + errorSteps.push(index); + } + }); + + //update error step higlightening + let wizardContainerId = $.formwizard.options[formName].wizardContainerId; + $("#" + wizardContainerId).smartWizard('updateErrorStep', errorSteps); + + //if no error steps then slear errors + if (errorSteps.length) { + $.formwizard.formNavigation.goToStep("#"+wizardContainerId, errorSteps[0]); + } + } + if (!res.length) { //check if last step then submit form @@ -533,7 +566,7 @@ $.formwizard = { newFields.push(element.id); if (typeof fieldOptions !== 'undefined') { //add field to the activeform validation - $.formwizard.validation.addField(formId, fieldOptions); + $.formwizard.formValidation.addField(formId, fieldOptions); } } }); @@ -559,7 +592,7 @@ $.formwizard = { $.formwizard.helper.removeField(element); //remove from the ActiveForm validation list - $.formwizard.validation.removeField(element); + $.formwizard.formValidation.removeField(element); }); rowContainer.remove(); diff --git a/src/assets/js/jquery.smartWizard.js b/src/assets/js/jquery.smartWizard.js index 0000490..4b958b7 100644 --- a/src/assets/js/jquery.smartWizard.js +++ b/src/assets/js/jquery.smartWizard.js @@ -140,9 +140,7 @@ } // Error steps if (this.options.errorSteps && this.options.errorSteps.length > 0) { - $.each(this.options.errorSteps, function (i, n) { - mi.steps.eq(n).parent('li').addClass('danger'); - }); + mi.updateErrorStep(this.options.errorSteps); } // Hidden steps if (this.options.hiddenSteps && this.options.hiddenSteps.length > 0) { @@ -625,7 +623,25 @@ break; } } - } + }, + updateErrorStep: function (errorSteps = []) { //update error step highlightening + var mi = this; + //if errorSteps array not empty + if (errorSteps.length) { + + //add error classes to steps + $.each(errorSteps, function (i, n) { + mi.steps.eq(n).parent('li').addClass('danger'); + }); + return; + } + + //remove the error class from the steps if empty array + $.each(mi.steps, function (i, n) { + $(n).parent('li').removeClass('danger'); + }); + }, + }); // Wrapper for the plugin From 6ee7d9584efedec801ee9dfd54107f39ce1033cd Mon Sep 17 00:00:00 2001 From: buttflattery Date: Fri, 17 Jan 2020 08:32:42 +0500 Subject: [PATCH 2/2] updated readme for the new option --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index fa55fd1..4d6d918 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,7 @@ or add into the `composer.json` file under `require` section #### Widget options - `wizardContainerId (string)`: Id of the main container for the wizard. +- `editMode (boolean)` : if wizard is in edit mode. Default value is `false`. see [wiki](https://github.com/buttflattery/yii2-formwizard/wiki/Edit-Mode) for details. - `formOptions (array)`: Specify the [ActiveForm](https://www.yiiframework.com/doc/api/2.0/yii-widgets-activeform) properties. - `labelNext (string)` : Next button label, default value `Next`. - `labelPrev (string)` : Previous button label, default value `Previous`.