简体   繁体   中英

AngularJS Selecting values from form created by ng-repeat

First of all: Sorry if the snippets are with many tabs (:

Hi everyone!

Currently i'm working on an AngularJS based application. The application has a database connection through the Prestashop Webservice . I'm trying to edit content that's in the database. I think the example will make it more clear.

Summary
The webservice can be used to create a link with an existing prestashop installation. The link itself is an REST API for accessing the database. With this information we're able to get, set, edit and delete data from the database. See the following example for a customers table:

 <?php require_once('.././PSWebServiceLibrary.php'); /** * get information from PrestaShop */ $webService = new PrestaShopWebservice($url, $key, $debug); $opt = array( "resource" => "customers", "display" => "full", ); $jsonUrl = ($webService->get( $opt )); //json encode it $json = json_encode($jsonUrl); echo($json); ?>

The definition of all the variables inside this example are as follow:

  • $webservice => Is the webservice it self. It is build up by a shop_url ( $url ), Authentication_key ( $key ) and a debug option ( $debug )
  • $opt => This is an array that creates the SELECT query deployed on the database in this case the query will be: SELECT * FROM customers . Where the resource = the db table and the display = the filter as in this case: everything.

The next step is to compile the JSON data in app.js so that we're able to select and show different parts of the query, see the example below:

 myApp.controller('CustomerController', function($scope, $http) { $http.get('config/get/getCustomers.php').then(function (response) { $scope.customers = response.data.customers.customer }); });

Now we're able to select different parts of the JSON data. we're able to show this data in HTML in combination with the ng-controller , ng-repeat and ng-bind . See the example below:

 <div ng-controller="CustomerController" class="col-lg-12"> <div class="row listrow" ng-repeat="customer in customers | orderBy: customer.id"> <div class="col-lg-8"> <p class="customer" ng-bind="customer.id + ' ' + customer.firstname + ' ' + customer.lastname"> </p> </div> </div> </div>

In this case we'll be repeating the customer id, firstname and lastname from the JSON data. The output would be something like this:

 <div ng-controller="CustomerController" class="col-lg-12"> <div class="row listrow" ng-repeat="customer in customers | orderBy: customer.id"> <div class="col-lg-8"> <p class="customer">1 John Doe</p> <p class="customer">2 John Don't</p> <p class="customer">3 John Does</p> </div> </div> </div>

So all works fine untill now, the next thing i've added is an edit button, this will open a modal with a form. The form will be loaded with all the customers information corresponding to the customers id. The information are things like address, phone number, etc. See the example below:

 <div class="row listrow" ng-repeat="customer in customers | orderBy: customer.id"> <div class="col-lg-8"> <p class="customer" ng-bind="customer.id + ' ' + customer.firstname + ' ' + customer.lastname"></p> </div> <div class="col-lg-2"> <a href="" data-toggle="modal" data-target=".bd-example-modal-sm{{customer.id}}"> {{'Wijzig' | translate }} </a> </div> <div ng-if="customer.id == address.id" ng-repeat="address in addresses" class="modal fade bd-example-modal-sm{{customer.id}}" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true"> <div class="modal-dialog modal-lg"> <div class="modal-content customer-modal"> <div class="modal-header product-modal-header no-border"> <div class="container"> <div class="row"> <form ng-controller="CustomerController" class="bottomborderinput margin-t-25 col-xs-12 col-sm-12 col-md-12 col-lg-12 col-xl-12"> <div class="form-group row justify-content-between"> <div> <label class="d-flex">{{ 'Customer_id' | translate }}</label> <input title="customer_id" type="number" name="customer_id" id="customer_id" class="form-control" aria-describedby="" ng-value="customer.id"> </div> <div class="col-6"> <label class="d-flex">{{ 'Voornaam' | translate }}</label> <input title="Voornaam" type="text" name="editFirstname" id="firstname" class="form-control" aria-describedby="" ng-value="customer.firstname"> </div> <div class="col-6"> <label class="d-flex">{{ 'Achternaam' | translate }}</label> <input title="Achternaam" type="text" name="editLastname" class="form-control" aria-describedby="" ng-value="customer.lastname"> </div> </div> <div class="form-group row justify-content-between"> <div class="col-12"> <label class="d-flex">{{ 'Email' | translate }}</label> <input title="Email" type="email" name="editEmail" class="form-control" aria-describedby="" ng-value="customer.email"> </div> </div> <!-- Addresscontroller for address table -> DB --> <div ng-if="customer.id == address.id" ng-repeat="address in addresses" class="form-group row justify-content-between"> <div class="col-12"> <label class="d-flex">{{ 'Straat en huisnummer' | translate }}</label> <input title="Straat en huisnummer" type="text" name="editResidential" class="form-control" aria-describedby="" ng-value="address.address1"> </div> </div> <div ng-if="customer.id == address.id" ng-repeat="address in addresses" class="form-group row justify-content-between"> <div class="col-6"> <label class="d-flex">{{ 'Postcode' | translate }}</label> <input title="Postcode" type="text" name="editArea_code" class="form-control" aria-describedby="" ng-value="address.postcode"> </div> <div class="col-6"> <label class="d-flex">{{ 'Plaats' | translate }}</label> <input title="Plaats" type="text" name="editCity" class="form-control" aria-describedby="" ng-value="address.city"> </div> </div> <!-- ID Lang omzetten naar text language --> <div class="form-group row justify-content-between"> <div class="col-6"> <label class="d-flex">{{ 'Land' | translate }}</label> <input title="Land" type="text" name="editCountry" class="form-control" aria-describedby="" ng-value="customer.id_lang"> </div> <!-- Address db --> <div ng-if="customer.id == address.id" ng-repeat="address in addresses" class="col-6"> <label class="d-flex">{{ 'Telefoon nummer' | translate }}</label> <input title="Telefoon nummer" type="tel" name="editPhone" class="form-control" aria-describedby="" ng-value="address.phone"> </div> </div> <div ng-if="customer.id == address.id" ng-repeat="address in addresses" class="form-group row justify-content-between"> <div class="col-6"> <label class="d-flex">{{ 'Bedrijfsnaam' | translate }}</label> <input title="bedrijfsnaam" type="text" name="editCompany_name" class="form-control" aria-describedby="" ng-value="address.company"> </div> <!-- Address DB --> <div class="col-6"> <label class="d-flex">{{ 'BTW nummer' | translate }}</label> <input title="BTW - nummer" type="text" name="editVat_number" class="form-control" aria-describedby="" ng-value="address.vat_number"> </div> </div> <div ng-repeat-end class="form-group row justify-content-between"> <div class="col-12"> <label class="d-flex">{{ 'Klantgroep' | translate }}</label> <input title="Klantroep" type="text" name="editKlantgroep" class="form-control" aria-describedby="" ng-value="customer.id_default_group"> </div> </div> <div class="form-group text-center"> <button type="submit" ng-click="EditCustomer()" class="defaultbutton margin-t-50"> <svg class="align-middle float-left " width="27" height="25" viewBox="13 12 27 21" xmlns="http://www.w3.org/2000/svg"> <path d="M23.065 32.28c-.287 0-.575-.124-.8-.373l-8.182-9.057c-.47-.52-.494-1.394-.052-1.95.443-.554 1.183-.58 1.653-.06l7.365 8.153 14.395-16.6c.46-.532 1.2-.523 1.652.022.452.544.443 1.416-.018 1.95L23.882 31.886c-.227.262-.522.393-.817.393z" fill="#FFF" fill-rule="evenodd"/> </svg>{{ 'Klant opslaan' | translate }} </button> </div> </form> </div> </div> </div> <div class="modal-footer no-border product-modal-footer"> <a data-dismiss="modal">{{ 'Sluit' | translate }}</a> </div> </div> </div> </div>

Short summary about the above snippet

The "wijzig" link could be translated to edit customer. on-click the modal will be opened. Before opening the modal the class will be filtered by ID so that the right information is requested from the database.

So if customer "3" lives on smurfs village: 3 the filter will obtain this from the address table in the database.

And now the problem
The problem is not with selecting the data but with updating the data. As you've seen the data is selected from the database and loaded as value in a form. The values then can be edited by the user. Like someone moved from one house to the other so his address has to be updated. the form is as following:

 <form ng-controller="CustomerController" class="bottomborderinput margin-t-25 col-xs-12 col-sm-12 col-md-12 col-lg-12 col-xl-12"> <div class="form-group row justify-content-between"> <div> <label class="d-flex">{{ 'Customer_id' | translate }}</label> <input title="customer_id" type="number" name="customer_id" id="customer_id" class="form-control" aria-describedby="" ng-value="customer.id"> </div> <div class="col-6"> <label class="d-flex">{{ 'Voornaam' | translate }}</label> <input title="Voornaam" type="text" name="editFirstname" id="firstname" class="form-control" aria-describedby="" ng-value="customer.firstname"> </div> <div class="col-6"> <label class="d-flex">{{ 'Achternaam' | translate }}</label> <input title="Achternaam" type="text" name="editLastname" class="form-control" aria-describedby="" ng-value="customer.lastname"> </div> </div> <div class="form-group row justify-content-between"> <div class="col-12"> <label class="d-flex">{{ 'Email' | translate }}</label> <input title="Email" type="email" name="editEmail" class="form-control" aria-describedby="" ng-value="customer.email"> </div> </div> <!-- Addresscontroller for address table -> DB --> <div ng-if="customer.id == address.id" ng-repeat="address in addresses" class="form-group row justify-content-between"> <div class="col-12"> <label class="d-flex">{{ 'Straat en huisnummer' | translate }}</label> <input title="Straat en huisnummer" type="text" name="editResidential" class="form-control" aria-describedby="" ng-value="address.address1"> </div> </div> <div ng-if="customer.id == address.id" ng-repeat="address in addresses" class="form-group row justify-content-between"> <div class="col-6"> <label class="d-flex">{{ 'Postcode' | translate }}</label> <input title="Postcode" type="text" name="editArea_code" class="form-control" aria-describedby="" ng-value="address.postcode"> </div> <div class="col-6"> <label class="d-flex">{{ 'Plaats' | translate }}</label> <input title="Plaats" type="text" name="editCity" class="form-control" aria-describedby="" ng-value="address.city"> </div> </div> <!-- ID Lang omzetten naar text language --> <div class="form-group row justify-content-between"> <div class="col-6"> <label class="d-flex">{{ 'Land' | translate }}</label> <input title="Land" type="text" name="editCountry" class="form-control" aria-describedby="" ng-value="customer.id_lang"> </div> <!-- Address db --> <div ng-if="customer.id == address.id" ng-repeat="address in addresses" class="col-6"> <label class="d-flex">{{ 'Telefoon nummer' | translate }}</label> <input title="Telefoon nummer" type="tel" name="editPhone" class="form-control" aria-describedby="" ng-value="address.phone"> </div> </div> <div ng-if="customer.id == address.id" ng-repeat="address in addresses" class="form-group row justify-content-between"> <div class="col-6"> <label class="d-flex">{{ 'Bedrijfsnaam' | translate }}</label> <input title="bedrijfsnaam" type="text" name="editCompany_name" class="form-control" aria-describedby="" ng-value="address.company"> </div> <!-- Address DB --> <div class="col-6"> <label class="d-flex">{{ 'BTW nummer' | translate }}</label> <input title="BTW - nummer" type="text" name="editVat_number" class="form-control" aria-describedby="" ng-value="address.vat_number"> </div> </div> <div ng-repeat-end class="form-group row justify-content-between"> <div class="col-12"> <label class="d-flex">{{ 'Klantgroep' | translate }}</label> <input title="Klantroep" type="text" name="editKlantgroep" class="form-control" aria-describedby="" ng-value="customer.id_default_group"> </div> </div> <div class="form-group text-center"> <button type="submit" ng-click="EditCustomer()" class="defaultbutton margin-t-50"> <svg class="align-middle float-left " width="27" height="25" viewBox="13 12 27 21" xmlns="http://www.w3.org/2000/svg"> <path d="M23.065 32.28c-.287 0-.575-.124-.8-.373l-8.182-9.057c-.47-.52-.494-1.394-.052-1.95.443-.554 1.183-.58 1.653-.06l7.365 8.153 14.395-16.6c.46-.532 1.2-.523 1.652.022.452.544.443 1.416-.018 1.95L23.882 31.886c-.227.262-.522.393-.817.393z" fill="#FFF" fill-rule="evenodd"/> </svg>{{ 'Klant opslaan' | translate }} </button> </div> </form>

The ng-click function in app.js:

 $scope.EditCustomer = function() { var customer_id = $('input[name="customer_id"]').val(); var firstname = $('input[name="editFirstname"]').val(); var lastname = $('input[name="editLastname"]').val(); var email = $('input[name="editEmail"]').val(); var residential = $('input[name="editResidential"]').val(); var area_code = $('input[name="editArea_code"]').val(); var city = $('input[name="editCity"]').val(); var country = $('input[name="editCountry"]').val(); var phone = $('input[name="editPhone"]').val(); var company_name = $('input[name="editCompany_name"]').val(); var vat_number = $('input[name="editVatnumber"]').val(); var customer_group = $('input[name="editCustomer_group"]').val(); $.ajax({ type:'POST', data:{customer_id:customer_id, firstname:firstname, lastname:lastname,email:email, residential:residential, area_code:area_code, city:city, country:country, phone:phone, company_name:company_name,vat_number:vat_number, customer_group:customer_group}, url:"config/edit/editCustomer.php", // PHP Page URL To php code saving the input to the database success : function(response) { alert(response.msg); } }) };

I'm aware about that the $.ajax should be changed to $http.post .

The corresponding php update file:

 <?php // Here we define constants /!\\ You need to replace this parameters define('DEBUG', true); require_once "../PSWebServiceLibrary.php"; // Here we use the WebService to get the schema of "customers" resource $webService = new PrestaShopWebservice($url, $key, DEBUG); // Edit customer. // Request the input field values. $customer_id = $_REQUEST['customer_id']; $customer_firstname = $_REQUEST['firstname']; $customer_lastname = $_REQUEST['lastname']; $customer_email = $_REQUEST['email']; $customer_residential = $_REQUEST['residential']; $customer_area_code = $_REQUEST['area_code']; $customer_city = $_REQUEST['city']; $customer_country = $_REQUEST['country']; $customer_phone = $_REQUEST['phone']; $customer_company_name = $_REQUEST['company_name']; $customer_vat_number = $_REQUEST['vat_number']; $customer_group = $_REQUEST['customer_group']; $opt = $webService->get(array( "resource" => "customers", "display" => "full", "filter[id]" => $customer_id )); $resource = $opt->children()->children(); $resource->id = $customer_id; $resource->id_shop = 1; $resource->passwd = ""; $resource->id_default_group = $customer_group; $resource->id_lang = $customer_country; $resource->firstname = $customer_firstname; $resource->lastname = $customer_lastname; $resource->email = $customer_email; $resource->date_add = ""; $xml = $opt->asXML(); // all of it! $ret = $webService->edit(array( 'resource' => 'customers', 'id' => $customer_id, 'putXml' => $xml )); $opt1 = $webService->get(array( 'resource' => 'addresses', 'display' => 'full', 'filter[id]' => $customer_id )); $resource = $opt1->children()->children(); $resource->id = $customer_id; $resource->company = $customer_company_name; $resource->lastname = $customer_lastname; $resource->firstname = $customer_firstname; $resource->id_country = $customer_country; $resource->alias = "mijn adres"; $resource->address1 = $customer_residential; $resource->postcode = $customer_area_code; $resource->city = $customer_city; $resource->phone_mobile = $customer_phone; $resource->vat_number = $customer_vat_number; $xml1 = $opt1->asXML(); // all of it! $ret1 = $webService->edit(array('resource' => 'addresses', 'id' => $customer_id, 'putXml' => $xml1));

So the actual problem is that when updating a customer i'm always retrieving id = 1. inside the filter this due to the first appearing <form> is with id=1. Since all input names are the same JS will grab the first one, in this case the one with id = 1.

So for editing the customer with id = 1. everything works fine but when i'm trying to edit the customer with, lets say id = 3 the first id is still selected.

My question is: is there a way to filter this in a more proporate way so that the right form with the right id is selected and edited?

I hope everything is clear and if it's not please let me know.

Thanks in advance!

First, I created a controller to handle the logic. I assume you have a similar layout.

For the guts, on your ng-repeat , create an ng-click for each <li> (or another similar element). The method on the ng-click should pass in the value of customer (or the individual value you get on each iteration)

So, clicking on any of the <li> will in turn reference the same model object it was created with.

 (function() { var app = angular.module("cus", []); var CustomerController = function() { var vm = this; vm.Customers = [{ // Should be like Edit #2 name: "Joe", age: 25, gender: "Male" }, { name: "Lisa", age: 18, gender: "Female" }, { name: "Foobar", age: 89, gender: "Dog" }, ]; vm.showInfo = function(customer) { console.log(customer.name + " is a " + customer.age + " year old " + customer.gender); } vm.submitInfo = function(customer) { // This is your $EditCustomer() console.log("Submitting " + customer.name + " to database."); console.log("Saving age as: " + customer.age); console.log("Saving gender as: " + customer.gender); console.log("Successfully saved " + customer.name + "!"); } } app.controller("CustomerController", [CustomerController]); })();
 <html> <head> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> </head> <body ng-app="cus"> <div ng-controller="CustomerController as vm"> <ul ng-repeat="customer in vm.Customers"> <li ng-click="vm.showInfo(customer);">{{ customer.name }}</li> <li ng-click="vm.showInfo(customer);">{{ customer.age }}</li> <li ng-click="vm.showInfo(customer);">{{ customer.gender }}</li> </ul> <div class="form-group" ng-repeat="customer in vm.Customers"> <!-- This is your form--> <ng-form name="userFieldForm"> <label>{{ customer.name }}'s Age</label> <input type="text" class="form-control" name="email" ng-model="customer.age"> <label>{{ customer.name }}'s Gender</label> <input type="text" class="form-control" name="gender" ng-model="customer.gender"> <button type="submit" ng-click="vm.submitInfo(customer)">Submit</button> </ng-form> </div> </div> </body> </html>

In your case, you would want to pass in the value of the customer on your $scope.EditCustomer .

So it'll become something like this,

$scope.EditCustomer = function(customer) {
    var customer_id = customer.id;
    var firstname = customer.firstName;
    var lastname = customer.lastName;
    var email = customer.email;
    ...


    $.ajax({
        type:'POST',
        data:{customer_id:customer_id, firstname:firstname, lastname:lastname,email:email, residential:residential, area_code:area_code, city:city, country:country, phone:phone, company_name:company_name,vat_number:vat_number, customer_group:customer_group},
        url:"config/edit/editCustomer.php", // PHP Page URL To php code saving the input to the database
        success : function(response) {
            alert(response.msg);
        }
    })
};

EDIT

I've updated it to create an ng-form inside an ng-repeat . A form gets created for each customer in Customers . Putting a <button> with an ng-click="submitInfo(customer)" will cause you to pass in that object into the method in order for the information to get from the form created from the ng-repeat to the method to parse the data in the form and save it.

EDIT #2

Instead of just setting $scope.customers = response.data.customers.customer , make it something like this,

myApp.controller('CustomerController', function($scope, $http) {
    vm.Customers =  [];
    var responseData; // Holds the JSON response
    $http.get('config/get/getCustomers.php').then(function (response) {
        responseData = response.data.customers; // response.data.customers.customer;
        for(var cus in responseData) { // Filling up vm.Customers with data from response
            vm.Customers.push(cus);
        }
    });
});

This way, you are populating the Customer objects after you get them from the response. Now if you hook them up with everything else mentioned, it should be working.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM