Is ng-pattern possible on contenteditable elements? - angularjs

Can't seem to find any info on this. Is it possible to use ng-pattern on a contenteditable div? When I try it doesn't work:
<div contenteditable="true" ng-model="x.number" ng-pattern='/^(\d)+$/'>{{ x.number }}</div>
More specifically, the ng validation classes on the div element do not change when I type invalid entries.

In case anyone is wondering, I ended up adding a validation function in my controller on 'keyup' action like so:
element.bind('keyup', function(event) {
if(element.hasClass("ip-input")){
var validPattern = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
var result = validPattern.test(element.html());
if(result == true) {
element.removeClass("invalid-input");
element.removeClass("valid-input");
element.addClass("valid-input");
}
else {
element.removeClass("valid-input");
element.removeClass("invalid-input");
element.addClass("invalid-input");
}
}
});
This validates that an IP address field is valid.
Cheers

Related

is it possible to use a variable filter?

I'm trying to use filter who gonna change depending on a click or write on an input.
<input
name="hotelinput"
type="text"
ng-keydown="changeFilterToKeyPressed()"
ng-click="changeFilterToClicked()">
<div ng-repeat="hotel in filteredHotels = (hotels | VARIABLEFILTER | orderBy: 'country') track by $index">
...
</div>
I know that you can do filter:variable and change it in the controller but I need to change the full filter for one of my custom filters every time.
I didn't tested it but something like this could be possible
JS
if(x){
$scope.VARIABLEFILTER = $filter('myCustomFilter')
} else {
$scope.VARIABLEFILTER = $filter('myCustomFilter2')
}
I made it to work and rewrote the filter I once did in other question
http://plnkr.co/edit/LuA3hYr7mImihYnVIxqQ
.filter('applyFilter', function($filter) {
return function(input, filterToApply) {
return filterToApply === undefined ? input : $filter(filterToApply)(input)
}
})
I hope that's what you were looking for
You need ngChange instead of ngClick
<input
name="hotelinput"
type="text"
ng-model="filterKey"
ng-change="changeFilterToKeyPressed()"
ng-focus="changeFilterToClicked()">
and update your function changeFilterToKeyPressed
$scope.changeFilterToKeyPressed = function() {
$scope.VARIABLEFILTER = someUpdatesWhichYouWant($scope.filterKey); //You can use filterKey on any change
}

How to add css class dynamically to input type html element in angular js controller function?

Requirement: Create a generic controller function in Angular JS that will cater to all the input types.
What you want then is to:
add the filled css class when the form field has a value, and
remove the filled css class when the form field doesn't have a value
do both of the above using a reusable function in an angular controller.
You can achieve this using Angular's built-in ng-class directive:
HTML:
<input
id="renewccCVV"
type="number"
class="form-control"
ng-class="isFilled(RenewCard.cvv)"
ng-model="RenewCard.cvv"
maxlength="4" />
JS:
$scope.isFilled = function(value){
return (!!value) ? "filled" : "";
}
Example Plunk
Add the below code to Angular js controller.
'filled' is the css class that I want to make use of. I am passing the $event from my ng-blur event in HTML input control.
$scope.addCssClass = function (event) {
if (event !== null && event.target !== null) {
if (event.target.value !== "") {
if (event.target.className.search('filled') < 0) {
var classes = event.target.className;
classes += ' filled';
event.target.className = classes;
}
}
else {
event.target.classList.remove('filled');
}
}
};
Here is the snippet of HTML code.
<input id="renewccCVV" type="number" class="form-control" ng-blur="addCssClass($event)" ng-model="RenewCard.cvv" maxlength="4" />
If my input control has value and css class 'filled' is not added to ng-class , then add the css class, if the input already has css class and value is not null, do not add the class. When the value from input control is removed, then remove the css class from the classList.

angular material md-autocomplete remove md-floating-label attribute not working

I have the following code when using the md-autocomplete directive in angular-material. I want to remove the md-floating-label entirely from the element if the acType != FORMULA:
html:
ng-attr-md-floating-label="{{ autocompleteFloatingLabel }}"
JS:
scope.autocompleteFloatingLabel = false;
if (scope.acType == Constants.Autocomplete.FORMULA) {
scope.autocompleteFloatingLabel = 'Add a formula here ';
}
I have tried setting the autocompleteFloatingLabel to undefined instead of false I have also tried remove the brackets in the HTML template. Nothing seems to work. I know that the scope.acType is evaluating to the proper value, but md-floating-label seems to still be there when it shouldn't be.
You could try something like this:
Give id to your autocomplete as 'autocomplete_id'
JS:
var elem=angular.element('#autocomplete_id');
elem.find('label').html('');
if (scope.acType == Constants.Autocomplete.FORMULA) {
elem.find('label').html('Add a formula here');
}

