I am working on the project that needs to be updates with some functions. One is where i need to update EAV registration form and make choose option, where i have 2 radio buttons and text field. When I click on one of the radio buttons, it takes the value and places it in the input textbox. The problems starts when i try to save registration. This text field attributes are saved in database where one of them is "isRequired". I can't save form because textfield asks to type something in it, but there is already a value. When I disable "isRequired" it saves the form, but there is no value saved in database. When I type any symbol next to radio button value required field disappears and then I can save the value in database. That's why my question is why field can't catch the value. I will put some of the code in this question because I can't make test environment. Have only files on the server. Hope someone can answer or give some clues what to do. I have opinions that this problem might be cause by keypress events, angularjs, jquery or EAV model.
Image: https://postimg.org/image/j8mgjia1d/
Creating fields:
backendComponents.directive('eavFormatted', function($compile)
{
return {
restrict: "E",
scope: true,
replace: true,
transclude: true,
template: '<div class="form-group field_eav field_eav_{{ config.ID }} field_eav_{{ config.handle }}"><label class="control-label">{{ config.name }}</label><div ng-transclude></div></div>',
link: function(scope, element, attrs)
{
var config = JSON.parse(attrs.config);
scope.config = config;
delete attrs.config;
element.removeAttr('ng-transclude');
}
}
});
backendComponents.directive('eavField', function($compile, $timeout) {
return {
restrict: "E",
scope: true,
replace: true,
link: function(scope, element, attrs)
if (html) {
var fieldName = 'eav_' + config.ID;
if (config.isRequired) {
html = html + '<div class="text-danger" ng-show="isSubmitted && eavform.' + fieldName + '.$error.required">Lūdzu aizpildiet šo lauku</div>';
}
html = '<div><ng-form name="eavform">' + html + element.html() + '</ng-form></div>';
var newElem = angular.element(html);
var attrElem = input ? newElem.find(input) : newElem;
attrElem.attr('ng-model', 'vals.eav.' + config.ID);
attrElem.addClass('form-control');
attrElem.attr('placeholder', config.description);
attrElem.attr('name', fieldName);
if (config.isRequired) {
attrElem.attr('ng-required', true);
}
}
}
}
Fields from inspect element from browser:
<div class="form-group field_eav field_eav_2 field_eav_epasts" config="{"ID":2,"eavFieldGroupID":null,"classID":2,"stringIdentifier":null,"name":"E-pasts","description":"E-PASTS *","type":3,"dataType":1,"position":1,"handle":"epasts","isMultiValue":null,"isRequired":1,"isDisplayed":null,"isDisplayedInList":null,"valuePrefix":null,"valueSuffix":null,"valueFieldID":null,"fieldName":"specField_2"}">
<label class="control-label ng-binding">E-pasts</label>
<div ng-transclude="">
<div class="ng-scope">
<ng-form name="eavform" class="ng-pristine ng-invalid ng-invalid-required">
<input type="text" ng-model="vals.eav.2" class="form-control ng-pristine ng-invalid ng-invalid-required" placeholder="E-PASTS *" name="eav_2" ng-required="true" required="required">
<div class="text-danger ng-hide" ng-show="isSubmitted && eavform.eav_2.$error.required">Lūdzu aizpildiet šo lauku</div>
</ng-form>
</div>
</div>
</div>
<div ng-transclude="">
<div class="ng-scope">
<ng-form name="eavform" class="ng-pristine ng-invalid ng-invalid-required">
<input type="text" ng-model="vals.eav.2" class="form-control ng-pristine ng-invalid ng-invalid-required" placeholder="E-PASTS *" name="eav_2" ng-required="true" required="required">
<div class="text-danger ng-hide" ng-show="isSubmitted && eavform.eav_2.$error.required">Lūdzu aizpildiet šo lauku</div>
</ng-form>
</div>
</div>
Code from the file
<eav-formatted config="[[ eavFieldsHandle.epasts.toJson() ]]">
<eav-field></eav-field>
</eav-formatted>
<legend style="padding-top: 0px;">Izvēlieties piegādes veidu: </legend>
<input type="radio" class="input" name="radio-1" id="radio-1" value="Option1">
<span><b>Choose 1</span>
<input type="radio" class="input" name="radio-1" id="radio-2" value="Option2">
<span><b>Choose 2</span>
Script of the file
$( function() {
$('input[name="radio-1"]').on('change', function() {
$('input[name="eav_2"]').val($(this).val());
});
} );
Related
I have a set of radio buttons inside a directive. The directive has an ng-repeat, so it exists multiple times.
I'm able to populate the input fields of the directive, but the radio buttons won't react.
angular.module('account-form-client-de', [])
.controller('ctrl', function($scope) {
$scope.owners = [];
$scope.addOwner = function() {
$scope.owners.push({
class: 'person',
name: 'new owner',
percentage: 0
});
}
$scope.addOwner();
$scope.addOwner();
})
.directive("newOwner", function() {
var options = {
restrict: 'E',
replace: true,
scope: {
owner: '=',
remove: '&'
},
link: function(scope, element, attrs, controller, $parent) {
},
template: `
<div class="table-owners item-row">
<div class="checkbox">
<input type="radio" name="type" ng-model="owner.class" value="person" validate-on-change>
<label for="person" translate>
table_owners.person
</label>
</div>
<div class="checkbox">
<input type="radio" name="type" ng-model="owner.class" value="company" validate-on-change>
<label for="company" translate>
table_owners.company
</label>
</div>
<input name="owners_name" ng-model="owner.name" type="text" placeholder="" class="form-control input-md">
<input name="owners_percentage" ng-model="owner.percentage" type="number" placeholder="" class="form-control input-md">
</div>`
};
return options;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="account-form-client-de" ng-controller="ctrl">
<pre>{{owners}}</pre>
<new-owner ng-repeat="owner in owners track by $index" owner="owner"></new-owner>
<button ng-click="addOwner()">add owner</button>
</div>
Since both the inputs and radio buttons refer to a property in the owner object, I fail to see why the inputs bind, and the radio buttons won't even become checked.
Any ideas?
It's because when you have the same directive multiple times, you have the same radio buttons with the same values multiple times. Then, the HTML parser gets confused. I fixed it by wrapping each row in a <form> (which you don't have to submit), so it's valid again.
angular.module('account-form-client-de', [])
.controller('ctrl', function($scope) {
$scope.owners = [];
$scope.addOwner = function() {
$scope.owners.push({
class: 'person',
name: 'new owner',
percentage: 0
});
}
// Add two owners to begin with
$scope.addOwner();
$scope.addOwner();
})
.directive("newOwner", function() {
var options = {
restrict: 'E',
replace: true,
scope: {
owner: '=',
remove: '&'
},
link: function(scope, element, attrs, controller, $parent) {
},
template: `
<form class="table-owners item-row">
<div class="checkbox">
{{owner.class}}
<input type="radio" name="person" value="person" ng-model="owner.class">
<label for="person" translate>
table_owners.person
</label>
</div>
<div class="checkbox">
<input type="radio" name="company" value="company" ng-model="owner.class">
<label for="company" translate>
table_owners.company
</label>
</div>
<input name="owners_name" ng-model="owner.name" type="text" placeholder="" class="form-control input-md">
<input name="owners_percentage" ng-model="owner.percentage" type="number" placeholder="" class="form-control input-md">
</form>`
};
return options;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="account-form-client-de" ng-controller="ctrl">
<pre>{{owners}}</pre>
<new-owner ng-repeat="owner in owners track by $index" owner="owner"></new-owner>
<button ng-click="addOwner()">add owner</button>
</div>
I Have input and I use a custom directive to display the input error with use of ng-messages. And I want to use attribute for showing the error, not ng-message.
Here is my Code
<md-input-container class="md-block" flex-gt-sm>
<label>Enter Your Message</label>
<input required md-no-asterisk ng-model="newEmployee.message" type="text" id="name" name="name" formValidate>
<div ng-messages="Employeeform.message.$error">
<div ng-message="messageValidator">Message is Invalid
</div>
</md-input-container>
Directive :
app.directive('formValidate', function() {
return {
restrict: 'A',
require: 'ngModel',
template: '<p>Name is required</p>',
link: function(scope, element, attr, ctrl) {
function formValidate(ngModelValue) {
if ([A - z].test(ngModelValue)) {
ctrl.$setValidity('formValidate', false)
} else {
ctrl.$setValidity('formValidate', true),
}
return ngModelValue;
}
ctrl.$parsers.push(formValidate);
}
};
});
Make use of angular-form. Go through this doc https://docs.angularjs.org/guide/forms
Without ng-messages
<div class="form-group" ng-class="{ 'has-error': vm.form.firstname.$touched && vm.form.firstname.$invalid }">
<label class="control-label col-xs-3" for="firstname">First Name</label>
<div class="col-xs-9">
<input class="form-control" name="firstname" id="firstname" ng-model="vm.firstname" type="text" ng-change = "vm.resetValidationErrors('firstname')" required/>
<p ng-show="vm.form.firstname.$error.required && vm.form.firstname.$touched" class="help-block">First name is required.</p>
<p ng-show="vm.form.firstname.$error.firstname && vm.form.firstname.$touched" class="help-block">{{ vm.form.firstname.errorMessage }}</p>
</div>
</div>
I would like to dynamically display Person and Address data using label and input value in Summary Section. As the user edits the form fields, a list items with label + value should display in the summary tables. If value has been removed in the form, that associated label and value should be removed from the Summary Section.
I have added client side validation for each input element. I tried to solve this and couldn't figure out what is best way to do it. Any help would be appreciated.
Example:
// the main (app) module
var myApp = angular.module("myApp", []);
// add a controller
myApp.controller("myCtrl", function($scope) {
$scope.vm = {
caller: {
person: {
firstName: '',
lastName: '',
phoneOne: '',
email: ''
},
address: {
lineOne: '',
lineTwo: ''
}
}
};
$scope.save = function() {
console.log($scope.vm);
}
});
// add a directive
myApp.directive('showErrors', function($timeout, $compile) {
return {
restrict: 'A',
require: '^form',
link: function(scope, el, attrs, formCtrl) {
// find the text box element, which has the 'name' attribute
var inputEl = el[0].querySelector("[name]");
// convert the native text box element to an angular element
var inputNgEl = angular.element(inputEl);
// get the name on the text box
var inputName = inputNgEl.attr('name');
// only apply the has-error class after the user leaves the text box
var blurred = false;
inputNgEl.bind('blur', function() {
blurred = true;
el.toggleClass('has-error', formCtrl[inputName].$invalid);
});
scope.$watch(function(scope) {
return formCtrl[inputName].$invalid;
}, function(invalid, scope) {
// we only want to toggle the has-error class after the blur
// event or if the control becomes valid
if (!blurred && invalid) {
return
}
el.toggleClass('has-error', invalid);
});
scope.$on('show-errors-check-validity', function() {
el.toggleClass('has-error', formCtrl[inputName].$invalid);
});
scope.$on('show-errors-reset', function() {
$timeout(function() {
el.removeClass('has-error');
}, 0, false);
});
}
}
});
.form-group .help-block {
display: none;
}
.form-group.has-error .help-block {
display: inline;
}
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp" ng-controller="myCtrl">
<form name="claimForm" ng-submit="save()">
<h3>PERSON</h3>
<div class="col-md-6">
<div class="form-group form-caller" show-errors>
<label class="control-label">First Name<span class="help-block" ng-if="claimForm.callerFirstName.$error.required"><i>[required]</i></span>
</label>
<input type="text" name="callerFirstName" ng-model="vm.caller.person.firstName" class="form-control" required="" />
</div>
</div>
<div class="col-md-6">
<div class="form-group form-caller" show-errors>
<label class="control-label">Last Name<span class="help-block" ng-if="claimForm.callerLastName.$error.required"><i>[required]</i></span>
</label>
<input type="text" name="callerLastName" ng-model="vm.caller.person.lastName" class="form-control" required="" />
</div>
</div>
<hr />
<h3>ADDRESS</h3>
<div class="col-md-6">
<div class="form-group" show-errors>
<label class="control-label">Address Line 1<span class="help-block" ng-if="claimForm.addressOne.$error.required"><i>[required]</i></span>
</label>
<input type="text" name="addressOne" ng-model="vm.caller.address.lineOne" class="form-control" required="" />
</div>
</div>
<div class="col-md-6">
<div class="form-group" show-errors>
<label class="control-label">Address Line 2<span class="help-block" ng-if="claimForm.addressTwo.$error.required"><i>[required]</i></span>
</label>
<input type="text" name="addressTwo" ng-model="vm.caller.address.lineTwo" class="form-control" required="" />
</div>
</div>
<hr />
<input type="submit" id="submit" value="SUBMIT" class="btn btn-primary btn-lg" />
{{vm | json }}
</form>
<h2>Summary</h2>
<div id="person">
<h3>PERSON </h3>
</div>
<hr />
<div id="address">
<h3>ADDRESS</h3>
</div>
</body>
Thanks in Advance
I have a custom directive which works when I once change input value but when I submit form without changing input field value directive does not display error message.
html code:
<form name="myform" role="form" class="form-horizontal" method="post" novalidate>
<div class="form-group">
<label class="control-label col-sm-3" for="firstName">First name :</label>
<div class="col-sm-9">
<input name='firstName' class="form-control" type='text' required ng-model='name' string>
</div>
</div>
<div class="form-group">
<input type="submit" value="Submit" class="btn btn-success" />
</div>
</form>
directive :
validationModule.directive('string', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attr, ctrl) {
function validationError(value) {
if (value.length < 1) {
ctrl.$setValidity('required', false);
//showPopOver(element, "Required field");
errorValidation(element, "Required field");
// $(element).popover('show');
}
if (/[a-zA-Z]/.test(value)) {
ctrl.$setValidity('invalid', true);
// $(element).popover('destroy');
successValidation(element);
}
if (/[0-9]/.test(value)) {
ctrl.$setValidity('invalid', false)
errorValidation(element, "number not allowed");
// showPopOver(element, "number not allowed");
// $(element).popover('show');
}
return value;
}
ctrl.$parsers.push(validationError);
}
};
});
How can I call directive to perform validation on submit event ?
I don't know which version of angular you are using, but since 1.3 validators are not hacked into parsers. See $validators in https://docs.angularjs.org/api/ng/type/ngModel.NgModelController
Also using such generic names for directives is discouraged due to possible name collisions. Use some prefix eg myString
I'm having a problem with AngularJs. I have created a directive that $watch the model and it takes some action based on the model's current status. However, although during debugging I can see that the $watch is set, it is only being triggered after the model get valid at least once and I don't know why that is happening. Debugging it doesn't even gets into the $watch function when something is typed.
The code is below:
Directive:
(function() {
'use strict';
var app = angular.module('app');
app.directive('tooltipValidation', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ngModel) {
var tooltip = $(element).qtip({
content: {
text: element.next('div')
},
show: false,
hide: true
}).qtip('api');
scope.$watch(attrs.ngModel, function() {
if (ngModel.$invalid && ngModel.$dirty) {
tooltip.show();
} else {
tooltip.hide();
}
});
}
};
});
})()
HTML:
<div class="form-address clearfix" ng-show="isNewShippingAddress" ng-form="newShippingAddressForm">
<h3>Include new shipping address:</h3>
<div class="novo-endereco clearfix" id="newAddress">
<div class="required address apelido">
<label for="newShippingAddressAlias">Alias</label>
<input id="newShippingAddressAlias" name="newShippingAddressAlias" type="text" tooltip-validation ng-model="newShippingAddress.Alias" required ng-maxlength="32" />
<div data-ng-show="newShippingAddressForm.newShippingAddressAlias.$dirty && newShippingAddressForm.newShippingAddressAlias.$invalid">
<p data-ng-show="newShippingAddressForm.newShippingAddressAlias.$error.required">obligatory</p>
<p data-ng-show="newShippingAddressForm.newShippingAddressAlias.$error.maxlength">max 32 char</p>
</div>
</div>
<div class="required endereco">
<label for="newShippingAddressStreet">Street</label>
<input id="newShippingAddressStreet" name="newShippingAddressStreet" type="text" tooltip-validation ng-model="newShippingAddress.Street" required ng-maxlength="256" />
<div data-ng-show="newShippingAddressForm.newShippingAddressStreet.$dirty && newShippingAddressForm.newShippingAddressStreet.$invalid">
<p data-ng-show="newShippingAddressForm.newShippingAddressStreet.$error.required">obligatory</p>
<p data-ng-show="newShippingAddressForm.newShippingAddressStreet.$error.maxlength">max 256 char</p>
</div>
</div>
<div class="required cep">
<label for="newShippingAddressZipCode">ZipCode</label>
<input id="newShippingAddressZipCode" name="newShippingAddressZipCode" type="text" tooltip-validation ng-model="newShippingAddress.ZipCode" required ng-pattern="/^[0-9]{8}$/" />
<div data-ng-show="newShippingAddressForm.newShippingAddressZipCode.$dirty && newShippingAddressForm.newShippingAddressZipCode.$invalid">
<p data-ng-show="newShippingAddressForm.newShippingAddressZipCode.$error.required">obligatory</p>
<p data-ng-show="newShippingAddressForm.newShippingAddressZipCode.$error.pattern">8 digits</p>
</div>
</div>
<input type="submit" class="button grey" value="Save new address" data-ng-click="saveShippingAddress()" ng-disabled="newShippingAddressForm.$invalid" />
</div>
</div>
Regards,
dimello
Try:
scope.$watch(function(){
return ngModel.$viewValue; //Watch for view value (the value in your input)
}, function() {
if (ngModel.$invalid && ngModel.$dirty) {
tooltip.show();
} else {
tooltip.hide();
}
});
DEMO
Explanation:
When you type an invalid value into the input with ng-model, the underlying model is not updated, causing your scope.$watch(attrs.ngModel not being fired because you're watching for changes in the model. If you need to fire the function every time the input changes no matter it's valid or not, try the above solution.