Ionic 4 - Select not showing selected value set in controller - ionic4

Problem:
I have an ion-select and in the controller when the user does something, I populate the ion-select with 1 value and make that value the selected value. The ion-select does not show that the value has been selected, but the [(ngModel)] has the correct value. When I open the ion-select it shows the value in the list and it is selected, when selecting the value in the list again it goes over the ion-select label.
How can I populate the ion-select with a value and make the populated value the selected value so that it shows on the ion-select as a selected item?
Screenshots:
The Make has value of CHEVROLET but it does not show as selected by ion-select:
When tapping on ion-select, it shows the CHEVROLET as selected and CHEVROLET goes over the Make label:
HTML:
<ion-item>
<ion-label position="floating">
<span class="required">* </span>Make
</ion-label>
<ion-select [interfaceOptions]="global.compactAlertOptions" id="make" [(ngModel)]="global.valuation.vehicle.make" name="make" #makeRef="ngModel" required>
<ion-select-option *ngFor="let make of makes">{{make}}</ion-select-option>
</ion-select>
</ion-item>
<ion-label *ngIf="makeRef.touched && makeRef.invalid && makeRef.errors.required" class="error">Make is required</ion-label>
Controller:
Modal Controller (the Make gets set in a popup modal):
this.global.valuation.vehicle.make = this.vehicleDetails.VehicleMake;
Populate the ion-select options in parent controller:
this.makes = [this.global.valuation.vehicle.make];

This generally happens when the value in ngModel is set before <ion-select-option> options are loaded on the DOM.
You will have to explicitly delay setting the value to ngModel until the <ion-select> and options are loaded on the DOM.
You can achieve it by adding a setTimeout in your component file and assign the ngModel value in the callback of setTimeout.

It seems to me that this has to do with some custom css that you are using on the template. Since when you use floating for a select is exactly the same as when you use stacked, Since the select is going to expand on the ion-item anyway. This floating works best with ion-input.
In your case, if the option was not selected, the select should be empty and the label above it. but it is on the item furthermore on the baseline of the select. When you select the option it will show in the baseline on the select left aligned.
like this:
If you remove the floating you will see what I mean.
it should show like this:
It will be easier to understand the issue if you just provide the CSS bits that are messing with the alignment of the elements.
My guess is that you have some styles that only reduce the ion-item and don't deal with alignment and positioning of the inner elements.

Related

Vuejs - How to change the text inside {{ }}

I've been building a data table recently and stuck at somewhere. I want my columns to be clickable to be able to display the rows in ascending and descending orders. When they are being displayed in ascending orders I want to show my arrow_upward icon and otherwise I want to show arrow_downward icon. Here is what I have done so far...
data () {
return {
arrow_upward: 'arrow_upward',
arrow_downward: 'arrow_downward',
}
}
and by the way, here is my usage of my Material Icons...
<span class="table-icons">arrow_upward</span>
I tried this one first;
<span class="table-icons" v-if="col == sortColumn">{{arrow_upward}}</span>
Basically I say, if it's sorted by column, show the arrow_upward icon. And here is my problem. How am I going to change inside the {{ }} everytime the column is clicked. It should work like a toggle and the interpolation tags should change between arrow_upward and arrow_downward. How do I do that?
You could use the following conditional rendering :
<span class="table-icons" >{{col == sortColumn?'arrow_upward':'arrow_downward'}}</span>
and no need to define them as data properties.

How to apply conditional style to unchecked checkbox

We are running Vue 2.x with vuetify and trying to figure out how to set some conditional, custom styling for unchecked checkboxes on a table for viewing/creating/updating user permissions. The roles are defined something like this:
Role A View and Role B Edit are being added. The gray boxes are permissions that have not changed. This is working as desired.
The issue is that I can't figure out how to assign color/style/class to the unchecked boxes so that we can mark revoked permissions with an empty red checkbox so that if manage were unchecked the last row would look like:
We are using but have also tried css overrides on . We have tried using css classes, :color, :fill, :style but nothing is working to get the box outline red.
This is what we currently have and is working for the checked boxes:
<template v-slot:item.view.id="{ item }">
<v-simple-checkbox
v-if="item.view.id"
v-model="item.view.active"
:disabled="!edit"
:color="getCheckboxColorForRole(item.view)"
#click="updateRolesRow(item, 'view')"
>
</v-simple-checkbox>
</template>
where getCheckboxColorForRole compares the initial vs current state and returns the appropriate color to display.
What am I missing here?
can you please provide some code? basically this is style binding
per #Anatoly I looked into the scoped css again and was able to get it to work. But then made it a global css rule so that I can use the scss var for the color and apply this on other pages. This is what I ended up with:
<template v-slot:item.view.id="{ item }">
<v-checkbox
v-if="item.view.id"
v-model="item.view.active"
:disabled="!edit"
:color="getCheckboxColorForRole(item.view)"
:class="[{'group-role-checkbox-original-checked': item.view.originalActive}]"
:ripple="false"
#click="updateRolesRow(item, 'view')"
>
</v-checkbox>
Had to switch it to <v-checkbox> since the simple checkbox wasn't allowing me to add classes. Then I checked/unchecked a few times and noticed that the only change is that the gray--text class is removed when unchecked. So then I added this css rule:
.group-role-checkbox-original-checked i:not(.gray--text) {
color: $anchor-color !important;
}
If anyone knows of a better way to do this I would love to know.

