Dynamic v-model as an array object with keys VueJs - javascript

From the title itself I am having problems of creating a v-model with dynamic keys. It always end up with undefined all the bookingRequiredDetails when creating the dynamic v-model.
v-model="travellerDetails['traveller_' + traveller][details]"
I want to create something like this.
travellerDetails:{
"traveller_1": {"Full Name":"Jane", "lastName":"Doe"},
"traveller_2": {"Full Name":"John", "lastName":"Doe"},
},
HTML
<div class="col-md-10">
<div class="form-row">
<div class="form-group col-md-6" v-for="details in bookingRequiredDetails">
<label for="required-details">{{ details }}</label>
<input
type="text"
class="form-control"
v-model="travellerDetails['traveller_' + traveller][details]"
placeholder="Required Details"
/>
</div>
</div>
VUE
data () {
return {
travellerDetails: { },
travellers: 3,
bookingRequiredDetails: [ 'Full Name', 'Age', 'Gender'],
};
},

Related

How to pass data to method from a vue element iteration

I am developing an invoice system in laravel vuejs. I am trying to pass data to the method from a form. In this form, I have used iteration to add/remove input text/select fields. In order to Iterate I have used v-model of these inputs. Now these v-models fail to pass data. When I console, I see they are empty.
I am sharing codes of that form :
For Iteration
<div class="form-group" v-for="(item,k) in inputs" :key="k">
<div class="row mb-2">
<div class="col-md-3">
<select class="form-control" v-model="item.product_id"
#change="getProductCost()">
<option value="">Select Product</option>
<option v-for="(product, i) in products" :key="i" :value="product.id">{{
product.product_name }}</option>
</select>
</div>
<div class="col-md-3">
<input type="text" class="form-control" placeholder="Quantity" v-
model="item.quantity" #keyup="getProductCost">
</div>
<div class="col-md-3">
<input type="text" class="form-control" placeholder="Total" v-
model="item.total">
</div>
<div class="col-md-3">
<span>
<i class="fa fa-minus-circle text-danger" #click="removeElement(k)" v-
show="k || ( !k && inputs.length > 1)"></i>
<i class="fa fa-plus-circle text-success ml-4" #click="addElement(k)" v-
show="k == inputs.length-1"></i>
</span>
</div>
</div>
</div>
From script, I need to pass data (item : {}) to getProductCost() method
export default {
data() {
return {
allerrors : [],
inputs : [{
product_id : '',
quantity : '',
total : '',
}],
item : {
product_id : '',
quantity : '',
total : '',
}
}
},
getProductCost() {
axios.get('/api/product-cost?
product_id='+this.item.product_id+'&&quantity='+this.item.quantity,
this.data).then(response => {
this.data.total_product_price = response.data
})
},
addElement() {
this.inputs.push({
product_id : '',
quantity : '',
total : ''
})
},
removeElement (index) {
this.inputs.splice(index, 1)
},
Well, actually you are overwriting the scope of item in the forloop.
I could imagine, that you just have to rename this line
<div class="form-group" v-for="(item,k) in inputs" :key="k">
to something like this:
<div class="form-group" v-for="(input,k) in inputs" :key="k">
and check for renaming the coresponding references aswell.
Edit 1:
You can look here for the vuejs way to handle dynamic data bindings and adjust it to your case: https://blog.logrocket.com/how-to-make-form-elements-dynamic-in-vue-js/

How to select rows based on string options in html vue js?

I need to add new rows based on the select options.
If my option is "kfc" I need to select a particular row. If my selected option is "cemrt", I need to add another row.
<div class="card-content" v-for="(bok, index) in rules" :key="index">
<div class="row">
<div class="col-md-6">
<div class="form-group label-floating">
<label class="control-label">Booked</label>
<select class="form-control" v-model="bok.name">
<option value="SEENAT">SEENAT</option>
<option value="CEMRT">CEMRT</option>
<option value="KFC">KFC</option>
</select>
</div>
</div>
</div>
<div class="row" v-if="bok.name == SEENAT"> //NOT WORKING FROM HERE
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Arms(if any)</label>
<input type="text" class="form-control" v-model="bok.data.head" required="">
</div>
</div>
</div>
<div class="row" v-if="bok.name == KFC">
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Arms(if any)</label>
<input type="text" class="form-control" required="">
</div>
</div>
</div>
</div>
But I am using this code not able to add rows based on the options.
My vue js code is
addForm = new Vue({
el: "#addForm",
data: {
rules : [{
name:null,
section:null,
data : [{head:null,value:null}]
}],
},
methods: {
addNewRules: function() {
this.rules.push({ name: null, section: null,data [{head:null,value:null}] });
},
},
});
If I use option value as 1,2,3 etc. I am getting the result.
But I need to send SEENAT,CEMRT,KFC as data. How can I able to achieve the result.
Hard to tell. A reproduction on codesandbox would be welcome.
What I can see in your code at a first glance :
1) You forgot quotes around the options keys and thus it expects a constant. The fact you're using double equals instead of triple doesn't help:
v-if="bok.name === 'SEENAT'" // this
v-if="bok.name == SEENAT" // instead of that
2) data should be a function:
data() {
return {
rules: [
{
name: null,
section: null,
data: [{ head: null, value: null }]
}
]
};
},

