How can I change errorElem? - parsley.js

I am trying to change how the error element is displayed. I am using the Bulma UI framework, and want the error message to be displayed in the following. The structure should look like the following. It should also remove the "li" tags around the error message:
<article class='message'>
<div class="message-body content">
<p> ERROR DISPLAYS HERE </p>
</div>
</article>
My attempt to fix it was as follows:
const parsleyConfig = {
errorElem: '<div class="message-body"></div>',
errorsWrapper: '<article class="message"></article>'
};
$('#myForm').parsley(parsleyConfig);
However, only the errorsWrapper seems to be working, the errorElem does not apply to the error message at all.

As Marc-André Lafortune stated, you're using Parsley.js v1.x.x, so errorsWrapper and errorElem should be defined in errors configuration. Here is a simple implementation of Parsley.js v1 based on your code:
$(function() {
const parsleyConfig = {
errors: {
container: function (elem) {
return elem.next('article.message');
},
errorsWrapper: '<div class="message-body content"></div>',
errorElem: '<p></p>'
}
};
$('#myForm').parsley(parsleyConfig);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/parsley.js/1.2.3/parsley.min.js"></script>
<form action="" method="" id="myForm">
<input type="text" name="field" parsley-required="true">
<article class="message"></article>
<input type="submit" value="Submit Form">
</form>
And here is a Parsley.js v2 implementation:
$(function() {
const parsleyConfig = {
errorsContainer: function (elem) {
return elem.$element.next('article.message');
},
errorsWrapper: '<div class="message-body content"></div>',
errorTemplate: '<p></p>'
};
$('#myForm').parsley(parsleyConfig);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/parsley.js/2.9.1/parsley.js"></script>
<form action="" method="" id="myForm">
<input type="text" name="field" required>
<article class="message"></article>
<input type="submit" value="Submit Form">
</form>

What version of Parsley are you using? errorElem is Parsley 1.x...
Use errorsContainer, errorsWrapper, and errorTemplate.

Related

AngularJS v1.5.5 Reset form not working for invalid input fields

I have the code below (or see the fiddle) and I try to reset form and clear all input fields too for each form.
With AngularJS version 1.2.1 is working fine! but in my app I using version 1.5.5 because I have other libraries for separating the nested forms in <md-tab> tags using material framework who need this version.
The problem is when any field it's invalid then reset does not work as expected and these fields remain unchanged instead to be clear.
There is another way to clearing all fields (of nested form) when I click reset button ?
angular.module("main", [])
.controller("register", function($scope) {
$scope.data = {
A: {},
B: {}
};
$scope.reset = function(form) {
form.$setPristine();
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<body ng-app="main">
<div ng-controller="register" class="form">
<form name="form" novalidate role="form">
<div class="form">
<h1>TAB1 - Form A:</h1>
<ng-form name="A">
A1:
<input type="text" ng-model="data.A.A1" ng-minlength="4" ng-maxlength="15" />A2:
<input type="text" ng-model="data.A.A2" ng-minlength="4" ng-maxlength="15" />
<button type="button" ng-disabled="A.$pristine" ng-click="reset(A); data.A=null;">Reset</button>
<br/>
<strong>A.$pristine =</strong> {{A.$pristine}}
<strong>A.$valid =</strong> {{A.$valid}}
</ng-form>
</div>
<br/>
<br/>
<div class="form">
<h1>TAB2 - Form B:</h1>
<ng-form name="B">
B1:
<input type="text" ng-model="data.B.B1" ng-minlength="4" ng-maxlength="15" />B2
<input type="text" ng-model="data.B.B2" ng-minlength="4" ng-maxlength="15" />
<button type="button" ng-disabled="B.$pristine" ng-click="reset(B); data.B=null;">Reset</button>
<br/>
<strong>B.$pristine =</strong> {{B.$pristine}}
<strong>B.$valid =</strong> {{B.$valid}}
</ng-form>
</div>
</form>
<h1>data:</h1>
<pre>{{data | json}}</pre>
</div>
</body>
It's because ng-model binds to the A and B objects by reference in $scope.data. If you remove the $scope.data.A = null from your ng-click and reset the object without creating a new one, it works:
https://jsfiddle.net/utwf604r/15/
$scope.reset = function (form)
{
// don't change the reference to A
// $scope.data.A = {} wont work!!
angular.extend($scope.data, {A:{A1:'',A2:''}, B:{B1:'',B2:''}});
form.$setPristine();
};

ng-Template CSS not working

Using AngularJS ngDialog.
Expecting that the CSS in the document is applied to the ngDialog, but it hwas not applied.
Code:
<script type="text/ng-template" id="attach_account_template">
<div id="attach_account_div" ng-controller="Opportunity_Controller" style="width:250px">
<input type="text" class="form-control" id="account_name" style="width:200px;height:35px" />
<input id="btn_account" type="button" style="margin-left:10px;height:35px;width:50px" value="GO" />
</div>
</script>
$scope.attach_account = function () {
//attach_account_template
ngDialog.open({ template: 'attach_account_template', scope: $scope });
};

validate dynamic form before submitting angular

I'm dynamically creating forms with ng-repeat and they have some validation attributes (simplified version):
<div class="row" ng-repeat="defect in model.defects">
<form name="form_{{defect.id}}" novalidate>
<input ng-model="defect.name" required/>
<input type="submit" ng-click="saveDefect(defect)"/>
</form>
</div>
Basically what I want to do is this:
$scope.saveDefect = function (defect) {
if ($scope.<how to get the form name here>.$invalid) {
return;
}
}
Since the form name has been created dynamically with an id how do I access it? Other ways of doing the same are also welcome ofcourse :)
You can use the bracket notation to access it :
$scope["form_"+defect.id]
What I advise you to do is :
var app = angular.module("App", []);
app.controller("Ctrl", function($scope) {
$scope.forms = {};
$scope.list = [{id: 1}, {id: 2}];
$scope.save = function(item) {
if ($scope.forms["form_" + item.id].$invalid) {
alert("error on form_" + item.id);
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="App" ng-controller="Ctrl">
<div class="row" ng-repeat="item in list">
<form name="forms.form_{{item.id}}" novalidate>
<input ng-model="item.name" required/>
<input type="submit" ng-click="save(item)" />
</form>
</div>
</body>

How to validate form when the forms are inserted using ng-include

I have 3 different form pages which are inserted using ng-include into DOM within a bootstrap modal window. What is the best way to do validation in every form and do a complete form submit(for all the 3 forms) in scenario like this?
HTML
<div ng-switch on="page">
<div ng-switch-when="Games">
<div ng-include="'Games.html'"></div>
</div>
<div ng-switch-when="Music">
<div ng-include="'Music.html'"></div>
</div>
<div ng-switch-when="Videos">
<div ng-include="'Videos.html'"></div>
</div>
</div>
Demo : http://plnkr.co/edit/D1tMRpxVzn51g18Adnp8?p=preview
There is to find a way to validate data yet
(may be with jqueryvalidation) but can be a starting point.
I think there is no way to get the value of games.$valid
so I've thought of
var app = angular.module("myApp", [])
app.controller("FormsCtrl", function($scope) {
//console.log($scope);
// $scope.items = ['Games', 'Music', 'Videos'];
$scope.$on('someEvent',function(e,a){
console.log(a);
})
});
app.directive("myform", function() {
return {
restrict: "A",
link:function(scope,element,attrs){
element.bind('submit',function(e){
var isValid = false; // TO DO :)
scope.$emit('someEvent', [attrs.fname,isValid]);
});
}
}
});
<div ng-controller="FormsCtrl">
<div ng-switch on="page">
<div ng-switch-when="Games">
<div ng-include="'Games.html'"></div>
</div>
<div ng-switch-when="Music">
<div ng-include="'Music.html'"></div>
</div>
<div ng-switch-when="Videos">
<div ng-include="'Videos.html'"></div>
</div>
</div>
</div>
<form name="games" class="simple-form" myform fname="games">
<input type="text" ng-model="prefix.games.name" name="uName" required /><br>
</form>
EDIT
A smarter quicker way :)
app.controller("FormsCtrl", function($scope) {
$scope.mySubmit = function(isValid){
console.log(isValid);
}
});
<form name="games" class="simple-form" ng-submit="mySubmit(games.$valid)">
<input type="text" ng-model="prefix.games.name" name="uName" required /><br>
</form>

ng-model from angular-payments is not working

I am trying to add angular-payments in order to integrate stripe.com payment processing to my AngularJS web app.
I duplicated the code from https://github.com/laurihy/angular-payments/blob/master/lib/angular-payments.js into my angular-payments.js file and the code from https://github.com/laurihy/angular-payments/blob/master/example/index.html into localhost:8888/stripe.html and got it to work.
However, when I try to integrate this code to my AngularJS web app, the ng-model is not working.
Here is how I integrated the code. I have a single page web app with app.js, which has the following code:
angular.module('io.config', []).value('io.config', {
'password': 'json/config.password.json',
....
....
});
...
...
angular.module('app.modules', ['app.config']);
var app = angular.module('app', ['ngCookies', 'io', 'ui', 'bs', '$strap',
'app.controllers', 'app.directives', 'app.factories', 'app.filters', 'app.modules', 'app.config']);
So, I added 'angularPayments' to:
var app = angular.module('app', ['ngCookies', 'io', 'ui', 'bs', '$strap',
'app.controllers', 'app.directives', 'app.factories', 'app.filters', 'app.modules', 'app.config', 'angularPayments']);
I also have an app.route.js file, which has the following code:
angular.module('app')
.config(['$routeProvider', function($routeProvider) {
var _view_ = 'view/', _app_ = 'app/';
$routeProvider
.when('/user/invite', {templateUrl:_view_+'app/invite.html'})
I added the following to app.route.js:
.when('/user/buy', {templateUrl:_view_+'app/buy.html'})
I duplicated the code from localhost:8888/stripe.html into app/buy.html, which maps to localhost:8888/#/user/buy
The exception is that I took the following lines out of buy.html and put them into index.html:
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script src="scripts/modules/angular-payments.js"></script>
My index.html has this code:
<!DOCTYPE html>
<html class="no-js" lang="en" data-ng-app="app">
...
<link href="./css/bootstrap.css" rel="stylesheet">
...
<body class="ng-cloak" data-ng-controller="AppCtrl">
...
<div data-ng-view></div>
...
<script src="bower_components/angular-io/src/scripts/ie.js"></script>
...
<script src="bower_components/angular-complete/angular.js"></script>
...
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
<script src="scripts/modules/angular-payments.js"></script>
...
Both stripe.html and buy.html has the following code:
<form stripe-form="handleStripe">
<div class="span3">
<label for="">Card number</label>
<input type="text" class="input-block-level" ng-model="number" payments-validate="card" payments-format="card" />
</div>
<div class="span1">
<label for="">Expiry</label>
<input type="text" class="input-block-level" ng-model="expiry" payments-validate="expiry" payments-format="expiry" />
</div>
<div class="span3">
<label for="">Name on card </label>
<input type="text" class="input-block-level">
</div>
<div class="span1">
<label for="">CVC</label>
<input type="text" class="input-block-level" ng-model="cvc" payments-validate="cvc" payments-format="cvc" />
</div>
<div class="span4">
<button type="submit" class="btn btn-primary btn-large">Submit</button>
</div>
number:{{number}}, expiry:{{expiry}}, cvc:{{cvc}}
</form>
However, the following code works in stripe.html but not in buy.html, as no values are coming back from the ng-model:
number:{{number}}, expiry:{{expiry}}, cvc:{{cvc}}
Hence, when I submit this form, Stripe returns an error with status = 402 because nothing is passed to Stripe.
I've tried changing ng-model to data-ng-model, but to no avail. I've tried putting the following code into a separate file: scripts/controllers/payment.js:
function PaymentCtrl($scope) {
$scope.handleStripe = function(status, response){
if(response.error) {
// there was an error. Fix it.
} else {
// got stripe token, now charge it or smt
token = response.id
}
}
}
and adding the following to app.route.js:
.when('/user/buy', {templateUrl:_view_+'app/buy.html', controller:PaymentCtrl})
and changing the following in buy.html:
data-ng-controller="MainController"
to:
data-ng-controller="PaymentCtrl"
but still to no avail.
Can anyone tell me how to get the ng-model variables to work in buy.html? Thanks in advance.
I got a tip from Ng-model does not update controller value and I solved the problem with a convoluted solution.
I added the following code to MainController in buy.html:
$scope.payment = {};
$scope.copyvariables = function() {
$scope.number = $scope.payment.number;
$scope.expiry = $scope.payment.expiry;
$scope.cvc = $scope.payment.cvc;
}
Then I added "payment." to the ng-model variables, like such:
<div class="span7">
<label for="">Card number</label>
<input id="number" name="number" type="text" class="input-block-level" data-ng-model="payment.number" payments-validate="card" payments-format="card" required />
</div>
<div class="span4" style="border: 1px solid red">
<label for="">Expiry</label>
<input type="text" class="input-block-level" data-ng-model="payment.expiry" payments-validate="expiry" payments-format="expiry" required />
</div>
<div class="span8">
<label for="">Name on card </label>
<input id="name" name="name" type="text" class="input-block-level" required />
</div>
<div class="span3">
<label for="">CVC</label>
<input type="text" class="input-block-level" data-ng-model="payment.cvc" payments-validate="cvc" payments-format="cvc" required />
</div>
Now the following code works and the values are being passed to Stripe:
number:{{number}}, expiry:{{expiry}}, cvc:{{cvc}}
I still don't know why I need this for buy.html but stripe.html works without this extra code.

Resources