Aurelia validator doesn't update UI - javascript

Using the aurelia-validator plugin, even though the code for form submission and validation works properly, all properties are properly updated, the UI doesn't change, like I don't get a red window around properties which are not correct, nor the statement of what is wrong with given form property.
It's not connected to my CSS, I tried removing whole my css and still it doesn't work. Any idea what's wrong here? Missing something?
contact.js
import {inject} from 'aurelia-framework';
import {Validation} from 'aurelia-validation';
#inject(Validation)
export class Contact{
firstName = 'John';
lastName = '';
company = '';
subject = 'product question';
email = '';
messageText = 'test';
constructor(validation){
this.validation = validation.on(this)
.ensure("firstName")
.isNotEmpty()
.ensure("lastName")
.isNotEmpty()
.ensure("email")
.isNotEmpty()
.isEmail();
}
contact(){
this.validation.validate()
.then(() => {
console.log("works");
})
.catch(() => {
console.log("error");
});
}
}
contact.html
<template>
<div class="row contact-container">
<div class="col-md-4 col-md-offset-3">
<form role="form" validate.bind="validation" submit.delegate="contact()">
<label>First Name</label>
<input type="text" value.bind="firstName" class="form-control" >
<label>Last name</label>
<input type="text" value.bind="lastName" class="form-control">
<label>Company</label>
<input type="text" value.bind="company" class="form-control">
<label>Email</label>
<input type="text" value.bind="email" class="form-control">
<label >Subject</label>
<select value.bind="subject" class="form-control">
<option value="product question">Product Question</option>
<option value="cooperation">Cooperation</option>
<option value="Other">Other</option>
</select>
<label for="message">Message</label>
<textarea rows="5" id="message" value.bind="messageText" class="form-control"></textarea>
<br></br>
<input type="submit" class="form-control">
</form>
</div>
</div>
</template>

I guess the problem is related to the fact that Your markup doesn't match ViewStrategy You are using.
I suspect You might be using some ViewStragegy provided by Aurelia, for example https://github.com/aurelia/validation/blob/master/doc/Intro.md#configuseviewstrategyviewstrategyinstance that expects Twitter Bootstrap markup. If that is the case, You should group Your form intputs to form-groups - see the demo (http://aurelia.io/validation/#/) and source of the TWBootstrapViewStrategyBase class: https://github.com/aurelia/templating-validation/blob/master/src/strategies/twbootstrap-view-strategy.js#L11

Use form-group class, don't forget about validate on input
try smth like
<div class="form-group">
<label class="col-sm-3">Land</label>
<div class="col-sm-6">
<input class="input-small col-sm-12" type="text"
placeholder="Land"
value.bind="model.item.country" validate="country">
</div>
</div>

Related

addEventListener for input not working anymore after validation error is thrown

