Polymer. It is possible to render element in {{}}? - dynamic

In json i have metadata of field's type of control (textbox, textarea, combobox, email, date, address etc).
{
"Metadata":
"Fields":
[
{
"Fieldname": "id",
"Title": "Uniq id",
"ClientValueType":"int",
"ClientControltType":"textbox",
"ClientInputWidth":"9"
},
{
"Fieldname": "name_full",
"Title": "org full name",
"ClientValueType":"string",
"ClientControlType":"textarea",
"ClientInputWidth":"100"
},
{
"Fieldname": "name_full",
"Title": "org full name",
"ClientValueType":"string",
"ClientControlType":"textarea",
"ClientInputWidth":"100"
}
]
},"Data":[ {id:1, name_full:"org1"}, {id:2, name_full:"org2"}]
}
Let's this controls in different files for each edit type: textbox.html, textarea.html, combobox.html etc.
Textbox.html for example
<polymer-element name="text-box" noscript>
<template>
here is textbox
</template>
</polymer-element>
I need to dynamically import these elements to render dynamic edit form based on field.ClientControlType value
<polymer-element name="rawc-detail" attributes="data">
<template>
<div class="panel panel-default">
<div class="panel-body">
<form class="form-horizontal" role="form">
<template id="fields" repeat="{{val in fields}}">
<div class="form-group">
<label for="val.Name" class="col-sm-2 control-label">{{val.Title}}</label>
<div class="col-sm-10">{{val.element}}</div>
</div>
</template>
</form>
</div>
</div>
<style>
</style>
</template>
<script>
Polymer({
data:{},
ready: function() {
this.fields = [];
},
dataChanged: function(oldValue, newValue) {
this.bindNewData();
},
bindNewData: function() {
console.log(this.data);
var t = document.querySelector('rawc-detail::shadow #fields');
if (t)
{
var model = {
fields: []
};
for (var i=0; i<this.data.Metadata.Fields.length; i++)
{
var field = this.data.Metadata.Fields[i];
//console.log(field);
if (field.ClientControlType == "textbox")
{
var link = document.createElement('link');
link.href='http://localhost/testdatafile?shema=polymer_parts&name=textbox.html';
this.parentNode.appendChild(link);
//this.ownerDocument
// Polymer.import(['http://localhost/testdatafile?shema=polymer_parts&name=textbox.html'], function() {
var name = 'el-'+field.Fieldname;
console.log(name);
var textbox = document.createElement(name, 'rawc-textbox');
console.log(textbox);
//t.appendChild(textbox);
field.element = textbox;
model.fields.push(field);
// var tt = document.querySelector('rawc-detail::shadow '+name);
// console.log('tt=', tt);
// tt.description = 'a dynamic import';
// });
}
// console.log(field);
}
t.model = model;
}
}
});
is this possible?

detail.html
<polymer-element name="rawc-detail" attributes="data">
<template>
<apply-author-styles></apply-author-styles>
<h3 title="{{data.Metadata.DescOne}}" class="text-center">{{data.Metadata.TitleOne}}</h3>
<div class="panel panel-default">
<div class="panel-body">
<form class="form-horizontal" role="form">
<div id="forminner">
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="button" class="btn btn-primary" on-tap="ClickOk()">Ок</button>
<button type="button" class="btn btn-primary" on-tap="ClickCancel()">Отмена</button>
</div>
</div>
</form>
</div>
</div>
<style>
</style>
</template>
<script>
Polymer({
data:{},
ready: function() {
this.fields = [];
},
dataChanged: function(oldValue, newValue) {
this.bindNewData();
},
inarray: function(val, arr) {
for(var i=0; i<arr.length; i++)
if (arr[i] == val)
return true;
return false;
},
bindNewData: function() {
var t = document.querySelector('rawc-detail::shadow #forminner');
var elementUrls = [];
for (var i=0; i<this.data.Metadata.Fields.length; i++)
{
var field = this.data.Metadata.Fields[i];
var el = null;
var name = 'el-'+field.Fieldname;
if (field.ClientControlType === "textbox")
{
el = document.createElement('rawc-textbox');
el.id = name;
el.data = this.data.Content[0].Data[field.Fieldname];
url = 'http://localhost/testdatafile?shema=polymer_parts&name=textbox.html';
if (!this.inarray(url, elementUrls))
elementUrls.push(url);
}
var div=document.createElement('div');
div.className="form-group";
var label = document.createElement('label');
label.id = name;
label.className = "col-sm-2 control-label";
label.for = field.Name;
label.innerHTML = field.Title;
div.appendChild(label);
if (el != null)
div.appendChild(el);
t.appendChild(div);
}
for(var i=0; i<elementUrls.length; i++)
Polymer.import([elementUrls[i]]);
}
});
</script>
</polymer-element>
textbox.html
<polymer-element name="rawc-textbox" attributes="data">
<template id="textbox">
<input type="text" value="{{data}}">
<button on-click="{{clickme}}">go</button>
</template>
<script>
Polymer(
{
clickme:function(e,p,o){
console.log(this.data);
}
});
</script>
</polymer-element>

Related

How change inputs type in VUE?

I have a input with type=radio
<div id="test">
<div class="input-group mb-3" v-for="(input, k) in inputs" :key="k">
<input type="radio" class="abc" disabled>
</div>
</div>
How can on click button i can change all inputs with class="abc" from radio to checkbox
<script>
var app = new Vue({
el: "#test",
methods: {
changeInputType(e) {
if (e.target.checked == true) {
alert('true');
} else {
alert('false');
}
},
}
});
</script>
is any simple way to do this in this changeInputType function ?
bind the input type to variable and change that variable
<template>
<div>
<input :type="inputType" />
<button #click="changeType />
</div>
</template>
<script>
export default {
data() {
return {
inputType: "text",
}
},
methods: {
changeType() {
if (this.inputType === "text") {
this.inputType = "radio"
} else {
this.inputType = "text"
}
}
}
}
</script>
Here is the solution of your answer, By clicking on button all input types will be changed from radio to checkbox.
<div id="test">
<div class="input-group mb-3" v-for="(input, k) in inputs" :key="k">
<input :type="input" class="abc" disabled>
</div>
<div class="btn btn-sm" #click="changeInputType">Change Input Type</div>
</div>
<script>
var app = new Vue({
el: "#test",
data() {
return {
inputs: ['radio', 'radio']
}
},
methods: {
changeInputType() {
this.inputs = ['checkbox', 'checkbox']
},
}
});
</script>
On butt click change the type variable to checkbox.
<script>
var app = new Vue({
el: "#test",
data() {
return {
input: 'radio'
}
},
methods: {
btnClick() {
this.input = 'checkbox'
},
}
});
</script>

How to use "this" in Vue 3

