1

I am struggling to get this form to work was wondering if anyone can give me any ideas why! So what I have is an index page with an ng-app=especial. In the DIV main_area_holder goes the ng_view. The Ng-view displays fine and form displays on index page (from localtion app/partials/cust_form.php). What I am struggling to get working is the http request to php file so I can import form data into DB. I know the php code works without ajax (straight post request). If you can help out I would be very grateful.

app.js UPDATED

var especial = angular.module('especial', ['ngRoute']);

especial.config(function($routeProvider) {
$routeProvider.when('/',
    {
        controller: 'custPage',
        templateUrl: 'app/partials/cust_form.tpl.html'
    });
});

especial.config(function($httpProvider) {
$httpProvider.defaults.transformRequest = function(request){
    if(typeof(request)!='object'){
        return request;
    }
    var str = [];
    for(var k in request){
        if(k.charAt(0)=='$'){
            delete request[k];
            continue;
        }
        var v='object'==typeof(request[k])?JSON.stringify(request[k]):request[k];
        str.push(encodeURIComponent(k) + "=" + encodeURIComponent(v));
    }
    return str.join("&");
};
$httpProvider.defaults.timeout=10000;
$httpProvider.defaults.headers.post = {
    'Content-Type': 'application/x-www-form-urlencoded',
    'X-Requested-With': 'XMLHttpRequest'
};
});
especial.controller('custPage', function($scope, $http){
    $scope = {};
    $scope.custCreUpd = function(){
        $http({
            method: 'POST',
            url: 'app/php/cust_cre_upd.php',
            data: $scope.cust,
            headers : {'Content-Type': 'application/x-www-form-urlencoded'}
        }).success(function(data){

            console.log("OK", data)

        }).error(function(err){"ERR", console.log(err)})
    };
});

cust_cre_upd.php

<?php

        $post = file_get_contents("php://input");
        $values = json_decode($post, true);
        $table='customers';
        $conn = new PDO('mysql:host=localhost;dbname=displaytrends;charset=utf8', 'displaytrends', 'displaytrends');
        $conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
                    //Strip array to fields with values     
        $values=array_filter($values);
                    //Take array keys from array
        $field_keys=array_keys($values);
                    //Implode for insert fields
        $ins_fields=implode(",", $field_keys);
                    //Implode for insert value fields (values will binded later)
        $value_fields=":" . implode(", :", $field_keys);
                    //Create update fields for each array create value = 'value = :value'.
        $update_fields=array_keys($values);
        foreach($update_fields as &$val){
            $val=$val." = :".$val;
        }
        $update_fields=implode(", ", $update_fields);
                    //SQL Query
        $insert = "INSERT INTO $table ($ins_fields) VALUES ($value_fields) ON DUPLICATE KEY UPDATE $update_fields";
        $query = $conn->prepare($insert);
                    //Bind each value based on value coming in.
        foreach ($values as $key => &$value) {
            switch(gettype($value)) {
                case 'integer':
                case 'double':
                $query->bindParam(':' . $key, $value, PDO::PARAM_INT);
                break;
                default:
                $query->bindParam(':' . $key, $value, PDO::PARAM_STR);
            }
        }
        $query->execute();

    ?>

index.php

<!doctype html>
<html ng-app="especial">
<head>
<meta charset="UTF-8">
<title>Especial - Database</title>
<link rel="stylesheet" href="css/index.css">
<script src="scripts/angular.js"></script>
<script src="scripts/angular-route.js"></script>
<script src="scripts/angular-animate.js"></script>
</head>

<body>
<div class="header">
<img id="logo" src="images/especial-logo.jpg">
<a id="logout" href="logout.php">Logout</a>
<div class="menu"></div>
</div>
<div class="sub_menu"></div>

<div class="main_area">
    <div id="main_area_holder" ng-view>
    </div>
</div>
<div class="footer"></div>
<script src="app/app.js"></script>
</body>
</html>

cust_form.php

