link1096 link1097 link1098 link1099 link1100 link1101 link1102 link1103 link1104 link1105 link1106 link1107 link1108 link1109 link1110 link1111 link1112 link1113 link1114 link1115 link1116 link1117 link1118 link1119 link1120 link1121 link1122 link1123 link1124 link1125 link1126 link1127 link1128 link1129 link1130 link1131 link1132 link1133 link1134 link1135 link1136 link1137 link1138 link1139 link1140 link1141 link1142 link1143 link1144 link1145 link1146 link1147 link1148 link1149 link1150 link1151 link1152 link1153 link1154 link1155 link1156 link1157 link1158 link1159 link1160 link1161 link1162 link1163 link1164 link1165 link1166 link1167 link1168 link1169 link1170 link1171 link1172 link1173 link1174 link1175 link1176 link1177 link1178 link1179 link1180 link1181 link1182 link1183 link1184 link1185 link1186 link1187 link1188 link1189 link1190 link1191 link1192 link1193 link1194 link1195 link1196 link1197 link1198 link1199 link1200 link1201 link1202 link1203 link1204 link1205 link1206 link1207 link1208 link1209 link1210 link1211 link1212 link1213 link1214 link1215 link1216 link1217 link1218 link1219 link1220 link1221 link1222 link1223 link1224 link1225 link1226 link1227 link1228 link1229 link1230 link1231 link1232

[Vue.js] Changing class with VueJS for several cards

there is this page with several cards and each card has its own status radio buttons: ok, missing, error.

I wanna change the status of each card without changing others. So I created a method to change the class on @change event, but as all cards bind the same ‘data’, like ‘status’, changing one, changing all.

Lets see some code

<input class=”form-check-input” type=”radio” name=”dadosCadastrais” id=”inlineRadio1” value=”option1” @change=”ok”>
<input class=”form-check-input” type=”radio” name=”dadosCadastrais” id=”inlineRadio2” value=”option2” @change=”falta”>
<input class=”form-check-input” type=”radio” name=”dadosCadastrais” id=”inlineRadio3” value=”option3” @change=”erro”>

The script part:

var vue.js = new Vue({
el: ‘#app’,
data: {
status: ‘’
}

And the method() part:

ok() {
this.status = ‘bg-primary text-white’},
//will code some AJAX too
falta() {
this.status = ‘bg-warning text-black’},
//will code some AJAX too
erro() {
this.status = ‘bg-danger text-white’
//will code some AJAX too
}

The hole card deck code is:

<div class=”card-columns”>
<div class=”card” :class=”status”>
<div class=”card-body”>
<h5 class=”card-title”>Dados Cadastrais</h5>
<p class=”card-text”>
LOGRADOURO: @{ rua }, </p><p> NMERO: @{ numero }, </p><p> BAIRRO: @{ bairro }, </p><p> TEMPO DE RESIDNCIA: @{ tempoResidencia
}, </p><p> CIDADE: @{ cidade }, </p><p> UF: @{ uf }, </p><p> TELEFONE: @{ telefone }, </p><p> CELULAR: @{ celular }, </p><p> CEP:
@{ CEP }
</p>
</div>
<div class=”card-footer text-muted”>
<div class=”form-check form-check-inline”> <input class=”form-check-input” type=”radio” name=”dadosCadastrais” id=”inlineRadio1” value=”option1” @change=”ok”> <label class=”form-check-label” for=”inlineRadio1”>OK</label> </div> <div class=”form-check form-check-inline”> <input class=”form-check-input” type=”radio” name=”dadosCadastrais” id=”inlineRadio2” value=”option2” @change=”falta”> <label class=”form-check-label” for=”inlineRadio2”>Falta</label> </div> <div class=”form-check form-check-inline”> <input class=”form-check-input” type=”radio” name=”dadosCadastrais” id=”inlineRadio3” value=”option3” @change=”erro”> <label class=”form-check-label” for=”inlineRadio3”>Erro</label> </div>
</div>
</div>
<div class=”card” :class=”status”>
<div class=”card-body”>
<h5 class=”card-title”>Dados do Bem</h5>
<p class=”card-text”>
CONTRATO: @{ contrato }, </p><p> GRUPO: @{ grupo }, </p><p> COTA: @{ cota }, </p><p> VALOR: @{ valor }, </p><p> PESSOA: @{ pessoa }, </p><p> BEM CONTRATADO: @{ segmento }, </p><p> BEM ESCOLHIDO: @{ novoSegmento }, </p><p> idERP: @{ idERP }, </p>
</div>
<div class=”card-footer text-muted”>
<div class=”form-check form-check-inline”> <input class=”form-check-input” type=”radio” name=”dadosBem” id=”inlineRadio1” value=”option1” @change=”ok”> <label class=”form-check-label” for=”inlineRadio1”>OK</label> </div> <div class=”form-check form-check-inline”> <input class=”form-check-input” type=”radio” name=”dadosBem” id=”inlineRadio2” value=”option2” @change=”falta”> <label class=”form-check-label” for=”inlineRadio2”>Falta</label> </div> <div class=”form-check form-check-inline”> <input class=”form-check-input” type=”radio” name=”dadosBem” id=”inlineRadio3” value=”option3” @change=”erro”> <label class=”form-check-label” for=”inlineRadio3”>Erro</label> </div>
</div>
</div>
<div class=”card” :class=”status”>
<div v-if=”contas != ‘’”>
<div class=”card-body”>
<h5 class=”card-title”>Dados Bancrios</h5>
<p class=”card-text”>
BANCO: @{ contas.banco }, </p>
<p> AGNCIA: @{ contas.agencia }, </p>
<p> CONTA CORRENTE: @{ contas.conta }, </p>
</div>
<div class=”card-footer text-muted”>
<div class=”form-check form-check-inline”> <input class=”form-check-input” type=”radio” name=”dadosBancarios” id=”inlineRadio1” value=”option1” @change=”ok”> <label class=”form-check-label” for=”inlineRadio1”>OK</label> </div> <div class=”form-check form-check-inline”> <input class=”form-check-input” type=”radio” name=”dadosBancarios” id=”inlineRadio2” value=”option2”> <label class=”form-check-label” for=”inlineRadio2”>Falta</label> </div> <div class=”form-check form-check-inline”> <input class=”form-check-input” type=”radio” name=”dadosBancarios” id=”inlineRadio3” value=”option3”> <label class=”form-check-label” for=”inlineRadio3”>Erro</label> </div>
</div>
</div>
<div v-else>
<div class=”card-body”>
<h5 class=”card-title”>Dados Bancrios</h5>
<form v-on:submit.prevent=”sub” action=”#” method=”post”>
@method(‘POST’)
@csrf
<div class=”form-group”>
<label for=”banco”>Banco</label>
<input type=”text” v-model=”banco” class=”form-control” id=”banco”>
</div>
<div class=”form-group”>
<label for=”agencia”>Agncia</label>
<input type=”text” v-model=”agencia” class=”form-control” id=”agencia”>
</div>
<div class=”form-group”>
<label for=”conta”>Conta Corrente</label>
<input type=”text” v-model=”conta” class=”form-control” id=”conta”>
</div>
<button type=”submit” class=”btn btn-primary”>Cadastrar</button>
</form>
</div>
<div class=”card-footer text-muted”>
<div class=”form-check form-check-inline”> <input class=”form-check-input” type=”radio” name=”dadosBancarios” id=”inlineRadio1” value=”option1” @change=”ok”> <label class=”form-check-label” for=”inlineRadio1”>OK</label> </div> <div class=”form-check form-check-inline”> <input class=”form-check-input” type=”radio” name=”dadosBancarios” id=”inlineRadio2” value=”option2”> <label class=”form-check-label” for=”inlineRadio2”>Falta</label> </div> <div class=”form-check form-check-inline”> <input class=”form-check-input” type=”radio” name=”dadosBancarios” id=”inlineRadio3” value=”option3”> <label class=”form-check-label” for=”inlineRadio3”>Erro</label> </div>
</div>
</div>
</div>
<div class=”card”>
<div class=”card-body”>
<h5 class=”card-title”>Dados de Patrimnio</h5>
<p class=”card-text”>
AES: @{ patrimonios.valorAcoes }, </p>
<p> AUTOMVEIS: @{ patrimonios.valorAutomovies }, </p>
<p> IMVEIS: @{ patrimonios.valorImovel }, </p>
<p> INVESTIMENTOS: @{ patrimonios.valorInvestimentos }, </p>
<p> TOTAL: @{ patrimonios.valorTotal }, </p>
</div>
<div class=”card-footer text-muted”>
<div class=”form-check form-check-inline”> <input class=”form-check-input” type=”radio” name=”dadosPatrimonio” id=”inlineRadio1” value=”option1”> <label class=”form-check-label” for=”inlineRadio1”>OK</label> </div> <div class=”form-check form-check-inline”> <input class=”form-check-input” type=”radio” name=”dadosPatrimonio” id=”inlineRadio2” value=”option2”> <label class=”form-check-label” for=”inlineRadio2”>Falta</label> </div> <div class=”form-check form-check-inline”> <input class=”form-check-input” type=”radio” name=”dadosPatrimonio” id=”inlineRadio3” value=”option3”> <label class=”form-check-label” for=”inlineRadio3”>Erro</label> </div>
</div>
</div>
<div class=”card”>
<div class=”card-body”>
<h5 class=”card-title”>Endereos de Patrimnios</h5>
<div v-for=”imovel in imoveis”>
<p class=”card-text”>RUA: @{ imovel.rua }, </p>
<p> NMERO: @{ imovel.nroReferencia }, </p>
<p> COMPLEMENTO: @{ imovel.complementoPatrimonio }, </p>
<p> BAIRRO: @{ imovel.bairroPatrimonio }, </p>
<p> CEP: @{ imovel.cep }, </p>
<p> CIDADE: @{ imovel.cidadePatrimonio }, </p>
<p> UF: @{ imovel.UFPatrimonio }, </p>
<hr>
</div>
</div>
<div class=”card-footer text-muted”>
<div class=”form-check form-check-inline”> <input class=”form-check-input” type=”radio” name=”endPatrimonio” id=”inlineRadio1” value=”option1”> <label class=”form-check-label” for=”inlineRadio1”>OK</label> </div> <div class=”form-check form-check-inline”> <input class=”form-check-input” type=”radio” name=”endPatrimonio” id=”inlineRadio2” value=”option2”> <label class=”form-check-label” for=”inlineRadio2”>Falta</label> </div> <div class=”form-check form-check-inline”> <input class=”form-check-input” type=”radio” name=”endPatrimonio” id=”inlineRadio3” value=”option3”> <label class=”form-check-label” for=”inlineRadio3”>Erro</label> </div>
</div>
</div>
<div class=”card” v-if=”correspondencia != ‘’”>
<div class=”card-body”>
<h5 class=”card-title”>Endereo de Correspondncia</h5>
<div v-if=”correspondencia != ‘’”>
<p class=”card-text”>RUA: @{ correspondencia.rua }, </p>
<p> NMERO: @{ correspondencia.numero }, </p>
<p> BAIRRO: @{ correspondencia.bairro }, </p>
<p> CEP: @{ correspondencia.cep }, </p>
<p> CIDADE: @{ correspondencia.cidade }, </p>
<p> UF: @{ correspondencia.UF }, </p>
</div>
</div>
<div class=”card-footer text-muted”>
<div class=”form-check form-check-inline”> <input class=”form-check-input” type=”radio” name=”endCorrespondencia” id=”inlineRadio1” value=”option1”> <label class=”form-check-label” for=”inlineRadio1”>OK</label> </div> <div class=”form-check form-check-inline”> <input class=”form-check-input” type=”radio” name=”endCorrespondencia” id=”inlineRadio2” value=”option2”> <label class=”form-check-label” for=”inlineRadio2”>Falta</label> </div> <div class=”form-check form-check-inline”> <input class=”form-check-input” type=”radio” name=”endCorrespondencia” id=”inlineRadio3” value=”option3”> <label class=”form-check-label” for=”inlineRadio3”>Erro</label> </div>
</div>
</div>
<div class=”card”>
<div class=”card-body”>
<h5 class=”card-title”>Dados Profissionais</h5>
<p class=”card-text”>PROFISSO: @{ profissao.profissao }, </p>
<p> CARGO: @{ profissao.cargo }, </p>
<p> SALRIO: @{ profissao.salario }, </p>
<p> EMPRESA: @{ profissao.empresa }, </p>
<p> EMAIL: @{ profissao.emailEmpresa }, </p>
<p> CNPJ: @{ profissao.cnpj }, </p>
<p> RUA: @{ profissao.logradouro }, </p>
<p> CEP: @{ profissao.cep }, </p>
<p> Cidade: @{ profissao.cidade }, </p>
<p> UF: @{ profissao.UF }, </p>
<p> BAIRRO: @{ profissao.bairro }, </p>
<p> TELEFONE: @{ profissao.ddd } - @{ profissao.telefoneComercial } </p>
<p> RAMAL: @{ profissao.ramal }</p>
</div>
<div class=”card-footer text-muted”>
<div class=”form-check form-check-inline”> <input class=”form-check-input” type=”radio” name=”dadosProfissionais” id=”inlineRadio1” value=”option1”> <label class=”form-check-label” for=”inlineRadio1”>OK</label> </div> <div class=”form-check form-check-inline”> <input class=”form-check-input” type=”radio” name=”dadosProfissionais” id=”inlineRadio2” value=”option2”> <label class=”form-check-label” for=”inlineRadio2”>Falta</label> </div> <div class=”form-check form-check-inline”> <input class=”form-check-input” type=”radio” name=”dadosProfissionais” id=”inlineRadio3” value=”option3”> <label class=”form-check-label” for=”inlineRadio3”>Erro</label> </div>
</div>
</div>
<div class=”card”>
<div class=”card-body”>
<h5 class=”card-title”>Referncias Pessoais</h5>
<div v-for=”referencia in referencias”>
<p class=”card-text”>NOME: @{ referencia.nome }, </p>
<p> ENDEREO: @{ referencia.endereco }, @{ referencia.numero }</p>
<p> CIDADE: @{ referencia.cidade }, </p>
<p> UF: @{ referencia.UF }, </p>
<p> CEP: @{ referencia.cep }, </p>
<p> COMPLEMENTO: @{ referencia.complemento }, </p>
<p> TELEFONE: (@{ referencia.ddd }) @{ referencia.telefone }, </p>
<hr>
</div>
</div>
<div class=”card-footer text-muted”>
<div class=”form-check form-check-inline”> <input class=”form-check-input” type=”radio” name=”refPessoais” id=”inlineRadio1” value=”option1”> <label class=”form-check-label” for=”inlineRadio1”>OK</label> </div> <div class=”form-check form-check-inline”> <input class=”form-check-input” type=”radio” name=”refPessoais” id=”inlineRadio2” value=”option2”> <label class=”form-check-label” for=”inlineRadio2”>Falta</label> </div> <div class=”form-check form-check-inline”> <input class=”form-check-input” type=”radio” name=”refPessoais” id=”inlineRadio3” value=”option3”> <label class=”form-check-label” for=”inlineRadio3”>Erro</label> </div>
</div>
</div>
</div>

How can I do it be as much as DRY as possible, and change only the card I wanna change?

Solution :

Add data elements:

data: {
oks: [],
faltas: [],
erros: []
}

Add some new logic to the methods:

falta(index) {
if (!this.faltas.includes(index)) {
this.faltas.push(index)
}

// other stuff
}

Repeat this for the erro() method.

Make sure you add the reverse logic for the ok() method:

if (this.erros.includes(index)) {
this.erros.splice(this.erros.findIndex(el => el === index), 1)
}

Dynamically change the card class based on the existence of the index:

<div class=”card” :class=”{‘bg-primary text-white’: this.faltas.includes(1)’}”>

Add any other conditionals there based on inclusion, such as for oks.includes(id) and errors.includes(id)

And update the methods for the input elements to pass the unique indexer for this card:

@change=”ok(1)”
@change=”falta(1)”
@change=”erro(1)”

And just change 1 to 2 for the next card and methods within that card and so on and so forth.

Solution 2:

You can use vue-refs to get a particular element.

Here is simple code to reproduce:

Template

<div class=”card” ref=”card-1”>
<div class=”card-body”>
…..
</div>
<div class=”card-footer text-muted”>
<input @click=”setClass(1, ‘bg-primary text-white’)”>
<input @click=”setClass(1, ‘bg-warning text-black’)”>
<input @click=”setClass(1, ‘bg-danger text-white’)”>
</div>
</div>

<div class=”card” ref=”card-2”>
<div class=”card-body”>
…..
</div>
<div class=”card-footer text-muted”>
<input @click=”setClass(2, ‘bg-primary text-white’)”>
<input @click=”setClass(2, ‘bg-warning text-black’)”>
<input @click=”setClass(2, ‘bg-danger text-white’)”>
</div>
</div>

Methods: {
setClass(index, className) {
const elem = this.$refs[`card-${index}`]
elem.className = className
}
}

Solution 3:

I would suggest to store the status on the object directly. For this to work the list used in the v-for must be inside the component data so it’s editable.

With this approach there is no need to track who has what status, indexes, etc. Each object is responsible for its own status. In this example I suppose there will be classes set up with correct styling, ok, falta and erro.

<div class=”card”>
<div class=”card-body” :class=”referencia.status”>
<h5 class=”card-title”>Referncias Pessoais</h5>
<div v-for=”referencia in referencias”>
<p class=”card-text”>
NOME: @{ referencia.nome }
</p>

<hr>
</div>
</div>
<div class=”card-footer text-muted”>
<button class=”some-styling-here” @click=”referencia.status = ‘ok’”> OK </button>
<button class=”some-styling-here” @click=”referencia.status = ‘falta’”> Falta </button>
<button class=”some-styling-here” @click=”referencia.status = ‘erro’”> Erro </button>
</div>
</div>