Material Autocomplete field validation in Angular 5 - angular5

We are developing our Angular 5 application using Angular material. we have 2 set of 4 similar autocomplete type fields. We have implemented using Material AutoComplete fields.
the first set of 4 fields are used to fetch the customer details. the second set of fields fetches the customer details but the visibility of the second set is optional controlled by a checkbox. The functionality was working fine. But when I implemented force selection by means of tag:MatAutocompleteTrigger subscribe the first set of fields are working fine. Whereas for the second set of fields on load should be invisible only while the checkbox is checked, the second set of fields will become visible.
Due to which there is an error, I am placing the code snippet where the error occurs. I am just showing here for one field altCustomerName with the id altCustomerNameId. I tried to make this id value to true on tag:ngOnInit and set to false on tag:ngAfterViewInit. But that also ends up in error.
HTML (view)
<mat-form-field>
<input placeholder="Customer Name" type="text" #altCustomerNameId matInput [formControl]="altCustomerNameControl" [(ngModel)]='selectedAltCustomerName' [matAutocomplete]="altCustomerName" required>
<mat-autocomplete #altCustomerName="matAutocomplete" class='customerDetails'>
<mat-option (click)="setAltCustomerDetails(altCustomer)" *ngFor="let altCustomer of filteredAltCustomersByName | async" [value]="altCustomer.name">
{{ altCustomer.custnum + ' ' + altCustomer.name + ' '+ altCustomer.countryname }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
Component code: (Inside the class the altCustomerNameControl is declared)enter code here
#ViewChild('altCustomerNameId', {
read: MatAutocompleteTrigger
})
altCustomerNameTrigger: MatAutocompleteTrigger;
..
....
....
ngAfterViewInit() {
this._subscribeToClosingActions();
}
ngOnDestroy() {
....
if(this.altCustomerNameSubscription &&
!this.altCustomerNameSubscription.closed)
.....
}
this.altCustomerCodeSubscription = this.altCustomerCodeTrigger.panelClosingActions.subscribe(
event => {
if (!event || !event.source) {
this.altCustomerNameControl.setValue('');
this.altCustomerCodeControl.setValue('');
this.selectedAltCustomerName = '';
this.selectedAltCustomerCode = '';
this.selectedAltCustomerCountry = '';
}
},err => this._subscribeToClosingActions(),
() => this._subscribeToClosingActions()
);
Please let me know if you need any clarifications in the code.

We have used *ngIf to show or hide the section based on the checkbox selection. Modified the same using [style.display] as in below code solved the above issue.
Old code: (This controls the section visibility)
<div class="row" **ngIf='optAlternativeCustomer'*>
New code: (Modified the section visibility as below)
<div class="row" *[style.display]="!optAlternativeCustomer?'none':'flex'"*>

Related

How to reset the values of an input and select in VUE?

I have an input and a select in my VUE application that are shown depending on the selection of a previous input.
If I insert values and change the initial input selection, I hide the second input and select, to restart the form.
The problem comes when I restart the form and I still get the selected values on the first load.
I'm trying to reset the values but none of the methods I've found in similar case reviews works fine.
Here's my select and my input that i want to reset values
<h1 v-if="this.isSelected"> What's your selection ?</h1>
<select
ref="item"
class="form-control"
id="selectedItem"
v-model="itemFormInfo.selectedItem"
#change="onChangeItem($event)">
<option v-for="item in filteredItem" v-bind:key="item.name">{{ item.name }}</option>
</select>
<div v-show="this.isItemSelected">
<h1>what's your item name ?</h1>
<input
type="text"
id="name"
ref="itemName"
class="form-control fields"
style="text-transform: capitalize"
v-model="itemFormInfo.name"
#keypress="formChange($event)"
/>
<div class="loader-spinner" v-if="loading">
<app-loader/>
</div>
</div>
and here's my method where I have tried the reset and document.getElementById('').value("") methods;
onChangeSpecie(event) {
let specie = event.target._value;
this.specieName = this.getSpecieName(specie);
this.breedName = this.getBreedName(specie);
this.$refs.breed.focus();
if (this.isBreedSelected = true) {
this.isBreedSelected = false;
this.isNameCompleted = false;
this.isLoaderFinished = false;
this.$refs.animalName.item()
}
},
If I print by console I see how the value is emptied but the input appears with the written value until I focus on the .
How do I stop it from appearing?
in neither method does it erase my previous values showing on the input.
what am I doing wrong?
thank you all for your help and time in advance
I believe you need to null the model not the target element's value.
this.itemFormInfo.name = null

Set v-checkbox programmatically using Vue and Vuetify

I'm building a list of v-checkboxes using this code
<div class="row form-group" v-for="(author, key) in authorData" :key="key">
<v-layout row wrap>
<v-flex xs1 sm1 md1 text-xs-center>
<div>
<v-checkbox
label
:key="author.PmPubsAuthorID"
v-model="authorData[key].checked"
v-bind:id="author.PmPubsAuthorID.toString()"
color="success"
#change="authorCBClicked(authorData[key])"
></v-checkbox>
</div>
The PmPubsAuthorID is a number like 1047602 and is a sequential number in the entire database, no 2 records are the same. When I run the code to build the list it works fine and shows a checkbox if the value is true. What I am trying to do is when a checkbox is checked in the
authorCBClicked(author) {
//PmPubsAuthorID = 1047602
// alert(author.PmPubsAuthorID + " " );
// author.checked = false; does not work
this.authorData[author.PmPubsAuthorID].checked = false; does not work
this.authorData["1047602"].checked = false; does not work
this.authorData[1047602].checked = false; does not work
this.authorData[2].checked = false; does work
},
As you can see I have tried various ideas and the only one that seems to work is passing in an ordinal but I have no way of knowing that. Do I need to use an index when building the checkboxes?
The reason: I have a checkbox then when checked calls a dialog box that asks " Are you sure you want to "Add this item to the list" if they say yes I want the original checkbox to be checked but if they say no then the original checkbox needs to be false. I have found that if I try to set the checked status of the calling checkbox to false it does not work but works fine once outside that method. I have passed the key and author information to the new dialog and let it change the checkbox to false if needed
Thanks for the help.
Just pass the key instead of the whole item to your method :
#change="authorCBClicked(key)"
and on your method :
authorCBClicked(key) {
this.authorData[key].checked = !this.authorData[key].checked;
}
Or :
you can do it directly on the template :
#change="author.checked = !author.checked"