<div ng-controller="custPage">
<div id="form">
        <form name="cust_form">   
           <label>Account No:</label>
           <input type="text" ng-model="cust.int_custID" name="cust[int_custID]" id="int_custID"/>
           <label>Company:</label>
           <input type="text" ng-model="cust.cust_company" name="cust[cust_company]" id="cust_company"/>
            <label>Address:</label>
            <textarea type="text" rows=5 ng-model="cust.cust_address" name="cust[cust_address]" id="cust_address"></textarea>
            <label>Postcode:</label>
            <input type="text" ng-model="cust.cust_postcode" name="cust[cust_postcode]" id="cust_postcode"/>
            <label>Contact 1:</label>
            <input type="text" ng-model="cust.cust_contact_1" name="cust[cust_contact_1]" id="cust_contact_1"/>
            <label>Contact 2:</label>
            <input type="text" ng-model="cust.cust_contact_2"  name="cust[cust_contact_2]"  id="cust_contact_2"/>
            <label>Telephone:</label>
            <input type="text" ng-model="cust.cust_tel" name="cust[cust_tel]" id="cust_tel"/>
            <label>Mobile:</label>
            <input type="text" ng-model="cust.cust_mob" name="cust[cust_mob]" id="cust_mob"/>
            <label>DDI:</label>
            <input type="text" ng-model="cust.cust_DDI" name="cust[cust_DDI]" id="cust_DDI"/>
            <label>Email:</label>
            <input type="email" ng-model="cust.cust_email" name="cust[cust_email]" id="cust_email"/>
            <label>Notes:</label>
            <textarea type="text" rows=5 colums=1 ng-model="cust.cust_notes"  name="cust[cust_notes]" id="cust_notes"></textarea>

           <button type="submit" ng-click="custCreUpd()"> Submit </button>
       </form>
</div>
</div>

3 Answers3

1

app.js:

var especial = angular.module('especial', ['ngRoute']);

especial.config(function($routeProvider) {
    $routeProvider.when('/',
    {
        controller: 'custPage',
        templateUrl: 'app/partials/cust_form.tpl.html'
    });
});

especial.config(function($httpProvider) {
$httpProvider.defaults.transformRequest = function(request){
    if(typeof(request)!='object'){
        return request;
    }
    var str = [];
    for(var k in request){
        if(k.charAt(0)=='$'){
            delete request[k];
            continue;
        }
        var v='object'==typeof(request[k])?JSON.stringify(request[k]):request[k];
        str.push(encodeURIComponent(k) + "=" + encodeURIComponent(v));
    }
    return str.join("&");
};
$httpProvider.defaults.timeout=10000;
$httpProvider.defaults.headers.post = {
    'Content-Type': 'application/x-www-form-urlencoded',
    'X-Requested-With': 'XMLHttpRequest'
};
});
especial.controller('custPage', function($scope, $http){
   $scope.cust = {};
   $scope.custCreUpd = function(){
    $http({
        method: 'POST',
        url: 'app/php/cust_cre_upd.php',
        data: $scope.cust,
        headers : {'Content-Type': 'application/x-www-form-urlencoded'}
    }).success(function(data){
        console.log(data)
    }).error(function(err){
        console.log(err)
    })
};
});

cust_cre_upd.php

<?php
//print_r($_POST); you can print_r it for understanding
//use $_POST as usual, example $_POST["cust_ID"] means your     
$values = $_POST;
$conn = new PDO('mysql:host=localhost;dbname=displaytrends;charset=utf8', 'displaytrends', 'displaytrends');
$conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
//Strip array to fields with values
$values=array_filter($values);
//Take array keys from array
$field_keys=array_keys($values);
//Implode for insert fields
$ins_fields=implode(",", $field_keys);
//Implode for insert value fields (values will binded later)
$value_fields=":" . implode(", :", $field_keys);
//Create update fields for each array create value = 'value = :value'.
$update_fields=array_keys($values);
foreach($update_fields as &$val){
    $val=$val." = :".$val;
}
$update_fields=implode(", ", $update_fields);
//SQL Query
$insert = "INSERT INTO $table ($ins_fields) VALUES ($value_fields) ON DUPLICATE KEY UPDATE $update_fields";
$query = $conn->prepare($insert);
//Bind each value based on value coming in.
foreach ($values as $key => &$value) {
    switch(gettype($value)) {
        case 'integer':
        case 'double':
            $query->bindParam(':' . $key, $value, PDO::PARAM_INT);
            break;
        default:
            $query->bindParam(':' . $key, $value, PDO::PARAM_STR);
    }
}
$query->execute();

index.php:

<!doctype html>
<html ng-app="especial">
<head>
    <meta charset="UTF-8">
    <title>Especial - Database</title>
