Adding Angular validation to #Html.EditorFor - angularjs

Is it possible to add angular validation for #Html.EditorFor. Please see code below.
--> This is how I get the partial view from the controller
$scope.editClient = function () {
var id = 1;
$http.get('/Clients/GetClientByClientId?id=' +id)
.then(function (response) {
debugger;
var divTemplate = response.data;
var element = angular.element(document.getElementById('id_chosen_view'));
element.empty();
element.append(divTemplate);
$compile(element)($scope);
})
}
<div class="form-group">
<label for="editCompany">Company</label>
#Html.EditorFor(model => model.Company, new { htmlAttributes = new { #class = "form-control", required="required", id="editCompany" } })
<span style="color: red;" ng-show="formEditClient.Company.$touched && formEditClient.Company.$invalid">Company name is required.</span>
</div>
but this works
<label for="inputContactPerson">Contact Person</label>
<input id="inputContactPerson" type="text"
class="form-control" ng-model="editClient.ContactPerson" name="ContactPerson" required/>
<span style="color: red;" ng-show="formEditClient.ContactPerson.$touched && formEditClient.ContactPerson.$invalid">Contact Person is required.</span>
I would like to use the first code but it doesn't work.

Related

Send/Add CVV/CVN Field on Cybersource Flex Microform

I am using Flex Microform and was able to successfully render the Credit Card Iframe from Cybersource.
Now, the question is to Add/Send CVN/CVV details along with above request.
In the document, we can pass only three parameters in the createToken Method - CardType, CardExpirationYear, and CardExpirationMonth.
I couldn't find anything about sending/Adding CVN.
Please guide if anyone has done similar implementation where we can send CVN details from the Flex Form.
Html
---
<label id="cardNumber-label">Card Number</label>
<div id="number-container" class="form-control"></div>
<label for="securityCode-container">Security Code</label>
<div id="securityCode-container" class="form-control"></div>
--
</div>
<div class="form-row">
----
</form>
Js
var flex = new Flex(captureContext);
var microform = flex.microform({ styles: myStyles });
var number = microform.createField('number', { placeholder: 'Enter card number' });
var securityCode = microform.createField('securityCode', { placeholder: '•••' });
number.load('#number-container');
securityCode.load('#securityCode-container');
Ref: developer-guides
I think this is what you're looking for
https://developer.cybersource.com/docs/cybs/en-us/digital-accept-flex/developer/all/rest/digital-accept-flex/microform-integ/api_reference/class_Microform.html
Example:
<div class="container card">
<div class="card-body">
<h1>Checkout</h1>
<div id="errors-output" role="alert"></div>
<div class="form-group">
<label for="cardholderName">Name</label>
<input id="cardholderName" class="form-control" name="cardholderName" placeholder="Name on the card">
<label id="cardNumber-label">Card Number</label>
<div id="number-container" class="form-control"></div>
<label for="securityCode-container">Security Code</label>
<div id="securityCode-container" class="form-control"></div>
</div>
<div class="form-row">
<div class="form-group col-md-6">
<label for="expMonth">Expiry month</label>
<select id="expMonth" class="form-control">
<option>01</option>
<option>02</option>
<option>03</option>
<option>04</option>
<option>05</option>
<option>06</option>
<option>07</option>
<option>08</option>
<option>09</option>
<option>10</option>
<option>11</option>
<option>12</option>
</select>
</div>
<div class="form-group col-md-6">
<label for="expYear">Expiry year</label>
<select id="expYear" class="form-control">
<option>2022</option>
<option>2023</option>
</select>
</div>
</div>
</div>
</div>
<script src="https://flex.cybersource.com/cybersource/assets/microform/0.11/flex-microform.min.js"></script>
<script>
$(document).ready(function() {
$('#submission-form').submit(function(e) {
e.preventDefault();
});
var form = document.querySelector('#submission-form');
var payButton = document.querySelector('#btnPay');
var flexResponse = document.querySelector('#SecureToken');
var expMonth = document.querySelector('#expMonth');
var expYear = document.querySelector('#expYear');
var errorsOutput = document.querySelector('#errors-output');
// the capture context that was requested server-side for this transaction
var captureContext = /*caputre context loaded here*/ ;
// setup
var flex = new Flex(captureContext);
var number = microform.createField('number', {
placeholder: 'Enter card number'
});
var securityCode = microform.createField('securityCode', {
placeholder: '•••'
});
number.load('#number-container');
securityCode.load('#securityCode-container');
payButton.addEventListener('click', function() {
var options = {
expirationMonth: expMonth.value,
expirationYear: expYear.value
};
microform.createToken(options, function(err, token) {
if (err) {
// handle error
} else {
flexResponse.value = JSON.stringify(token);
form.submit();
}
});
});
});
</script>