I'm working on a component in Vue3/TypeScript. I'm relatively new to Vue.
I'm dynamically creating a div. I want to be able to delete it when a user clicks on the "x" button. This is the "closeStatus" method.
In JavaScript I can pass this, but Vue hates it.
If anyone can help.
Thanks.
Here is the code:
<template>
<div>
<button #click="addStatus()" >Add Status</button>
<div id="slide" class="slide-modal">
<div class="clear-notifications" #click='clearAllNotifications()'>Clear all notifications</div>
<div class="status-div">
<div>11:00 Booking requested</div>
<div #click="closeStatus(this)"><img src="../assets/cross.svg" /></div>
</div>
<div class="status-div">
<div>11:30 Booking requested</div>
<div #click="closeStatus(this)"><img src="../assets/cross.svg" /></div>
</div>
</div>
</div>
</template>
<script lang="ts">
export default {
name: 'SlideModal',
methods: {
clearAllNotifications() {
const allNotifications = document.querySelectorAll(".status-div");
for(let x=0;x<allNotifications.length;x++) {
allNotifications[x].remove(); //removes all the child elements.
}
document.getElementById('slide').style.visibility='hidden'; //This should be Vue reactive.
},
addStatus() {
document.getElementById('slide').style.visibility='visible'; //This should be Vue reactive.
const statusMessage = "Another Message"
var div = document.createElement('div');
div.setAttribute('class', 'status-div');
div.innerHTML = '<div>' + statusMessage + '</div><div onclick="closeStatus(this)"><img src="/src/assets/cross.svg" /></div>'
document.getElementById('slide').appendChild(div);
},
closeStatus(elm: any) {
elm.parentNode.remove();
const allNotifications = document.querySelectorAll(".status-div");
if(allNotifications.length == 0 ) {
document.getElementById('slide').style.visibility='hidden'; //This should be Vue reactive.
}
}
}
}
</script>
Code is javascript DOM management stuff and far from Vue style.
Vue manages DOM with variables and that is what makes javascript frameworks awesome.
Let me first share the modified code.
<template>
<div>
<button #click="addStatus()" >Add Status</button>
<div id="slide" class="slide-modal" v-show="visibleSlide">
<div class="clear-notifications" #click='clearAllNotifications()'>Clear all notifications</div>
<div class="status-div">
<div>11:00 Booking requested</div>
<div #click="closeStatus(this)"><img src="../assets/cross.svg" /></div>
</div>
<div class="status-div">
<div>11:30 Booking requested</div>
<div #click="closeStatus(this)"><img src="../assets/cross.svg" /></div>
</div>
</div>
</div>
</template>
<script lang="ts">
export default {
name: 'SlideModal',
data() {
return {
visibleSlide: true
}
},
methods: {
clearAllNotifications() {
const allNotifications = document.querySelectorAll(".status-div");
for(let x = 0; x < allNotifications.length; x++) {
allNotifications[x].remove(); //removes all the child elements.
}
this.visibleSlide = false
},
addStatus() {
this.visibleSlide = true;
const statusMessage = "Another Message";
var div = document.createElement('div');
div.setAttribute('class', 'status-div');
div.innerHTML = '<div>' + statusMessage + '</div><div onclick="closeStatus(this)"><img src="/src/assets/cross.svg" /></div>'
document.getElementById('slide').appendChild(div);
},
closeStatus(elm: any) {
elm.parentNode.remove();
const allNotifications = document.querySelectorAll(".status-div");
if(allNotifications.length == 0 ) {
this.visibleSlide = false
}
}
}
}
</script>
I have just updated what is commented: "//This should be Vue reactive."
But it is still not benefiting from Vue framework.
Here is my whole idea of Vue code
<template>
<div>
<button #click="addStatus()" >Add Status</button>
<div id="slide" class="slide-modal" v-if="statuses.length">
<div class="clear-notifications" #click='clearAllNotifications()'>Clear all notifications</div>
<div v-for="status in statuses" :key="status.id" class="status-div">
<div>{{ status.text }}</div>
<div #click="closeStatus(status)"><img src="../assets/cross.svg" /></div>
</div>
</div>
</div>
</template>
<script lang="ts">
export default {
name: 'SlideModal',
data() {
return {
statuses: [
{
id: 1,
text: '11:00 Booking requested'
}, {
id: 2,
text: '11:30 Booking requested'
}
]
}
},
methods: {
clearAllNotifications() {
this.statuses = []
},
addStatus() {
const statusMessage = "Another Message";
this.statuses.push({
id: this.statuses.length + 1,
text: statusMessage
})
},
closeStatus(elm: any) {
const index = this.statuses.map((status) => status.id).indexOf(elm.id);
this.statuses.splice(index, 1);
}
}
}
</script>
As you can see, DOM elements are managed by variables and their operations instead of DOM management methods.
Hope this is helpful

How to make disabled button after click in Vuejs