<!--    <link rel="stylesheet" href="css/index.css">-->
    <script src="scripts/angular-1.3.8.min.js"></script>
    <script src="scripts/angular-route.min.js"></script>
<!--    <script src="scripts/angular-animate.js"></script>-->
</head>

<body>
<div class="header">
    <img id="logo" src="images/especial-logo.jpg">
    <a id="logout" href="logout.php">Logout</a>
    <div class="menu"></div>
</div>
<div class="sub_menu"></div>

<div class="main_area">
    <div id="main_area_holder" ng-view>
    </div>
</div>
<div class="footer"></div>
<script src="app/app.js"></script>
</body>
</html>

cust_form.php (cust_form.tpl.html):

<div id="form">
    <form name="cust_form">
        <label>Account No:</label>
        <input type="text" ng-model="cust.int_custID" id="int_custID"/>
        <label>Company:</label>
        <input type="text" ng-model="cust.cust_company"  id="cust_company"/>
        <label>Address:</label>
        <textarea type="text" rows=5 ng-model="cust.cust_address" id="cust_address"></textarea>
        <label>Postcode:</label>
        <input type="text" ng-model="cust.cust_postcode" id="cust_postcode"/>
        <label>Contact 1:</label>
        <input type="text" ng-model="cust.cust_contact_1"  id="cust_contact_1"/>
        <label>Contact 2:</label>
        <input type="text" ng-model="cust.cust_contact_2"  id="cust_contact_2"/>
        <label>Telephone:</label>
        <input type="text" ng-model="cust.cust_tel" id="cust_tel"/>
        <label>Mobile:</label>
        <input type="text" ng-model="cust.cust_mob" id="cust_mob"/>
        <label>DDI:</label>
        <input type="text" ng-model="cust.cust_DDI" id="cust_DDI"/>
        <label>Email:</label>
        <input type="email" ng-model="cust.cust_email" id="cust_email"/>
        <label>Notes:</label>
        <textarea type="text" rows=5 colums=1 ng-model="cust.cust_notes" id="cust_notes"></textarea>

        <button type="submit" ng-click="custCreUpd()"> Submit </button>
    </form>
</div>

I creat a repository here https://github.com/Danzeer/forJoshCrocker

To debug with script in web browser, you can use chrome's Developer's tools - network (option+command+i in OSX, F12 in window, and chose the network card).When you click submit, you can see request in network card and check http header by clicking the request.

enter image description here enter image description here

danzeer
  • 86
  • 6
  • Thank you so much for all your help. Posting data now!!!! I was looking out at the debugging console and couldn't see anything which is why I asked if there should be changes... Thank again!!! :) – Josh Crocker Mar 19 '15 at 14:52
  • tutorial https://developer.chrome.com/devtools and detail https://developer.chrome.com/devtools/docs/network – danzeer Mar 19 '15 at 14:59
  • Sorry didn't make that clear, I couldn't see changes but updated script now and all is working and can see the http header... :) Cheers, – Josh Crocker Mar 19 '15 at 15:00
  • open Develop tool before your clicking! I add two pic to be clear about debug; you can do it again using your oldest script to find the difference of post's data. But the recent problem was the ' $post = file_get_contents("php://input"); ' in cust_cre_upd.php. Since we have rewritten the httpProvider in angular js , we can get "custMob" value by using "$custMob = $_POST["custMod"]" in php . And ' $post = file_get_contents("php://input"); ' will work without rewriting $httpProvider. – danzeer Mar 19 '15 at 15:27
  • And the recent problem was exactly what you said - "The problem I have must be between either the post in app.js to PHP file or the decoding as it enters the PHP file" – danzeer Mar 19 '15 at 15:36
0

I think you can find answer for "post" here AngularJs $http.post() does not send data

angualr's get works well, but angular's post does not seralize form-data as jquery. my solution (maybe wrong, according to what I have searched) was rewriting angular's httpProvider:

app.config(function($httpProvider) {
    $httpProvider.defaults.transformRequest = function(request){
        if(typeof(request)!='object'){
                return request;
        }
        var str = [];
        for(var k in request){
                if(k.charAt(0)=='$'){
                        delete request[k];
                        continue;
                }
                var v='object'==typeof(request[k])?JSON.stringify(request[k]):request[k];
                str.push(encodeURIComponent(k) + "=" + encodeURIComponent(v));
        }
        return str.join("&");
   };
   $httpProvider.defaults.timeout=10000;
   $httpProvider.defaults.headers.post = {
        'Content-Type': 'application/x-www-form-urlencoded',
        'X-Requested-With': 'XMLHttpRequest'
   };
  });

2 your

ng-click="custCreUpd"

should be

ng-click="custCreUpd()"

3 check the result of below, I'm not familiar with it

$.param($scope.cust)

Community
  • 1
  • 1
danzeer
  • 86
  • 6
0

I have rewrite your code, that seems sending post. You can compare it with yours:

app.js :

var especial = angular.module('especial', ['ngRoute']);

especial.config(function($routeProvider) {
$routeProvider.when('/',
    {
        controller: 'custPage',
        templateUrl: 'app/partials/cust_form.tpl.html'
    });
});

especial.config(function($httpProvider) {
$httpProvider.defaults.transformRequest = function(request){
    if(typeof(request)!='object'){
        return request;
    }
    var str = [];
    for(var k in request){
        if(k.charAt(0)=='$'){
            delete request[k];
            continue;
        }
        var v='object'==typeof(request[k])?JSON.stringify(request[k]):request[k];
        str.push(encodeURIComponent(k) + "=" + encodeURIComponent(v));
    }
    return str.join("&");
};
$httpProvider.defaults.timeout=10000;
$httpProvider.defaults.headers.post = {
    'Content-Type': 'application/x-www-form-urlencoded',
    'X-Requested-With': 'XMLHttpRequest'
};
});
//when using 1.3.8 version , consider how to write controller with []
especial.controller('custPage', ['$scope', '$http', function($scope, $http){
    $scope.cust = {};
    //$scope = {}; !!!!
    $scope.custCreUpd = function(){ // pay attention of params
        $http({
            method: 'POST',
            url: "app/php/cust_cre_upd.php",
            data: $scope.cust,
            headers : {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
        }).success(function(data){

            console.log("OK", data)

        }).error(function(err){"ERR", console.log(err)})
    };
}]);

index.php:

!doctype html>
<html ng-app="especial">
<head>
<meta charset="UTF-8">
<title>Especial - Database</title>
<script src="js/angular-1.3.8.min.js"></script>
<script src="js/angular-route.min.js"></script>
<!--    <script src="scripts/angular-animate.js"></script>-->
</head>

<body>
   <div id="main_area_holder" ng-view>
    </div>
<script src="app/app.js"></script>
</body>
</html>

custForm.tpl.html(your cust_form.php):

<!--<div ng-controller="custPage"> !none ng-controller when using ng-route-->

<div id="form">
   <form name="cust_form">
       <label>Account No:</label>
       <input type="text" ng-model="cust.int_custID" name="cust[int_custID]" id="int_custID"/>
       <button type="submit" ng-click="custCreUpd()"> Submit </button>
    </form>
</div>

naming custForm.tpl.html instead of cust_form.php seems much meaningful) and request of .php will be pass to php executor by apache/nginx while request for html only through apache/nginx. And pay attention to angular cache problem when using ng-route. -- some tools not relavent https://github.com/karlgoldstein/grunt-html2js and https://github.com/angular-ui/bootstrap, enjoy!

Points: 1 definition of controller

2 post of angularjs

3 how to use ng-view with ng-route

4 params-"$scope" of function custCreUpd hide $scope service

danzeer
  • 86
  • 6
  • Hi man, used code above still not working at all. Is there something I am missing. This code all worked before angularjs and still can't get anything to post to PHP files now after 3 days with angular. There is nothing special I have to do to webserver to make this work is there? – Josh Crocker Mar 19 '15 at 11:21
  • Thanks for all this, I just thought I'd add some thought. Angularjs is working! If I use {{ cust }} on html form page it will echo in an array in the form {"int_custID":"test","cust_company":"test","cust_address":"test"} etc. This is good. The problem I have must be between either the post in app.js to PHP file or the decoding as it enters the PHP file. As I said I know the rest of the php code works provided it is given a php array. A couple other things, is the address bar meant to change on submit to something index.php#?xxxxx as currently it is not??? Thanks again... – Josh Crocker Mar 19 '15 at 11:55