The problem
I use a form on a webpage where users fill in all sorts of details. There are 3 fields which generate the input for another field. That field gets generated like this: Firstname + Lastname + Date of birth. However, when a validation error is thrown on the form and the page reloads, the generated input isn't the expected format anymore. Only the Date of birth is then in that input.
It looks like it isn't initializing the Firstname + Lastname field anymore after a validation error is thrown on the page. Any suggestions on how to make it so that the fields gets initialized constantly? Or is there maybe a better way to handle this?
This is the code I use for the generated input
window.onload = function() {
let studentNoField = document.getElementById('input_7_9');
let enteredDetails = {
name: '',
lastname: '',
date: ''
};
/* set value in the third input: Studentnummer */
function generateInput() {
let studentNumber = Object.values(enteredDetails).join('').toLowerCase();
studentNoField.value = studentNumber;
}
/* event listener for first input: Voornaam */
document.getElementById('input_7_1').addEventListener('input', function(event) {
enteredDetails.name = event.target.value.replace(/\s/g, '').slice(0, 8);
generateInput();
});
/* event listener for second input: Achternaam */
document.getElementById('input_7_25').addEventListener('input', function(event) {
enteredDetails.lastname = event.target.value.replace(/\s/g, '').slice(0, 8);
generateInput();
});
/* event listener for second input: Date */
document.getElementById('input_7_3').addEventListener('input', function(event) {
enteredDetails.date = event.target.value.replace(/-/g, '').slice(0, 4);
generateInput();
});
/* Get selected training and format it properly for the PDF */
jQuery('#input_7_23').change(function(e) {
var optionChange = jQuery('#input_7_23 option:selected').text().toUpperCase();
jQuery('#input_7_58').val(optionChange);
});
}
<html>
<body>
<form method="post" enctype="multipart/form-data" id="gform_7" action="/budget/" _lpchecked="1">
<div>
<div id="gform_fields_7">
<div id="field_7_9">
<label for="input_7_9">Studentnummer
<input name="input_9" id="input_7_9" type="text" value="" maxlength="20" aria-required="true" aria-invalid="false">
</div>
</div>
<div id="field_7_1">
<label for="input_7_1">Voornaam</label>
<div><input name="input_1" id="input_7_1" type="text" value="" aria-required="true" aria-invalid="false"> </div>
</div>
<div id="field_7_25">
<label for="input_7_25">Achternaam</label>
<div><input name="input_25" id="input_7_25" type="text" value="" aria-required="true" aria-invalid="false"> </div>
</div>
<div id="field_7_3">
<label for="input_7_3">Geboortedatum</label>
<div>
<input name="input_3" id="input_7_3" type="text" value="" placeholder="dd-mm-yyyy" aria-describedby="input_7_3_date_format" aria-invalid="false" aria-required="true">
<span id="input_7_3_date_format">DD dash MM dash JJJJ</span>
</div>
</div>
</div>
</div>
<div>
<input type="submit" id="gform_submit_button_7" value="Versturen" onclick="if(window["gf_submitting_7"]){return false;} window["gf_submitting_7"]=true; " onkeypress="if( event.keyCode == 13 ){ if(window["gf_submitting_7"]){return false;} window["gf_submitting_7"]=true; jQuery("#gform_7").trigger("submit",[true]); }">
</div>
</form>
</body>
</html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Any help or suggestions is appreciated.
There were a few non-existing ids referenced in your code. In the following snippet I have tried to "correct" these errors, but I also went further: I removed all repetitions, thereby following the DRY principle "Don't repeat yourself". The "input"-event listener now works for all elements of the inps array. There is, however one differentiation: the first two elements are limited to 8 characters while the date is limited to 4: .slice(0,i<2?8:4).
const [stNr, ...inps]=[9, 1, 25, 3].map(n=> document.getElementById(`input_7_${n}`));
inps.forEach(inp=>inp.addEventListener("input",()=>
stNr.value=inps.map((el,i)=>
el.value.replace(/[\s-]/g,"").slice(0,i<2?8:4).toLowerCase()
).join(""))
)
<form method="post" enctype="multipart/form-data" id="gform_7" action="/budget/" _lpchecked="1">
<div>
<div id="gform_fields_7">
<div id="field_7_9">
<label for="input_7_9">Studentnummer</label>
<input name="input_9" id="input_7_9" type="text" value="" maxlength="20" aria-required="true" aria-invalid="false">
</div>
</div>
<div id="field_7_1">
<label for="input_7_1">Voornaam</label>
<div><input name="input_1" id="input_7_1" type="text" value="" aria-required="true" aria-invalid="false"> </div>
</div>
<div id="field_7_25">
<label for="input_7_25">Achternaam</label>
<div><input name="input_25" id="input_7_25" type="text" value="" aria-required="true" aria-invalid="false"> </div>
</div>
<div id="field_7_3">
<label for="input_7_3">Geboortedatum</label>
<div>
<input name="input_3" id="input_7_3" type="text" value="" placeholder="dd-mm-yyyy" aria-describedby="input_7_3_date_format" aria-invalid="false" aria-required="true">
<span id="input_7_3_date_format">DD dash MM dash JJJJ</span>
</div>
</div>
</div>
</div>
<div>
<input type="submit" id="gform_submit_button_7" value="Versturen">
</div>
</form>
I removed your jQuery statements at the end of your script, as they referred to non-existent ids. These statements can definitely also be re-written in Vanilla JS, if necessary.
And, as #CherryDT already mentioned: there is no validation code visible here. If it happens on the server then it is the server's responsibility to produce a suitable response that allows the client to render the page with the previously (possibly annotated) content.

