Using ng-disabled on a directive - javascript

I am wondering if the following is possible:
<directiveName parameter1=value1 parameter2=value2 ng-disabled="true"> </directiveName>
For some reason, it wasn't working for me and I wasn't able to find much examples of a use like this.
I can, however, toggle the visibility of the directive using this:
<directiveName parameter1=value1 parameter2=value2 ng-if="true"> </directiveName>
Why can't I seem to use ng-disabled?
(The purpose of the directive is to make a connection with a topic and display the messages in the topic, so all it outputs is plain text.)

As per the documentation for ngDisabled:
This directive sets the disabled attribute on the element if the
expression inside ngDisabled evaluates to truthy.
But in your case, it seems ngDisabled will be adding a disabled attribute to an element that does nothing with it.
'disabled' only makes logical sense for elements that allow user input or interaction. Out of the box, it works for form inputs, anchor tags and buttons. If you require 'disabled' behaviour for other things then you need to provide it yourself.

Related

How to tell if a React web-component button is disabled in Cypress?

We're in the process of replacing our custom react components with components from the company's design system.
These are web-components and it has been made a react-wrapper to make them work in React.
The element is rendered like this in our app:
<custom-button title="" data-test-id="save" disabled mode="primary">
#shadow-root
<button data-mode="primary" size="small" type="button" title="" disabled>Save</button>
</custom-button>
In Cypress I have tried to check if it is disabled like so:
cy.getByTestId('save').should('be.disabled'); //Doesn't work, but its the way I want to do it
cy.getByTestId('save').find('button').should('be.disabled'); // Works
The first way doesn't work but its the way i want to do it because thats how all our tests work today.
I want to having having to do the second way because that means we have to handle buttons from our design-system different from regular buttons.
Does anyone know why the first way doesnt work? Even though the <custom-button> has the disabled attribute applied to it in the DOM?
The difference is between attribute and property.
Under the hood cy.getByTestId('save').should('be.disabled') is checking that the element has property disabled. The standard button translates the attribute disabled into a corresponding property, so it passes the above assertion.
The custom button obviously does not have that behavior, so it might be difficult to treat custom-button the same as button.
One thing that works for your sample is
cy.getByTestId('save').should('have.attr', 'disabled')
This should work for all occurrences of custom-button (if my assumption about it's behavior is correct).
If you have trouble with standard button, you can check both:
cy.getByTestId('save').should($el => {
return $el.attr('disabled').length > 0 || $el.prop('disabled').length > 0
})
You can make a custom assertion if that's a pain to code everywhere.
IMO using .find('button') isn't optimal, since it's an internal implementation of the custom-button.
As the comments state, you only retrieve the custom-button element and not the button, which has the disabled attr.
The working solution is fine.
cy.getByTestId('save').find('button').should('be.disabled')
cy.getByTestId('save').contains(/save/i).should('be.disabled') // find based on text instead
You can check if in your design-system repo if a data-testid can be passed to the component or add the change yourself, which could be a more cumbersome process.

Clearing fieldGroup's fields when hidden

I need to clear all fields when they are hidden by a hideExpression, right now i have some code that adds a watcher to fields, and clearing them if they are hidden.
Problem is that this doesnt work for hideExpression's used on fields with fieldGroup's, since its apearently not allowed to add watcher to that type.
My example might explaine the issue better:
http://jsbin.com/fodijeziyu/1/edit?js,output
If you fill in the values, and click the hide checkbox, they should clear the model/view on the fields that gets hidden.
Generally on angular I would think different ways of doing things so that I won't be using watchers. It decreases performance a lot (and yes that sometimes might mean to use jQuery for it).
Now for angular-formly a way of doing what you want would be to use a function for hideExpression and achieve what you want.
Here is a working example.
Also read this link on the official angular-formly documentation.
There's an example on the website for this: http://angular-formly.com/#/example/very-advanced/remove-property-on-hide
You could use the watch with the true flag, in conjunction with your hideExpression:
$scope.$watch('someMiscForm', function() {
console.log('The model has changed!');
}, true);
Then alter/reset the fields you are interested in.

Is there any configuration option in Parsley.js that allows you to not add the parsley-success field to an input if you want to ignore it altogether?

I'm already excluding one input, and it adds the success class (which I don't mind)
$('form').parsley({ excluded: '[data-parsley-sum-total="all"]' });
but there are a number of other inputs that have no validations on them, and I don't want the 'parsley-success' class added on submit. If I add them to the list of excluded inputs, it still shows the 'parsley-success' class after submission. I'm just removing them manually right now on submit, but is there an option to not give them the class in the first place?
Using parsley 2.0.7
Thanks in advance for any help.
Edit:
In case this helps, my inputs I'd like to have the validation show up on are all in a single div like so:
<form id="f">
<input>
<input>
<div id="d">
<input>
<input>
</div>
I'd like to do something like $('#d').parsley() but that obviously doesn't work.
Also, besides using parsley excluded like I mentioned above, using data-parsley-group="" doesn't work for me either, both just exclude from validations, but don't solve the parsley-success problem for me.
Interesting point, it should be easier.
It's not too hard to get what you want though. You can listen for parsley:field:validate event, and toggle a class "no-constraint" depending on if it has constraints or not. A simple tweak to your CSS file will give the result you want.

