web-dev-qa-db-fra.com

Générer des champs de saisie de formulaire dynamiques et collecter des données de champ dans un tableau

Je suis coincé avec cette petite tâche . Je dois générer des champs de saisie de formulaire de manière dynamique en cliquant sur le bouton "ajouter" du formulaire .Le formulaire est censé créer un schéma de table de base de données. Ainsi, chaque champ d'entrée est un nom de champ de table de base de données.

Je peux bien générer les champs de manière dynamique, mais je ne parviens pas à rassembler les données réelles.

<form ng-controller="NewTableCtrl" ng-submit="submitTable()">
  <input type='text' ng-model='table.title' placeholder='Title:'>
  <input ng-repeat="field in fields" type='text' ng-model='table.fields' placeholder='Field:'>
  <div>
    <button type='submit'>Submit</button>
    <button ng-click="addFormField()">Add</button>
  </div>
</form>

.. et le contrôleur

.controller('NewTableCtrl', function($scope) {
  $scope.fields = [];
  $scope.table = {};

  $scope.addFormField = function () {
    $scope.fields.Push({});
  }

  $scope.submitTable = function () {
    console.log($scope.table);
  }
});

Ça a l'air simple. Lorsque je clique sur le bouton 'Ajouter', il génère le nouveau champ de saisie, mais le fait avec le même objet de modèle (de manière bien visible). Et c'est là que réside mon incompréhension. Je pensais que si je déclarais $scope.fields = [];dans le contrôleur, la répétition des données de champ irait simplement dans le tableau. Mais cela ne fait que refléter l'entrée dans chaque champ d'entrée répété. Je comprends maintenant que c’est ce qui est supposé être une liaison bidirectionnelle.

La raison pour laquelle j'ai pensé à cela est par analogie avec une soumission de formulaire ordinaire dans laquelle les noms de champs d'entrée répétés deviennent un tableau dans les données de formulaire codées en URL.

Alors, comment puis-je résoudre ce problème? Le serveur doit obtenir un tableau de champs comme celui-ci: fields: [field1, field2 ...] Dois-je générer des champs d'entrée avec une variable de portée différente pour chaque champ? Comment puis-je faire cela?

Est-ce plus complexe alors je pensais et cela doit être une directive? Si oui, s'il vous plaît, montrez-moi comment faire cela.

Merci.

7
r.sendecky

En ce moment, vous parcourez $scope.fields. Lorsque vous ajoutez un nouveau champ, vous placez un objet vide dans $scope.fields, mais le modèle-ng de chaque entrée pointe sur $scope.table.fields (qui n'existe pas jusqu'à ce que la première entrée y soit écrite - il contiendra alors une variable chaîne).

Pour ce cas d'utilisation simple, vous pouvez essayer:

app.controller('NewTableCtrl', function($scope) {

  $scope.table = { fields: [] };

  $scope.addFormField = function() {
    $scope.table.fields.Push('');
  }

  $scope.submitTable = function() {
    console.log($scope.table);
  }

});

Et:

<input ng-repeat="field in table.fields track by $index" type='text' ng-model='table.fields[$index]' placeholder='Field:'>

Démo: http://plnkr.co/edit/6iZSIBa9S1G95pIMBRBu?p=preview

11
tasseKATT

Regarde ça

Démo de travail

html

<body>
<div ng-app=''>
    <div ng-controller="questionCtrl">
        <div>
            <ul>
                <li ng-repeat="elemnt in questionelemnt">

                    <div>
                        <div id={{elemnt.id}} style="display:inline" >
                            <span  ng-model="elemnt.question" ng-hide="editorEnabled" ng-click="editorEnabled=true">
                                {{elemnt.question}}
                            </span>
                            <div  ng-show="editorEnabled">
                                <input  ng-model="elemnt.question" ng-show="editorEnabled" >
                                <button href="#" ng-click="editorEnabled=false">Done editing</button>
                            </div>
                        </div>
                        <div style="display:inline">
                            <span>
                                <input type="text" ng-model="elemnt.answer" placeholder="Answer" required/>
                            </span>
                        </div>

                        <span ng-hide="elemnt.length == 1">

                             <button ng-click="questionelemnt.splice($index, 1)">Remove</button>

                        </span>
                    </div>
                    <hr/>
                </li>
                <li>
                     <button ng-click="addFormField($event)">Add</button>
                </li>
            </ul>
        </div>
        <div>
            <button ng-click="showitems($event)">Submit</button>
        </div>
        <div id="displayitems" style="visibility:hidden;">
            {{questionelemnt}}
        </div>
    </div>
</div>
</body>

script

function questionCtrl($scope) {
    var counter = 0;
    $scope.questionelemnt = [{
        id: counter,
        question: 'Question-Click on me to edit!',
        answer: ''
    }];

    $scope.addFormField = function ($event) {
        counter++;
        $scope.questionelemnt.Push({
            id: counter,
            question: 'Question-Click on me to edit!',
            answer: ''
        });
        $event.preventDefault();
    }

    $scope.showitems = function ($event) {
        $('#displayitems').css('visibility', 'none');
    }
}
2
Nidhish Krishnan

Variation de la solution tasseKATT en utilisant une table de hachage au lieu d'un tableau ..__ Cela me permet d'avoir un objet JSON sympa que je peux rentrer pour construire mon filtre de requête.

http://plnkr.co/edit/CArP3Lkmn7T5PEPdXgNt?p=preview

<!DOCTYPE html>
<html>

  <head>
    <script data-require="angular.js@*" data-semver="1.3.0" src="//code.angularjs.org/1.3.0/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
    <style>
      div{ margin: 1em;}
      input{margin-left:1em;}
    </style>
  </head>

  <body ng-controller="myCtrl">

    <h2>Using a filter map tied to ng-model to create a filter object</h2>

    <div ng-repeat="field in fields">
      {{field}}<input ng-model=filters[field] />
    </div>

    <hr>
    <h3>Filter</h3>
    {{filters}}

    <script>

      var app=angular.module("app",[]);

      app.controller("myCtrl",function($scope){
        $scope.filters={};
        $scope.fields=["name","address","phone","state"];
      });

      angular.bootstrap(document,["app"]);

    </script>

  </body>

</html>
0
mccainz