Am trying to validate an Email id field in angularJs using ng-pattern directive.
But am new to AngularJs. I need to show an error message as soon as the user enters the wrong email id.
The code which I have below is am trying to solve. Help me out with using ng-pattern for getting the proper result.
<script type="text/javascript" src="/Login/script/ang.js"></script>
<script type="text/javascript">
function Ctrl($scope) {
$scope.text = 'enter email';
$scope.word = /^[a-z]+[a-z0-9._]+#[a-z]+\.[a-z.]{2,5}$/;
}
</script>
</head>
<body>
<form name="myform" ng-controller="Ctrl">
<input type="text" ng-pattern="word" name="email">
<span class="error" ng-show="myform.email.$error.pattern">
invalid email!
</span>
<input type="submit" value="submit">
</form>
</body>
If you want to validate email then use input with type="email" instead of type="text". AngularJS has email validation out of the box, so no need to use ng-pattern for this.
Here is the example from original documentation:
<script>
function Ctrl($scope) {
$scope.text = 'me#example.com';
}
</script>
<form name="myForm" ng-controller="Ctrl">
Email: <input type="email" name="input" ng-model="text" required>
<br/>
<span class="error" ng-show="myForm.input.$error.required">
Required!</span>
<span class="error" ng-show="myForm.input.$error.email">
Not valid email!</span>
<br>
<tt>text = {{text}}</tt><br/>
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
<tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
<tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
<tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
<tt>myForm.$error.email = {{!!myForm.$error.email}}</tt><br/>
</form>
For more details read this doc: https://docs.angularjs.org/api/ng/input/input%5Bemail%5D
Live example: http://plnkr.co/edit/T2X02OhKSLBHskdS2uIM?p=info
UPD:
If you are not satisfied with built-in email validator and you want to use your custom RegExp pattern validation then ng-pattern directive can be applied and according to the documentation the error message can be displayed like this:
The validator sets the pattern error key if the ngModel.$viewValue
does not match a RegExp
<script>
function Ctrl($scope) {
$scope.text = 'me#example.com';
$scope.emailFormat = /^[a-z]+[a-z0-9._]+#[a-z]+\.[a-z.]{2,5}$/;
}
</script>
<form name="myForm" ng-controller="Ctrl">
Email: <input type="email" name="input" ng-model="text" ng-pattern="emailFormat" required>
<br/><br/>
<span class="error" ng-show="myForm.input.$error.required">
Required!
</span><br/>
<span class="error" ng-show="myForm.input.$error.pattern">
Not valid email!
</span>
<br><br>
<tt>text = {{text}}</tt><br/>
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
<tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
<tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
<tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
<tt>myForm.$error.pattern = {{!!myForm.$error.pattern}}</tt><br/>
</form>
Plunker: https://plnkr.co/edit/e4imaxX6rTF6jfWbp7mQ?p=preview
There is nice example how to deal with this kind of problem modyfing built-in validators angulardocs. I have only added more strict validation pattern.
app.directive('validateEmail', function() {
var EMAIL_REGEXP = /^[_a-z0-9]+(\.[_a-z0-9]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/;
return {
require: 'ngModel',
restrict: '',
link: function(scope, elm, attrs, ctrl) {
// only apply the validator if ngModel is present and Angular has added the email validator
if (ctrl && ctrl.$validators.email) {
// this will overwrite the default Angular email validator
ctrl.$validators.email = function(modelValue) {
return ctrl.$isEmpty(modelValue) || EMAIL_REGEXP.test(modelValue);
};
}
}
};
});
And simply add
<input type='email' validate-email name='email' id='email' ng-model='email' required>
According to the answer of #scx ,I created a validation for GUI
app.directive('validateEmail', function() {
var EMAIL_REGEXP = /^[_a-z0-9]+(\.[_a-z0-9]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/;
return {
link: function(scope, elm) {
elm.on("keyup",function(){
var isMatchRegex = EMAIL_REGEXP.test(elm.val());
if( isMatchRegex&& elm.hasClass('warning') || elm.val() == ''){
elm.removeClass('warning');
}else if(isMatchRegex == false && !elm.hasClass('warning')){
elm.addClass('warning');
}
});
}
}
});
And simply add :
css
.warning{
border:1px solid red;
}
html
<input type='email' validate-email name='email' id='email' ng-model='email' required>
This is jQuery Email Validation using Regex Expression. you can also use the same concept for AngularJS if you have idea of AngularJS.
var expression = /^[\w\-\.\+]+\#[a-zA-Z0-9\.\-]+\.[a-zA-z0-9]{2,4}$/;
Source.
You can use ng-messages
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular-messages.min.js"></script>
include the module
angular.module("blank",['ngMessages']
in html
<input type="email" name="email" class="form-control" placeholder="email" ng-model="email" required>
<div ng-messages="myForm.email.$error">
<div ng-message="required">This field is required</div>
<div ng-message="email">Your email address is invalid</div>
</div>
Below is the fully qualified pattern for email validation.
<input type="text" pattern="/^[_a-z0-9]+(\.[_a-z0-9]+)*#[a-z0-9-]*\.([a-z]{2,4})$/" ng-model="emailid" name="emailid"/>
<div ng-message="pattern">Please enter valid email address</div>
Now, Angular 4 has email validator built-in
https://github.com/angular/angular/blob/master/CHANGELOG.md#features-6
https://github.com/angular/angular/pull/13709
Just add email to the tag. For example
<form #f="ngForm">
<input type="email" ngModel name="email" required email>
<button [disabled]="!f.valid">Submit</button>
<p>Form State: {{f.valid?'VALID':'INVALID'}}</p>
</form>
angularjs controller way, just an example to look for one or more email in the body of a message.
sp = $scope.messagebody; // email message body
if (sp != null && sp.match(/([\w-]+(?:\.[\w-]+)*)#((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)\S+/)) {
console.log('Error. You are not allowed to have an email in the message body');
}
I tried #Joanna's method and tested on the following websites and it didn't work.
https://regex101.com/
https://www.regextester.com/
https://regexr.com/
I then modified it to and it worked.
/([\w-]+(?:\.[\w-]+)*)#((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)\S+
I have tried wit the below regex it is working fine.
Email validation : \w+([-+.']\w+)#\w+([-.]\w+).\w+([-.]\w+)*
Spend some time to make it working for me.
Requirement:
single or comma separated list of e-mails with domains ending name.surname#gmail.com or team-email#list.gmail.com
Controller:
$scope.email = {
EMAIL_FORMAT: /^\w+([\.-]?\w+)*#(list.)?gmail.com+((\s*)+,(\s*)+\w+([\.-]?\w+)*#(list.)?gmail.com)*$/,
EMAIL_FORMAT_HELP: "format as 'your.name#gmail.com' or comma separated 'your.name#gmail.com, my.name#list.gmail.com'"
};
HTML:
<ng-form name="emailModal">
<div class="form-group row mb-3">
<label for="to" class="col-sm-2 text-right col-form-label">
<span class="form-required">*</span>
To
</label>
<div class="col-sm-9">
<input class="form-control" id="to"
name="To"
ng-required="true"
ng-pattern="email.EMAIL_FORMAT"
placeholder="{{email.EMAIL_FORMAT_HELP}}"
ng-model="mail.to"/>
<small class="text-muted" ng-show="emailModal.To.$error.pattern">wrong</small>
</div>
</div>
</ng-form>
I found good online regex testing tool.
Covered my regex with tests:
https://regex101.com/r/Dg2iAZ/6/tests
Use below regular expression
^[_\.0-9a-z-]+#([0-9a-z][0-9a-z-]+)+((\.)[a-z]{2,})+$
It allows
test#test.com
test#test.co.in
test#test.gov.us
test#test.net
test#test.software
Related
I need to include jinja templating in element.innerHTML but jinja is not working.
Code script.js:
contentDiv.innerHTML = getContent(fragmentId);
function getContent(fragmentId) {
var pages = {
quad1: `
<form class="form-inline" method="POST" id="form1">
<h3>
<input type="number" id="quad_a1" name="input_a" class="form-control mx-2 col-1" placeholder="a">
<b>x² +</b>
<input type="number" id="quad_b1" name="input_b" class="form-control mx-2 col-1" placeholder="b">
<b>x +</b>
<input type="number" name="input_c" class="form-control mx-2 col-1" placeholder="c">
<b>=</b>
<input type="number" name="input_d" class="form-control mx-2 col-2" placeholder="Default(0)">
<button type="submit" class="btn btn-primary float-right mr-5" onclick="return empty_quad()">Solve</button>
</h3>
</form>
{{ sol }}
`,
.
.
.
};
return pages[fragmentId];
}
But the output is literally {{ sol }}, not the value of sol:
So how to access the variable sol passed through flask's render_template() in script.js?
You can't use jinja2 template in your js file.
First method: You have to use inline javascript in html file using <script></script> tag, and then you can access the sol variable by assigning it to javascript variable
<script> sol = "{{sol}}" </script> // {{sol}} should be between quotation marks
Second method: If you have seperate js file. you can make a div tag, define it's class and set it's id to {{sol}}. get the element by class name and then get it's id.
Html
<div class="myclass" id="{{sol}}" style="display:none"></div>
javascript
elem= document.getElementsByClassName("myclass") ;
console.log(elem.id) // this is the sol value.
json_script
Safely outputs a Python object as JSON, wrapped in a <script> tag, ready for use with JavaScript.
Argument: HTML “id” of the <script> tag.
For example:
{{ value|json_script:"hello-data" }}
If value is the dictionary {'hello': 'world'}, the output will be:
<script id="hello-data" type="application/json">{"hello": "world"}</script>
The resulting data can be accessed in JavaScript like this:
const value = JSON.parse(document.getElementById('hello-data').textContent);
XSS attacks are mitigated by escaping the characters “<”, “>” and “&”. For example if value is {'hello': 'world</script>&'}, the output is:
<script id="hello-data" type="application/json">{"hello": "world\\u003C/script\\u003E\\u0026amp;"}</script>
This is compatible with a strict Content Security Policy that prohibits in-page script execution. It also maintains a clean separation between passive data and executable code.
django doc
I am Using WFFM with Sitecore-8.2-Update 4 Version. So i have a requirement to change HTML structure of WFFM webforms.
Let me share my case.
We have Name Section that contains first name and last name.
IN WFFM form designer i have created like below
Then the Html is generated like below by WFFM.
<div class="required-field form-group">
<input id="wffm26cf3ccb39024ed0974e0f60d9292156_Sections_0__Fields_0__Id" name="wffm26cf3ccb39024ed0974e0f60d9292156.Sections[0].Fields[0].Id" type="hidden" value="{6DAF46AC-CEE6-4CB2-9391-40ACC39CCE74}" />
<label class="control-label" for="wffm26cf3ccb39024ed0974e0f60d9292156_Sections_0__Fields_0__Value">LastName</label>
<input class=" form-control text-box single-line" data-val="true" data-val-length="The LastName field must be a string with a minimum length of 0 and a maximum length of 256." data-val-length-max="256" data-val-required="This field is required." data-val-required-tracking="{7E86B2F5-ACEC-4C60-8922-4EB5AE5D9874}" id="wffm26cf3ccb39024ed0974e0f60d9292156_Sections_0__Fields_0__Value" name="wffm26cf3ccb39024ed0974e0f60d9292156.Sections[0].Fields[0].Value" placeholder="" style="" type="text" value="" /><span class="field-validation-valid help-block" data-valmsg-for="wffm26cf3ccb39024ed0974e0f60d9292156.Sections[0].Fields[0].Value" data-valmsg-replace="true">
</span>
</div>
<div class="required-field form-group">
<input id="wffm26cf3ccb39024ed0974e0f60d9292156_Sections_0__Fields_1__Id" name="wffm26cf3ccb39024ed0974e0f60d9292156.Sections[0].Fields[1].Id" type="hidden" value="{FF409749-4574-4D8C-971D-1A2D66B82FDA}" />
<label class="control-label" for="wffm26cf3ccb39024ed0974e0f60d9292156_Sections_0__Fields_1__Value">FirstName</label>
<input class=" form-control text-box single-line" data-val="true" data-val-length="The FirstName field must be a string with a minimum length of 0 and a maximum length of 256." data-val-length-max="256" data-val-required="This field is required." data-val-required-tracking="{7E86B2F5-ACEC-4C60-8922-4EB5AE5D9874}" id="wffm26cf3ccb39024ed0974e0f60d9292156_Sections_0__Fields_1__Value" name="wffm26cf3ccb39024ed0974e0f60d9292156.Sections[0].Fields[1].Value" placeholder="" style="" type="text" value="" /><span class="field-validation-valid help-block" data-valmsg-for="wffm26cf3ccb39024ed0974e0f60d9292156.Sections[0].Fields[1].Value" data-valmsg-replace="true">
</span>
</div>
But I need a Html like below one
<div class="required-field form-group has-feedback">
<span>
<input class=" form-control text-box single-line" data-val="true" data-val-length="The First field must be a string with a minimum length of 0 and a maximum length of 256." data-val-length-max="256" data-val-required="This field is required." data-val-required-tracking="{7E86B2F5-ACEC-4C60-8922-4EB5AE5D9874}" id="wffm26cf3ccb39024ed0974e0f60d9292156_Sections_0__Fields_1__Value" name="wffm26cf3ccb39024ed0974e0f60d9292156.Sections[0].Fields[1].Value" placeholder="" style="" type="text" value="">
<input id="wffm26cf3ccb39024ed0974e0f60d9292156_Sections_0__Fields_1__Id" name="wffm26cf3ccb39024ed0974e0f60d9292156.Sections[0].Fields[1].Id" type="hidden" value="{FF409749-4574-4D8C-971D-1A2D66B82FDA}">
<label class="control-label" for="wffm26cf3ccb39024ed0974e0f60d9292156_Sections_0__Fields_1__Value">First</label>
<span class="field-validation-valid help-block" data-valmsg-for="wffm26cf3ccb39024ed0974e0f60d9292156.Sections[0].Fields[1].Value" data-valmsg-replace="true">
</span>
</span>
<span>
<input class=" form-control text-box single-line" data-val="true" data-val-length="The Last field must be a string with a minimum length of 0 and a maximum length of 256." data-val-length-max="256" data-val-required="This field is required." data-val-required-tracking="{7E86B2F5-ACEC-4C60-8922-4EB5AE5D9874}" id="wffm26cf3ccb39024ed0974e0f60d9292156_Sections_0__Fields_0__Value" name="wffm26cf3ccb39024ed0974e0f60d9292156.Sections[0].Fields[0].Value" placeholder="" style="" type="text" value="">
<input id="wffm26cf3ccb39024ed0974e0f60d9292156_Sections_0__Fields_0__Id" name="wffm26cf3ccb39024ed0974e0f60d9292156.Sections[0].Fields[0].Id" type="hidden" value="{6DAF46AC-CEE6-4CB2-9391-40ACC39CCE74}">
<label class="control-label" for="wffm26cf3ccb39024ed0974e0f60d9292156_Sections_0__Fields_0__Value">Last</label>
<span class="field-validation-valid help-block" data-valmsg-for="wffm26cf3ccb39024ed0974e0f60d9292156.Sections[0].Fields[0].Value" data-valmsg-replace="true">
</span>
</span>
</div>
Steps that i followed change html structure of WFFM.
WFFM using Sitecore.Forms.Mvc.Controllers.FormController and Its using default index action. By this it is using ~\Views\Forms\Index.cshtml on root web site.
Its basically using Editor for template.
So in my case i need to find out name section and need to change my html structure. From my findings SectionViewModel.cshtml is responsible for rendering all sections.
I have create one method to check whether current section needs to customized or not.
#if
(Renderer.IsCustomisedSection(Model))
Below my full SectionViewModel view file. (~\Views\Form\EditorTemplates\SectionViewModel.cshtml)
#using Sitecore.Forms.Mvc.Html
#using AAA.Foundation.HtmlHelper.WffmRenderer;
#model Sitecore.Forms.Mvc.ViewModels.SectionViewModel
<!--Render customised action-->
#if (Renderer.IsCustomisedSection(Model))
{
var customisedFieldHtml = Html.EditorFor(x => Model.Fields);
#Html.Raw(Renderer.RenderCustomisedFieldSection(customisedFieldHtml))
}
else
<!--Render customised action Ends-->
if (Model.ShowTitle && !string.IsNullOrEmpty(Model.Title))
{
<fieldset class="#Model.CssClass">
<legend>#Html.BootstrapText("Title")</legend>
#if (Model.ShowInformation && !string.IsNullOrEmpty(Model.Information))
{
<p>#Html.BootstrapText("Information")</p>
}
<div class="row">
<div class="col-md-12">
#Html.EditorFor(x => Model.Fields)
</div>
</div>
</fieldset>
}
else
{
#Html.EditorFor(x => Model.Fields)
}
This is how i can catch Name section by model title.Below my renderer class file
public static bool IsCustomisedSection(Sitecore.Forms.Mvc.ViewModels.SectionViewModel model) {
bool result = false;
// Check the model needs to customised
if (model.Title == "Name") { // For Ex:
result = true;
}
return result;
}
Then i will call respective customize html section like below.
var customisedFieldHtml = Html.EditorFor(x => Model.Fields);
#Html.Raw(Renderer.RenderCustomisedFieldSection(customisedFieldHtml))
Using "Html.EditorFor(x => Model.Fields)" this i can get default generated html. Then i will pass it to my customise render method. This will identify which sites and which section rendere needs to apply.
public static HtmlString RenderCustomisedFieldSection(HtmlString
customisedSectionHtml)
{
string caseValue = "SiteName-SectionName";
HtmlString result = new HtmlString(string.Empty);
switch (caseValue) {
case "SiteName-SectionName":
result = SiteName_Renderer.NameSection(customisedSectionHtml);
break;
}
return result;
}
My final customised html rendere method like below. I am using html agility pack to reframe the htmls.
public static HtmlString NameSection(HtmlString rawHtml)
{
HtmlNode customisedRoot = null;
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(rawHtml.ToString());
// Find each form group elements
var groupHtml = doc.DocumentNode
.Descendants("div")
.Where(d =>
d.Attributes.Contains("class")
&&
d.Attributes["class"].Value.Contains("form-group")
);
if (groupHtml.Count() > 0)
{
// Initialise root
customisedRoot = groupHtml.First().Clone();
customisedRoot.RemoveAllChildren();
// Customised the html
foreach (HtmlNode htmlNode in groupHtml)
{
HtmlDocument innerRootDoc = new HtmlDocument();
HtmlNode innerRoot = innerRootDoc.CreateElement("span");
var helpBlock = htmlNode.Descendants("span").Where(d =>
d.Attributes.Contains("class")
&&
d.Attributes["class"].Value.Contains("help-block")
);
innerRoot.PrependChild(helpBlock.FirstOrDefault());
var label = htmlNode.Descendants("label");
innerRoot.PrependChild(label.FirstOrDefault());
var inputs = htmlNode.Descendants("input");
foreach (HtmlNode inputsNode in inputs)
{
innerRoot.PrependChild(inputsNode);
}
customisedRoot.PrependChild(innerRoot);
}
}
return (customisedRoot!=null)?new HtmlString(customisedRoot.OuterHtml): new HtmlString(String.Empty);
}
By this approach i can able to customize WFFM web form html.
Below are i have tested after my html changes.
Does validation working or not in website.
If i submit the form will it available in form-reports section.In download excel whether submitted value will present or not.
So all the above cases or passed.
My query is above approach will break any other functionality.
How can I check if a value match certain pattern in the code?
Not use ng-pattern but in the function.
Thanks.
Use pure javascript match function.
var str = "The rain in SPAIN stays mainly in the plain";
var res = str.match(/ain/g);
res will be an array with matched values.
You can test if there is match checking array length:
if ( res.length > 0 )
console.log("match");
from here
Use it in a directive, better as controller since in Angular 2 there would be no controllers.
For HTML, you need to specify the regex in "pattern" object for e.g:
<form name="form1" novalidate ng-submit="data.submitTheForm()">
<input type="text" placeholder="Type Here" name="inputName" ng-model="data.inputName" required="required" pattern="^((?!_)[A-Z a-z0-9])+$" maxlength="20"/></form>
Then you need to add the condition in the controller function called on submit
$scope.data.submitTheForm = function() {
if($scope.form1.projectName.$error.pattern)
{
alert("Project name should contain only alphanumeric characters");
return;
}
}
<form name="myform">
<label class="span5">Full Name:<span style="color: red" ng-show="myform.personname.$error.required" >Must be enter Full name</span>
</label>
<input class="span12" type="text" name="personname" ng-pattern="/^[a-zA-Z ]+$/" ng-minlength="2" ng-maxlength="25" required>
<span style="color: red" ng-show="myform.personname.$error.maxlength">Allow maximum 25 characters.</span>
<span style="color: red" ng-show="myform.personname.$error.minlength">Allow minimum 2 characters.</span>
<span style="color: red" ng-show="myform.personname.$error.pattern">Any other symbol are not allow. Only Alphabate allow</span>
</div>
</form>
Plz check example where i need to show "??" into textbox initially.
but those "??" should not save to the server means it should save data validated by regEx.
For that i am assigning "??" initially its fire the validation however
"??" not showing to the textbox.
So what is work around for that ?
Below is the HTML
<div ng-app ng-controller="formCtrl">
<form name="myForm" ng-submit="onSubmit()">
<input type="text" ng-model="price" name="price_field" ng-pattern="/^[0-9]{1,7}$/" required>
<span ng-show="myForm.price_field.$error.pattern">Not a valid number!</span>
<input type="submit" value="submit"/></form></div>
Below is the Javascript
function formCtrl($scope){
$scope.price= "??";
$scope.onSubmit = function(){
alert("form submitted");
}}
Plz check on JsFiddle sample
-Thanks,
Yogesh
It seems input doesn't show up until it matches the regex
So try this,
Html file,
<div ng-app ng-controller="formCtrl">
<form name="myForm" ng-submit="onSubmit(price)">
<input type="text" ng-model="price" required />
<span ng-hide="validater">Not a valid number!</span><br>
<input type="submit" value="submit"/>
</form>
</div>
Js file,
function formCtrl($scope){
$scope.price= "??";
$scope.onSubmit = function(price){
$scope.validater= new RegExp("^\[0-9]{1,7}$").test(price);
//alert("validater "+ $scope.validater);
if(!$scope.validater){
$scope.price= "??";
}else{
alert("form submitted");
}
return $scope.validater;
}
}
Hope this solves your problem :)
Here is the working demo jsfiddle
Try using like this.
<div ng-app ng-controller="formCtrl">
<form name="myForm" ng-submit="onSubmit()">
<input type="text" ng-model="price" name="price_field" placeholder="Enter a number" ng-pattern="/^[0-9]{1,7}$/" required>
<span ng-show="myForm.price_field.$error.pattern">Not a valid number!</span>
<input type="submit" ng-disabled="myForm.$invalid" value="submit"/></form></div>
And in your JS
function formCtrl($scope){
$scope.price= "-1";
$scope.onSubmit = function(){
alert("form submitted");
}}
Take a look at this.
Working Demo
html
<div ng-app ng-controller="formCtrl">
<form name="myForm" ng-submit="onSubmit()">
<input type="text" ng-model="price" name="price_field" ng-pattern="/^[0-9]{1,7}$/" placeholder="??" required >
<span ng-show="myForm.price_field.$error.pattern">Not a valid number!</span>
<input type="submit" value="submit"/>
</form>
</div>
script
function formCtrl($scope){
$scope.price= "";
$scope.onSubmit = function(){
alert("form submitted");
}
}
I am trying to setup stripe as my payement gateway and having some issue.
I want my user to input their credit card info to be able to charge them later on. (aka creating a customer)
After entering all information and press enter, my customer is created on Stripe.com but the credt card information is not saved (so I cannot charge it later on).
On my database the token is saved and when i try to put a charge on the customer I got an answer from Stripe api "cannot charge, user do not have credit card" ...
Here is my code:
views.py
import stripe
def paiements(request):
stripe.api_key = "sk_test_mytestapikey"
utilisateur = request.user
cc_save = Stripetoken.objects.filter(utilisateur= request.user).exists() #check if the user have already a stripe token.
if request.method == 'POST':
token_cc = request.POST.get('stripeToken') #request.POST['stripeToken'] give me an error.
customer = stripe.Customer.create(
card = token_cc,
description = utilisateur.email,
email = utilisateur.email
)
Stripetoken.objects.create(utilisateur= request.user, token = customer.id , description= request.user.email) #save the customer information and token to charge later on
return HttpResponseRedirect('/frontprop/tb/') # Redirect after POST
args = {}
args.update(csrf(request))
args['cc_save'] = cc_save
return render_to_response('b_param_paiement.html', args)
and my html page:
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
<!-- jQuery is used only for this example; it isn't required to use Stripe -->
<script type="text/javascript">
// This identifies your website in the createToken call below
Stripe.setPublishableKey('pk_test_withmyid');
var stripeResponseHandler = function(status, response) {
var $form = $('#payment-form');
if (response.error) {
// Show the errors on the form
$form.find('.payment-errors').text(response.error.message);
$form.find('button').prop('disabled', false);
} else {
// token contains id, last4, and card type
var token = response.id;
// Insert the token into the form so it gets submitted to the server
$form.append($('<input type="hidden" name="stripeToken" />').val(token));
// and re-submit
$form.get(0).submit();
}
};
jQuery(function($) {
$('#payment-form').submit(function(e) {
var $form = $(this);
// Disable the submit button to prevent repeated clicks
$form.find('button').prop('disabled', true);
Stripe.card.createToken($form, stripeResponseHandler);
// Prevent the form from submitting with the default action
return false;
});
});
</script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js">
</script>
<script>
$(document).ready(function(){
$("#toggle").click(function(){
$("#cbinfo").toggle();
});
});
</script>
<form action="/frontprop/tb/param/paiements/" method="POST" id="payment-form"> {% csrf_token %}
<span class="payment-errors"></span>
<div class="form-row">
<label>
<span>Votre numero de carte bancaire:</span>
<input class="form-control" type="text" size="20" data-stripe="number"/>
</label>
</div>
<div class="form-row">
<label>
<span>CVC:</span>
<input class="form-control" type="text" size="4" data-stripe="cvc"/>
</label>
</div>
<div class="form-inline">
<label>
<span>Expiration (MM/YYYY):</span> <br>
<input class="form-control" type="text" size="2" data-stripe="exp-month"/>
</label>
<span> / </span>
<input class="form-control" type="text" size="4" data-stripe="exp-year"/>
</div>
<br>
<button id="stripebutton" class="btn btn-primary" type="submit">Enregistrer la carte</button>
</form>
FYI: I have followed this https://stripe.com/docs/tutorials/forms
Thank you for your help
You need to create a Plan that is free and assign them to that plan, you can later charge that customer with your one off charges as needed.
As stated by Tom, there was a Javascript problem when loading/posting the form.
I have to move on top right after the stripe.js.
Thank Tom I am all set :)