Selecting specific element in vue 2 inside v-for loop

Please see the code
<div v-for="msg in leftMsg">
div v-if="msg.last_sender" #click.prevent="loadMsg(msg)">
<tr :class="['active',{ 'seens' : !msg.seen, 'selected':msg.isActive}]">
// some html
</tr>
</div>
</div>
loadMsg(obj){
obj.isActive = !obj.isActive;
}
The problem is, it is adding selected class properly but when I click another item it adds selected but doesn't remove the old one. How can I keep only the most recent clicked item selected?
Thank you.
Add a data property outside of the msg objects and use that to track the active message.
data(){
return {
activeMessage: null,
...
}
}
Then in your template, set the activeMessage.
<div v-for="msg in leftMsg">
<div v-if="msg.last_sender" #click.prevent="activeMessage = msg">
<tr :class="['active',{ 'seens' : !msg.seen, 'selected': msg === activeMessage}]">
// some html
</tr>
</div>
</div>
The key parts I changed here are #click.prevent="activeMessage = msg" and 'selected': msg === activeMessage. This will set activeMessage to the clicked message, and then the selected class will be applied to the activeMessage and will only apply to the activeMessage.
I would also note that it's strange that you have a tr element nested inside div. I assume it was just because of your example, but that's not technically valid HTML.
I have solved this issue using a for loop. I thought it may help some other.
In order to remove the all other previous active classes all you need to run a for loop and make them false and then assign active=true to the newest one.
Here is the code that may help
// make all other selected class false first
for(let i=0; i<this.leftMsg.length; i++){
this.leftMsg[i].isActive=false;
}
/*now making the newest one active*/
obj.isActive = true;

Aurelia Validation on Select List

I have a simple select list in my Aurelia view which I'm trying to set a default value on of 'Select...'. I'm also using the aurelia-validation plugin to ensure that the value is changed before the form is submitted. The plugin works great for other field types in my project.
<div class="form-group">
<label for="agencies" class="control-label">Agency</label>
<select value.bind="agencyId" class="form-control">
<option value="">Select..</option>
<option repeat.for="agency of agencies" value.bind="agency.id">${agency.name}</option>
</select>
</div>
In the VM:
constructor(validation) {
this.agencies = null;
this.agencyId = 0;
this.validation = validation.on(this)
.ensure('agencyId')
.isNotEmpty();
}
activate() {
//call api and populate this.agencies
}
After the page initially loads I get my agencies in the list and my default value is correct, but it shows the validation error message:
Other form fields, like text boxes don't do this and show no error message until the user interacts with the form controls.
Is there something special I need to do for a select list to hide validation errors on the initial loading of the view? I suspect that binding the select list in the view is somehow triggering a change event.
Thanks to a kind Aurelia user on Gitter, the problem was solved by setting the initial value of this.agencyId to "". Originally I had the this.agencyId = null. That was my mistake. Because it was null and not "" (as was the default value in the select list) the values didn't match so the select list was invalid when the view loaded. At least, that's my understanding.
The lesson is, if you want to validate a select list, make sure you VM property is initialized to the same value as your select list's default value.
constructor() {
this.agencyId = ""; **//must match the bound property's initial value**
}
And in the view:
<div class="form-group">
<label for="agencies" class="control-label">Agency</label>
<select value.bind="agencyId" class="form-control">
<option value="" **<!-- this value must match the VM initial value -->** selected="true">Select...</option>
<option repeat.for="agency of agencies" value.bind="agency.id">${agency.name}</option>
</select>
</div>

Pass text box value to a dojo grid's query parameter

I am trying to pass the value in a text box as a query parameter in a dojo data grid and would like to get clarified on two questions listed below. The dojo grid initiates a call to the server with the query params to initiate a search and bring back results (that is diplayed on the data grid)
Is it possible to reload the gird based on the value in the text by invoking refresh (dijit.byId("mygrid").refresh
If yes, how can I pass the value of the text box as a query parameter to the data grid.
Listed below is my relevant code
function reload(){
dijit.byId("mygrid").refresh;
}
<div class="test">
<input id="searchParam" >
<button dojoType="dijit.form.Button" type="submit" onclick=reload()>
Search
</button>
</div>
<div dojoType="dojox.grid.DataGrid"
id="mygrid"
jsid="mygrid"
store="dojox.data.JsonRestStore"
target="<c:url value='members' />">
query="{
searchCriteria: ? TODO How to pass value of text box here?,
}"
rowsPerPage="1000"
autoWidth="true"
autoHeight="true"
selectionMode="single"
selectable="true"
errorMessage="Error loading data"
noDataMessage="<span class='dojoxGridNoData'>No members found.</span>">
</div>
You should be able do something like the following:
function reload() {
var val = dojo.byId('searchParam').attr('value');
dijit.byId("mygrid").setQuery({ propName: val });
}
You will need to properly build the query { propName: val }.