I have created a function that does some error checkings and will be used in different input fields. My function code is below:
errorChecks = (element, minlength) => {
if (element.$dirty) {
if (element.$error.required == true) {
this.errorMessage = "REQUIRED";
return;
} else if (element.$viewValue.length < minlength) {
this.errorMessage = "MINLENGTH" // MINLENGTH error with parameters here
return;
} else {
this.errorMessage = null;
return;
}
}
}
I am using the angularjs translate for my error messages.
"MINLENGTH": "{{ element }} must be at least {{ value }} characters",
I wanted to dynamically change my error message by passing a parameter to the translations like so:
errorChecks(username, 5);
If I enter 1 character to the username field the error would say: username must be at least 5 characters.
Is what I am trying to do even possible?
It'll probably be best if you translate inside the controller for this one, unless you want to pass element and minlength to the template.
Firstly you'll need inject $translate into your controller. Then to generate your message:
this.errorMessage = $translate('MINLENGTH', { element: element, value: minlength });
This method is also outlined here.
To do this in the template (outlined here):
{{ MINLENGTH | translate : { element: element, value: minlength } }}
For anyone wondering how the syntax is, for using methods to retrieve the input for translation, this worked for me:
{{ MINLENGTH | translate : { x: table.getShownCount(), y: table.getTotalCount() } }}
You can also do this in the template like this.
<span data-translate="MINLENGTH" data-translate-values="{ element: element, value: minlength }"></span>
You can also use $translate.instant('MINLENGTH', { element: element, value: minlength })
This worked fine for me:
{{'commisionMessage' | translate : {fee:fee} }}|
Json File
"commisionMessage": "BLA {{fee}} BLA BLA"
Related
I have an Angular ui-boostrap typeahead component that is working correctly until I added one requirement to the whole function. I want to call the backend for the suggested results just after user types in 3 letters. It is done correctly but my problem is that the results are visible only when users type in the 4th letter. Is there any way to bypass this, by forcing it to refresh the UI just after user types in the 3rd letter.
Code is :
HTLM
<input name="states" id="states" type="text" ng-model="vm.cityName"
uib-typeahead="municipality as municipality.city + ' (' + municipality.name + ') '+municipality.zipCode for municipality in vm.getMunicipalitiesByCity($viewValue) | filter:$viewValue | limitTo:8" class="form-control" typeahead-on-select="vm.citySelected()" >
JS Controller
vm.getMunicipalitiesByCity = function (cityName) {
if (cityName != undefined && cityName.length == 3) {
CalculationEndpointService.municipalitiesByCity({cityName: cityName}, function (result) {
vm.municipalities = result.map(
function (item) {
return item;
}
);
});
}
if(cityName.length<3){
vm.municipalities=[""];
}
return vm.municipalities;
};
you could use typeahead-min-length attribute. see https://angular-ui.github.io/bootstrap/#/typeahead
I have a Laravel 5.2 Backend API and a AngularJS Frontend and at some point I perform a laravel validation and return and error if validation fails.
When I iterate trough errors and display them on the frontend I get somthing like this:
["The email has already been taken."]
and I would like to be like this
The email has already been taken.
without the [""] stuff.
My code is:
Angular controller:
if (error.statusText === "Unprocessable Entity") {
$scope.registerErrors = error.data;
}
Angular template:
<div class="alert alert-warning animated pulse" ng-if="registerError && isLoading === false">
<p ng-repeat="(error, errorText) in registerErrors">{{errorText}}</p>
</div>
Laravel controller:
$this->validate($request, [
'firstname' => 'required|max:100|min:3',
'lastname' => 'required|max:100|min:3',
'email' => 'required|email|unique:users|max:255',
]);
Console.log:
Thanks in advance!
because of errorText contain email array and you shown full email array. if email contain multiple error then
can try like:
<p ng-repeat="(error, errorObject) in registerErrors">
<span ng-repeat=" singleError in errorObject">{{singleError}}</span>
</p>
or for single error can try like:
<p ng-repeat="(error, errorText) in registerErrors">{{errorText[0]}}</p>
or just assign error.data.email instead of error.data
if (error.statusText === "Unprocessable Entity") {
$scope.registerErrors = error.data.email;
}
Actually you need change $scope.registerErrors = error.data; into $scope.registerErrors = error.data.email;. Because error.data.email is an array.
If you have several errors at the same time, it's better to try this
if (error.statusText === "Unprocessable Entity") {
$scope.registerErrors=[];
if(error.data.email)$scope.registerErrors.push(error.data.email[0]);
if(error.data.firstname)$scope.registerErrors.push(error.data.firstname[0]);
if(error.data.lastname)$scope.registerErrors.push(error.data.lastname[0]);
}
Working fiddle: https://jsfiddle.net/udr9dksa/
{{emailTaken | cleanError}}
Filter:
app.filter("cleanError", function() {
return function(input) {
if(!input) return "";
return input.slice(2, -2);
}
});
I've got a UI page setup through Angular, and I'm trying to take advantage of the built in ng-maxlength validator on an input element. Long story short, I know about $scope.form.$error and how that object has a maxlength property in the case that the validation fails. But I want to display an error message specific to the character length that was violated, and I don't see anywhere that the length that I specified was stored on this object. Does anyone know if it's possible to access this, so I don't have to write out a separate error message for each input that has the max length violated?
EDIT: To answer your question, yes angular does store a boolean value in the $error object that is accessible to your via the key(s) that are set in the object. In the case of the code I provided below and in th jsFiddle, we are setting the key for angular, and the value of either true or false.
Be mindful when setting the value as it is reversed. ex. $setValidity( true ), flips the $error to false.
Ok, here is what I think you were looking for...
In Angularjs v1.2.13 you will not have access to ng-message or the $validator pipeline,
which is why are are using $formatters and $parsers.
In this case, I am using named inputs, but perhaps in your case you need dynamic input names?
Plus, if you are using inputs but no form, then getting the error message to display would have to be done with a separate custom directive.
If so, then please look here for dynamically named input fields for some help.
dynamic input name in Angularjs link
Let me know if this works; I'll make changes as needed to HOOK YOU UP!
In case you don't know, you can write over Angular's maxlength for each individual input.
If you changed 'maxlength' in the updateValidity() function in the directive below, to something like 'butter', then $scope.form.inputname.$error would be something like
$scope.formname.inputname.$error { butter: true }
if you also used ng-maxlength="true", then it would be
$scope.formname.inputname.$error { butter: true, maxlength: true }
Another example if you used ng-maxlength, and capitalized the 'maxlength' in the directive to 'Maxlength'
Then you would get
$scope.formname.inputname.$error { maxlength: true(angular maxlength), Maxlength: true(your maxlength)
And of course if you name it the same, then yours writes over angulars
$scope.formname.inputname.$error { maxlength: true };
The point is YOU can add your own names to the angular $error object; you can write over Angular's; and you can just use what Angular gives you when you use Angular's directives: like ng-required="true", or ng-maxlength="true"
Link to YOUR angularjs version on jsFiddle
jsFiddle LInk
<div ng-app="myApp">
<form name="myForm">
<div ng-controller="MyCtrl">
<br>
<label>Input #1</label>
<br>
<input ng-model="field.myName" name='myName' my-custom-length="8" />
<span ng-show="myForm.myName.$error.maxlength">
Max length exceeded by {{ myForm.myName.maxlength }}
</span>
<br>
<br>
<label>Input #2</label>
<br>
<input ng-model="field.myEmail" name='myEmail' my-custom-length="3" />
<span ng-show="myForm.myEmail.$error.maxlength">
Max length exceeded by {{ myForm.myEmail.maxlength }}
</span>
</div>
</form>
</div>
var app = angular.module('myApp', []);
app.controller('MyCtrl', function ($scope) {
$scope.field = {};
});
app.directive("myCustomLength", function () {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ctrl) {
if (!ctrl) { return } // ignore if no ngModel controller
ctrl.$formatters.push(validateInput);
ctrl.$parsers.unshift(validateInput);
function validateInput(value) {
if (!value) {
updateValidity(false);
return;
}
inputLength(value);
var state = value.length > attrs.myCustomLength;
updateValidity(state);
}
function inputLength(value) {
ctrl.maxlength = null;
var length = value.length > attrs.myCustomLength;
if (length) {
ctrl.maxlength = (value.length - attrs.myCustomLength).toString();
}
}
function updateValidity(state) {
ctrl.$setValidity('maxlength', !state);
}
} // end link
} // end return
});
CSS Here if you need it.
input.ng-invalid {
border: 3px solid red !important;
}
I have a column in a Kendo grid that I want to perform some specific logic for when rendering, and am using Angular. I have the grid columns set up using the k-columns directive.
After looking at the documentation, it seemed simple: I could add the template option to my column, define the function to perform my logic, and pass the dataItem value in. What I have looks something like this:
k-columns='[{ field: "Name", title: "Name",
template: function (dataItem){
// Perform logic on value with dataItem.Name
// Return a string
}
}]'
However, running this causes a syntax error complaining about the character '{' that forms the opening of the block in my function.
I have seen several examples of defining a template function in this format. Is there something else that needs to be done for this to work? Am I doing something incorrectly? Is there another way of defining the template as a function and passing the column data to it? (I tried making a function on my $scope, which worked, except I couldn't figure out how to get data passed into the function.)
Thank you for your help.
It appears that defining a column template in this fashion isn't supported when using AngularJS and Kendo. This approach works for projects that do not use Angular (standard MVVM), but fails with its inclusion.
The workaround that a colleague of mine discovered is to build the template using ng-bind to specify a templating function on the $scope, all inside of a span:
template: "<span ng-bind=templateFunction(dataItem.Name)>#: data.Name# </span>"
This is the default column templating approach that is implemented by Telerik in their Kendo-Angular source code. I don't know yet if the data.Name value is required or not, but this works for us.
Warning: Don't have access to Kendo to test the code at the moment, but this should be very close
In your case, you are assigning a a string to the value of k-columns and that string contains the the word function and your curly brace {
You need to make sure the function gets executed ... something like this:
k-columns=[
{
field: "Name",
title: "Name",
template: (function (dataItem){
// Perform logic on value with dataItem.Name
// Return a string
}())
}
];
Note the difference:
We create an object -- a real honest-to-goodness object, and we use an IIFE to populate the template property.
Maybe, it will be useful for someone - this code works for me too:
columns: [
{
field: "processed",
title:"Processed",
width: "100px",
template: '<input type="checkbox" ng-model="dataItem.processed" />'
},
and you get the two-way binding with something like this:
<div class="col-md-2">
<label class="checkbox-inline">
<input type="checkbox" ng-model="vm.selectedInvoice.processed">
processed
</label>
</div>
This can be done via the columns.template parameter by supplying a callback function whose parameter is an object representing the row. If you give the row a field named name, this will be the property of the object you reference:
$("#grid").kendoGrid({
columns: [ {
field: "name",
title: "Name",
template: function(data) {
return data.name + "has my respect."
}
}],
dataSource: [ { name: "Jane Doe" }, { name: "John Doe" } ]
});
More information is available on Kendo's columns.template reference page.
After hours of searching. Here is the conclusion that worked:
access your grid data as {{dataItem.masterNoteId}} and your $scope data as simply the property name or function.
Example
template: '<i class="fa fa-edit"></i>',
I really hope this safes somebody life :)
just use like my example:
}, {
field: "TrackingNumber",
title: "#T("Admin.Orders.Shipments.TrackingNumber")",
//template: '<a class="k-link" href="#Url.Content("~/Admin/Shipment/ShipmentDetails/")#=Id#">#=kendo.htmlEncode(TrackingNumber)#</a>'
}, {
field: "ShippingMethodName",
title: "#T("Admin.Orders.Shipments.ShippingMethodName")",
template:function(dataItem) {
var template;
var ShippingMethodPluginName = dataItem.ShippingMethodPluginName;
var IsReferanceActive = dataItem.IsReferanceActive;
var ShippingMethodName = dataItem.ShippingMethodName;
var CargoReferanceNo = dataItem.CargoReferanceNo;
var ShipmentStatusId = dataItem.ShipmentStatusId;
if (ShipmentStatusId == 7) {
return "<div align='center'><label class='label-control'><b style='color:red'>Sipariş İptal Edildi<b></label></div>";
} else {
if (ShippingMethodPluginName == "Shipping.ArasCargo" || ShippingMethodPluginName == "Shipping.ArasCargoMP") {
template =
"<div align='center'><img src = '/content/images/aras-kargo-logo.png' width = '80' height = '40'/> <label class='label-control'><b>Delopi Aras Kargo Kodu<b></label>";
if (IsReferanceActive) {
template =
template +
"<label class='label-control'><b style='color:red; font-size:20px'>"+CargoReferanceNo+"<b></label></div>";
}
return template;
}
I've looked around, found several resources labeled 'ng-placeholder' or something incredibly similar. I cannot get this to work:
<input type="text" placeholder="{{option.name}}" class="form-control" ng-switch-when="text" />
I've noticed there doesn't appear to be anything on the input documentation as well. I'm pretty new to angular, and this has done nothing but frustrate me for a few hours. There must be a way to do this.
Why not write your own directive for ng-placeholder? Something simple like this should work. You can call it in your html like this
<input ng-placeholder='test'>
Where test is a scope variable in the current controller.
.directive('ngPlaceholder', function($document) {
return {
restrict: 'A',
scope: {
placeholder: '=ngPlaceholder'
},
link: function(scope, elem, attr) {
scope.$watch('placeholder',function() {
elem[0].placeholder = scope.placeholder;
});
}
}
});
There exists a conditional attribute property in AngularJS ng-attr-{property_name}
For example, I'm using different placeholders for different search terms using
ng-attr-placeholder="{{isAdvanceSearch ? setPlaceholder(searchOption) : 'John Smith, 08/23/1970, 123'}}"
Here on the basis of isAdvanceSearch variable, I'm setting different placeholders in setPlaceholder method.
setPlaceholder method returns the placeholder to set in the input field.
$scope.setPlaceholder = function(searchOption) {
if (searchOption === "foo") {
return "Search by foo… e.g. foo1";
} else if (searchOption === "bar") {
return "Search by bar… e.g. bar123";
} else {
return "John Smith, 08/23/1970, 123";
}
};
Note: John Smith, 08/23/1970, 123 is the default placeholder.
Don't forget to wrap the expression in the {{}} brackets.