HTML Form Not Displaying Correct Data in Handlebars View

I'm working with handlebars for the first time while creating an express app with sequelize and postgresql (courtesy of brad traversy). Upon filling out a form, I am using Joi for validating the request body , if there is an error I re-render the form (view) keeping the originally entered values. The problem is when this happens the text is being trimmed automatically.
E.G. I fill out the title field with "Hello World" and don't fill another field in the form, Joi won't be happy so I re-render the form (view) and when the title repopulates in the form, it will just say "Hello" instead.
Post Endpoint for Gig Resource
// Add a Gig
router.post("/add", (req, res) => {
let { title, technologies, budget, description, contact_email } = req.body;
const { error } = validateGig(req.body);
if (error) {
// Re-Render The Form
return res.status(400).render("add", {
error: error.details[0].message,
title,
technologies,
budget,
description,
contact_email
});
} else {
budget == "" ? (budget = "Unknown") : (budget = `$${budget}`);
// Make Lower Case and Remove Space After Comma
technologies = technologies.toLowerCase().replace(/, /g, ",");
// Insert Into Table
Gig.create({
title,
technologies,
budget,
description,
contact_email
})
.then((gig) => res.redirect("/gigs"))
.catch((err) => console.log("Error Adding Gig" + err));
}
});
Handlebars View
<section id="add" class="container">
<div class="form-wrap">
<h1>Add A Gig</h1>
<p>Your contact email will be shared with registered users to apply to your gig</p>
{{#if error}}
<div class="error">
<p>{{error}}</p>
</div>
{{/if}}
<form action="/gigs/add" method="POST">
<div class="input-group">
<label for="title">Gig Title</label>
<input type="text" name="title" id="title" class="input-box"
placeholder="eg. Small Wordpress website, React developer" maxlength="100" value={{title}}>
</div>
<div class="input-group">
<label for="technologies">Technologies Needed</label>
<input type="text" name="technologies" id="technologies" class="input-box"
placeholder="eg. javascript, react, PHP" maxlength="100" value={{technologies}}>
</div>
<div class="input-group">
<label for="budget">Budget (Leave blank for unknown)</label>
<input type="number" name="budget" id="budget" class="input-box" placeholder="eg. 500, 5000, 10000"
value={{budget}}>
</div>
<div class="input-group">
<label for="description">Gig Description</label>
<textarea name="description" id="description" class="input-box"
placeholder="Describe the details of the gig" rows="10">{{description}}</textarea>
</div>
<div class="input-group">
<label for="budget">Contact Email</label>
<input type="email" name="contact_email" id="contactemail" class="input-box"
placeholder="Enter an email" value={{contact_email}}>
</div>
<input type="submit" value="Add Gig" class="btn btn-reverse">
</form>
</div>
</section>
When using variables in your template, you'll still want to include the quotes around the attribute value.
For example:
value={{title}}
Should be written as
value="{{title}}"

Form object is empty after closing modal

I have two forms in two different modals. When I open the first modal, I console.log the form which I've attached to $scope (I mean n the controller I've given $scope.updateSecurityForm = {} in the beginning) and given name="updateSecurityForm" and I see all the properties like $valid etc. I
When I open the second modal and again console.log the first modal's form, the object is empty. Then I close the second modal and then open the first modal again and see in the console, I see an empty object again. I expected to see the form properties, but there was only an empty object.
The first form in modal:
<div class="modal-body">
<form name="updateSecurityForm" ng-submit="updatePersonnels(upObj, updateSecurityForm)" ng-repeat="upObj in personnelProfileData" novalidate>
<div class="col-md-4">
<label for="vendor-name" class="control-label">Vendor Name:</label>
<select name="vendorname" ng-model="upObj.vendor_id" class=" text-center form-control" ng-options="data.vendor_id as data.vendor_name for data in getvendetailsdata">
{{data.vendor_name}}
</select>
</div>
</form>
</div>
The second modal:
<div class="modal-body">
<form name="addPlumberForm" ng-submit="addPersonnelsByRole(addObj,8, addPlumberForm)" novalidate>
<div class="col-md-4">
<div class="form-group">
<label for="message-text" class="control-label">
Name of the vendor:<span style="color: red;">*</span>
</label>
<select class="text-center form-control ng-valid ng-empty ng-dirty ng-touched" name="vendorname" ng-model="addObj.vendor_id">
<option value="" selected="selected">- Please select a vendor name -
</option>
<option ng-repeat="ae in getvendetailsdata" value="{{ae.vendor_id}}" class="ng-binding ng-scope">{{ae.vendor_name}}</option>
</select>
</div>
</form>
</div>
</div>
Both the modals are in the same page and they are mostly similar. I used the same names in the form so that it will be easy to validate.
In my controller, in the beginning I have
$scope.updateSecurityForm = {} and $scope.addPlumberForm = {} if that matters to anyone reading.
When I do the validation, I get Cannot read property '$invalid' of undefined when I do
$scope.addPersonnelValidation = function(formName) {
console.log(formName, "formName");
if (formName.vendorname.$invalid) {
$.bootstrapGrowl('Please select vendor name', {
type: 'danger',
delay: 2000,
});
return;
}
Calling the validate function:
$scope.addPersonnelsByRole = function(addObj, user_role_type_id, formName) {
if ($scope.addPersonnelValidation(formName)) {
//valid form
}
}
I have put together all your code in jsfiddle and it is not giving undefined error. Though there were few corrections that would be needed for your validation to work.
I have provided the jsfiddle link at the end. Let me know if this is helpful
required attribute is missing in your select of second modal.
closing div missing in the second modal above form tag.
<div class="modal-body">
<form name="addPlumberForm" ng-submit="addPersonnelsByRole(addObj,8, addPlumberForm)" novalidate>
<div class="col-md-4">
<div class="form-group">
<label for="message-text" class="control-label">Name
of the vendor:<span style="color: red;">*</span>
</label>
<select
class="text-center form-control ng-valid ng-empty ng-dirty ng-touched"
name="vendorname" ng-model="addObj.vendor_id" required>
<option value="" selected="selected">- Please
select a vendor name -
</option>
<option ng-repeat="ae in getvendetailsdata"
value="{{ae.vendor_id}}" class="ng-binding ng-scope">{{ae.vendor_name}}</option>
</select>
</div>
<input type="submit">
</div>
</form>
</div>
jsfiddle link : https://jsfiddle.net/anilsarkar/txbmg2wy/3/

BrainTree Hosted Fields onPaymentMethodReceived function not working returning nonce

I am having a hard time figuring out why the onPaymentMethodReceived in a hosted fields is not returning any values.
`
<form action="" id="my-form" method="post">
<label for="a">Amount</label>
<div id="amount">
<input type="text" name="amount" value="400" id="amount" />
</div>
<label for="card-number">Card Number</label>
<div id="card-number">
<input type="text" name="cardNumber" value="4111111111111111" id="cardNumber" />
</div>
<label for="cvv">CVV</label>
<div id="cvv">
<input type="text" name="CVV" value="020" id="cv-v" />
</div>
<label for="expiration-month">Expiration Month</label>
<div id="expiration-month">
<input type="text" name="expirMonth" value="10" id="expirMonth" />
</div>
<label for="expiration-year">Expiration Year</label>
<div id="expiration-year">
<input type="text" name="expirYear" value="20" id="expirYear" />
</div>
<input type="submit" value="Pay" id="btn_submit"/>
</form>
<script>
var nonce0 ;
braintree.setup(clientToken, "custom",
{
id: "my-form",
hostedFields: {
number: {
selector: "#card-number"
},
cvv: {
selector: "#cvv"
},
expirationMonth: {
selector: "#expiration-month"
},
expirationYear: {
selector: "#expiration-year"
},
},
onPaymentMethodReceived:function(nonce){
console.log("in onPaymentMethodReceived");
console.log(nonce);
nonce0 = nonce;
alert('OnPaymentMR');
console.log(JSON.stringify(nonce));
return false;
},
onError :function(obj){
alert('onError');
console.log(JSON.stringify(obj));
}
});
console.log('BTree = '+ nonce0);
</script>
`
I wanted to store the nonce returned but nothing is happening, console.log is not showing any values. Even the onError is not doing anything either.
Using breakpoints,I can tell that the hidden nonce is coming back but the callback function is not getting fired.
I tried it with the Dropin-UI and it does work and I can get the nonce from the onPaymentMethodReceived.
Not sure what I am doing wrong.
Full disclosure: I work as a developer for Braintree
When using Hosted Fields, the form should only include a div container for each payment field. Your implementation would look something like this:
<form action="" id="my-form" method="post">
<label for="a">Amount</label>
<div id="amount"></div>
<label for="card-number">Card Number</label>
<div id="card-number"></div>
<label for="cvv">CVV</label>
<div id="cvv"></div>
<label for="expiration-month">Expiration Month</label>
<div id="expiration-month"></div>
<label for="expiration-year">Expiration Year</label>
<div id="expiration-year”></div>
<input type="submit" value="Pay" id="btn_submit"/>
</form>
The Braintree setup script will then render iframes to handle payment field inputs. If you continue to have issues, you can always get in touch with Braintree support.
In "onPaymentMethodReceived" method you need to try "nonce.nonce" var to check nonce in responce.
Like -
onPaymentMethodReceived:function(obj) {
var nonce_from_braintree = obj.nonce
}
Also you can check below link to get more detailed script to manipulate braintree payment gateway integration with hosted field.
http://www.ilovephp.net/php/simple-braintree-paypal-payment-gateway-integration-in-php-with-demo-examples/
Hope this helps you...:)

How to set the value of an option when using ng-options in controller?

I am getting customer for given id,Customer details are name, email and type of customer {0,1}. For 0, customer will be Regular and 1 will Temporary.
I am able to show details of customer on form but but able to select the type of customer. My select options are showing {'regular', 'temporary'}, but not select any option value.
For example
customer1={'name':'john', 'email':'john#gmail.com', 'customer_type':0}
Form is able to show name and email but not selecting 'regular' options
Controller
$scope.customers_type=['regular','temporary'];
//I will get details of customer
$scope.customer=getCustomer($scope.id);
if($scope.customer.customer_type ==0)
$scope.customer.type=$scope.customers_type[0]
else
$scope.customer.type=$scope.customers_type[1]
HTML
<div>
<label for="Name">Name </label>
<input ng-model='customer.name' name="Name" type="text">
</div>
<div>
<label for="email">Email </label>
<input ng-model='customer.email' name="email" type="text">
</div>
<div>
<label for="enterprise">Type of type of Customer </label>
<select ng-model='customer.type' type="text" ng-options="type for type in customers_type">
</select>
</div>
Code is working fine without any error for angularjs 1.2.23
Just have replaced getCustomer method to object.
If it is not working then Check customer object using breakpoint and check whether it's proper or not and also check which version of angularjs you are using.
angular.module("myApp", []).controller('MyContrl', function($scope) {
$scope.customers_type = ['regular', 'temporary'];
//I will get details of customer
$scope.customer = {
'name': 'john',
'email': 'john#gmail.com',
'customer_type': 0
};
if ($scope.customer.customer_type === 0) {
$scope.customer.type = $scope.customers_type[0]
} else {
$scope.customer.type = $scope.customers_type[1]
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyContrl">
<div>
<label for="Name">Name</label>
<input ng-model='customer.name' name="Name" type="text">
</div>
<div>
<label for="email">Email</label>
<input ng-model='customer.email' name="email" type="text">
</div>
<div>
<label for="enterprise">Type of type of Customer</label>
<select ng-model='customer.type' type="text" ng-options="type for type in customers_type">
</select>
</div>
</div>
I think you need to specify ng-selected and set it to your current customer type.
If you don't specify ng-selected you'll end up with 3 options: '', 'regular', 'temporary'

Categories