Populate formControlName checkbox from pre-defined data in Angular 2+ - angular-reactive-forms

I have a dynamically created checkbox list and I'm having trouble to check the some trues according to a pre-defined list.
HTML:
<div class="row">
<div class="example-container col-md-6">
<div *ngFor="let atribuicao of atribuicoesOcorrencia" formArraylName="inputAtribuicaoOcorrencia">
<mat-checkbox [value]="atribuicao.id" (change)="onChange(atribuicao, $event)">
<div style="white-space: pre-wrap;">
{{ atribuicao.descricao }}
</div>
</mat-checkbox>
</div>
</div>
</div>
CLASS TS:
I try populate formControl name inputAtribuicaoOcorrencia in a list, in this case
the only one checekd was id 3, but nothing happens
this.atribuicoesOcorrencia.forEach(listAtibuicoes=> {
ocorrencia.atribuicoesDTO.forEach(x => {
if(listAtibuicoes.id == x.id){
this.formCadastro.get('inputAtribuicaoOcorrencia').setValue('checked');
}
});
});
CLASS TS2:
Or the code bellow for one ID checked only
this.formCadastro.patchValue({
inputAtribuicaoOcorrencia: 'checked',
});

You need to use the [checked] attribute for the mat-checkbox
// example
<mat-checkbox
[value]="atribuicao.id"
[checked]="atribuicao.id" // This is what you need to add. If id is there, it will get checked
(change)="onChange(atribuicao, $event)"
>
<div style="white-space: pre-wrap;">
{{ atribuicao.descricao }}
</div>
</mat-checkbox>

Related

Vue.js 3 - Add list items from component dynamically

I am new to vue, I found some examples but I could not reproduce in my situation.
I have some inputs user will fill out and once it clicks the button, the information will populate a list of items. I am trying to crete < li > with a OrderListItem component. But I am getting this error:
runtime-core.esm-bundler.js?5c40:217 Uncaught ReferenceError: machines is not defined
at eval (OrderListItem.vue?fb66:14)
Here is the form
<template>
<div>
<div class="flex flex-col mb-4 md:w-full m-1">
<label for="planter_model_id">Planter</label>
<select v-model="registration.planter_model_id" name="planter_model_id">
<option disabled selected>Planter</option>
<option v-for="planter in planters" :key="planter" :value="planter.id">{{planter.brand.name}} {{planter.name }}</option>
</select>
</div>
<div class="flex flex-col mb-4 md:w-full m-1">
<label class=" for="lines">Lines</label>
<Input v-model="registration.lines" type="number" name="lines" />
</div>
<Button type="button" #click="addItemOrder">Add</Button>
</div>
<div>
<ul>
<OrderListItem :machines="machines" />
</ul>
<div>
</template>
Here is my code
export default {
components: {
OrderListItem,
Button,
},
props: {
planters:{
type:Array,
required: true
},
},
data() {
return {
machines: [], //this what I wish to be passed to OrderListItem component
registration:{
lines:null,
planter_model_id:null,
},
}
},
methods:{
addItemOrder(){
let item = {}
item.planter_model_id = this.registration.planter_model_id
item.lines = this.registration.lines
this.machines.push(item)
}
}
};
And here is my OrderListItem component that I created on another file:
<template>
<li v-for="machine in machines" :key="machine">
<div class="flex-initial w-3/5">
<p>Planter: {{machine.planter_model_id}}</p>
<p>Lines: {{machine.lines}}</p>
</div>
</li>
</template>
<script>
export default {
name: 'OrderListItem',
props:{
machines,
}
}
</script>
I don’t know if it is relevant but I am using vue3 and laravel.
I am very newbie here and from what I learned I think if machines array was a prop I would be able to access it on my component. But I will dynamically add a and remove itens from machines array and I think props receive data from server so It should not be declared there, that why I declared inside data().
Thanks =)
You should define the prop by adding its type and default value :
export default {
name: 'OrderListItem',
props:{
machines:{type:Array,default:()=>[]},
}
}

Alpine JS - Creating a menu with active states

I am trying to create a sidebar menu with Alpine JS
I am not even sure if this is possible to do with Alpine JS.
#foreach($kanbans as $kanban)
<div x-data="activeKanban : ????">
<div #click="activeKanban = {{$kanban->id}}">
<div x-show="activeKanban !== {{$kanban->id}}">
// Design for collapsed kanban
</div>
<div>
<div x-show="activeKanban === {{$kanban->id}}">
// Design for active kanban
</div>
</div>
#endforeach
As I switch trough the pages, the $kanban->id changes, and I was wondering instead of manually setting activeKanban : 1 is there a way to pass this information to AlpineJS?
So that by default if I load the other page, the default menu that would be open would be based on the ID instead of them all being collapsed or just 1 that is specified being open?
If you're aiming for an accordion menu of sorts here's how you might achieve it with AlpineJs based on the code you shared:
// Set x-data on a div outside the loop and add your active kanban as a property
<div x-data="{
activeKanban: {{ $activeKanbanId ?? null }}
}">
#foreach($kanbans as $kanban)
<div #click="activeKanban = {{ $kanban->id }}">
<div x-show="activeKanban !== {{ $kanban->id }}">
// Collapsed view
</div>
<div x-show="activeKanban === {{ $kanban->id }}">
// Expanded view
</div>
</div>
#endforeach
</div>
Here each kanban menu item will have access to the activeKanban property in AlpineJs component instance and can set it reactively.
i.e. if activeKanban is set to a new id the current open item will close and the new one will open
Adding flexibility
What if you want to open and close them all independently though? There's more than one way to achieve this but in this case we can modify the code above to allow for it:
// Here we add an array of openItems and two helper functions:
// isOpen() - to check if the id is either the activeKanban or in the openItems array
// toggle() - to add/remove the item from the openItems array
<div x-data="{
activeKanban: {{ $activeKanbanId ?? null }},
openItems: [],
isOpen(id){
return this.activeKanban == id || openItems.includes(id)
},
toggle(id){
if(this.openItems.includes(id)){
this.openItems = this.openItems.filter(item => {
return item !== id
});
}else{
this.openItems.push(id)
}
}
}">
#foreach($kanbans as $kanban)
<div #click="toggle({{ $kanban->id }})">
<div x-show="!isOpen({{$kanban->id}})">
// Collapsed view
</div>
<div x-show="isOpen({{$kanban->id}})">
// Expanded view
</div>
</div>
#endforeach
</div>
This allows us to set an active item and also optionally open/close other menu items.

