Vue.js: how to have routing across 3 columns - vuejs2

I am trying to set up an page resembling:
========================================================================
+ Nav + Items + Individual Item +
+---------------+---------------+--------------------------------------+
+ * Cats + List + Individual Selected +
+ * Dogs + Of + Cat +
+ + Cats + OR +
+ + OR + Dog +
+ + Dogs + +
+ + + +
+ + + +
========================================================================
Usage example: Select 'Cats' in the 'Nav' column => retrieve a list of Cats (via REST/JSON) into the 'Items' column; Select an individual Cat from the list => retrieve an individual Cat (via REST/JSON) into the "Individual Item" column.
This looks like an application of Nested Routes (https://router.vuejs.org/guide/essentials/nested-routes.html) but my google-fu must be weak and I can't find a 3-level example like this anywhere.
It is easy to arrange an either/or approach where a single right-hand column renders either "List of Items" or 'Item.'
I have tried to use named views but I get to a point where I have 3 columns but when I render an 'Item' component, then the "List of Items" column is emptied.
It may be that I need to arrange to render both "List of Items" and 'Items' column at the same time (via 'components' in my router config) BUT these are remote REST calls so this is too heavyweight to be practical. Maybe 'computed' or 'watched' properties will assist in this case?
Is there an example of this three-level navigation somewhere?
Any help appreciated.
Edit:
this is the sort of thing I thought would be needed:
<div class="row">
<div class="col-2 bg-light sidebar">
<div class="sidebar-sticky">
<h3 class="h3 pl-3">Actions</h3>
<navigation />
</div>
</div>
<div class="col-3 ml-auto bg-info px-3">
<router-view />
</div>
<div class="col-7 bg-warning px-3">
<router-view name="entity" />
</div>
</div>
...
{
path: 'persons',
component: httpVueLoader('persons.vue'),
children: [
{
path: 'person/:id',
components: {
default: httpVueLoader('persons.vue'),
entity: httpVueLoader('person.vue')
}
}
]
},

Related

How to add id to items when using v-for in VueJS

I have a data table and when I render those records on the website, I will add ids to the elements, each element is a different id(id="item-first"), so what to do?
<div class="" v-for="(item, index) in producthots" :key="index">
<div
:class="
index % 2 == 0 ? 'product-item row-reverse' : 'product-item'
"
>
I want when rendered, each element will have an id object
for adding id you can bind it as like as :src and :class, it would be like this :id look at the example below:
<div :id="'CollapseState' + index" aria-expanded="false"
class="ChangeState bg-white collapse"></div>
I binded the id and also for making it uniq I added + index end of it so the short answer is below code:
:id="'CollapseState' + index"

Populate Dynamic Input Box with existing Data VueJs

From the title itself, I want to populate a dynamically created input box that I will load via AJAX upon page load.
<div class="col-md-10" id="app">
<div class="form-row" v-for="i in travellers">
<div class="form-group col-md-6" v-for="(details, index) in bookingRequiredDetails">
<label for="required-details">{{ details }}</label>
<input
type="text"
class="form-control"
#input="prop('traveller_' + i, details, $event)"
placeholder="Required Details"
/>
</div>
</div>
</div>
data () {
return {
bookingForm: {
...
bookingRequiredDetails: ''
},
travellerDetails: {},
}
},
load: function () {
... where the data variable has value upon page load
vm.bookingForm.bookingRequiredDetails = data.bookingRequiredDetails;
if (data.travellerDetails) {
vm.travellerDetails = data.travellerDetails;
}
}
Loaded Data:
The input boxes generated will depend on the required details. So for this instance, there will be 3 generated input boxes.
bookingRequiredDetails: Array(1)
0: Array(3)
0: "Full Name"
1: "Age"
2: "Gender"
travellerDetails: Array(1)
0:
traveller_1: Object
Age: "12"
Full Name: "Jane"
Gender: "M"
1: ...
2: ...
Sample Output:
What I want is to populate the existing travellerDetails object with data loaded from the server to their respective input boxes. However, I have problems with pairing the correct data to their respective key-value pairs of the input box as shown in the screenshot.
Any idea would be greatly appreciated.
So I manage to solve it. By adding v-model.
v-model="travellerDetails['traveller_' + i][details]"
div class="col-md-10" id="app">
<div class="form-row" v-for="i in travellers">
<div class="form-group col-md-6" v-for="(details, index) in bookingRequiredDetails">
<label for="required-details">{{ details }}</label>
<input
type="text"
class="form-control"
v-model="travellerDetails['traveller_' + i][details]"
#input="prop('traveller_' + i, details, $event)"
placeholder="Required Details"
/>
</div>
</div>
</div>

How can I bind multiple values from array in v-model for form-input on vue.js?

I need to show full address in one form-input with buttons 'Edit' and 'Delete', so it's working, but in browser console I have error for all addresses like this
'[Vue warn]: Error in event handler for "input": "TypeError: Cannot use 'in' operator to search for 'zip' in 'Country Name', 'City', 'Street Address', [object Object]"'
My vue code:
<template>
<div>
....
</div>
...
<form class="form-inline" >
<div class="form-row col-md-6" v-for="address in addressList">
<b-form-group>
<b-form-input class="form-control mb-2 mr-sm-2" id="address.id" v-model="address.countryName + ', ' + address.city + ', ' + address.streetAddress + ', ' + address.zip" />
</b-form-group>
<div class="btn-group mr-2" role="group">
<button type="button" class="btn btn-secondary mb-2">Edit</button>
<button type="button" class="btn btn-secondary mb-2">Delete</button>
</div>
</div>
</form>
</b-form>
</div>
</template>
<script>
...
data() {
return {
addressList: [],
}
},
async beforeRouteEnter(to, from, next) {
next(async (c) => await c.initData());
},
methods: {
async initData() {
await this.loadAddressList();
},
async loadAddressList() {
this.addressList = await accountService.getAddressList();
},
}
}
</script>
I don't understand why I am getting this error but it's working. Is there another better solution for this? And without error?
v-model="address.countryName + ', ' + address.city + ', ' + address.streetAddress + ', ' + address.zip"
I think your problem lays with binding the v-model. How you have it, it binds/concats multiple variables which isn't the intended use for v-modal.
If you only want to display the value, you could try changing:
v-model="address.countryName + ', ' + address.city + ', ' + address.streetAddress + ', ' + address.zip"
to
:value="address.countryName + ', ' + address.city + ', ' + address.streetAddress + ', ' + address.zip"

