Quasar q-tabs: how to dynamically show/hide q-tab by code? - vue.js

There is a dropdownlist, if user choose a option, some q-tab-panel will show/hide to make a response. But how can I dynamically set the q-tab-panel show/hide by code? Hope someone can make suggestions here. Thanks
<q-select filled
v-model="datasource.datasourcetype"
:options="datasource.options"
option-value="value"
option-label="label"
emit-value
map-options
:label="ui.datasourcetype" />
<q-tabs v-model="dataEntryTab"
dense
class="bg-grey-2 text-teal"
align="left">
<q-tab name="tabCustomized" v-if="dataentry.showOptionsTab" icon="mail" :label="ui.datasourceOptions" />
<q-tab name="tabEntryInfo" v-if="dataentry.showDataEntryTab" icon="alarm" :label="ui.datasourceEntryInfo" />
<q-tab name="tabCascadeField" v-if="dataentry.showCascadeFieldTab" icon="movie" :label="ui.datasourceCascadeField" />
</q-tabs>
<q-tab-panels v-model="dataEntryTab" animated>
<q-tab-panel name="tabCustomized">
<q-input :label="ui.dataentryOptions"
v-model="dataentry.options"
filled
type="textarea" />
</q-tab-panel>
<q-tab-panel name="tabEntryInfo">
</q-tab-panel>
<q-tab-panel name="tabCascadeField">
</q-tab-panel>
</q-tab-panels>
For example, there are 3 q-tabs, if the user only want to let 2 of them to show, and 1 of them to hide after a dropdown option selected.

There is an event #input about q-select, and we can trigger a model variable for every q-tab. It works for me
onDataSourceTypeChanged (event) {
var dstype = this.datasource.datasourcetype
if (dstype === 'datasourcetype.Customized') {
this.dataentry.showOptionsTab = true
this.dataentry.showDataEntryTab = false
this.dataentry.showCasacdeFieldTab = false
} else {
this.dataentry.showOptionsTab = false
this.dataentry.showDataEntryTab = true
this.dataentry.showCasacdeFieldTab = true
}
}

Related

vue-next-select element not selecting value on selection

import VueSelect from 'vue-next-select';
const app = createApp({})
app.component('vue-select', VueSelect)
<vue-select v-model="tankno" :options="tanks1" searchable #input="form.tankno = $event.target.value" close-on-select label-by="tankno" class="text-left h-10 sinput" search-placeholder=" Search Tank No" placeholder="Select Tank No" track-by="tankno"></vue-select>
When I submit form, vue-select not selecting value but only get on search input
<vue-select
v-model="tankno"
:options="tanks1"
searchable
#input="form.tankno = $event.target.value"
close-on-select label-by="tankno"
class="text-left h-10 sinput"
search-placeholder=" Search Tank No"
placeholder="Select Tank No"
track-by="tankno"
#selected="onSelected"
ref="selectRef"
>
</vue-select>
const onSelected = (e) => {
selectRef.value.input.input.value = e;
}
In my case using Vue js 3, I create template refs (selectRef), then pass the selected value to the search input field.

Select Option (for dropdown) Laravel

