Vue.js - Transfer objects between two selects - javascript

I have the following HTML with 2 selects and 2 buttons to transfer options between the selects:
<div class="col-xs-1" style="width:45%">
<label for="txtDescricao">Motivos</label>
<select multiple="multiple" class="form-control" id="todosMotivos" v-model="Motivos_selected" style="width: 100%;">
<option v-for="motivo in Motivos" v-bind:value="motivo.Codigo">{{motivo.Descricao}}</option>
</select>
</div>
<div class="col-xs-1 text-center align-middle" style="width:10%">
<br />
<p><button type="button" class="btn btn-default btn-sm fa fa-arrow-right" v-on:click.prevent="adicionarItensSelect"></button></p>
<p><button type="button" class="btn btn-default btn-sm fa fa-arrow-left" v-on:click.prevent="removerItensSelect"></button></p>
</div>
<div class="col-xs-1" style="width:45%">
<label for="txtDescricao">Motivos vinculados</label>
<select multiple="multiple" class="form-control" id="selectedMotivos" v-model="Motivos_vinculados_selected" style="width: 100%;">
<option v-for="motivo in Motivos_vinculados" v-bind:value="motivo.Codigo">{{motivo.Descricao}}</option>
</select>
</div>
Here is the vue app data:
Motivos: [],
Motivos_selected: [],
Motivos_vinculados: [],
Motivos_vinculados_selected: [],
The list of "Motivos" is being loaded this way:
getMotivos: function (motivosVinculados) {
var self = this;
$.ajax({
type: "POST",
url: "../Motivo/GetMotivos",
success: function (data) {
self.Motivos = data.motivos;
},
error: function (error) {
console.log(error);
alert('Erro ao executar operação.');
}
});
},
I am trying to transfer the selected options to the second Select this way:
adicionarItensSelect: function () {
var self = this;
self.Motivos_vinculados.push(self.Motivos_selected);
},
But, instead, the option goes blank to the second Select:
I think the item is not going to the second Select as the same object. What can I do to solve this?

You need to bind the object to the options like so:
<option v-for="motivo in Motivos" v-bind:value="motivo>{{motivo.Descricao}}</option>
var appEquipamento = new Vue({
el: "#equipamentoApp",
data: {
Motivos: [
{ Codigo: 1, Descricao: "Motivo 1" },
{ Codigo: 2, Descricao: "Motivo 2" },
{ Codigo: 3, Descricao: "Motivo 3" }
],
Motivos_selected: [],
Motivos_vinculados: [],
Motivos_vinculados_selected: []
},
methods: {
adicionarItensSelect: function () {
var self = this;
self.Motivos_vinculados = self.Motivos_vinculados.concat(self.Motivos_selected);
}
}
});
<script src="https://unpkg.com/vue"></script>
<section id="equipamentoApp" class="content">
<div class="col-xs-1" style="width:45%">
<label for="txtDescricao">Motivos</label>
<select multiple="multiple" class="form-control" id="todosMotivos" v-model="Motivos_selected" style="width: 100%;">
<option v-for="motivo in Motivos" v-bind:value="motivo">{{motivo.Descricao}}</option>
</select>
</div>
<div class="col-xs-1 text-center align-middle" style="width:10%">
<br />
<p><button type="button" class="btn btn-default btn-sm fa fa-arrow-right" v-on:click.prevent="adicionarItensSelect"> -> </button></p>
<p><button type="button" class="btn btn-default btn-sm fa fa-arrow-left" v-on:click.prevent="removerItensSelect"> <- </button></p>
</div>
<div class="col-xs-1" style="width:45%">
<label for="txtDescricao">Motivos vinculados</label>
<select multiple="multiple" class="form-control" id="selectedMotivos" v-model="Motivos_vinculados_selected" style="width: 100%;">
<option v-for="motivo in Motivos_vinculados" v-bind:value="motivo.Codigo">{{motivo.Descricao}}</option>
</select>
</div>
</section>
hope it helps :)