How can I exclude controls from making form Dirty?

I'm using this: $('form').dirtyForms(); from https://github.com/snikch/jquery.dirtyforms to check if my form is dirty. However, on my page I have some dropdown's that are simply used for filtering (they should not make my form "dirty"). Right now when I select any of these drop down's it causes my form to become dirty. Using jquery.dirtyforms (I read their docs but do not see how), how do I exclude selectors (dropdowns, textboxes, etc.) maybe via a class name so that they do not mark the form as dirty.
I tried various things like assigning these dropdowns / filters a class called ignoreDirty then in my jquery I did this:
$('form').dirtyForms().ignoreClass('ignoreDirty');
This produces an error, so I must be doing something wrong.
Note I've also tried setting it via property:
$('form').dirtyForms({ ignoreClass : "ignoreDirty" });
But this still makes my form dirty for any control whose class name is still ignoreDirty
Please note these filters cause postbacks but lets say I go to my form and have not made a single change. I start clicking on these filters and the minute they post back this happens:
What can one say, the plugin code makes almost no sense to me :D However to make it quickly work for ignoring select boxes, you could replace its onSelectionChange with following
Original function
var onSelectionChange = function() {
$(this).dirtyForms('setDirty');
}
New version
var onSelectionChange = function () {
//this is the new line. self explanatory
if ($(this).hasClass($.DirtyForms.ignoreClass)) return;
$(this).dirtyForms('setDirty');
}
After this you should rely on the original developer for a proper fix. I just posted this as an answer because of space in comments
There seems to be 2 different issues here.
First of all, you are attempting to set the ignoreClass to ignoredirty. ignoredirty is the default value, so there is no reason to set it. However, if you do need to set it to something else, you can do so using the syntax:
$.DirtyForms.ignoreClass = 'my-ignore-class';
Secondly, in version 1.0.0 the ignoreClass only worked on Hyperlinks. This behavior has been amended to work with input and selection elements in version 1.1.0.
In version 1.2.0, you can now also set the ignoreClass to parent container elements to ignore input or clicks from any element within.

Update select "the Angular Way"

I'm trying to manipulate a <select> tag so that it has a different text colour depending on whether the default, disabled <option> is selected or a valid option.
My guess was to put an ng-change directive and pass it an update function, but I don't know what flags I can pass to my function... The documentation is pretty useless to me.
Here is my jsFiddle: http://jsfiddle.net/33QFj/2/
As a rule, don't mess with DOM changes and manipulations anywhere except in a directive.
Hence, you have 2 options:
1) Create a directive to do DOM manipulations to your select.
2) Use ng-class to change the class according to some logic.
Here's your example with using the ng-class:
http://jsfiddle.net/WkFR8/
I changed your code a bit:
<body ng-app="myApp">
<div ng-controller="TestController">
<select ng-model="val" ng-options="opt.name for opt in options" ng-class="{two: val}">
<option disabled value="">Default</option>
</select>
</div>
Note the ng-class I've added. I'm assuming you wanted the text to be blue if we choose anything in the drop down except default.
What the ng-class did was to check if val has something in it (e.g. not 0, not null, not "" etc.) and this rule is satisfied when we change the select value. In this case, the class "two" is added to the element.
I think ng-class is what you are looking for.
Try this: http://jsfiddle.net/rBQu9/1/
After further investigation, I discovered another possible solution particular to this problem.
Since Angular will set classes to the form as defined here, I can use these classes for styling.
So, when a user selects anything other than the disabled default, I know that I can look for the ng-dirty class and style it like that.
Example: http://jsfiddle.net/33QFj/3/

Categories