I make a dropdown for a form, I will show the code below. However, when I click the submit button, there is an error saying,
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'brand' cannot be null (SQL: insert into supplier_details.
The data that I chose from the dropdown is actually null. Actually, I'm new to Laravel.
I don't want to make a dropdown list from a database, I just want to display the option and the option will be inserted into the database when the user clicks the submit button after filling in the form.
<div class="form-group row">
<label style="font-size: 16px;" for="id" class = "col-sm-2">Item Brand </label>
<label for="supp_name" class = "col-sm-1">:</label>
<div class="col-sm-7">
<select name="brand" class="form-control js-example-basic-single" required>
<option >Please select item brand</option>
<option value="machine1"> Item Brand 1 </option>
<option value="machine1"> Item Brand 2 </option>
<option value="machine1"> Tem Brand 3 </option>
</select>
</div>
</div>
Controller
public function createsupplierdetails()
{
return view ('frontend.praiBarcode.getweight');
}
public function supplierdetails(Request $r)
{
$details = new SupplierDetail;
$getuserPO = Supplier::where('PO',$r->PO)->first();
$details->brand = $getuserPO->brand;
$details->container_no = $getuserPO->container_no;
$details->date_received = $getuserPO->date_received;
$details->gross_weight = $getuserPO->gross_weight;
$details->tare_weight = $getuserPO->tare_weight;
$details->net_weight = $getuserPO->net_weight;
$details->save();
return view ('frontend.praiBarcode.viewsupplierdetails')
->with('details',$details);
}
This to check to verify if it is working:
Make sure you are submitting the correct form.
Try doing dd on your controller dd($request->all())
If data is reaching the controller and not inserted into the database, check on your model, if it is added to fillable or if there is only id in the guarded array. You can know about more here in https://laravel.com/docs/9.x/eloquent#mass-assignment
Error should be fixed, as soon as you fix it.
Controller
use Validator;
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'brand' => 'required',
]);
if ($validator->fails()) {
return redirect()->back()->with('error', $validator->errors()->first());
}
$details = new SupplierDetail();
$details->brand = $request->brand;
$details->container_no = $request->container_no;
$details->date_received = $request->date_received;
$details->gross_weight = $request->gross_weight;
$details->tare_weight = $request->tare_weight;
$details->net_weight = $request->net_weight;
$details->save();
if ($trending) {
return redirect(route('details.index'))->with('success', 'Field added successfully');
} else {
return redirect()->back()->with('error', 'Field has been not added successfully');
}
}

Vue 2 Moving Window with Keyboard Navigation

I have created a list in my program. In this list, you press ArrowUp or ArrowDown to navigate between the items that are generated with a v-for in said list. When you use the arrows to navigate the list, a counter is used to know which item inside this list is the "selected" one. My current problem is: When you "select" an item that is outside your view, the Browser's Window doesn't follow it down, allowing the selection to keep "going down" this list, but the user isn't able to see the other selected items.
I've tried messing around with the focus() function, but I don't know how to focus() a specific item without using the ref atribute, which I also can't seem to implement since it's being generated with v-for.
Here's my current table:
<table class="table table-striped p-0 m-0" v-show="pedidos.length > 0">
<thead class="table-dark">
<tr class="">
<th>Cliente Emissor</th>
<th>Produto</th>
<!-- <th>Endereço</th> -->
<!-- <th>Valor</th> -->
<th>Data Emissão</th>
<th>Estado</th>
</tr>
</thead>
<tbody>
<template v-for="(pedido, index) in pedidos">
<itemPedido :pedido="pedido" :key="index" :endereco="endereco" :class="[(navegacaoAtual == index) ? 'teste' : '']" ref="teste"></itemPedido>
<itemEdit #atualizarListaPedidos="atualizarListaPedidos" #atualizarStatusModal="atualizarStatusModal" class="animation-dropdown" :pedido="pedido" :key="pedido.nome"></itemEdit>
</template>
</tbody>
</table>
Here's the current navigateWithArrows() function I've made:
navegarSetas(key) {
if (this.navegacaoSetasAtiva == false) {
this.navegacaoSetasAtiva = true
this.navegacaoAtual = 0
} else if (this.modalAtivado == false && this.navegacaoSetasAtiva == true) {
if (key == 'ArrowDown' && this.navegacaoAtual < this.pedidos.length - 1) {
this.navegacaoAtual++
Vue.nextTick().then(() => {
let teste1 = this.$refs.teste[this.navegacaoAtual]
teste1.$el.focus()
})
} else if (key == 'ArrowUp' && this.navegacaoAtual <= this.pedidos.length && this.navegacaoAtual > 0) {
this.navegacaoAtual--
} else if (key == 'Enter') {
let pedidoSelecionado = this.pedidos[this.navegacaoAtual].id
Event.$emit('changeShow', pedidoSelecionado)
}
}
},
All help is appreciated. Thank you!
After taking a break and resuming my search, I stumbled upon something that did exactly what I wanted: the scrollIntoView() function.
https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView

How to bind mobx-react-form with mobx-state-tree store

