0

I am trying to create a multi form/wizard step navigation. I am using ng-switch to create the steps. But I got stuck, this is the relevant code:

HTML:

<div ng-controller="stepCtrl">
<div ng-switch="step">
   <div ng-switch-when="1">
      <div ng-controller="postAddressDataCtrl">
         <form url="users/createaddress" ng-submit="add()">
            <label class="input-label">
            <span class="label-title">
            Line 1
            </span>
            <input type="text" name="line-1" ng-model="line1" placeholder="Line 1">
            </label>

            <label class="input-label">
            <span class="label-title">
            Line 2
            </span>
            <input type="text" name="line-2" ng-model="line2" placeholder="Line 2">
            </label>

            <label class="input-label">
            <span class="label-title">
            City
            </span>
            <input type="text" name="city" ng-model="city" placeholder="City">
            </label>

            <label class="input-label">
            <span class="label-title">
            Postcode
            </span>
            <input type="text" name="postcode" ng-model="postcode" placeholder="Postcode">
            </label>

            <label class="input-label">
            <span class="label-title">
            Country
            </span>
            <input type="text" name="country" ng-model="country" placeholder="Country">
            </label>

            <input type="hidden" name="_token" value="{{ csrf_token() }}">
            <div class="form-group">
               {{ Form::button('Save Address', array('type'=>'submit', 'class'=>'btn btn-primary', 'style' => 'width:100%;')) }}
            </div>
         </form>
      </div>
      <button ng-click="setStep(2)">Step 2</button>
   </div>
   <div ng-switch-when="2">
      Step 2 - another form
      <button ng-click="setStep(1)">Step 1</button>
      <button ng-click="setStep(3)">Step 3</button>
   </div>
   <div ng-switch-when="3">
      Step 3 - another form
      <button ng-click="setStep(2)">Step 2</button>
   </div>
</div>
</div> 


Controllers:

stepCtrl

myApp.controller('stepCtrl',function($scope){
    $scope.step = 1;
    $scope.setStep = function(step){
        $scope.step = step;
    } 
});

postAddressDataCtrl

myApp.controller('postAddressDataCtrl', ['$scope', '$http', 'CSRF_TOKEN', function($scope, $http, CSRF_TOKEN) {
    $scope.urlpath = '{{ url('/') }}';
    $scope.add = function() {
        var line1 = $scope.line1;
        var line2 = $scope.line2;
        var city = $scope.city;
        var postcode = $scope.postcode;
        var country = $scope.country;

        return $http({
            url: "/users/createaddress",
            method: "POST",
            data: {
                'line1': line1,
                'line2': line2,
                'city': city,
                'postcode': postcode,
                'country': country,
                '_token': CSRF_TOKEN
            },
        }).success(function(data, status, headers, config) {
              console.log(data);
              if (data.status == 200) {
                  // move to the next step
              }
        }).error(function(data, status, headers, config) {
              console.log(data);
        });
    };
}]);

How can I check if the data entered in the form are valid and if they are then to move in the next step with a single button?

How can I set the step equal to 2 when the data.status is equal to 200, so only then it will move on?

cch
  • 3,336
  • 8
  • 33
  • 61

1 Answers1

2

Use Angular's form validation. For example add required to your input field if you want to require the field and ng-minlength or ng-maxlength for character limits. You can also write custom validation if you need specific validation on certain fields.

To change the step you can increment your step variable inside ng-submit. To increment only if your $http request is successful you can put it directly in your .success function.

<form url="users/createaddress" ng-submit="add()" novalidate>
    <label class="input-label">
        <span class="label-title">
        Line 1
        </span>
        <input type="text" name="line-1" ng-model="line1" placeholder="Line 1" ng-minlength=3 ng-maxlength=20 required>
    </label>
    <button type="submit" class="btn btn-primary">Save Address</button>
</form>

postAddressDataCtrl

myApp.controller('postAddressDataCtrl', ['$scope', '$http', 'CSRF_TOKEN', function($scope, $http, CSRF_TOKEN) {
    $scope.urlpath = '{{ url('/') }}';
    $scope.add = function() {
        var line1 = $scope.line1;
        var line2 = $scope.line2;
        var city = $scope.city;
        var postcode = $scope.postcode;
        var country = $scope.country;

        return $http({
            url: "/users/createaddress",
            method: "POST",
            data: {
                'line1': line1,
                'line2': line2,
                'city': city,
                'postcode': postcode,
                'country': country,
                '_token': CSRF_TOKEN
            },
        }).success(function(data, status, headers, config) {
              console.log(data);
              if (data.status == 200) {
                  // move to the next step
                  $scope.step += 1;
              }
        }).error(function(data, status, headers, config) {
              console.log(data);
        });
    };
}]);
Community
  • 1
  • 1
j_buckley
  • 1,926
  • 1
  • 12
  • 13
  • Great, thanks for the answer. Although, I have one concern how can I prevent the step from increasing `+1` if the request got back in the `add()` function equals to a response code `400` (which this might be the occasion if the backend validation fails)? Basically I think it should be more appropriate if the step gets increased if I the response code `200`. – cch May 12 '15 at 12:01
  • You can change `step = step + 1` to be a function like `incrementStep()` where you can check the response code in your controller and increase the step if necessary. – j_buckley May 12 '15 at 13:56
  • Can you include an example please? – cch May 12 '15 at 13:57
  • I updated my answer. You should just be able to increment the step inside your `.success` function – j_buckley May 12 '15 at 15:14
  • Thanks for the updates. I am not sure if this is going to work because `$scope.step` is inside the `stepCtrl` therefore I think that `postAddressDataCtrl` won't know about it. – cch May 12 '15 at 15:25
  • It should work because `postAddressDataCtrl` is nested inside `stepCtrl` so it should have access to its scope. – j_buckley May 12 '15 at 15:35
  • 1
    Thanks for your replies, got it working! Although I had to do `$scope.$parent.$parent.step += 1;` – cch May 12 '15 at 16:03