I have a button on my website that gives bonuses to the user. Button have several conditions in 1 button:
<button class="btn btn--small btn--purple" :disabled="isDisabled" #click="takeBonus">Take</button>
<script>
......
computed: {
isDisabled() {
return this.heal_used === 1 || this.diff < 10;
this.$forceUpdate();
},
},
.......
</script
But when user click Take button, and if all success, button is still active this.$forceUpdate(); not working. And i need make when user click Take button, and if all success, make this button disabled.
My full Bonus.vue:
<template>
<div class="inner-page">
<div class="account" v-if="loaded && !$root.isMobile">
<div class="page-header">
</div>
<div class="form-panels hide-below-m">
<div class="col-7" style="margin-top: 5rem;margin-right: 3rem;">
<div class="faucet-component mx-5" rv-class-boost="data.boostIsOpen">
<img src="https://dota2.skins1.games/src/img/components/shine.png?v=8ce59643e70cb2f8550deb6a249b5f29" class="faucet-component__shine-bg">
<div class="faucet-component__content d-flex justify-content-between align-items-center flex-column w-100" style="
height: 15rem;">
<div class="faucet-component__available-amount-block round-circle p-2">
<div class="faucet-component__availabe-amount-coins d-flex justify-content-center align-items-center round-circle h-100" rv-currency="model:amount">Спасение</div>
</div>
<!-- rivets: unless model:cnt | eq 0 --><div class="faucet-component__remaining">
<span rv-t="">Left</span>:
<span>{{ bonus_num }}</span><br>
<span rv-t=""></span>
<span>{{ diff }}</span>
</div>
<!-- rivets: if model:cnt | eq 0 -->
<div class="faucet-component__buttons-container d-flex align-items-center w-75 justify-content-around">
<button class="btn btn--small btn--purple" :disabled="isDisabled" #click="takeBonus">Take</button>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
loaded: false,
bonus: {},
diff: {},
user: {},
bonus_num: 0,
heal_used: {}
}
},
mounted() {
this.$root.isLoading = true;
if (!this.$cookie.get('token')) {
this.$root.isLoading = false;
this.$router.go(-1);
}
this.domain = window.location.protocol + '//' + window.location.hostname;
setTimeout(() => {
this.getUser();
}, 100);
},
computed: {
isDisabled() {
return this.heal_used === 1 || this.diff < 10;
this.$forceUpdate();
},
},
methods: {
getUser() {
this.$root.axios.post('/user/getProfile')
.then(res => {
const data = res.data;
console.log(data.heal_used);
console.log(data.diff);
this.loaded = true;
this.user = data.user;
this.bets = data.bets;
this.bonus = data.bonus;
this.diff = data.diff;
this.heal_used = data.heal_used;
this.new_day = data.new_day;
this.bonus_num = data.bonus_num;
this.$root.isLoading = false;
})
.catch(err => {
this.$root.isLoading = false;
this.$router.go(-1);
})
},
takeBonus() {
this.$root.axios.post('/user/takeBonus', {
value: this.user.cashback
})
.then(res => {
const data = res.data;
if (data.type === 'success') {
console.log(data.heal_used);
this.bonus_num = data.bonus_num;
this.$root.user.balance = data.newBalance;
this.heal_used = data.heal_used;
this.$forceUpdate();
}
this.$root.showNotify(data.type, this.$t(`index.${data.message}`));
})
},
}
}
How i can make it, when user click Take button, and if all success, so that the Take button becomes disabled?
I'm sorry but your code has no indentation, so I just did that on jsfiddler so you know "How to make disabled button after click in Vuejs". You can have a look on : https://jsfiddle.net/o81yvn05/1/
<div id="app">
<button :disabled="isDisabled" #click="disableButton()">Please click here</button>
</div>
<script>
new Vue({
el: "#app",
data: {
isDisabled: false,
},
methods: {
disableButton() {
this.isDisabled = true
}
}
})
</script>

Append Textarea (description) when uploading an image

