Clearing fieldGroup's fields when hidden - javascript

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.

Related

How to make dirty or touched input programmatically in Angular2?

I needs to use one jquery plugin with Angular2.In General terms, this plugin creates a copy of a piece of html, which has inputs.When data changes, angular2 rerenders it with all the errors etc.But Jquery must pass data back to angular2 when something changes.I did it through the
ControlGroup.controls['control_id'].updateValue(value,{emitEvent,emitModelToViewChange}).
All is well,data comes.But angular2 input in which jquery passes data doesn't become dirty or touched, but I need it to display errors.How to force the input to be touched or dirty? Thanks in advance.
P.S: I know that all this is bad, but I have no choice
There is a pull request to make these properties available https://github.com/angular/angular/pull/7288/files
Currently it is marked
- touched when the input emits the blur event
- changed when the input emits the input event
These events probably vary between different types of input controls.
See also https://github.com/angular/angular/blob/master/modules/angular2/src/common/forms/directives/default_value_accessor.ts
I would use the updateValueAndValidity after calling the updateValue one:
var ctrl = ControlGroup.controls['control_id'];
ctrl.updateValue(value,{emitEvent,emitModelToViewChange});
ctrl.updateValueAndValidity();

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.

Is there a way to close the dropdown menu for typeahead.js?

I'm using typeahead.js for a typeahead.
I basically want to do the reverse of this: Programmatically triggering typeahead.js result display
I've tried to do a .trigger('blur'); on the typeahead, but I set the value right before that by doing .typeahead('setQuery', value);. Doing 'setQuery' fires off an ajax request to fetch results with the new query term. So the "blur" takes place, but the box is opened soon thereafter.
The proper way to do this, as of version 0.11:
$('.typeahead').typeahead('close');
Manual: https://github.com/twitter/typeahead.js/blob/master/doc/jquery_typeahead.md#jquerytypeaheadclose
Ref: https://github.com/twitter/typeahead.js/blob/master/doc/jquery_typeahead.md
$('.typeahead-input').typeahead('close');
Undocumented but there is way to set precondition and not allow dropdown to open:
$('.typeahead-input').on('typeahead:beforeopen', function() {
return false;
});
In case someone comes across this in the future, the best way to do this now is:
$('.tt-dropdown-menu').css('display', 'none')
If you open Chrome developer tools and watch what happens as you type and erase, this is all Typeahead is doing, nothing magical.
Besides, if you try with the current version (10.5) to set the query, you'll get an error that looks like this:
Uncaught TypeError: Cannot assign to read only property 'highlight' of
In my particular case the dedicated close method from typeahead API (typeahead.js#0.11.1) did not work. Maybe because of custom CSS or some bug in my code.
While the method described in the other answer of hiding the menu by setting the display property to none worked, I needed to set it then back to display:block to show it back for subsequent use. Plus it is not using the API.
Another better way for me was to clear the value of the input so the dropdown gets hidden:
$('.typeahead').typeahead('val', '');
or
$('#place_typeahead_control').typeahead('val', ''); in case you have multiple search controls on the page and you want to target a specific one.
You can trigger 'blur' in the "opened" event handler. If the drop down flickers for a moment, you can use CSS to hide it for the interim.
Instead of calling setQuery, add another function that doesnt do getSuggestions, and youll have a good time.

Single <select> has multiple selected options

My tag is a single-choice pulldown, the default behavior for a tag. I have three values in it, "No", "Yes", "All". I am trying to change the selected programmatically, as I have done a thousand times before, with the following code (I'm using JQuery 1.9.1):
$('#select').children(':selected').removeAttr('selected');
$('#select').children('option[value="yes"]').attr('selected', 'selected');
$('#select').children(':selected');
I don't even know how this is possible, but somehow, in Chrome 26.0.1410.65 running on 10.8.3, there will be two selected options. Only one of them will show in the UI, but the last line of code will return two elements.
This does work correctly in Firefox 16.0.2, so I am mystified. Does anyone know if this is a quirk of Chrome, or if this is correct behavior and it's just changed?
You can do this to select desired value
$('#select').val('yes');
Stop trying to manipulate properties using attribute methods! Older versions of jQuery let you do this, but newer ones won't.
$('#select').children(':selected').prop("selected",false);
$('#select').children('option[value="yes"]').prop("selected",true);
//$('#select').children(':selected');
Though .val() as pointed out by Mohammad Adil is a better way of handling this.
You should not use the selected attribute to change what option is selected. Instead, use the selectedIndex property of your dropdwn.
For instance, in your case you might want this:
document.getElementById('select').selectedIndex = 1;

Conditionally skip form fields from submission, Reduce URL clutter

I have multiple hidden form fields which store values about the the current view (e.g. if certain, normally hidden div's are visible etc.) to restore the layout when the form posts back.
The problem is that I'm always submitting all these hidden fields, even if they are in default, generating lots of unnecessary URL clutter in the process (e.g. http://www.example.com/view?ab=&ac=&ad= and so on).
I'd rather submit only the fields which are actually influencing the view (meaning, don't have a specified default value) so that the URL clutter is at a minimum.
I tried manually deleting/inserting input's but its a nightmare. Is there a better way to do this?
Using jQuery, you might just remove() those form elements before transmitting. Another way I could think of is to remove the name attribute.
$('form').bind('submit', function(){
$(this).children('input').each(function(){
if(this.value === this.defaultValue)
$(this).remove();
});
});
Try disabling them-
"Controls that are disabled cannot be successful." -- http://www.w3.org/TR/html401/interact/forms.html#h-17.13.2
Unless you have a reason for keeping these options in the URL, why not store those values in a cookie? In fact, this is often done on many sites. If you want to be more careful, the display options can be stored in a database for each user, but that's your choice.

Categories