Proceed to another view on button click AngularJS - angularjs

I have a drop down which is displaying data from a Web API. The data is shown below
here's the code for the drop down
<select ng-model="details" ng-options="x.Name for x in customers"></select>
then I have a text box and a button:
<input type="password" ng-model="pin" ng-required="true"/>
<button ng-click="pinForm.$valid && (count = count + 1)" ng-init="count=0">Proceed</button>
Now there are 2 things I want to implement:
with details.PIN I get the PIN of the selected person in the drop down. What I want to do is on button click to check if the pin entered in the text box match to details.PIN; if so, proceed to another view
I have implemented a count on the button. If the count reach to 3 and the pin entered is wrong, I need to show an error message.
The HTML for the only view I have till now
<body ng-app="customerApp">
<div ng-controller="CustomerCtrl" align="center">
<select ng-model="details" ng-options="x.Name for x in customers"></select>
<h1>you selected {{details.Name}}</h1>
<p>his card status is {{details.cardStatus}}</p>
<hr>
<div ng-switch="details.cardStatus">
<div ng-switch-when="0">
<form name="pinForm">
<input type="password" ng-model="pin" ng-required="true"/>
<p><button ng-click="pinForm.$valid && (count = count + 1)" ng-init="count=0">Proceed</button></p>
<p><span>Attempts left: {{3-count}}</span></p>
</form>
</div>
<div ng-switch-when="1">
<p>This card has been reported as stolen and will be retained. If it is yours, please contact your nearest branch</p>
</div>
<div ng-switch-when="2">
<p>This card has been reported as lost and will be retained. If it is yours, please contact your nearest branch</p>
</div>
</div>
</div>
</body>
</html>
Here is the code for the API
namespace test.Controllers
{
[RoutePrefix("Customer")]
public class CustomerController : ApiController
{
[Route("CustomerRecords")]
public List<Customer> Get()
{
return new List<Customer>()
{
new Customer { CID=1, Name="Bruce Wayne", PIN="1234", Bal=1000000, cardStatus= "0" }
,new Customer { CID=2, Name="Steve Rogers", PIN="2246", Bal=900000, cardStatus= "0" }
,new Customer { CID=3, Name="Jon Snow", PIN="2398", Bal=3000, cardStatus= "1" }
,new Customer { CID=4, Name="Rustin Cohle", PIN="7549", Bal=450000, cardStatus= "2" }
//NOTE
//cardStatus '0' :valid
//cardStatus '1' :stolen
//cardStatus '2' :lost
};
}
}
public class Customer
{
public int CID { get; set; }
public string Name { get; set; }
public string PIN { get; set; }
public int Bal { get; set; }
public string cardStatus { get; set; }
}
}
here's the module, the service and the factory method the code for routing the views:
var customerAppModule = angular.module("customerApp", []);
customerAppModule.controller('CustomerCtrl', function ($scope, CustomerService)
{
getCustomerRecords();
function getCustomerRecords() {
CustomerService.getCustomers()
.success(function (data) {
console.log(data);
$scope.customers = data;
})
.error(function (data, status) {
console.error('failure loading the customer record', status, data);
$scope.customers = {};
});
}
});
customerAppModule.factory('CustomerService', ['$http', function ($http) {
var customerService = {};
var urlBase = 'http://localhost:51701/Customer';
customerService.getCustomers = function () {
return $http.get(urlBase + '/CustomerRecords');
};
return customerService;
}]);
var app = angular.module('routeApp', ['ngRoute']);
app.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'Views/Home/index.cshtml',
controller: 'CustomerCtrl'
})
.when('/MainMenu', {
templateUrl: 'Views/Home/MainMenu.cshtml',
controller: 'CustomerCtrl'
})
});
I'm not sure I've written the code for the routing correctly.