I have a basic file upload in Vue.js. I am trying to append a textarea so that I can add a description about the file. However, I can not see to get this to work. The idea is to be able to send files through the API that i am creating in laravel.
<template>
<div class="container">
Files
<input type="file" id="files" ref="files" multiple v-on:change="handleFilesUpload()" />
<div v-for="(file, key) in files" :key="file.id" class="file-listing">
{{ file.name }}
<textarea
name="description"
id="description"
cols="30"
rows="10"
v-model="description"
></textarea>
<span class="remove-file" v-on:click="removeFile( key )">Remove</span>
</div>
<button v-on:click="addFiles()">Add Files</button>
<button v-on:click="submitFiles()">Submit</button>
</div>
</div>
</template>
<script>
export default {
data() {
return {
files: [],
description: ""
};
},
methods: {
addFiles() {
this.$refs.files.click();
},
submitFiles() {
let formData = new FormData();
let description = this.description;
description = JSON.stringify(description);
for (var i = 0; i < this.files.length; i++) {
let file = this.files[i];
formData.append("files[" + i + "]", file);
formData.append("description[" + i + "]", description);
}
axios
.post("/media", formData, {
headers: {
"Content-Type": "multipart/form-data"
}
})
.then(function() {
console.log("SUCCESS!!");
})
.catch(function() {
console.log("FAILURE!!");
});
},
handleFilesUpload() {
let uploadedFiles = this.$refs.files.files;
for (var i = 0; i < uploadedFiles.length; i++) {
this.files.push(uploadedFiles[i]);
}
},
removeFile(key) {
this.files.splice(key, 1);
}
}
};
</script>
I am trying to add a description for each file. Does anyone have any ideas please?
Here there is one description model but we need a description model for each file.
So let define them
<template>
<div class="container">
Files
<input
id="files"
ref="files"
type="file"
multiple
#change="handleFilesUpload()"
/>
<div v-for="(item, key) in files" :key="key" class="file-listing">
{{ item.file.name }}
<textarea
v-model="item.description"
name="description"
cols="30"
rows="10"
></textarea>
<span class="remove-file" #click="removeFile(key)">Remove</span>
</div>
<button #click="addFiles()">Add Files</button>
<button #click="submitFiles()">Submit</button>
</div>
</template>
<script>
export default {
data() {
return {
files: [],
description: ''
}
},
methods: {
addFiles() {
this.$refs.files.click()
},
submitFiles() {
let formData = new FormData()
for (var i = 0; i < this.files.length; i++) {
let item = this.files[i]
formData.append('files[' + i + ']', item.file)
formData.append('description[' + i + ']', item.description)
}
axios
.post('/media', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
.then(function() {
console.log('SUCCESS!!')
})
.catch(function() {
console.log('FAILURE!!')
})
},
handleFilesUpload() {
let uploadedFiles = this.$refs.files.files
for (var i = 0; i < uploadedFiles.length; i++) {
this.files.push({
file: uploadedFiles[i],
description: ''
})
}
},
removeFile(key) {
this.files.splice(key, 1)
}
}
}
</script>
See working example here
<div class="field relative">
<label>Description</label>
<textarea class="textarea" v-model="description" type="text" maxlength="10000"> </textarea>
<label for="upload-file" class="icn icn-camera cursor-pointer absolute bottom-3 right-4">
<input type="file" id="upload-file" hidden ref="file" #change="getImage($event)" accept="image/**" />
</label>
</div>
use Relative and Absolute position to put the camera icon inside the
textarea
use bottom-3 right-4 to find the proper position
change the default upload file icon to a camera icon

Select checkbox and shows its related objects in Vue.js

In my Vue.js project, I have two separate components are Country and States. I have merged them in one page. So now if I select one country it will display related states. How to do this?
<template>
<div>
<div style=margin-left:355px><country-index></country-index></div>
<div style=margin-left:710px><state-index></state-index></div>
</div>
</template>
<script>
import { ROAST_CONFIG } from '../../../config/config.js';
import CountryIndex from './components/country/Index';
import StateIndex from './components/state/Index';
import { listen } from '../../../util/history.js';
import axios from 'axios'
let baseUrl = ROAST_CONFIG.API_URL;
export default {
name: 'LocationsView',
layout: 'admin/layouts/default/defaultLayout',
middleware: 'auth',
components: {
'country-index' : CountryIndex,
'state-index' : StateIndex,
},
data() {
return { currentComponent:'','countryId':''}
},
methods: {
updateCurrentComponent(){
console.log(this.$route.name);
let vm = this;
let route = vm.$route;
if(this.$route.name == "Locations"){
this.currentComponent = "country-index";
}
}
},
mounted() {
let vm = this;
let route = this.$route;
window.addEventListener('popstate',this.updateCurrentComponent);
},
created() {
this.updateCurrentComponent();
}
}
Country Component
<template>
<div style="display:flex;height:100%">
<d-dotloader v-if="componentLoading" />
<div id="parent" class="list-manager" v-if="!componentLoading">
<div class="list-header">
<div class="bulk-action" :class="{'hide': showTop}" >
<div class="pull-left">
Countries
</div>
<!-- /pull-left -->
<div class="pull-right">
<d-button #click.native = "addCountry();"><i class="icon icon-sm"></i><span>New</span></i></d-button>
</div>
</div>
<!-- /bulk-action -->
<div class="bulk-action" :style ="{display:(showTop)?'block!important':'none!important'}" >
<div class="btn-toolbar">
<d-check field-class="check" v-model="selectAll" wrapper-class="field-check field-check-inline" label-position="right" label="" value="sel" #click.native = "toggleSelectAll();"/>
<d-button :is-loading="isLoading" #click.native = "deleteCountry();">Delete<i class="icon icon-sm" name="trash-2"></i></d-button>
<!-- <div class="pull-right mt5"><div class="green-bubble"></div>{{SelectedItems}}</div> -->
<d-button #click.native = "closeBulkToolBar();">close<i class="icon icon-sm" name="x"></i></d-button>
</div>
</div>
<!-- /bulk-action -->
</div>
<d-dotloader v-if="subListComponentLoading" />
<d-list-items :data="fetchData" #rowClick="changeCountryView" ref="itemsTable">
<d-list-cell column-class="list-item-check" :column-styles="{width: '40px'}" type="selectAll">
<template scope="row">
<div class="field-check field-check-inline" #click.stop="toggleSelect(row.rowIndex)" >
<input type="checkbox" class="check" :id="row.id" :value="row.id" :checked="row.selectAll">
<label></label>
</div>
<d-button #click.native = "editCountry(row.id);">Edit</d-button>
</template>
</d-list-cell>
<d-list-cell column-class="list-item-content">
<template scope="row">
<div class="list-item-content">
<div class="list-item-title">
<div class="pull-right">{{row.ISO_Code}}</div>
<div title="" class="pull-left">{{row.country_name}}</div>
</div>
<div class="list-item-meta">
<div class="pull-right">{{row.Default_Currency}} | {{row.Call_prefix}} </div>
<div class="pull-left">{{row.Zone}}</div>
</div>
<span class="list-item-status enabled"></span>
</div>
</template>
</d-list-cell >
</d-list-items>
</div>
</div>
</template>
<script>
import axios from 'axios'
import { ROAST_CONFIG } from '../../../../../config/config.js';
var baseUrl = ROAST_CONFIG.API_URL;
export default {
data () {
return {
SelectedItems:"",
isLoading:false,
show:true,
searchBy: '',
activeSearch: '',
showTop: false,
selectAll : false,
componentLoading:true,
subListComponentLoading:false,
showModal: false,
form :{
country_name: '',
isCountryEnabled: true,
}
}
},
methods: {
async fetchData ({search, page, filter, sort,rows}) {
let resData;
let vm = this;
axios.defaults.headers.common['Authorization'] = "Bearer "+localStorage.getItem('token');
const res = await axios.post(baseUrl+'/country/fetch',{search, page, filter, sort,rows})
.then((response) => {
if( (typeof(response) != 'undefined') && (typeof(response.data) != 'undefined') && (typeof(response.data.fetch) != 'undefined')){
return response.data.fetch;
}
});
return res;
},
toggleSelect(rowId){
if(typeof(this.$refs.itemsTable.rows[rowId]) != 'undefined'){
this.$refs.itemsTable.rows[rowId].selectAll = !this.$refs.itemsTable.rows[rowId].selectAll;
let data = this.$refs.itemsTable.rows;
let status = false;
let selectAllStatus = true;
let items = 0;
for(var i=0;i <= data.length;i++){
if((typeof(data[i])!= 'undefined')&&(data[i].selectAll)){
items++;
this.SelectedItems = items +" Selected Items";
status = true;
}
if((typeof(data[i])!= 'undefined')&&(!data[i].selectAll)){
selectAllStatus = false;
}
this.showTop = status
}
}
},
toggleSelectAll(){
this.selectAll = !this.selectAll;
let items = 0;
let data = this.$refs.itemsTable.rows;
let status = false;
let rowId = '1'
for(var i=0;i <= data.length;i++){
if((typeof(data[i])!= 'undefined')){
items++;
this.SelectedItems = items +" Selected Items";
status = this.selectAll;
data[i].selectAll = status;
}
}
this.showTop = status
},
closeBulkToolBar(){
this.SelectedItems = "";
this.showTop = false;
},
}
}
State Component
<template>
<div style="display:flex;height:100%">
<d-dotloader v-if="componentLoading" />
<div id="parent" class="list-manager" v-if="!componentLoading">
<div class="list-header">
<div class="bulk-action" :class="{'hide': showTop}" >
<div class="pull-left">
States
</div>
<!-- /pull-left -->
<div class="pull-right">
<d-button #click.native = "addState();"><i class="icon icon-sm"></i><span>New</span></i></d-button>
</div>
</div>
<!-- /bulk-action -->
<div class="bulk-action" :style ="{display:(showTop)?'block!important':'none!important'}" >
<div class="btn-toolbar">
<d-check field-class="check" v-model="selectAll" wrapper-class="field-check field-check-inline" label-position="right" label="" value="sel" #click.native = "toggleSelectAll();"/>
<d-button :is-loading="isLoading" #click.native = "deleteState();">Delete<i class="icon icon-sm" name="trash-2"></i></d-button>
<!-- <div class="pull-right mt5"><div class="green-bubble"></div>{{SelectedItems}}</div> -->
<d-button #click.native = "closeBulkToolBar();">close<i class="icon icon-sm" name="x"></i></d-button>
</div>
</div>
<!-- /bulk-action -->
</div>
<d-dotloader v-if="subListComponentLoading" />
<d-list-items :data="fetchData" #rowClick="changeStateView" ref="itemsTable">
<d-list-cell column-class="list-item-check" :column-styles="{width: '40px'}" type="selectAll">
<template scope="row">
<div class="field-check field-check-inline" #click.stop="toggleSelect(row.rowIndex)" >
<input type="checkbox" class="check" :id="row.id" :value="row.id" :checked="row.selectAll">
<label></label>
</div>
<d-button #click.native = "editState(row.id);">Edit</d-button>
</template>
</d-list-cell>
<d-list-cell column-class="list-item-content">
<template scope="row">
<div class="list-item-content">
<div class="list-item-title">
<div class="pull-right">{{row.ISO_Code}}</div>
<div title="" class="pull-left">{{row.state_name}}</div>
</div>
<div class="list-item-meta">
<div class="pull-left">{{row.country_name}} </div>
<div class="pull-right">{{row.Zone}}</div>
</div>
<span class="list-item-status enabled"></span>
</div>
</template>
</d-list-cell >
</d-list-items>
</div>
<state-add></state-add>
<state-edit></state-edit>
</div>
</template>
<script>
import axios from 'axios'
import { ROAST_CONFIG } from '../../../../../config/config.js';
var baseUrl = ROAST_CONFIG.API_URL;
export default {
data () {
return {
SelectedItems:"",
isLoading:false,
show:true,
searchBy: '',
activeSearch: '',
showTop: false,
selectAll : false,
componentLoading:true,
subListComponentLoading:false,
showModal: false,
form :{
country_name: '',
isCountryEnabled: true,
}
}
},
methods: {
async fetchData ({search, page, filter, sort,rows}) {
let resData;
let vm = this;
axios.defaults.headers.common['Authorization'] = "Bearer "+localStorage.getItem('token');
const res = await axios.post(baseUrl+'/state/fetch',{search, page, filter, sort,rows})
.then((response) => {
if( (typeof(response) != 'undefined') && (typeof(response.data) != 'undefined') && (typeof(response.data.fetch) != 'undefined')){
return response.data.fetch;
}
});
return res;
},
changeStateView(row){
if(typeof(this.$children[7]) != 'undefined'){
this.$parent.stateId = row.id;
this.viewComponent = "state-main";
this.$children[7].readState(this.$parent.stateId);
this.$router.push({name:"StatesView", params: {id:row.id}});
}
},
toggleSelect(rowId){
if(typeof(this.$refs.itemsTable.rows[rowId]) != 'undefined'){
this.$refs.itemsTable.rows[rowId].selectAll = !this.$refs.itemsTable.rows[rowId].selectAll;
let data = this.$refs.itemsTable.rows;
let status = false;
let selectAllStatus = true;
let items = 0;
for(var i=0;i <= data.length;i++){
if((typeof(data[i])!= 'undefined')&&(data[i].selectAll)){
items++;
this.SelectedItems = items +" Selected Items";
status = true;
}
if((typeof(data[i])!= 'undefined')&&(!data[i].selectAll)){
selectAllStatus = false;
}
this.showTop = status
}
}
},
toggleSelectAll(){
this.selectAll = !this.selectAll;
let items = 0;
let data = this.$refs.itemsTable.rows;
let status = false;
let rowId = '1'
for(var i=0;i <= data.length;i++){
if((typeof(data[i])!= 'undefined')){
items++;
this.SelectedItems = items +" Selected Items";
status = this.selectAll;
data[i].selectAll = status;
}
}
this.showTop = status
},
closeBulkToolBar(){
this.SelectedItems = "";
this.showTop = false;
},
}
}
Without your component codes it will be difficult to accuratly answer but I can give a try. To communicate between your two components that don't have parent/child relationship you can use an EventBus. You have several choices on how to set up your EventBus; you can pass your event through your Vue root instance using $root, or you can create a dedicated Vue component like in this example.
Considering that you already have binded the event countrySelected($event) on each of your country checkbox, you could achieve to display the related states using something like this:
./components/country/Index
The CountryIndex trigger an event while a country is selected
methods: {
countrySelected(event) {
let currentTarget = event.currentTarget
this.$root.$emit("display-states",currentTarget.countryId);
}
}
./components/state/Index
The stateIndex component listen to the event and display the related state
mounted() {
/**
* Event listener
*/
this.$root.$on("display-states", countryId => {
this.diplayStates(countryId);
});
},
methods: {
displayStates(countryId) {
//your method selecting the states to be diplayed
}