Cannot pass data to the as.net mvc controller from $http in angularJS

I am Getting null value in action method when i am pass data from angular js to action method. data is coming up to $scope.custmodel and i debug and see it hit to the AddCutomer method but data is null. can anyone help me to fix this issue
Admin.js code
var app = angular.module("adminmdl", [])
app.controller("admincontroller", function ($scope,AdminService) {
$scope.Action = 'Add';
$scope.data = {
cus_code: '',
cus_name: ''
}
$scope.savecu = function () {
AdminService.saveCustomerDdetails($scope.cusmodel).then(function (data) {
if (data != null) {
alert('Insert successfully');
} else {
alert('error in inerting data');
}
});
}
})
.factory("AdminService", function ($http) {
var fact = {};
fact.saveCustomerDdetails = function (d) {
return $http({
url: '/Admin/AddCutomer',
method: 'POST',
data: JSON.stringify(d),
headers: { 'content-type': 'application/json' }
});
};
return fact;
});
ASP MVC Method
[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" action="#" 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>
add [FromBody] attribute to the controller as shown below
public JsonResult AddCutomer([FromBody] Customer customer)

How can I do event on text box in Angular?

I have a text box that show when I click on checkbox and I need to make an event on it that can make me bind it to object from DB
HTML:
<div ng-repeat="feture in featureEnumArray">
<input id="txtchkFet" type="checkbox" ng-model="feture.IsChecked" />
{{feture.DisplayText}}
<div ng-show="feture.IsChecked" >
<input class="form-control" type="text" ng-model="feture.Value" ng-change="getFeatureID(feture)" id="txtValue" placeholder="Type Feature Value" />
</div>
<div class="label label-danger" ng-show="feture.IsChecked && !feture.Value">
Type Value
</div>
</div>
And in Angular controller I did Like this :
$scope.getFeatureID = function (feture) {
if (feture.IsChecked) {
$scope.Planfeature = angular.copy(feture);
$scope.PlanFeatureTemp.FeatureID = $scope.Planfeature.ID;
$scope.PlanFeatureTemp.Value = $scope.Planfeature.Value;
$scope.Planfeature = [];
}
else {
var index = $scope.JAdminPlan.PlanFeatureValues.indexOf(feture);
$scope.JAdminPlan.PlanFeatureValues.splice(index, 1);
}
if (!$scope.$$phase) $scope.$apply();
};

Passing hidden value in angular

View:
<ul ng-repeat="x in posts.post">
{{x.name}} {{x._id}} {{x.post}} {{x.user_id}}
<br>
<ul ng-repeat="y in x.comment">
{{y.comment}}
</ul>
<input type="text" style="display: none;" ng-model='new_comment.userId' value={{users2.id}} name="userId" >
<input type="text" style="display: none;" ng-model='new_comment.name' value={{users2.name}} name="userName" >
<textarea ng-model='new_comment.comment' name="comment" rows="4" cols="50">
</textarea>
<br>
<input type="submit" value="Post Comment!" ng-click="addComment(x._id, new_comment)">
</ul>
Controller:
UserFactory.getUser(function (data) {
$scope.users2 = data;
});
Factory:
factory.getUser = function(callback) {
$http.get("/user").success(function(output) {
users2 = output;
callback(users2);
});
};
I am trying to pass the hidden values of users2.id and users2.name from the controller/factory into a form. I tried ng-init, ng-value as well as input type="hidden", but none works.
So this is what I did to get it working:
View:
<form>
<textarea ng-model='new_comment.comment' name="comment" rows="4" cols="50">
</textarea>
<br>
<input type="submit" value="Post Comment!" ng-click="addComment(x._id, new_comment, users2.name, users2._id)">
</form>
Controller:
$scope.addComment = function(id, comment, userName, userId) {
var commentValue = comment.comment;
var newComment = {comment: commentValue, name: userName, userId: userId};
postFactory.addComment(id, newComment, function () {
postFactory.getComment(function (data) {
$scope.comments = data;
});
$scope.new_comment = {};
});
};
Try this
<input type="hidden" ng-model='new_comment.userId' value="{{users2.id}}" name="userId" >
And while you are changing things
UserFactory.getUser
.then(function (data) {
$scope.users2 = data;
});
with
factory.getUser = function() {
return $http.get("/user");
};
as $http returns a promise
Two way binding wouldn't work with hidden element, so I'd use ng-value to set the value of type="hidden" element
<input type="hidden" ng-value='new_comment.userId' name="userId"/>
<input type="hidden" ng-value='new_comment.name' name="userName"/>
Do something like this, return the promise.
factory.getUser = function(callback) {
return $http.get("/user")
};
Controller:
UserFactory.getUser().success(function(output) {
$scope.users2 = output.data;
});

Cleaning up validation logic

I've just got validation working the way I want with the following code:
<div class="control-group" ng-class="{ error : (submitted || accountForm.name.$dirty) && accountForm.name.$invalid }">
<label for="name" class="control-label">Company Name:</label>
<input type="text" name="name" ng-model="account.name" ng-maxlength="50" required />
<span class="help-inline" ng-show="(submitted || accountForm.name.$dirty) && accountForm.name.$error.maxlength">Name too long</span>
<span class="help-inline" ng-show="(submitted || accountForm.name.$dirty) && accountForm.name.$error.required">Required</span>
</div>
But there seems to be a lot of similar code with only slight differences. What would be the best method of simplifying this to make it a) clearer, b) more maintainable?
Update 23/07 Doesn't seem like there's an immediate best practice.
You could make an error variable in the $scope of the controller that controls that template. Something like this:
html
<div ng-controller="FormCtrl" class="control-group" ng-class="{ error : (submitted || accountForm.name.$dirty) && accountForm.name.$invalid }">
<label for="name" class="control-label">Company Name:</label>
<input type="text" name="name" ng-model="account.name" ng-maxlength="50" required />
<input type="button" ng-click="submitForm()" />
<span class="help-inline">{{ error }}</span>
</div>
controller
window.FormCtrl = function ($scope) {
$scope.error = "";
$scope.submitForm = function() {
if ($scope.accountForm.name.length > 50) {
$scope.error = "Name too long";
}
else if ($scope.accountForm.name == null || $scope.accountForm.name == undefined) {
$scope.error = "Name required";
}
else {
$scope.error = "";
//submit logic
}
}
}
Since you want to reuse the same code for other form fields, and the validation logic seems to be similar for each of them, i could not find anything with ngForm that would help reuse the code. Rather I would suggest a different approach, where you don't use ngForm and do the validation in js yourself. This way you can reuse the method everywhere.
Here is the link for the jsFiddle:
http://jsfiddle.net/rCDg8/1/
<div ng-app>
<div ng-controller="DemoCtrl">
<form name="accountForm" ng-submit="submit()">
<div class="control-group" ng-class="class">
<label for="name" class="control-label">Company Name:</label>
<input type="text" name="name" ng-model="account.name" ng-change="validateEntry(account.name)" required></input>
<span class="help-inline" ng-show="accountForm.$dirty||accountForm.$invalid">{{msg}}</span>
</div>
</form>
</div>
</div>
Controller:
function DemoCtrl($scope) {
var longName = 'Name too long';
var nameRequired = 'Name is required!';
$scope.class = '';
$scope.showMsg = false;
$scope.validateEntry = function (validateItem) {
if (angular.isDefined(validateItem)) {
if (validateItem.length > 50) {
showErrorMsg(longName);
} else if (validateItem.length === 0) {
showErrorMsg(nameRequired);
} else {
$scope.class = '';
$scope.showMsg = false;
$scope.accountForm.$dirty = false;
$scope.accountForm.$pristine = true;
}
} else {
showErrorMsg(nameRequired);
}
};
$scope.submit = function(){
alert('IS Form Dirty: '+$scope.accountForm.$dirty);
};
function showErrorMsg(msg) {
$scope.class = 'error';
$scope.showMsg = true;
$scope.msg = msg;
$scope.accountForm.$dirty = true;
}
};

Resources