I have a form with three fields A, B and C. I am using mobx-react-form to handle the fields because it comes with onChange updates and validation baked in. I have set this up and it's working fine when I log out the values.
const View = inject('store')(observer(({ title }: Props) => {
return (
<div>
<form onSubmit={form.onSubmit}>
<label htmlFor={form.$('A').id}>
{form.$('A').label}
</label>
<input {...form.$('A').bind()} />
<label htmlFor={form.$('B').id}>
{form.$('B').label}
</label>
<input {...form.$('B').bind()} />
<label htmlFor={form.$('C').id}>
{form.$('C').label}
</label>
<input {...form.$('C').bind()} />
<button type="submit" onClick={form.onSubmit}>
Submit
</button>
</form>
</div>
);
}));
I will use the values from fields A, B and C to calculate additional values D and E which will appear in the app.
For state management, I am using mobx-state-tree to create the store.
export const Store = types.model('Store',
{
A: types.maybeNull(types.number),
B: types.maybeNull(types.number),
C: types.maybeNull(types.number),
D: types.maybeNull(types.number),
E: types.maybeNull(types.number),
})
.views(self => {
return {
getD: () => self.D,
getE: () => self.E
};
})
.actions(self => {
return {
setD: (A, B) => self.D = A + B,
setE: (B, C) => self.E = C - B,
resetStore: () => {
self.A = defaultState.A;
self.B = defaultState.B;
self.C = defaultState.C;
self.D = defaultState.D;
self.E = defaultState.E;
},
};
});
How can I bind the mobx-react-form fields A, B and C to corresponding values in the store so they update on change?
Well,
first of all,
I want you to notice , you are trying to connect 2 different state managers .
I like mobx-recat-form very much ! but you should consider that it
manages the state for you automatically .
You can bind yourself to onChange, and update D,E accordingly .
For Example:
<input onChange={e => {
form.$('B').set(e.target.value);
// handle D,E according to value
}} />
this is the most "direct" way to deal with it.
if you want to solve it in more "mobx" way ,
Do something likes this:
form.$('B')
.observe(({ form, field, change }) => {
// deal with D,E according to values
});
For further information I would take a look into:
https://foxhound87.github.io/mobx-react-form/docs/extra/mobx-events.html
And I would suggest to stick with this library(mobx-react-form) for controlling
the forms , and with direct hooks(1 st example) or by observing the form propagate changes to other values in other stores .

Unselect effect Radio Material2 Angular 5

I'm using mat-radio-button(material2) and I have something like a quiz. When I select an answer and go to the next quiz, the visual effect of unselect is showing in the second quiz. This happens if the selected option in the first quiz, appears in the second too, in the same position or after.
I made a simple example. You can reproduce it selecting "aa", then click ">>" button.
HTML
<mat-radio-group class="example-radio-group" [(ngModel)]="radioSelected">
<mat-radio-button *ngFor="let option of tempSublist" [value]="option" class="example-radio-button" color="primary">
{{option}}
</mat-radio-button>
</mat-radio-group>
<hr>
<button (click)="prev()"><<</button>
<button (click)="next()">>></button>
Typescript
list = [
['aa','bb','cc'],
['cc','aa','bb'],
['bb','cc','ee'],
['dd','bb','cc'],
];
index = 0;
tempSublist = this.list[this.index];
radioSelected:string;
next(){
if(this.index < this.list.length){
this.radioSelected = null;
this.index++;
this.tempSublist = this.list[this.index];
}
}
prev(){
if(this.index >= 1){
this.radioSelected = null;
this.index--;
this.tempSublist = this.list[this.index];
}
}
https://stackblitz.com/edit/angular-7s9qvs?file=app%2Fradio-ng-model-example.html
How can I solve this?
Adding trackBy option on ngFor helps to reduce the transition between the two states. Also disabling repples with [disableRipple]="true" seems to reduce the visual effect:
HTML
<mat-radio-button [disableRipple]="true" *ngFor="let option of tempSublist;
trackBy: trackByFn" ...>
...
Typescript
next() {
if (this.index < this.list.length - 1) {
//add this ^
...
trackByFn(index, item) {
return index;
}
I thought adding a control on navigation buttons would be nice:
<button [disabled]="index <= 0" (click)="prev()"><<</button>
^- this
<button [disabled]="index === tempSublist.length" (click)="next()">>></button>
^- this
Demo
If this is not enough, in last recourse, hide and show the whole block.
Wrap it in a div and set ngIf:
<div *ngIf="isVisible">
<mat-radio-group class="example-radio-group" [(ngModel)]="radioSelected">
...
and use timeout in the class on button click:
next() {
isVisible = true;
this.isVisible = false;
if (this.index < this.list.length - 1) {
...
}
setTimeout(() => this.isVisible = true, 30)
}
Demo