How to filter through assertion on deep child div content but yield original element?

I have a DOM tree and would like to use cypress to do e2e testing.
<div class="this-is-an-array">
<div class="array-item-element">
...
</div>
<div class="array-item-element">
<div class="very">
<div class="deep">
<div class="child">
<div class="element">
Expected Content
</div>
</div>
</div>
</div>
<div class="another">
<div class="component">
<div class="dom">
<div class="tree">
<button>ButtonToClick</button>
</div>
</div>
</div>
</div>
</div>
<div class="array-item-element">
...
</div>
</div>
I would like to filter out expected item by asserting on its one child component and click on its another child button through possible code like this:
cy.get('.this-is-an-array') // get the root node of array
.find('.array-item-element') // looping over all items
.should(($el) => {
// the very deep child element should contain text of 'Expected Content'
})
.get('.another .component .dom .tree button')
.click()
How can I write the should clause to achieve this?
Without fully understanding what you're trying to do, I think what you need is cy.within():
cy.get(`.this-is-an-array`)
.find(`.array-item-element`).then( $elems => {
$elems.each((idx, elem) => {
cy.wrap(elem)
.should(elem => {
// assert on child element
})
// ensure all subsequent DOM commands are scoped within
// the wrapped DOM elem
.within(() => {
cy.get(`.another .component .dom .tree button`)
.click();
});
});
});

Passing the Div id to another vue component in laravel

I created a simple real-time chat application using vue js in laravel.
I am having a problem with the automatic scroll of the div when there is a new data.
What I want is the div to automatically scroll down to the bottom of the div when there is a new data.
Here is my code so far.
Chat.vue file
<template>
<div class="panel-block">
<div class="chat" v-if="chats.length != 0" style="height: 400px;" id="myDiv">
<div v-for="chat in chats" style="overflow: auto;" >
<div class="chat-right" v-if="chat.user_id == userid">
{{ chat.chat }}
</div>
<div class="chat-left" v-else>
{{ chat.chat}}
</div>
</div>
</div>
<div v-else class="no-message">
<br><br><br><br><br>
There are no messages
</div>
<chat-composer v-bind:userid="userid" v-bind:chats="chats" v-bind:adminid="adminid"></chat-composer>
</div>
</template>
<script>
export default {
props: ['chats','userid','adminid'],
}
</script>
ChatComposer.vue file
<template>
<div class="panel-block field">
<div class="input-group">
<input type="text" class="form-control" v-on:keyup.enter="sendChat" v-model="chat">
<span class="input-group-btn">
<button class="btn btn-primary" type="button" v-on:click="sendChat">Send Chat</button>
</span>
</div>
</div>
</template>
<script>
export default{
props: ['chats','userid','adminid'],
data() {
return{
chat: ''
}
},
methods: {
sendChat: function(e) {
if(this.chat != ''){
var data = {
chat: this.chat,
admin_id: this.adminid,
user_id: this.userid
}
this.chat = '';
axios.post('/chat/sendChat', data).then((response) => {
this.chats.push(data)
})
this.scrollToEnd();
}
},
scrollToEnd: function() {
var container = this.$el.querySelector("#myDiv");
container.scrollTop = container.scrollHeight;
}
}
}
</script>
I am passing a div id from the Chat.vue file to the ChatComposer.vue file.
As you can see in the ChatComposer.vue file there is a function called scrollToEnd where in it gets the height of the div id from Chat.vue file.
When the sendchat function is triggered i called the scrollToEnd function.
I guess hes not getting the value from the div id because I am getting an error - Cannot read property 'scrollHeight' of null.
Any help would be appreciated.
Thanks in advance.
the scope of this.$el.querySelector will be limited to only ChatComposer.vue hence child component can not able to access div of parent component #myDiv .
You can trigger event as below in ChatComposer
this.$emit('scroll');
In parent component write ScollToEnd method and use $ref to assign new height
<chat-composer v-bind:userid="userid" v-bind:chats="chats" v-bind:adminid="adminid" #scroll="ScollToEnd"></chat-composer>
..

Laravel applying search filers

I have a page which has a search box(input text) which takes a place name as input and returns all the nearby dealers.
I also happen to have filters (checkboxes) for all the brand
<div class="col-sm-12 col-md-12">
{!! Form::checkbox('filters',$bike_oem, false,['style'=>'padding-right:5px;'] ) !!} <span style="padding-left:5px;"></span>{{ $bike_oem }}
</div>
How do I implement get the value of filter in my controller ?
<div class="col-sm-12 col-md-12">
<input style="padding-right:5px;" name="Hyundai " type="checkbox" value="Y"> <span style="padding-left:5px;"></span>Hyundai
</div>
This is how each filter appears in the page. Is the code correct to fetch the value in controller ? Please suggest
You can get the value of checkbox in this way also(in controller)
public function myFunction(Request $request){
if (isset($request['Hyundai']) && ($request['Hyundai'] == "on")) {
$value = "Y";
}
}

Resources