AngularJS: Push Checked Checkboxes

I'm trying to work out how to push checked checkboxes, that are submitted via a form, to an object called services, using AngularJS.
These are my objects:
$scope.sectors = [ 'health', 'social', 'education' ];
$scope.services = [
{
'name': 'Hernia Repair',
'sectors': { 'health': true }
},
{
'name': 'Cancer',
'sectors': { 'health': true, 'social': true, 'education': true }
},
];
And this is my form:
<form role="form" ng-submit="createService(newService)">
<div class="form-group">
<label for="serviceName">Name of Service</label>
<input id="serviceName" type="text" class="form-control" ng-model="newService.name" placeholder="Name of Service">
</div>
<div class="form-group">
<label for="serviceName">Another</label>
<input id="serviceName" type="text" class="form-control" ng-model="newService.another" placeholder="Name of Antoher">
</div>
<div class="checkbox-inline" ng-repeat="sector in sectors">
<label>
<input type="checkbox" name="optionsRadios" id="{{sector}}" value="{{sector}}" ng-model="service.sectors[sector]">
{{sector}}
</label>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
And here's the JS I'm using to push the data onto the form:
function createService(service) {
$scope.services.push(service);
}
$scope.createService = createService;
The name seems to get added to the list of services, but the sectors do not. Can anyone point me in the right direction, or explain what I might be doing wrong.
Any help is appreciated. Thanks in advance!

Angular js not retrieving value by id's for dropdowns

