1

I want to create a simple form with some nested data. When I click the addSite() function, I want to create a new Site item and append it to my $scope.info.

I cannot create more than one form and the $index variable is not be passed to the scope. Here is a,

plunkr link.

HTML

<!DOCTYPE html>
<html>

  <head>
    <script data-require="[email protected]" data-semver="1.5.8" src="https://opensource.keycdn.com/angularjs/1.5.8/angular.min.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body> 
  <div ng-app="myApp" ng-controller="myCtrl">

    <form>
      <label for="Domain Name">Domain Name</label>
      <input ng-model="info.name" type="text" /><br />
      <label for="IP">IP</label><input ng-model="info.ip" type="text" />
      <hr>
    <div ng-repeat="site in sites track by $index">
      <label for="">ID</label><input type="text" ng-model="site.id" />
      <label for="">title</label><input type="text" ng-model="site.title" />
      <label for="">desc</label><input type="text" ng-model="site.meta_desc" />
      <label for="">meta_keys</label><input type="text" ng-model="site.meta_keys" />


    </div>
      <br />
      <button ng-click="addSite()">Add Site</button>
    </form>

      <pre>
        {{info | json}}

      </pre>


</div>

script.js

angular.module('myApp', [])
.controller('myCtrl', function($scope){
  $scope.info = {};
  $scope.info.sites = {};


  $scope.addSite = function(){
    $scope.info.sites = {id:'',
                         title:'',
                         meta_desc:'',
                         meta_keys:''
    }

}


});

Data which I try to generate:

{
  "name": "myDomain",
  "ip": "11.22.33.44.55",
  "sites": {
    {"id": "1" ,"title": "myTitle Site 1","meta_desc": "myDescription Site 1", "meta_keys": ["my", "meta", "keys"]},
    {"id": "2" ,"title": "myTitle Site 2","meta_desc": "myDescription Site 2", "meta_keys": ["my", "meta", "keys"]},
    {"id": "3" ,"title": "myTitle Site 3","meta_desc": "myDescription Site 3", "meta_keys": ["my", "meta", "keys"]}
},

}

Data which I get now:

{
  "sites": {
    "id": "",
    "title": "",
    "meta_desc": "",
    "meta_keys": ""
  },
  "name": "myDomain",
  "ip": "11.22.33.44.55"
}

Thanks a lot for any help.

1
  • You can check the answer below Commented Nov 22, 2016 at 2:38

1 Answer 1

2

You have done few things wrong as below.

  1. Your ng-repeat="site in sites track by $index" is iterating sites instead of info.sites as in your $scope.info.sites
  2. Also $scope.info.sites should be an array like $scope.info.sites = [] instead of object which you have like $scope.info.sites = {}
  3. On addSite method instead of adding a new item to the array with $scope.info.sites.push(), you are overwriting the value by assigning it.

It worked after correcting the above stuffs.

angular.module('myApp', [])
    .controller('myCtrl', function($scope){
      $scope.info = {};
      $scope.info.sites = [];
      
      
      $scope.addSite = function(){
        $scope.info.sites.push({id:'',
                             title:'',
                             meta_desc:'',
                             meta_keys:''
        });
  
     };
      
      
    });
<!DOCTYPE html>
<html>

  <head>
    <script data-require="[email protected]" data-semver="1.5.8" src="https://opensource.keycdn.com/angularjs/1.5.8/angular.min.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body> 
  <div ng-app="myApp" ng-controller="myCtrl">
  
    <form>
      <label for="Domain Name">Domain Name</label>
      <input ng-model="info.name" type="text" /><br />
      <label for="IP">IP</label><input ng-model="info.ip" type="text" />
      <hr>
    <div ng-repeat="site in info.sites track by $index">
      <label for="">ID</label><input type="text" ng-model="info.id" />
      <label for="">title</label><input type="text" ng-model="site.title" />
      <label for="">desc</label><input type="text" ng-model="site.meta_desc" />
      <label for="">meta_keys</label><input type="text" ng-model="site.meta_keys" />
      
      
    </div>
      <br />
      <button ng-click="addSite()">Add Site</button>
    </form>
      
      <pre>
        {{info | json}}
        
      </pre>
      
      
</div>

Method 2: (Using Object instead of array)

angular.module('myApp', [])
    .controller('myCtrl', function($scope){
      $scope.info = {};
      $scope.info.sites = {};
      
      
      $scope.addSite = function(){
        var index = Object.keys($scope.info.sites).length;
        $scope.info.sites['item' + index] = {id:'',
                             title:'',
                             meta_desc:'',
                             meta_keys:''
        };
  
     };
      
      
    });
<!DOCTYPE html>
<html>

  <head>
    <script data-require="[email protected]" data-semver="1.5.8" src="https://opensource.keycdn.com/angularjs/1.5.8/angular.min.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body> 
  <div ng-app="myApp" ng-controller="myCtrl">
  
    <form>
      <label for="Domain Name">Domain Name</label>
      <input ng-model="info.name" type="text" /><br />
      <label for="IP">IP</label><input ng-model="info.ip" type="text" />
      <hr>
    <div ng-repeat="(idx, site) in info.sites track by $index">
      <label for="">ID</label><input type="text" ng-model="info.id" />
      <label for="">title</label><input type="text" ng-model="site.title" />
      <label for="">desc</label><input type="text" ng-model="site.meta_desc" />
      <label for="">meta_keys</label><input type="text" ng-model="site.meta_keys" />
      
      
    </div>
      <br />
      <button ng-click="addSite()">Add Site</button>
    </form>
      
      <pre>
        {{info | json}}
        
      </pre>
      
      
</div>

Sign up to request clarification or add additional context in comments.

10 Comments

Thanks for your fast answer Aruna. Please can you explain me point 2. Why do we need to pass an array instead of an object. it wonders me that it is not possible in angular to easyliy concatenate 2 objects. In angularjs are methods like merge and extend. Is it not a scenario for using this methods or i am wrong? thanks a lot
Objects work with the key and won't work, if it does not have any key. In your data "sites": { {"id": "1"}, {"id": "2} }, this is an invalid object, since the parent object does not have any key for the child it has. To be a valid object, it should be like this with a key, "sites": { "item1": {"id": "1"}, "item2": {"id": "2} } . If you don't have any key then, it should be an array as "sites": [ {"id": "1"}, {"id": "2} ]
okay, it is possible to reproduce the object like this "sites": { "item1": {"id": "1"}, "item2": {"id": "2} } or does it make sense at all?
Okay, I will make the change.
@Hema, Do you mean something like this, stackoverflow.com/a/9593447/7055233
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.