Overwrite data-dojo-props for title attribute in dijit/TitlePane

I have created a TitlePane and wish to load data dynamically from a get method into the Title property. As of the current this all works. However, now when the data is loaded (4 separate types), its all getting mushed together. I wish to divide this received data evenly (25%) across the title.
For example:
<div id="tp2" data-dojo-type="dijit/TitlePane" data-dojo-props="title: 'I'm a TitlePane
Too'">
Click arrow to close me.
</div>
In this example the title is set to "I'm a TitlePane Too".
I wish to change the title so that each of the four words is evenly distributed across the title section of the pane. However there are no extra properties for doing this sort of thing.
Use the "set" method to set the new title.
E.g:-
<div id="tp2" data-dojo-type="dijit/TitlePane" data-dojo-props="title: 'I'm a TitlePane
Too'">
Click arrow to close me.
</div>
//For this above example, title is replaced as follows in JS
dijit.byId('tp2').set('title','New title');
Update: If this title pane is created dynamically without an ID, then get the widget object using the css query.
dijit.getEnclosingWidget(dojo.query(".dijitTitlePane")[0]).set('title','New title');
dojo.query(".dijitTitlePane") => will give array of all titlepane domNodes. From this chose the one you need. I chose at "0"th index i.e. 1st title pane node in the page.
Then I get the widget object of that domNode and then set the title.

dijit.form.Select won't set value programmatically

I have a dynamic dojo form in which I have a dijit.form.Select whose selected value I have tried to set dynamically through various ways. I get the select widget to load and show the data, but it always ignores my every attempt. I am using dojo 1.7.
var bcntryval = <?= $this->billingContact->countryId;?>;
var countryStore;
function onBillingShow() {
if (countryStore) countryStore.close();
countryStore = new dojo.data.ItemFileReadStore({url: 'CartUtilities.php?action=getcountries'});
dijit.byId("bcntry").setStore(countryStore, bcntryval); // does not set value! but does set the store
dijit.byId("bcntry").attr('value', String(bcntryval)); // doesn't set the value either
dijit.byId("bcntry").set('value', bcntryval)); // nor does this!
}
My markup for the bcntry widget is as follows:
<td><input data-dojo-type="dijit.form.Select" style="width: 10em;" data-dojo-props="sortByLabel:false, maxHeight:'-1'" data-dojo-id="bcntry" id="bcntry" name="bcntry" />
I've invested a fair amount of time on learning dojo. When it works its nice, but the docs leave a lot to be desired!
I am also seeing a similar problem with the dijit.form.FilteringSelect. That also ignores setting the value via javaScript.
I've also tried completely programmatic versions of this code. I have come to the conclusion that setting the value just doesn't work when you're selecting from a store.
This DID work, but its not dynamic.
<div name="scntry" data-dojo-type="dijit.form.Select" data-dojo-props="maxHeight:'-1',sortByLabel:false" value="<?= $this->shippingContact->countryId;?>" >
<?php foreach($this->countryList as $c):?>
<span value="<?= $c->id;?>"><?= $c->name;?></span>
<?php endforeach;?>
</div>
The reason most likely is, that youre trying to set the value of the 'searchAttr'. Instead you would want to set value to the 'identifier'.
Answer is here, check the timeout function on bottom shelf: http://jsfiddle.net/TTkQV/4/
The trick is to set the value as you would set option.value (not option.innerHTML).
normalSelect.set("value", "CA");
filteringSelect.set("value", "AK");
Take a look here, I believe this does what you want in the Dojo way:
Setting the value (selected option) of a dijit.form.Select widget
If not, you can always just use the actual dom selection object and use straight Javascript:
How do I programatically set the value of a select box element using javascript?

valueUpdate: 'afterkeydown' for input type="numeric" in Knockoutjs 2.0

[see fiddle for illustration]
I set up a value bind to an input of type number, and want the bound observable to immediately reflect changes to the value of the field. to do that I set the afterkeydown valueUpdate binding. This works well for changing the number input using the arrow up and arrow down keys. However, if I change the number using the browser-generated (tested in chrome) increment/decrement control the change is only reflected upon changing focus to a different element. I assume this reflects the default update upon change event.
My question is whether there is any way to set the update to occur for both changes using the up down keyboard errors and browser-generated up/down error controls?
The valueUpdate additional binding can take an array of events. It looks like the oninput event is fired when clicking on the up/down arrows.
So, you can bind it like:
<input type="number" data-bind="value: y, valueUpdate: ['afterkeydown', 'input']"/>
http://jsfiddle.net/rniemeyer/hY5T2/9/