Vue bind function on dynamic html elements

I am using datatable and has to add render different html based on few checks and that's why vue code has lots of jQuery events. I was wondering is there any way to assign event on dynamic html elements.
Inside Data table columns object
render:function(data, type, full, meta) {
let html = '<div class="catagory-checkbox">'
+ '<label>'
+ '<input id="' + data.LeadTrackingId + '" class="statusDetail" type="checkbox" />'
+ '<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>'
+ '</label>'
+ '</div>';
if(vm.isSuperAdmin)
return html;
return "";
}
Please don't do this. You're constructing html with string methods. This is not the way, and there's no need. Use template:, not render: :-)
Your code above should look like...
template : `
<div v-if"isSuperAdmin" class="catagory-checkbox">'
<label>
<input :id="LeadTrackingId" class="statusDetail" type="checkbox" />'
<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>
</label>
</div>
`
You can bind id like that, but do you need to? Good Vue code doesn't need ids on html elements.

Vue JS, Drag n drop, and Get Ids

I manage differents teams, and a single column of competitors.
With vue-dragula, I can drag n' drop competitors to the team I want, this is working fine.
Now, I need to detect which competitors is added to which team and modify the myTeam variable each drag and drop.
I wrote a fiddle here:
https://jsfiddle.net/xoco70/vzk27smw/9/
I removed the events because they won't work in fiddle, but they are like:
Vue.vueDragula.eventBus.$on(
'drop',
function (args) {
...
}
);
Vue.vueDragula.eventBus.$on(
'dropModel',
function (args) {
...
}
)
How should I get teams Id, and competitor Id that I moved, so I can persist asignations ???
Here is my Fiddle: https://jsfiddle.net/kanlidy/tsofafzq/4/
In your HTML template panel-body part:
<div class="panel-body">
<div class="container-dragula"
v-dragula="copyOne"
:team-id="team.id"
bag="third-bag">
<div v-cloak
v-for="(competitor, index) in copyOne"
:team-id="team.id"
:id="compotitor.id"
:index="index"
:key="competitor.id"
>{{competitor.name}}
</div>
</div>
</div>
In your wrapper-dragula part: :competitor="competitor" to :id="competitor.id"
<div class="wrapper-dragula">
<div class="container-dragula" v-dragula="competitorsArea"
bag="third-bag">
<div v-cloak
v-for="(competitor, index) in competitorsArea"
:id="competitor.id"
:index="index"
:key="competitor.id"
>{{competitor.name}}
</div>
</div>
</div>
In your JS:
created: function () {
Vue.vueDragula.eventBus.$on('drop', function (args) {
alert('teams ID is:'+args[1].parentNode.getAttribute("team-id"));
alert('competitors ID is: ' + args[1].getAttribute("id"));
})
}
Hope helps.