I think you are pushing an entire array (Motivos_selected) into the Motivos_vinculados array. This would result in a nested array.
you should probably use:
self.Motivos_vinculados.concat(self.Motivos_selected);
if you want to join the two arrays, override the entire array:
self.Motivos_vinculados = self.Motivos_selected;
or loop through the first array and push the items to the second:
self.Motivos_vinculados.map(item => { self.Motivos_selected.push(item) });
EDIT---------
After looking at the fiddle, my solution was as followed:
adicionarItensSelect: function () {
var self = this;
self.Motivos_vinculados = this.Motivos.filter(motivo => {
return self.Motivos_selected.indexOf(motivo.Codigo) !== -1;
});
}
Hope this helps!

Related

vue3 v-model not work in js auto complete

I use javascript auto complete to finish the input text.
But I can't use v-model function of vue3 to get full value in my code.
Does any one can give me some advise, thanks.
<div class="row">
<div class="col-md-3">
<label for="fnode">fnode:</label>
<input type="text" class="form-control required" id="fnode" name="fnode" v-model="fnode">
</div>
<div class="col-md-3">
<label for="fnode">fnode:</label>
<button class="btn btn-primary form-control">{{ fnode }}</button>
</div>
</div>
<script>
Vue.createApp({
data: function(){
return {
fnode: '',
};
},
methods: {
},
mounted: function() {
},
}).mount('#form1');
</script>

Create many forms with loop

Hello I am trying to create several forms from a loop that comes from dynamic elements loaded from the database. However I think I am doing it wrong here is what I have already done. It works more or less but I would like to have the right way to proceed.
Thanks in advance
submitForm: function (e) {
e.preventDefault();
e.target.elements.techId.value // OK
this.selectUser // value is other form not form used button
}
Template
<div v-for="tech in techs" :key="tech.id" class="col-12 col-lg-3">
<h3>{{ tech.name }}</h3>
<form
name="form_tech"
method="POST"
#submit="submitForm"
>
<input type="hidden" :value="tech.id" name="techId" id="techId" />
<select
name="select_user"
class="form-select"
v-model="selectUser"
>
<option value="user_one">user one</option>
<option value="user_two">user two</option>
</select>
<button type="submit" >
Confirm
</button>
</form>
Maybe like following snippet:
const app = Vue.createApp({
data() {
return {
techs: [{id: 0, name: 'aa'}, {id: 1, name: 'bb'}, {id: 3, name: 'cc'}],
selectUser: []
};
},
methods: {
submitForm(id) {
console.log(this.selectUser[id])
}
}
})
app.mount('#demo')
<script src="https://unpkg.com/vue#3/dist/vue.global.prod.js"></script>
<div id="demo">
<div v-for="tech in techs" :key="tech.id" class="col-12 col-lg-3">
<h3>{{ tech.name }}</h3>
<form name="form_tech" method="POST"
#submit.prevent="submitForm(tech.id)"
>
<input type="hidden" :value="tech.id" name="techId" id="techId" />
<select name="select_user" class="form-select"
v-model="selectUser[tech.id]"
>
<option value="user_one">user one</option>
<option value="user_two">user two</option>
</select>
<button type="submit">Confirm</button>
</form>
</div>
</div>

form does not return values

