Removing ngModel from a component - angular-components

I have some components created for my angular application, and after upgrading my project to version 6 of Angular, I have received a message that worries me.
It looks like you're using ngModel on the same form field as
formControl.
Support for using the ngModel input property and ngModelChange event with
reactive form directives has been deprecated in Angular v6 and will be removed
in Angular v7.
For more information on this, see our API docs here:
https://angular.io/api/forms/FormControlDirective#use-with-ngmodel
This is due to my following component:
<input type="text" id="{{id}}" name="{{name}}" [formControl]="ctrl" [(ngModel)]="value" appPfMaskCpf="999.999.999-99" placeholder="{{placeholder}}"
class="form-control">
<div *ngIf="flagCpfInvalido && value.length > 0">
<small class="text-danger">
CPF inválido.
</small>
<br>
</div>
It is very simple, it receives an input and I check the value.
How can I remove the use of ngModel in this case?

You should not be using ngModel which is part of template-driven form inside a Reactive form.
In stead of setting values using ngModel you can set the value using formControlName: Ex:
<form [formGroup]="form">
<input formControlName="first">
</form>
Set this value in component: this.form.get('first').setValue('some value');
Or you can choose to silence the console warning for now:
imports: [
ReactiveFormsModule.withConfig({warnOnNgModelWithFormControl: 'never'});
]
To update your code before v7, you'll want to decide whether to stick with reactive form directives (and get/set values using reactive forms patterns) or switch over to template-driven directives.
More details are available in documentation

Related

What does the Thymeleaf tag "th:for" do?

Anyone know that "th:for" is in Thymeleaf? I know it's a simple question, but I can't find the answer online, even in the Thymeleaf documentation.
It is the Thymeleaf attribute equivalent of the HTML for attribute used by <label> elements. For example:
<div class="preference">
<label for="cheese">Do you like cheese?</label>
<input type="checkbox" name="cheese" id="cheese">
</div>
It is listed in the Thymeleaf documentation section 5.2:
There are quite a lot of attributes like these, each of them targeting a specific HTML5 attribute...
It's no different from most other HTML attributes which have a Thymeleaf version - you can use it with a Thymeleaf expression. If you don't need a Thymeleaf expression, just use the plain for attribute instead.

Difference between th:text and th:value in Thymeleaf

I just recently started using Thymeleaf through one of my projects. I have seen few examples where th:text=${example} is being used in some places th:value=${example}.
I have gone through the Thymeleaf documentation but couldn't find anything explicitly citing the difference, nor did any question on SO.
Any help would be really appreciated! Thanks.
th:value is modification of html attribute value.
For button, input and option elements, the value attribute specifies the initial value of the element
th:text is used for tag body modification.
div{background-color: lightblue; padding: 2px} // to highlight empty div
<!--th code: <div th:value="${value}"/></div> -->
<br/>Result th:value div: <div value="sometext"/></div>
<!--th code: <form><input th:value="${value}"/></form>-->
<br/>Result th:value form: <form><input value="sometext"></form>
<!--th code: <div th:text="${value}"></div>
Same as: <div>[[${value}]]</div> -->
<br/>Result th:text div: <div>sometext</div>
Here is docs of different Thymeleaf attributes features
Lets see an example:
<input type="radio" name="gender" value="male"> Male<br>
if we want to use thymeleaf in value portion of this input tag, then we will use,
<input type="radio" name="gender" th:value="${someValue}"> Male<br>
if we want to see the text (here Male) sent from the controller dynamically, then we use,
<input type="radio" name="gender" th:text="${someText}""> <br>
th:name => This would be the name of the value that you will be passing to another page (Exemplar scenario).
th:value => This would be the actual value that you would be passing. It could be obtained from a model or straight from the database explicitly.
<form th:action="#{confirm-pass-details.html}">
<button type="submit" th:name="event-id" th:value="${event.get().getEventid()}">Buy Passes</button>
</form>

Rails-Backbone Model save issue