What if you change the ng-click logic, to consums a function instead an expression.
Example
HTML
<body ng-controller="MainCtrl as vm">
<select ng-model="vm.details" ng-options="x.Name for x in vm.customers">
<option value="">Select...</option>
</select>
<h1>you selected {{vm.details.Name}}</h1>
<p>his card status is {{vm.details.cardStatus}}</p>
<hr>
<div ng-switch="vm.details.cardStatus">
<div ng-switch-when="0">
<form name="vm.pinForm">
<input type="password" ng-model="vm.pin" ng-required="true"/>
<p><button ng-disabled="vm.count >=3" ng-click="vm.pinFormCheck();" ng-init="vm.count=0">Proceed</button></p>
<p><span>Attempts left: {{3-vm.count}}</span></p>
</form>
</div>
<div ng-switch-when="1">
<p>This card has been reported as stolen and will be retained. If it is yours, please contact your nearest branch</p>
</div>
<div ng-switch-when="2">
<p>This card has been reported as lost and will be retained. If it is yours, please contact your nearest branch</p>
</div>
<div ng-if="vm.failPin">
<p>Invalid Pin</p>
</div>
<div ng-if="vm.count >=3">
<p>Not Enoguh Attempts</p>
</div>
</div>
</body>
CONTROLLER
var vm = this;
vm.customers = [
{CID:1, Name:'Bruce Wayne', PIN: '1234', Bal: 10000, cardStatus: '0'},
{CID:2, Name:'Steve Rogers', PIN: '2246', Bal: 90000, cardStatus: '0'},
{CID:3, Name:'Jon Snow', PIN: '2398', Bal: 30000, cardStatus: '1'},
{CID:4, Name:'Rustin Cohle', PIN: '7549', Bal: 45000, cardStatus: '2'}
];
vm.pinFormCheck = function(){
vm.count++;
if(vm.pinForm.$valid && (vm.details.PIN === vm.pin) && (vm.count <= 2)){
console.log('all good'); //change location.
}else{
vm.failPin = true;
console.log('atemps', vm.count);
}
};
Working Example in this HERE
Hope this example is good enough for your UNIT CASE

Related

ng-submit refreshes the page instead of submit [duplicate]

