Angular checkbox labels not firing change events - forms

i have implemented a group checkbox component as explained in this SO post:
Angular how to get the multiple checkbox value?
All is working well except i have one issue, the labels of the check boxes do not trigger change events, only the actual checkbox portion. In the plunker below, try clicking both the checkbox square and the label, both trigger the checkbox and update the data model but only the checkbox portion fires a change. I suspect its something to do with the transcluded value.
See this plunker
http://plnkr.co/edit/BAhzLYo9e4H8PdAt9lGR?p=preview
Code
<checkbox-group [(ngModel)]="selectedItems">
<checkbox *ngFor="let item of availableItems"
[value]="item"
(change)="onItemChange($event, item)">
{{item}}
</checkbox>
</checkbox-group>
<p>Selected items - {{selectedItems | json}}</p>

Use on click event listener instead of on change. like this
(click)="onItemChange($event, item)"

If you are using ngModel, you can also use the (ngModelChange) event.
I have some normal checkboxes <input type="checkbox"/>, and the (click) and the (change) events are never fired.
With (ngModelChange), it works (should also work with other tags than <input type="checkbox"/>, if they are using ngModel):
<input type="checkbox"
(ngModelChange)="selectAllForBatchImport($event)"
[ngModel]="areAllEntriesChecked"/>
The $event parameter will be a boolean if ngModelChange is fired from a checkbox (instead of e.g. a MouseEvent when using (click) or (change)).
By using ngModel and ngModelChange, you split up the banana-box [(ngModel)], so that you can do the change (and maybe additional work) yourself, instead of [(ngModel)], which does a "simple" ngModelChange-update by itself.

Related

ng-bootstrap datepicker popup placement not changing

I'm trying to use the placement option listed under input options for the NgbInputDatePicker.
I'd like to change the default bottom-left position of the popup datepicker, but when I try to use placement in the plunker example (https://ng-bootstrap.github.io/app/components/datepicker/demos/popup/plnkr.html) It doesn't change the position of the popup.
I've tried:
adding [placement]="top" inside of the input tag:
<input class="form-control" placeholder="yyyy-mm-dd"
name="dp" [placement]="top" [(ngModel)]="model" ngbDatepicker #d="ngbDatepicker">
I've also tried just placing it in the parent div:
<div class="input-group" placement="top">
<input class="form-control" placeholder="yyyy-mm-dd"
name="dp" [(ngModel)]="model" ngbDatepicker #d="ngbDatepicker">
but neither seems to change the pop up position. I'm new to Angular, so perhaps I just have the syntax wrong somehow? I noticed other input APIs in the documentation that seemed to be used in this fashion so I thought it might work...
I'm using ng-bootstrap 1.0.0-beta.2, and Angular 4.3.4.
Thanks.
The problem is that you are using a binding to an expression (top means expression in [placement]="top") while I think that your intention is to use "top" constant. You can solve it using one of the 2 methods:
placement="top" (preferred)
[placement]="'top'" (notice additional quotes around top)
When specified properly the placement option works perfectly fine as illustrated in this plunker: http://plnkr.co/edit/NCNmpm3tlxapH4jZS08F?p=preview

Lock/unlock form with toggle

I'm looking for a way to have a button toggeling the field of my form. When "locking" the form with the toggle button no data can be typed. When "unlocking" data should be allowed to be typed. What I want to achieve with this is simple avoiding users to accidentally type.
I found the code below and it works. Only problem is that it only applies to one input field. I want it to work on more that one.
<input type="checkbox" id="yourBox">
<input type="text" id="yourText">
<script>
document.getElementById('yourBox').onchange = function() {
document.getElementById('yourText').disabled = this.checked;
};
</script>
Mark the fields you want to disable with a CSS class, and then use jQuery to disable them.
jQuery - Disable Form Fields
If you want a pure Javascript solution, just repeat this line
document.getElementById('yourText').disabled = this.checked;
for each field.
Or, you can do something like this this: How to Get Element By Class in JavaScript?. Note that you can assign multiple CSS classes to the same field, so assign another class to identify those fields that need to be disabled.