How can I make it so only an empty state or a drop target placeholder of ui-sortable show?

I have two connected ui-sortable lists. When one of the lists is empty, I need to show a message; when that empty list is hovered while dragging, I need to show a styled drop target and hide the empty list message. I was able to program the vast majority of this code and here is a simplifed Codepen of it working.
The bug is that when you drag from the populated list over the empty list and then out again, the empty list shows both the empty list placeholder and the styled drop target. Here is a screen capture:
The root of the problem appears to be in way I calculate if the list is empty for the sortableList directive:
scope.isEmpty = function() {
if (!scope.attachments) {
return true;
} else if (scope.dragDirection === 'drag-out' && !scope.hovered) {
return scope.attachments.length <= 1;
} else if (scope.hovered) {
return false;
} else {
return scope.attachments.length === 0;
}
};
Note that I am keeping track of the state on the scope and using $apply to ensure the DOM updates like so:
function onDragStart() {
scope.$apply(function() {
scope.dragDirection = 'drag-out';
});
}
function onDragStop() {
scope.$apply(function() {
scope.dragDirection = '';
});
}
function onDragOver() {
scope.$apply(function() {
scope.hovered = true;
});
}
function onDragOut() {
scope.$apply(function() {
scope.hovered = false;
});
}
Here is the html for the directives template:
<div class="drop-target" ui-sortable="sortOptions" ng-model="attachments">
<div ng-repeat="attachment in attachments" class="attachment-box">
<span class="fa fa-bars pull-left drag-handle"></span>
<div class="link-attachment">
<a href ng-href="{{ attachment.fileUrl }}" target="_blank" class="attachment-name">{{ attachment.name }}</a>
<div class="extra-info link-info">{{ attachment.fileType }}</div>
</div>
</div>
<attachment-empty-state ng-show="isEmpty()"></attachment-empty-state>
</div>
The dependency list is quite long for the codepen to work, I simplified the code from actual production code and eliminating the dependencies would have made the custom code quite substantial. Here is a list of the dependencies if you want to try to get it running yourself: jquery, jquery-ui, angular, bootstrap, lodash, and sortable from angular-ui. There is some font-awesome in there as well.
I think I solved the problem. Here is a codepen with the solution.
Basically, the problem was that the dragout event was being (correctly) fired when your cursor dragged the item out of a sortable-list, but the placeholder would stay in the sortable-list until you dragged it into another sortable-list. So in that in between time, both the attachment-empty-state element and the placeholder would be shown in the sortable-list.
Here are the lines that I edited in the code:
Less file:
attachment-empty-state {
...
// hide empty state when the placeholder is in this list
.placeholderShown & {
display:none;
}
}
JS:
//Inside sortable-list
// Helper function
function setPlaceholderShownClass(element) {
$(".drop-target").removeClass("placeholderShown");
$(element).addClass("placeholderShown");
}
...
function onPlaceholderUpdate(container, placeholder) {
setPlaceholderShownClass(container.element.context);
...
}
If you don't like using jQuery to add and remove classes globally, you could use $rootScope.$broadcast("placeholderShown") and $rootScope.$on("placeholderShown",function() { // scope logic }. I figured a little jQuery is less complex, even though it isn't pure Angular.

how to stop bind in angularjs

I hava a checkbox ,the model status.useJoin also bind the div.
<input type="checkbox" ng-model="status.useJoin" ng-click="toggleJoin($event);" >
<div ng-if="status.useJoin"> show area</div>
when status.useJoin is true ,will show div.
My question is ,when I want to prevent the default action of the checkbox. I will write function toggleJoin like this.
$scope.toggleJoin = function (dimension,$event) {
if (status.useJoin) {
$event.preventDefault();
return;
}
}
the checkbox action is stopped ,but status.useJoin is still modified. How can I stop the bind?
You can use ng-disabled directive
<input type="checkbox" ng-model="status.useJoin" ng-disabled="onYourDisableCondition();" >
$scope. onYourDisableCondition = function () {
if (status.useJoin) { //Add your additional conditions
return true;
}
}

Resources