This question already has an answer here:
ng-click refreshes the page instead of submit
(1 answer)
Closed 5 years ago.
Hi i have an angular web form which takes input from the user and inserts into the database.I am using jersey-jackson rest web services and hibernate.But when i try to submit the form,the previous page which had the hyperlink to the current page is refreshed and the current page is reloaded again(Loading of previous page is seen in the network log).The url specified in the http request is not even invoked.Following is my code
<div id="main">
<h1>Create Leave</h1>
<form class="form-horizontal" ng-controller="MyAddController" >
<div class="form-group">
<label for="employeeName" class="col-sm-3 control-label">Employee Name</label>
<div class="col-sm-6">
<input type="text" id="num" class="form-control" ng-model="num" />
</div>
<div class="col-sm-3"></div>
</div>
<div class="form-group">
<label for="leaveType" class="col-sm-3 control-label">Leave Type</label>
<div class="col-sm-2">
<select id="leaveType" class="form-control" ng-model="leaveType">
<option value="">Hospital</option>
<option value="female">leave type 2</option>
<option value="female">leave type 3</option>
<option value="female">leave type 4</option>
<option value="female">leave type 5</option>
<option value="female">leave type 6</option>
</select>
</div>
<div class="col-sm-7"></div>
</div>
<div class="form-group">
<label for="leaveStartDate" class="col-sm-3 control-label">Leave Start Date</label>
<div class="col-sm-2">
<input type="date" id="startDates" class="form-control" ng-model="startDate" />
</div>
<div class="col-sm-7"></div>
</div>
<div class="form-group">
<label for="leaveEndDate" class="col-sm-3 control-label">Leave End Date</label>
<div class="col-sm-2">
<input type="date" id="endDate" class="form-control" ng-model="endDate" />
</div>
<div class="col-sm-7"></div>
</div>
<div class="form-group">
<div class="col-sm-3"></div>
<div class="col-sm-2">
<span><b>Is Half Day leave</b></span>
<div class="radio">
<label><input value="Yes" type="radio" name="halfDay" ng-model="isHalfDay" />Yes</label>
</div>
<div class="radio">
<label><input value="No" type="radio" name="halfDay" ng-model="isHalfDay" />No</label>
</div>
</div>
</div>
<input type="submit" value="Save" ng-click='add();' class="btn btn-primary col-sm-offset-3" />
<input type="reset" value="Reset" ng-click="resetForm()" class="btn" /> <br/>
</form>
<script>
function MyAddController($scope, $http) {
$scope.add = function() {
$http.get("webapi/blog/create", {
params : {
signum : $scope.num,
leaveType : $scope.leaveType,
startDate : $scope.startDate,
endDate : $scope.endDate,
isHalfDay : $scope.isHalfDay
}
}).success(function(data, status, headers, config) {
if (data) {
$scope.data = data;
alert("success")
}
}).error(function(data, status, headers, config) {
alert("error");
})
}
}
</script>
and the bean class
package com.king.entity;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.Id;
#Entity
public class LeaveDetails {
#Id
private String num;
public String getnum() {
return num;
}
public void setnum(String num) {
this.num = num;
}
public String getLeaveType() {
return leaveType;
}
public void setLeaveType(String leaveType) {
this.leaveType = leaveType;
}
public Date getStartdate() {
return startdate;
}
public void setStartdate(Date startdate) {
this.startdate = startdate;
}
public Date getEndDate() {
return endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
public String getIsHalfDay() {
return isHalfDay;
}
public void setIsHalfDay(String isHalfDay) {
this.isHalfDay = isHalfDay;
}
private String leaveType;
private Date startdate;
private Date endDate;
private String isHalfDay;
}
DAO
package com.king.dao;
import java.util.Date;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.king.entity.Blog;
import com.king.entity.LeaveDetails;
import com.king.test.HibernateTest;
public class AddLeaveDao {
public void addDetails(LeaveDetails data) {
Session session = HibernateTest.getSession();
Transaction ts = session.beginTransaction();
session.saveOrUpdate(data);
session.flush();
ts.commit();
session.close();
}
and the WS
package com.king.webapi;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import javax.ws.rs.BeanParam;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import com.king.dao.AddLeaveDao;
import com.king.dao.BlogDao;
import com.king.dao.LeaveDao;
import com.king.entity.Blog;
import com.king.entity.LeaveBalance;
//import com.king.entity.Love;
import com.king.entity.LeaveDetails;
#Path("/blog")
public class BlogWS {
#GET
#Path("list")
#Produces({ "application/json" })
public List<LeaveBalance> list() {
List l= new LeaveDao().getAllLeaves();
Iterator i=l.iterator();
while(i.hasNext())
{
LeaveBalance m=(LeaveBalance)i.next();
System.out.println(m.getLeaveBalance());
}
return l;
}
#GET
#Path("create")
#Produces({ "application/json" })
public String create(#BeanParam LeaveDetails ld) {
System.out.println("Entered here");
new AddLeaveDao().addDetails(ld);
System.out.println("Returned here");
return "{}";
}
#GET
#Path("findById")
#Produces({ "application/json" })
public Blog findById(#QueryParam("id") String id) {
return new BlogDao().findBlogById(id);
}
#GET
#Path("update")
#Produces({ "application/json" })
public String update(#BeanParam Blog blog) {
new BlogDao().updateBlog(blog);
return "{}";
}
}
edit:actual js i am using
var app = angular.module('myApp', ['ui.calendar','ui.router']);
app.controller('myNgController', ['$scope', '$http', 'uiCalendarConfig', function ($scope, $http, uiCalendarConfig) {
$scope.SelectedEvent = null;
var isFirstTime = true;
$scope.events = [];
$scope.eventSources = [$scope.events];
$scope.events.push({
title: "Leave",
description: "jahsojoaisjjoijaso",
start: new Date("2017-05-03"),
end: new Date("2017-05-03"),
allDay : false,
stick: false
});
/*//Load events from server
$http.get('/home/getevents', {
cache: true,
params: {}
}).then(function (data) {
$scope.events.slice(0, $scope.events.length);
angular.forEach(data.data, function (value) {
});
});*/
//configure calendar
$scope.uiConfig = {
calendar: {
height: 450,
editable: false,
displayEventTime: false,
header: {
left: 'month basicWeek basicDay agendaWeek agendaDay',
center: 'title',
right:'today prev,next'
},
eventClick: function (event) {
$scope.SelectedEvent = event;
},
eventAfterAllRender: function () {
if ($scope.events.length > 0 && isFirstTime) {
//Focus first event
uiCalendarConfig.calendars.myCalendar.fullCalendar('gotoDate', $scope.events[0].start);
isFirstTime = false;
}
}
}
};
}]);
app.controller("MyDbController",function ($scope, $http) {
//$scope.data = [{title: 'welcome hello'},{title: 'great testing'}];
$http.get("webapi/blog/list", {}).success(function(data, status, headers, config) {
$scope.data = data;
}).error(function(data, status, headers, config) {
alert("error");
})
});
app.controller("MyAddController",function ($scope, $http) {
$scope.add = function() {
$http.get("webapi/blog/create", {
params : {
signum : $scope.num,
leaveType : $scope.leaveType,
startDate : $scope.startDate,
endDate : $scope.endDate,
isHalfDay : $scope.isHalfDay
}
}).success(function(data, status, headers, config) {
if (data) {
$scope.data = data;
alert("success");
}
}).error(function(data, status, headers, config) {
alert("error");
})
}
});
app.config(function($stateProvider){
$stateProvider
.state("applyLeave",{
url:"/applyLeave",
templateUrl:"html/LeaveApply.html",
controller:"leaveController",
controllerAs:"leaveController"
});
v.controller("leaveController",function($scope)
{
})
});
When i click on save this is the url pattern shown in the browser. http://localhost:8081/hibernate-jersey-angularjs/?halfDay=No#/applyLeave .I dont understand why .On running http://localhost:8081/hibernate-jersey-angularjs/webapi/blog/create with dummy parameters everything works fine.But on submit i dont think the webservice is not being called.
Please help
Try putting ng-submit="add()" on your <form> element and remove the ng-click from your submit button.
As things stand I don't think that Angular is intercepting the form post and you're just posting form values to the current URL...

ng-click refreshes the page instead of submit

Hi i have an angular web form which takes input from the user and inserts into the database.I am using jersey-jackson rest web services and hibernate.But when i try to submit the form,the previous page which had the hyperlink to the current page is refreshed and the current page is reloaded again(Loading of previous page is seen in the network log).The url specified in the http request is not even invoked.Following is my code
<div id="main">
<h1>Create Leave</h1>
<form class="form-horizontal" ng-controller="MyAddController" >
<div class="form-group">
<label for="employeeName" class="col-sm-3 control-label">Employee Name</label>
<div class="col-sm-6">
<input type="text" id="num" class="form-control" ng-model="num" />
</div>
<div class="col-sm-3"></div>
</div>
<div class="form-group">
<label for="leaveType" class="col-sm-3 control-label">Leave Type</label>
<div class="col-sm-2">
<select id="leaveType" class="form-control" ng-model="leaveType">
<option value="">Hospital</option>
<option value="female">leave type 2</option>
<option value="female">leave type 3</option>
<option value="female">leave type 4</option>
<option value="female">leave type 5</option>
<option value="female">leave type 6</option>
</select>
</div>
<div class="col-sm-7"></div>
</div>
<div class="form-group">
<label for="leaveStartDate" class="col-sm-3 control-label">Leave Start Date</label>
<div class="col-sm-2">
<input type="date" id="startDates" class="form-control" ng-model="startDate" />
</div>
<div class="col-sm-7"></div>
</div>
<div class="form-group">
<label for="leaveEndDate" class="col-sm-3 control-label">Leave End Date</label>
<div class="col-sm-2">
<input type="date" id="endDate" class="form-control" ng-model="endDate" />
</div>
<div class="col-sm-7"></div>
</div>
<div class="form-group">
<div class="col-sm-3"></div>
<div class="col-sm-2">
<span><b>Is Half Day leave</b></span>
<div class="radio">
<label><input value="Yes" type="radio" name="halfDay" ng-model="isHalfDay" />Yes</label>
</div>
<div class="radio">
<label><input value="No" type="radio" name="halfDay" ng-model="isHalfDay" />No</label>
</div>
</div>
</div>
<input type="submit" value="Save" ng-click='add();' class="btn btn-primary col-sm-offset-3" />
<input type="reset" value="Reset" ng-click="resetForm()" class="btn" /> <br/>
</form>
<script>
function MyAddController($scope, $http) {
$scope.add = function() {
$http.get("webapi/blog/create", {
params : {
signum : $scope.num,
leaveType : $scope.leaveType,
startDate : $scope.startDate,
endDate : $scope.endDate,
isHalfDay : $scope.isHalfDay
}
}).success(function(data, status, headers, config) {
if (data) {
$scope.data = data;
alert("success")
}
}).error(function(data, status, headers, config) {
alert("error");
})
}
}
</script>
and the bean class
package com.king.entity;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.Id;
#Entity
public class LeaveDetails {
#Id
private String num;
public String getnum() {
return num;
}
public void setnum(String num) {
this.num = num;
}
public String getLeaveType() {
return leaveType;
}
public void setLeaveType(String leaveType) {
this.leaveType = leaveType;
}
public Date getStartdate() {
return startdate;
}
public void setStartdate(Date startdate) {
this.startdate = startdate;
}
public Date getEndDate() {
return endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
public String getIsHalfDay() {
return isHalfDay;
}
public void setIsHalfDay(String isHalfDay) {
this.isHalfDay = isHalfDay;
}
private String leaveType;
private Date startdate;
private Date endDate;
private String isHalfDay;
}
DAO
package com.king.dao;
import java.util.Date;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.king.entity.Blog;
import com.king.entity.LeaveDetails;
import com.king.test.HibernateTest;
public class AddLeaveDao {
public void addDetails(LeaveDetails data) {
Session session = HibernateTest.getSession();
Transaction ts = session.beginTransaction();
session.saveOrUpdate(data);
session.flush();
ts.commit();
session.close();
}
and the WS
package com.king.webapi;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import javax.ws.rs.BeanParam;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import com.king.dao.AddLeaveDao;
import com.king.dao.BlogDao;
import com.king.dao.LeaveDao;
import com.king.entity.Blog;
import com.king.entity.LeaveBalance;
//import com.king.entity.Love;
import com.king.entity.LeaveDetails;
#Path("/blog")
public class BlogWS {
#GET
#Path("list")
#Produces({ "application/json" })
public List<LeaveBalance> list() {
List l= new LeaveDao().getAllLeaves();
Iterator i=l.iterator();
while(i.hasNext())
{
LeaveBalance m=(LeaveBalance)i.next();
System.out.println(m.getLeaveBalance());
}
return l;
}
#GET
#Path("create")
#Produces({ "application/json" })
public String create(#BeanParam LeaveDetails ld) {
System.out.println("Entered here");
new AddLeaveDao().addDetails(ld);
System.out.println("Returned here");
return "{}";
}
#GET
#Path("findById")
#Produces({ "application/json" })
public Blog findById(#QueryParam("id") String id) {
return new BlogDao().findBlogById(id);
}
#GET
#Path("update")
#Produces({ "application/json" })
public String update(#BeanParam Blog blog) {
new BlogDao().updateBlog(blog);
return "{}";
}
}
edit:actual js i am using
var app = angular.module('myApp', ['ui.calendar','ui.router']);
app.controller('myNgController', ['$scope', '$http', 'uiCalendarConfig', function ($scope, $http, uiCalendarConfig) {
$scope.SelectedEvent = null;
var isFirstTime = true;
$scope.events = [];
$scope.eventSources = [$scope.events];
$scope.events.push({
title: "Leave",
description: "jahsojoaisjjoijaso",
start: new Date("2017-05-03"),
end: new Date("2017-05-03"),
allDay : false,
stick: false
});
/*//Load events from server
$http.get('/home/getevents', {
cache: true,
params: {}
}).then(function (data) {
$scope.events.slice(0, $scope.events.length);
angular.forEach(data.data, function (value) {
});
});*/
//configure calendar
$scope.uiConfig = {
calendar: {
height: 450,
editable: false,
displayEventTime: false,
header: {
left: 'month basicWeek basicDay agendaWeek agendaDay',
center: 'title',
right:'today prev,next'
},
eventClick: function (event) {
$scope.SelectedEvent = event;
},
eventAfterAllRender: function () {
if ($scope.events.length > 0 && isFirstTime) {
//Focus first event
uiCalendarConfig.calendars.myCalendar.fullCalendar('gotoDate', $scope.events[0].start);
isFirstTime = false;
}
}
}
};
}]);
app.controller("MyDbController",function ($scope, $http) {
//$scope.data = [{title: 'welcome hello'},{title: 'great testing'}];
$http.get("webapi/blog/list", {}).success(function(data, status, headers, config) {
$scope.data = data;
}).error(function(data, status, headers, config) {
alert("error");
})
});
app.controller("MyAddController",function ($scope, $http) {
$scope.add = function() {
$http.get("webapi/blog/create", {
params : {
signum : $scope.num,
leaveType : $scope.leaveType,
startDate : $scope.startDate,
endDate : $scope.endDate,
isHalfDay : $scope.isHalfDay
}
}).success(function(data, status, headers, config) {
if (data) {
$scope.data = data;
alert("success");
}
}).error(function(data, status, headers, config) {
alert("error");
})
}
});
app.config(function($stateProvider){
$stateProvider
.state("applyLeave",{
url:"/applyLeave",
templateUrl:"html/LeaveApply.html",
controller:"leaveController",
controllerAs:"leaveController"
});
v.controller("leaveController",function($scope)
{
})
});
When i click on save this is the url pattern shown in the browser. http://localhost:8081/hibernate-jersey-angularjs/?halfDay=No#/applyLeave .I dont understand why
Please help
Easiest way to fix this is to remove type="submit" from your button that calls the add() method, replacing it with type="button"
<input type="button" value="Save" ng-click='add()' class="btn btn-primary col-sm-offset-3" />
Otherwise, you need to add ng-submit="add()" on your form, and then remove the ng-click="add()" from your button with type=submit.
Your form should look like this:
<form class="form-horizontal" ng-controller="MyAddController" ng-submit="add()">
And your button like this:
<input type="submit" value="Save" class="btn btn-primary col-sm-offset-3" />
Either of these should work.
By the way, you don't need to use ; at the end of an ng-click instruction. Also, try using the button tag instead of input for the save button.
EDIT: You forgot to declare the app to use in your html. On the body of your HTML code, use ng-app='myApp'

the server responded with a status of 500 (Internal Server Error)(asp.net mvc and angular js)

I am Getting null value in action method when i am pass data from angular js to action method. i debug and see it hit to the AddCutomer method but data is null(the server responded with a status of 500 (Internal Server Error). can anyone help me to fix this issue
Admin.js
var app = angular.module("adminmdl", [])
app.controller("admincontroller", function ($scope, AdminService) {
$scope.Action = 'Add';
GetAllCustomer();
function GetAllCustomer() {
var getcust = AdminService.getCustomer();
getcust.then(function (cust) {
$scope.customers = cust.data;
}, function () {
alert('Error');
});
}
$scope.data = {
cus_code: '',
cus_name: ''
}
$scope.savecu = function () {
AdminService.saveCustomerDdetails($scope.cusmodel).then(function (d) {
$scope.msg = "Insert Successfully";
});
}
})
.service('AdminService', function ($http) {
this.getCustomer = function () {
return $http.get('GetCustomer');
}
this.saveCustomerDdetails = function (customer) {
return $http.post('/AddCutomer', customer);
}
})
ASP.NET MVC
[HttpPost]
public JsonResult AddCutomer(Customer customer) {
te.Customers.Add(customer);
te.SaveChanges();
string message = "Success";
return new JsonResult { Data = message, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
html code
<form class="form-horizontal" method="post" ng-submit="savecu()" name="basic_validate" id="basic_validate" novalidate="novalidate">
<div class="control-group">
<label class="control-label">Customer Code</label>
<div class="controls">
<input type="text" ng-model="cusmodel.Customercode" name="required" id="required" >
</div>
</div>
<div class="control-group">
<label class="control-label">Customer Name</label>
<div class="controls">
<input type="text" ng-model="cusmodel.Customername" name="name" id="name" >
</div>
</div>
<div class="control-group">
<div class="controls">
<input type="submit" value="Save" ng-click="savecu()" class="btn btn-success">
<input type="submit" value="Clear" class="btn btn-success" />
</div>
</div>
<div class="control-group">
<div class="controls">
<p style="color:green">{{msg}}</p>
</div>
</div>
#*<div class="form-actions">
</div>*#
</form>
Ok, so this is your autogenerated class
public partial class Customer
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.??Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Customer()
{
this.projects = new HashSet<project>();
}
public string cus_code { get; set; }
public string cus_name { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.??Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<project> projects { get; set; }
}
The first issue I see is that your client object that you post to the server doesn't match the class definition.
Change the ng-models to cusmodel.cus_code and cusmodel.cus_name
<div class="control-group">
<label class="control-label">Customer Code</label>
<div class="controls">
<input type="text" ng-model="cusmodel.cus_code" name="required" id="required" >
</div>
</div>
<div class="control-group">
<label class="control-label">Customer Name</label>
<div class="controls">
<input type="text" ng-model="cusmodel.cus_name" name="name" id="name" >
</div>
</div>
The names in the scope model need to match the class specification else the json deserializer don't know what to do here.
Try to make a new post when these changes are added and see if the values of the cus_code and cus_name is populated.
If this doesn't work I would use a data transfer object to handle the communication with the client instead. Populating autogenerated classes from EF(or what orm you use) from the client can be a mess.
Add this class:
public class CustomerDTO
{
public string cus_code { get; set; }
public string cus_name { get; set; }
}
And use it in the controller method
[HttpPost]
public JsonResult AddCutomer(CustomerDTO customer) {
var cust = new Customer{ cus_code = customer.cus_code, cus_name = customer.cus_name };
te.Customers.Add(cust);
te.SaveChanges();
string message = "Success";
return new JsonResult { Data = message, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}

Angular JS form validation using ModelState in Web API Core

I am working on a Web Application with client side in AngularJS, TypeScript and HTML, and the server side is a .NET Core Web API.
I want to implement server side validation using ModelState and DTOs. The thing is that I don't want to display all the validation errors at the top of the Form, but I want to display them in-line with the textbox
So first I added the validations to a DTO and then checking in the controller for ModelState.IsValid
public class TestDTO
{
[Required(ErrorMessage = "This field is required")]
public string TestName { get; set; }
}
public class ManyTestDTO
{
[Required(ErrorMessage = "Many Item is required")]
public string ManyItem { get; set; }
}
public class RestaurantDTO
{
public int RestaurantId { get; set; }
[Required(ErrorMessage = "This field is required")]
public string Name { get; set; }
[Required(ErrorMessage = "This field is required"), MaxLength(20), MinLength(1)]
public string Description { get; set; }
[Required(ErrorMessage = "This field is required")]
public string Address { get; set; }
public TestDTO TestModel { get; set; }
public List<ManyTestDTO> TestMany { get; set; }
public RestaurantDTO()
{
}
}
Getting the idea from this link: Link - I have created a directive in my Application to display the validation message in-line, it is working fine the problem is that the HTML I am writing to show the validation message is complex.
The Directive
export class ServerValidationDirective implements ng.IDirective {
constructor() { }
restrict: "A";
require: "ngModel";
link = function (scope, element, attrs, ctrl) {
scope.$watch("controller.modelState", () => {
let modelState = scope.controller.modelState;
console.log(modelState);
if (modelState == null) return;
let state = modelState[attrs.ngServerValidate];
if (state) {
// Server Errors exist for the ngServerValidate
scope.controller.parsedModelState[attrs.ngServerValidate] = state;
} else {
// No Error for the ngServerValidate
if (scope.controller.parsedModelState[attrs.ngServerValidate]) {
scope.controller.parsedModelState[attrs.ngServerValidate] = null;
}
}
});
};
static factory(): ng.IDirectiveFactory {
var directive = () => new ServerValidationDirective();
return directive;
}
}
The Controller:
class CreateRestaurantController {
static $inject = ["$scope"];
restaurantModel: any;
modelState: any;
parsedModelState: any;
testModelState:any;
constructor($scope) {
this.scope = $scope; // create a local copy of the $scope
this.scope.controller = this; //put controller reference in this.scope.controller
this.restaurantModel = {name: "Dawood",testModel: {},testMany: [{ ManyItem: "I have a Value" },{}]};
this.modelState = null;
this.parsedModelState = {};
this.testModelState = JSON
.parse('{"Address":["This field is required"],"Description":["This field is required"],"TestModel.TestName":["This field is required"],"TestMany[1].ManyItem":["Many Item is required"]}');
console.log(this.testModelState);
}
testValidation() {
this.modelState = this.testModelState;
//Normally modelStae will be return from server
// Submit to Server
//this.apiService.post("/api/RestaurantDashboard/GetTestValidation",
// null, this.restaurantModel,
// response => {
// console.log(response);
// },
// response => {
// this.modelState = response.data;
// });
}
}
The HTML for the Form
<div ng-app="validationApp">
<div ng-controller="validationController">
<form name="restaurantForm" class="form">
<div class="form-group" ng-class="{'has-error': controller.parsedModelState.Name != null}">
<label>Restaurant Name</label>
<input type="text" class="form-control" ng-server-validate="Name" ng-model="controller.restaurantModel.name">
<span class="help-block" ng-repeat="errorMessage in controller.parsedModelState.Name"> {{errorMessage}} </span>
</div>
<div class="form-group" ng-class="{'has-error': controller.parsedModelState.Address != null}">
<label>Address</label>
<input type="text" class="form-control" ng-server-validate="Address" ng-model="controller.restaurantModel.address">
<span class="help-block" ng-repeat="errorMessage in controller.parsedModelState.Address"> {{errorMessage}} </span>
</div>
<h3>Nested Object</h3>
<div class="form-group" ng-class="{'has-error': controller.parsedModelState['TestModel.TestName'] != null}">
<label>TestModel.TestName</label>
<input type="text" class="form-control" ng-server-validate="TestModel.TestName" ng-model="controller.restaurantModel.testModel.testName">
<span class="help-block" ng-repeat="errorMessage in controller.parsedModelState['TestModel.TestName']"> {{errorMessage}} </span>
</div>
<h3>Many Array/List</h3>
<ul class="list-unstyled">
<li ng-repeat="item in controller.restaurantModel.testMany">
<div class="form-group" ng-class="{'has-error': controller.parsedModelState['TestMany[' + $index + '].ManyItem'] != null}">
<label>Many Item {{$index}}</label>
<input type="text" class="form-control" ng-server-validate="{{'TestMany[' + $index + '].ManyItem'}}" ng-model="item.ManyItem">
<span class="help-block" ng-repeat="errorMessage in controller.parsedModelState['TestMany[' + $index + '].ManyItem']"> {{errorMessage}} </span>
</div>
</li>
</ul>
<button class="btn btn-primary" ng-click="controller.testValidation()">Click Me to Check</button>
</form>
</div>
</div>
As you can see the HTML structure for the Many Array/List and Nested Object is a bit complex. Is there a better way to do this?
Fiddle: https://jsfiddle.net/mdawood1991/ua9mk7qz/

Angularjs sending null object to asp mvc action on $http get

I'm trying to use Angularjs to send an object to an asp mvc controller on submit, but the value is going as null.
What I'm missing here?
My controller:
public class RelatorioIndiceController : Controller
{
public ActionResult Index()
{
return View();
}
public JsonResult GerarRelatorio(RelatorioFiltroPesquisa filtro)
{
throw new NotImplementedException();
}
}
My parameter class:
public enum TipoRelatorio
{
IndiceCapacidade,
ImpactoMedio,
TempoMedio
}
public class RelatorioFiltroPesquisa
{
public TipoRelatorio TipoRelatorio { get; set; }
public string NomeRelatorio { get; set; }
public string Data { get; set; }
}
And my view:
<div ng-app="mainApp" id="body">
<div ng-controller="myCtrl" id="form">
<div class="radio">
<label>
<input type="radio" ng-model="Filtro.TipoRelatorio" value="0" name="TiposRelatorio" />
Índice Capacidade
</label>
</div>
<div class="radio">
<label>
<input type="radio" ng-model="Filtro.TipoRelatorio" value="1" name="TiposRelatorio" />
Impacto Médio
</label>
</div>
<div class="radio">
<label>
<input type="radio" ng-model="Filtro.TipoRelatorio" value="2" name="TiposRelatorio" />
Tempo Médio
</label>
</div>
<div class="input-group">
<label>Nome Relatório</label>
<input type="text" ng-model="Filtro.NomeRelatorio" class="form-control" />
</div>
<div class="input-group">
<label>Data</label>
<input type="text" ng-model="Filtro.Data" class="form-control" placeholder="__/__/____" />
</div>
<input type="submit" ng-click="Submit()" value="Gerar Relatório" />
</div>
</div>
#section scripts
{
<script src="~/Scripts/angular.min.js"></script>
<script>
angular.module('mainApp', [])
.controller('myCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.Submit = function () {
$http({
method: "GET",
url: "/RelatorioIndice/GerarRelatorio/",
params: { filtro: $scope.Filtro }
})
.success(function (data) {
console.log("Sucesso");
});
}
}]);
</script>
}
I've checked if the object has the same properties names and they are ok, I made of copy and paste them. I've already checked another similar questions here on SO, but they didn't help me on this issue.
It happened the problem was with this code:
$http({
method: "GET",
url: "/RelatorioIndice/GerarRelatorio/",
params: { filtro: $scope.Filtro }
})
.success(function (data) {
console.log("Sucesso");
});
Changing it to this version solved the problem:
$scope.submit = function() {
$http.get("/RelatorioIndice/GerarRelatorio/", $scope.Filtro)
.success("Sucesso");
};
In the controller you need to allow get requests:
public JsonResult GerarRelatorio(FiltroRelatorioPesquisa filtro)
{
...
return Json(result, JsonRequestBehavior.AllowGet);
}
The old code is a working solution, but only with earlier versions of Angular (I'm not sure which we use at my work. There I'm used to that sintax). As for 1.5.8 the new code was what worked.

Resources