I have an angular app with the following function:
$scope.search= function(){
var lname = document.getElementById("lastname").value;
var campus2 = document.getElementById("campusid").value;
StudentSearchService.getStudents(lname, campus2, function(data){
if(data!=null){
$scope.students = data;
}
});
}
and in the html page, I have the following 2 fields:
<div class="form-group col-lg-4 col-md-4">
<label for="lastname"> Last Name: </label>
<input type="text" id="lastname" placeholder="Last Name" class="form-control" />
</div>
<div class="form-group col-lg-4 col-md-4">
<label for="campus"> Campus:</label>
<select class="form-control" id="campusid" ng-model="newcampus" ng-options="camp.name for camp in campus" >
<option value="">ALL - District</option>
</select>
</div>
When i click to Search, the value for the lname is being retrieved just fine but the value from the dropdown campus2 is not being being initialized. Thus the call to the service is not being made properly.
Where am I going wrong?
First, it is not necessary to pick values from DOM elements if you are using Angular. It is way more easier to bind variables and use the variables themselves. I have created your example in JSFiddle: http://jsfiddle.net/rmadhuram/1n14eqfw/2/
HTML:
<div ng-app="app" ng-controller="FormController">
<div class="form-group col-lg-4 col-md-4">
<label for="lastname">Last Name:</label>
<input type="text" id="lastname" ng-model="lastName" placeholder="Last Name" class="form-control" />
</div>
<div class="form-group col-lg-4 col-md-4">
<label for="campus">Campus:</label>
<select class="form-control" id="campusid" ng-model="newcampus" ng-options="camp.name for camp in campus">
</select>
</div>
<button ng-click='search()'>Search</button>
</div>
JavaScript:
angular.module('app', [])
.controller('FormController', ['$scope', function ($scope) {
$scope.campus = [
{ name: 'campus 1' },
{ name: 'campus 2' }
];
$scope.newcampus = $scope.campus[0];
$scope.lastName = '';
$scope.search = function() {
alert('Name: ' + $scope.lastName + ' Campus: ' + $scope.newcampus.name);
};
}]);
Hope this helps!
The biggest place you are going wrong is by trying to access values directly from the DOM inside your Angular controller, rather than relying on Angular to bind properties on the scope to your inputs and handle all of that for you.
I have made a version in Plunkr that demonstrates the "Angular way" of approaching this.
The guts of the controller is:
app.controller('MainCtrl', function($scope, StudentSearchService) {
$scope.campus = [
{name: "Campus 1"},
{name: "Campus 2"}
];
$scope.searchParams = {
lastName: "",
campus: null
};
$scope.search = function() {
StudentSearchService.getStudents($scope.searchParams.lastName,
$scope.searchParams.campus.name,
function(data) {
if (data !== null) {
$scope.students = data;
}
});
}
});
And then your markup becomes:
<div class="form-group col-lg-4 col-md-4">
<label for="lastname">Last Name:</label>
<input type="text" id="lastname" placeholder="Last Name" class="form-control" ng-model="searchParams.lastName" />
</div>
<div class="form-group col-lg-4 col-md-4">
<label for="campus">Campus:</label>
<select class="form-control" id="campusid" ng-model="searchParams.campus" ng-options="camp.name for camp in campus">
<option value="">ALL - District</option>
</select>
</div>
Note the use of ng-model to bind the inputs to scope properties. Also note there is no DOM access code in the controller. This makes it easier to test, and allows you to test your controller without any DOM at all. That is the core philosophy Angular is based around.

Clear form after submit

I am submitting a form - and adding the contents to an array, however whenever the item is added to the array, it is still bound to the form.
I would like to add the item, clear the form. Something like jquery's reset();
Here's my template:
<div class="col-xs-12" ng-controller="ResourceController">
<div class="col-md-4">
<h3>Name</h3>
</div>
<div class="col-md-8">
<h3>Description</h3>
</div>
<form class="form-inline" role="form" ng-repeat="item in resources">
<div class="form-group col-md-4">
<input type="text" class="form-control" value="{{ item.name }}"/>
</div>
<div class="form-group col-md-7">
<input type="text" class="form-control" value="{{ item.description }}"/>
</div>
</form>
<form class="form-inline" role="form" name="addResourceForm" ng-submit="addResource()">
<div class="form-group col-md-4">
<input type="text" class="form-control" name="name" ng-model="name" placeholder="Name"/>
</div>
<div class="form-group col-md-7">
<input type="text" class="form-control" name="description" ng-model="description" placeholder="Description"/>
</div>
<div class="form-group col-md-1">
<button type="submit" class="btn btn-default">Add</button>
</div>
</form>
</div>
And my controller:
(function(){
var app = angular.module('event-resources', []);
app.controller('ResourceController', function($scope){
$scope.addResource = function(){
$scope.resources.push(this);
}
var defaultForm = {
name : '',
description: ''
};
$scope.resources = [
{
name: 'Beer',
description: 'Kokanee'
},
{
name: 'Pucks',
description: 'Black Round Things'
}
]
});
})();
Use angular.copy() to copy the item data to the resources array, and then you can safely clear the item data. The angular.copy() makes a deep copy of the object, which is what you want.
Alternately, here is a simpler method, which doesn't use any extra method calls:
$scope.addResource = function() {
$scope.resources.push({
name: $scope.name, // recreate object manually (cheap for simple objects)
description: $scope.description
});
$scope.name = ""; // clear the values.
$scope.description = "";
};
$scope.addResource = function(){
$scope.resources.push(angular.copy(this));
$scope.name="";
$scope.description=""
}
Push the copy to the resources array and change name and description back to ""

Categories

Resources