as soon as I send the form, it does not return the values I want. i'm using ajax to receive the data.
<form action="registro-de-dominios.php" method="POST" id="ajax-form" class="form-inline">
<label class="sr-only" for="inlineFormInputName2">WWW</label>
<input type="text" class="p-3 form-control form-control-lg mb-2 mr-sm-2 input-ro www" id="inlineFormInputName2" name="www" value="www" placeholder="www." readonly>
<label class="sr-only" for="inlineFormInputGroupUsername2">Domínio</label>
<div class="input-group justify-content-center mb-2 mr-sm-2">
<input type="text" name="dominio" id="dominio" class="input-dom form-control form-control-lg" placeholder="Digite o domínio desejado">
</div>
<div class="form-check mb-2 mr-sm-2 select-padding">
<select name="point" id="point" class="form-control form-control-lg">
<option value=".com">.com</option>
<option value=".com.br">.com.br</option>
<option value=".net">.net</option>
</select>
</div>
<button type="submit" id="salvar-form" class="btn btn-dominio btn-outline-danger" name="enviar" value="Enviar" data-toggle="modal" data-target="#ExemploModalCentralizado">
<i class="fas fa-search"></i>
</button>
</form>
AJAX:
<script>
$(document).ready(function() {
const www = $('.www').val();
const dominio = $('#dominio').val();
const com = $('#point').val();
$("#salvar-form").click(function(e) {
e.preventDefault();
$.ajax({
method: "POST",
url: "registro-de-dominios.php",
dataType: "json",
data: {
www: www,
dominio: dominio,
com: com
},
beforeSend: function() {
alert("ENVIANDO...");
},
success: function(data) {
alert('ok');
},
error: function() {
alert('tente novamente');
}
})
});
});
</script>
this is what returns:
does not return anything in the "dominio" field and returns the ".com" option, even if I choose another option
You are assigning the www, dominio, and com consts outside the button click event handler. So they are only set once, while the document is loading, not when the button is clicked. So you are getting the default values in AJAX call. They should be assigned inside the click handler, like this:
$(document).ready(function() {
$("#salvar-form").click(function(e) {
const www = $('.www').val();
const dominio = $('#dominio').val();
const com = $('#point').val();
...
});
});

V-model modifies objects with the same property