This page is to edit the account information.
Template file,
<input type="text" id="account_name" class="form-control" placeholder="Enter Name" value="<%=account.name%>"/>
<input type="text" id="account_company_name" class="form-control" placeholder="Enter Company Name" value="<%=account.company_name%>"/>
<a id="account_next_btn" class="btn" role="button">Next</a>
view file,
events:
'click #account_next_btn': "updateAccount"
updateAccount: (e)->
e.preventDefault()
#account.save({"name": #$el.find("#account_name").val(),"company_name": #$el.find("#account_company_name").val()})
ok, this works fine. it sends the updated input form parameters.
the thing i'm curious is, there should be a better way, not setting the updated values manually like my code.
in rails backbone:scaffold it doesn't have this kind of code.
it just
#model.save()
that is all they do.
but in my code, if i just call
#account.save()
it sends the parameter, that not have been updated.
That’s because Backbone by default doesn’t include any kind of data binding library. Data binding lets you keep a model attribute synced with a form field value.
Backbone-Rails includes the simple backbone_datalink.js, which sets up a simple form binding when you create the scaffold.
There are many other binding plugins that work with Backbone, such as Backbone.ModelBinder and Rivets.js.

Property binding for element with contenteditable="true"

Property binding is working fine if I have an input in my template
<div id="textAreaDiv"><input type="text" value={{item.mainText}}></div>
but I would like to have an editable div
<div id="textAreaDiv" contenteditable="true">{{item.mainText}}</div>
Is that possible? Can't find anything in the documentation.
Seems not to be supported. You should file a bug/feature request.
https://code.google.com/p/dart/issues/list

knockout validation with typeahead combobox plugin

I am trying to use Knockout Validation in combination with Bootstrap Combobox Plugin.
I have a select control that is bound to my observable property which has the required attribute (for KO Validation).
<select data-bind="attr: { options: TypeAheadSource, value: XYZ, validationOptions: {errorElementClass: 'input-validation-error'}, typeaheadCombobox: {}"></select>
I have a custom binding associated with the select control in which I basically just call the Bootstrap Combobox Plugin. That creates a Div with an input control over the select control and hides the select control.
The knockout validation fires up when I dont select a value in the comobox and shows the error message next to the control BUT the field is not highlighted. Here is how it looks like
As you can see, the error message shows up but the input field is not highlighted.
Here is the final html that is generated when the validation fires.
<div class="combobox-container">
<input style="position:static;" type="text" autocomplete="off" data-bind="{ value: Name, validationOptions: { errorElementClass: 'input-validation-error' }" class="input-large">
<span class="add-on btn dropdown-toggle" data-dropdown="dropdown"><span class="caret"></span>
<span class="combobox-clear"><i class="icon-remove"></i></span></span>
<select data-bind="validationOptions: { errorElementClass: 'input-validation-error' }, options: TypeAheadSource, value: Name, typeaheadSimpleCombobox: { }" class="combobox input-validation-error"></select>
</div>
As you can see, the select control (which was hidden by the plugin) gets the validation error class I defined ('input-validation-error') but the input control created by the plugin does not.
That is the main issue here.
So, I thought it could be becasue the input control is not directly bound to the property. So, I tried adding the same value binding as the select control to the input control created by the plugin inside the custom binding. I also added the validationOptions binding. These changes didnt work either.
Strange thing is I also have a typeahead textbox bound to another property which uses a similar design (custom binding to create the typeahead plugin over an input control) and the validation + highlighting works perfectly on that. Here is the final html from that.
<input type="text" data-bind="value: xyz, validationOptions: { errorElementClass: 'input-validation-error' }, typeaheadTextBox: { source: $data.TypeAheadSource }" class="typeaheadValue input-mini" data-provide="customtypeahead" autocomplete="off">
Could someone tell me if I am missing any additional steps. I am sure you might need more details.
Please leave a comment and I will try to add more details.
Thanks.
I figured the issue. In case someone has the same issue, here is what I did.
Even though I setting up the value bindings on the input control created by the plugin, the bindings were applied before the control is created and so, I had to reapply the bindings specifically on the input control created by the plugin. That did the trick for me.

Resources