Getting "Change" event for a text field whose contents is changed by jQuery

I've made some pretty checkboxes using some pretty simple jQuery
HTML
<span class="iconElement checkBox" id="update_Check"></span>
<input type="text" id="update" name="update" value="0" class="hidden savedData" />
JS
$('.checkBox').live('click', function (e) {
if ($(this).hasClass('disabled') != true) {
$(this).toggleClass('checked')
var thisValue = parseInt($(this).next().val());
var newValue = (thisValue - 1) * (-1); // enusures the output is either 1 or 0, [ (1-1)*-1=0 and (0-1)*-1 =1 ]
$(this).next().val(newValue);
};
});
This is simply a span with a nice CSS background sprite, which when clicked changes toggles it's "checked" class, adjusting the CSS sprite from a "Tick" to an empty box. At the same time it also changes the content of a text field (hidden by CSS class 'hidden') to a 1 or a 0 to indicate whether the box is checked.
It has to have this 1 or 0 as when the data is passed to the next stage I have to have a value, an unchecked checkbox sends no value.
This all works fine!
BUT... I also need to be able to detect the "change" event of the hidden text field.
This is to be controlled by the "savedData" class.
$('.savedData').live('change', function () {
// do stuff now we know this has been changed
});
I could of course include this within the "click" event in the code above, but that's not practical for the application.
It seems that the "change" even is only trigger by elements which are changed by the keyboard or mouse, anything changed by jQuery is not being flagged.
Initially I was using hidden input type and thought that was the issue, but have changed them all to text type now and the problem is still there!
Any tips?!
It seems that the "change" even is only trigger by elements which are changed by the keyboard or mouse, anything changed by jQuery is not being flagged.
Yes, that is correct. That is precisely how this works. Only changes made by the user trigger event handlers: programmatic changes do not. The only way to trigger them is to do so yourself:
$(this).next().val(newValue).change();
The .change() triggers a change event on the element, so the handler will be called.

Getting a value from a label at POST

There's a place into my screen that I populate a label with a specific string value after some interaction with my user during the runtime. I use javascript for that.
Is there anyway to get the value of this lavel with my controller after its POST method is activated ?
Thanks, guys !
Option #1
Put the value in an HTML <input> element with a name attribute? Might need to dress down
the input element, since it will look like a textbox.
Option #2
Mirror the value in a hidden input <input type="hidden" value="yourValue" /> inside the form you're posting.

Tapestry 5 zone inside a form

I have a form and inside it I have a country/city/etc selection.
The form is inside a zone.
When calling the onSelected for make the change of the country/city, when returning I loose the other form data. How can I keep it ?
I think a zone inside the form would help, but I am getting:
Form components may not be placed inside other Form components.
The Ubigeos type is just a component with other selects that are filled from the pais select
My .tml is
<t:zone t:id="datosPersonalesZone">
<form t:type="form" t:id="formulariodatospersonales" t:zone="datosPersonalesZone">
<t:errors/>
Sexo: <select t:type="Select" t:id="sexo" t:value="actual.sexo" model="sexo" />
PaĆ­s: <input t:type="Select" t:id="pais" model="paises" t:value="pais" t:zone="ubigeosZone"/>
<t:zone t:id="ubigeosZone">
<input t:type="Ubigeos" t:id="ubigeo_nacimiento" t:ubigeo="ubigeoNacimiento" t:zone="ubigeosZone"/>
</t:zone>
</form>
Regards !
You either have to submit a form and process country selection differently (i.e. only updating form contents by returning a block) or try using ideas from FormFragment component and TriggerFragment mixin (probably you can't use them directly but you can try extending them to support select components).
Personally, I go with first option - I have a "SubmitFormOnEvent" mixin and attach it to select-s in the form. Then I found that similar approach is demonstrated at http://jumpstart.doublenegative.com.au/jumpstart/examples/javascript/ajaxselect1 -> so you just can start with that example and update it to your needs.