I'm working on a VueJS project and I'm having trouble using v-model with Objects. When I modify one of the object that is bound with v-model it modifies all the different objects with the same property name.
Here's my code:
HTML
<div v-if="!editMode">
<ul class="list-group">
<li class="list-group-item">Nombre de Usuario: {{userGlobal.username}}</li>
<li class="list-group-item">Nombre: {{userGlobal.first_name}}</li>
<li class="list-group-item">Apellido: {{userGlobal.last_name}}</li>
<li class="list-group-item">Email: {{userGlobal.email}}</li>
<li class="list-group-item">DNI: {{userGlobal.dni}}</li>
<li class="list-group-item">Fecha de Nacimiento: {{userGlobal.birth_date}}</li>
</ul>
<a href="#">
<button class="btn btn-block btn-primary mt-2"
#click.prevent="modifyModal">Modificar Informacion</button>
</a>
</div>
<div v-else style="padding: 1px;">
<form>
<input type="text" class="form-control" v-model="userEditable.username" />
<input type="text" class="form-control" v-model="userEditable.first_name" />
<input type="text" class="form-control" v-model="userEditable.last_name" />
<input type="text" class="form-control" v-model="userEditable.email" />
<input type="integer" class="form-control" v-model="userEditable.dni" />
<input type="text" class="form-control" v-model="userEditable.birth_date" />
</form>
<button class="btn btn-block btn-success mt-2">Guardar</button>
<button class="btn btn-block btn-danger mt-2"
#click.prevent="cancelEdit">Cancelar</button>
</div>
Script
data: function() {
return {
profile: 1,
userGlobal: "",
userEditable: [],
editMode: false
};
},
created: function() {
this.fetchUser();
},
methods: {
fetchUser: function() {
const vm = this;
axios
.get(
"http://localhost:4000/api/users/96759c00-2682-11ea-827a-48ba4e44ff52"
)
.then(function(res) {
vm.userGlobal = res.data.user[0];
})
.catch(function(err) {
console.log(err);
});
},
cancelEdit: function(){
this.userEditable = this.userGlobal;
this.editMode = false;
},
modifyModal: function() {
this.userEditable = JSON.stringify(this.userGlobal)
this.editMode = true;
},
When I modify any of the form entries of userEditable it also modifies the userGlobal variable. This happens to me on other components. (I didn't code the patch function because I want to solve this issue first).
How can I resolve this problem?

AngularJs - how to reload page after adding new data to datatable

I am very new to angularjs and using angularjs bootstrap datatable. Now when I add new record to my datatable it is being updated in mysql database but I need to reload my page so new record can be displayed in table also but I don't know how to do it. Can anyone please help me? Can I init tableRoleCtrl on success of addRoleData() in ui-bootstrp.js?
Here is my code
ui-bootstrap.js
.controller('ModalInstanceCtrl', function ($scope, $modalInstance, content, tableService) {
//add new role
$scope.addRole = function(w) {
tableService.addRoleData(w)
}
})
table.js
.controller('tableRoleCtrl', function($filter, $sce, ngTableParams, tableService) {
//var data = tableService.data;
var self = this;
var promise = tableService.getRoleData();
self.data = [];
promise.then(
function(payload) {
self.data = payload.data;
//alert(JSON.stringify(self.data));
//console.log("test" + self.data)
self.tableEdit = new ngTableParams({
page: 1, // show first page
count: 10 // count per page
}, {
total: self.data.length, // length of data
getData: function($defer, params) {
$defer.resolve(self.data.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
},
function(errorPayload) {
$log.error('failure loading movie', errorPayload);
});
//to updaate data
self.updateRole = function(w) {
tableService.updateRoleData(w);
}
})
service.js
.factory('tableService', ['$http', function($http){
var _this = this;
return {
// role
getRoleData: function() {
return $http.get("data/getRoles.php");
},
updateRoleData: function(w) {
$http.post("data/updateRole.php", w)
},
addRoleData: function(w) {
$http.post("data/addRole.php", w)
}
}
}])
html
<div data-ng-controller="ModalDemoCtrl">
<script type="text/ng-template" id="addrole.html">
<div class="modal-header">
<h4 class="modal-title">Add Role</h4>
</div>
<div class="modal-body m-l-15">
<form role="form">
<div class="row">
<div class="col-md-8">
<div class="input-group">
<span class="input-group-addon"><i class="zmdi zmdi-account"></i></span>
<div class="fg-line">
<input type="text" name="role_title" ng-model="add_role.role_title" class="form-control" placeholder="Title">
</div>
</div>
<br/>
<div class="">
<div class="input-group"><span class="input-group-addon"><i class="zmdi zmdi-account-circle"></i></span>
<select chosen multiple>
<option>Use seetings from</option>
<option>HR</option>
<option>Employee</option>
<option>Admin</option>
</select>
</div>
</div>
</div><br/>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-link" ng-click="ok(); addRole(add_role)">Submit</button>
<button class="btn btn-link" ng-click="cancel()">Cancel</button>
</div>
</script>
<button class="btn btn-default" ng-click="openStatic('addrole')">Add Roles</button>
</div>
<div class="table-responsive">
<table ng-table="tctrl.tableEdit" class="table table-striped" show-filter="true">
<tr ng-repeat="w in $data" ng-class="{ 'active': w.$edit }" ng-click="ShowHide12()" style="cursor:pointer">
<a href="" ng-click="getSingleRole()">
<td><span ng-if="!w.$edit">{{ w.rl_title }}</span>
<div ng-if="w.$edit"><input class="form-control" type="text" ng-model="w.rl_title" /></div>
</td>
</a>
<td>
<button type="button" class="btn btn-default" ng-if="!w.$edit" ng-click="w.$edit = true; "><i class="zmdi zmdi-edit"></i></button>
<button type="button" class="btn btn-default" ng-if="!w.$edit" ng-click="w.$edit = false"><i class="zmdi zmdi-close"></i></button>
<button type="button" class="btn btn-success" ng-if="w.$edit" ng-click="w.$edit = false; tctrl.updateRole(w)"><i class="zmdi zmdi-check"></i></button>
<button type="button" class="btn btn-default" ng-if="w.$edit" data-ng-click="w.$edit = 0" ><i class="zmdi zmdi-close"></i></button>
</td>
</tr>
</table>
</div>
You don't actually need to reload page when data is updated, AngularJS is MVC framework and each model AngularJS will create a watcher to update view.
Basically, you just need to store your table data to a scope variable $scope.tableData in your controller then use ng-repeat="row in tableData" to iterate your table data. ng-repeat will watch your tableData changes then update your table.
If you changed the ngTable data dynamically, you can refresh it with:
self.tableEdit.reload();

Categories

Resources