How to get Dropdown data using Vue JS? - javascript

my dropdown is not getting any value from my database, it keeps return {{item.cmp_Name}}, Is there anything i have missed?
<label for="user_CompID" class="col-form-label">Company Name</label>
<select class="form-control" name="user_CompID">
<option value="">Select Company Name</option>
<option v-for="item in sel_comp" :value="item.cmp_id">{{item.cmp_Name}}</option></select>
Script
var vm = new Vue({
el: '#maint_user_ctrl',
data: {
sel_comp: []
},
created: function () {
this.doLoadParam();
},
mounted: function () {
$(".bt-table").bootstrapTable();
var dropdownMenu;
$('.bt-table').on('show.bs.dropdown', function (e) {
dropdownMenu = $(e.target).find('.dropdown-menu');
$('body').append(dropdownMenu.detach());
var eOffset = $(e.target).offset();
dropdownMenu.css({
'display': 'block',
'top': eOffset.top + $(e.target).outerHeight(),
'left': eOffset.left
});
});
$('.bt-table').on('hide.bs.dropdown', function (e) {
$(e.target).append(dropdownMenu.detach());
dropdownMenu.hide();
});
},
methods: {
doLoadParam: function () {
var self = this;
ajaxJsonProcess("get", myPath + "/company-dropdown", "", function (inDat) {
self.sel_comp = inDat;
}, dftError);
},
i try debug, it getting the dropdown value but not displaying

If you see the string {{item.cmp_Name}} instead of the results so you didnt setup vue well from webpack / cli.
Also you should check if the request to the server is send because you have problem there.
Move your doLoadParams into methods property.
{
created() { ... },
methods: {
doLoadParam() { ... }
}
}
Also if you need this request to run when component is mounted you can load the request itself from the mounted hook.

Make sure you are getting the values from the rest api. Add console.log and confirm you are getting response from Rest api.
doLoadParam: function () {
var self = this;
ajaxJsonProcess("get", myPath + "/company-dropdown", "", function (inDat) {
console.log('inDat', inDat)
self.sel_comp = inDat;
}, dftError);
}
Or else try the below steps
Step 1: HTML template like
<div id="app">
<label for="user_CompID" class="col-form-label">Company Name</label>
<select class="form-control" name="user_CompID" v-model="selectedCompany">
<option value="">Select Company Name</option>
<option
:key="index"
v-for="(item, index) in sel_comp"
:value="item.cmp_id"
>
{{ item.cmp_Name }}
</option>
</select>
{{ selectedCompany }}
</div>
Step 2: data modal will be
data() {
return {
selectedCompany: "",
sel_comp: [],
};
},
Step 3: methods loadFromAPI function for loading data from api. I just added dummy data instead of api call.
methods: {
loadFromAPI() {
// Load from AJAX API
this.sel_comp = [
{
cmp_Name: "Cognizant",
cmp_id: "cts",
},
{
cmp_Name: "Infosys",
cmp_id: "infy",
},
{
cmp_Name: "Accenture",
cmp_id: "acc",
},
];
},
},
Step 4: By default page load get company details from api by created
created() {
this.loadFromAPI();
},
DEMO

Html
<label for="user_CompID" class="col-form-label">Company Name</label>
<select class="form-control" name="user_CompID" v-model="company">
<option value="" selected>Select Company Name</option>
<option v-for="item in sel_comp" :key="item.cmp_id">{{item.cmp_Name}}</option></select>
Script
data: { company:'',
sel_comp: []
},
mounted: function () {
//the function can be called in mounted.
this.doLoadParam();
$(".bt-table").bootstrapTable();
var dropdownMenu;
$('.bt-table').on('show.bs.dropdown', function (e) {
dropdownMenu = $(e.target).find('.dropdown-menu');
$('body').append(dropdownMenu.detach());
var eOffset = $(e.target).offset();
dropdownMenu.css({
'display': 'block',
'top': eOffset.top + $(e.target).outerHeight(),
'left': eOffset.left
});
});
$('.bt-table').on('hide.bs.dropdown', function (e) {
$(e.target).append(dropdownMenu.detach());
dropdownMenu.hide();
});
},

Related

Framework 7 + Vue 3 smart select display dynamically select option

I try without success to display the options of smart select. I recover the options with axios and I make a v-for to display the options but without success. I first put the function that allows me to retrieve the data in the computed hook without success then I put it in the mounted hook and I used the setvalue property of smart select without success too. Any help is welcome and I thank you in advance.
methods: {
async getTokensLists() {
const self = this;
let url = f7.store.getters.getApiUrl.value + "tokens/";
await self
.axios({
url,
method: "get",
withCredentials: false,
})
.then((response) => {
if (response.satus == 200) {
self.tokensList == response.data.data;
}
})
.catch((error) => {
console.log(error);
});
},
},
async created() {
const self = this;
// Error: Uncaught Error: Smart Select requires initialized View
self.getTokensLists();
},
computed: {
/*case 1
Error items readonly
code:
items () {
return this.tokensList
}*/
},
mounted(){
/*case 2
Error: new data not display in front
code:
this.$nextTick(() => {
this.$refs.item.f7SmartSelect.setValue(['test']);
});*/
}
Here is the template part
<f7-list-item
title="Add tokens"
smart-select
:smart-select-params="{
openIn: 'popup',
searchbar: true,
searchbarPlaceholder: 'Search token',
pageTitle: 'Add tokens',
}"
#smartselect:closed="updateSelectedtokensData"
>
<select v-model="tokensList" name="select-token" multiple>
<optgroup label="">
<option
v-for="(item, key) in tokensList"
:key="key"
:value="item.symbol"
>
{{ item.name + " (" + item.symbol + ")" }}
</option>
</optgroup>
</select>
<template #media>
<f7-icon
ios="f7:plus_circle"
aurora="f7:plus_circle"
md="material:add_circle_outline"
size="30"
></f7-icon>
</template>
</f7-list-item>
To load the async data I used the setup method and the Suspense component of view 3
radar component
...
async setup(){
const tokensList = ref(null)
await axios({
url: f7.store.getters.getApiUrl.value+"tokens/",
method: "get",
withCredentials: false,
}).then(response =>{
if (response.status == 200) {
tokensList.value = response.data.data;
}
}).catch(error =>{
console.log(error)
})
return {
tokensList
};
}...
app.vue
<!-- Radar View -->
<f7-view
id="view-radar"
:class="{ 'web-view': isDesktop }"
name="Radar"
tab
:router="false"
>
<Suspense>
<template #default>
<radar></radar>
</template>
<template #fallback>
<f7-page name="radar">
<!-- Top Navbar -->
<f7-navbar title="Radar">
<f7-nav-right>
<f7-link
icon-ios="f7:funnel_fill"
icon-aurora="f7:funnel_fill"
icon-md="material:filter_alt"
popup-open=".filter-popup"
></f7-link>
</f7-nav-right>
</f7-navbar>
<f7-block class="text-align-center" style="margin-top: 20%;"
><f7-preloader color="multi" :size="42"></f7-preloader
></f7-block>
</f7-page>
</template>
</Suspense>
</f7-view>
...

Dropzone instance works on first element but not cloned elements (Vue)

I have a snippet below which is essentially my entire code block at this point, and essentially it creates a div and when you click "add another zone" it will clone that div. This allows the user to enter multiple lines of info and each have their own result and image.
The issue is that I'm successfully cloning everything with it's own unique identity thanks to my card setup. However, dropzone is not replicating. The first file dropzone form will work perfectly, but when I clone the div and have 2 or more dropzone insnstances on the page they don't work (they don't show the upload image text or anything)
How can I successfully apply my same logic to the dropzone instance here?
new Vue({
components: {},
el: "#commonNameDiv",
data() {
return {
searchString: [''],
results: [],
savedAttributes: [],
cards: [],
showList: false,
zoneNumber:[],
imageZoneNames: [] }
},
methods: {
autoComplete(ev, card) {
this.results = [];
console.log(this.searchString);
if (ev.target.value.length > 2) {
axios.get('/product/parts/components/search', {
params: {
searchString: ev.target.value
}
}).then(response => {
card.results = response.data;
this.showList = true;
console.log(this.results);
console.log(this.searchString);
});
}
},
saveAttribute(result, card) {
card.value = result.attribute_value;
card.results = [];
card.zone = this.zoneNumber;
this.showList = false;
},
addCard: function() {
this.cards.push({
index: "",
value: "",
zoneNumber: "",
results: [],
componentImage:""
});
console.log(this.cards);
},
hideDropdown() {
this.showList = false;
},
},
created() {
this.addCard();
let instance = this;
Dropzone.options = {
maxFilesize: 12,
renameFile: function (file) {
var dt = new Date();
var time = dt.getTime();
return time + file.name;
},
acceptedFiles: ".jpeg,.jpg,.png,.gif",
addRemoveLinks: true,
timeout: 50000,
removedfile: function (file) {
console.log(file.upload.filename);
var name = file.upload.filename;
var fileRef;
return (fileRef = file.previewElement) != null ?
fileRef.parentNode.removeChild(file.previewElement) : void 0;
},
init: function() {
this.on("addedfile",
function(file) {
instance.imageZoneNames.push({name: file.upload.filename, desc: 'Line Drawing'});
console.log(file);
console.log(instance.imageZoneNames);
});
}
};
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"> </script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.5.0/dropzone.js"></script>
<div id="commonNameDiv">
<div class="uk-grid" v-for="(card, i) in cards" :key="i">
<div class="uk-width-1-10" >
<input v-model=" card.zoneNumber" size="4" type="text" name="mapNumber">
</div>
<div class="uk-width-6-10">
<input
style="width:100%"
placeholder="what are you looking for?"
v-model="card.value"
v-on:keyup="autoComplete($event, card)"
>
<div v-if="showList" class="panel-footer componentList" v-if="card.results.length">
<ul>
<li v-for="(result, i) in card.results" :key="i">
<a v-on:click="saveAttribute(result, card)">#{{ result.attribute_value }}</a>
</li>
</ul>
</div>
</div>
<div class="uk-width-3-10">
<form method="post" action="{{url('product/parts/upload/store')}}" enctype="multipart/form-data"
class="dropzone">
</form>
</div>
</div>
<div style="height: 35px;">
</div>
<div>
<a v-on:click="addCard">Add another zone</a>
</div>
</div>
When you instantiate the Dropzone class, it automatically looks for elements to transform in dropzones (by default, elements with the .dropzone class).
It looks like you want to dynamically add elements that are dropzones. Then you need to trigger the dropzone transformation yourself.
I would suggest you disable the autoDiscover option, and manually designates each element you want to transform into dropzones :
addCard() {
this.cards.push({
...
});
let cardIndex = this.cards.length - 1;
// Waiting for the element #dropzone-X to exist in DOM
Vue.nextTick(function () {
new Dropzone("#dropzone-"+cardIndex, {
...
});
});
},
created() {
...
Dropzone.autoDiscover = false
// no new Dropzone()
...
// Starting setup
this.addCard();
},
<form ... class="dropzone" v-bind:id="'dropzone-'+i">
Working jsbin
There are several ways to select the element to transform ($refs, ids, classes), here I'm suggesting ids.
See the doc on programmatically creating dropzones
Actually it is being created, but the Dropzone is not being reconstructed.
I think you have to create a new instance of the Dropzone.
if you try to insert:
created() {
this.addCard();
var myDropzone = new Dropzone('.dropzone')
let instance = this;
Dropzone.options.myDropzone = {
or even add the options to the addCard method or set a setupDropzones method and add it to the addCard method.

clone form include dependent fields by vuejs

I have a form in which there should be submitting a price for various health care services. Treatments are already categorized. Now, I want to first select a treatment group from a selector and then select the treatment list for that category in the next selector. When I have just one form on the page, I have no problem. But I need to clone this form and the user can simultaneously record the price of some treatments. In this case, all the second selectors are set according to the last selector for the categories. While having to match their category's selector. I searched for the solution very well and did not get it. My code in vuejs is as follows. Please guide me. Thank you in advance.
<template>
<div>
<div id="treatment_information">
<div class="col-md-3">
<select id="category_name" class="form-control show-tick"
v-on:change="getTreatmentList($event)"
name="treatment_rates[]category_id" v-model="treatment_rate.category_id"
>
<option value="0"> -- select category --</option>
<option class="form-control main"
v-for="item in vue_categories" :id="item.id+1000" :value="item.id"
:name="item.name">
{{ item.name }}
</option>
</select>
</div>
<div class="col-md-3">
<select id="treatment_id" class="form-control show-tick"
name="treatment_rates[]treatment_id" v-model="treatment_rate.treatment_id"
>
<option value="0"> -- select treatment --</option>
<option class="form-control main"
v-for="item in vue_treatments" :value="item.id">
{{ item.value }}
</option>
</select>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
vue_temp: [],
vue_categories: [],
vue_treatments: [],
vue_category: '',
//for clone form
treatment_rate: {
category_id: 0,
treatment_id: 0,
hospital_id: 0,
dollar: 'دلار',
rial: 'ریال'
},
treatment_rates: [],
};
},
mounted() {
console.log('Component mounted.');
this.getList();
},
methods: {
getList() {
var self = this;
axios.get('/vueDashboard/get/categories').then(function (response) {
self.vue_temp = response.data;
const len = self.vue_temp.length;
self.vue_temp.forEach(function (item) {
if (self.vue_right.length > 0) {
while (self.vue_right[self.vue_right.length - 1] < item['rgt']) {
self.vue_right.pop();
if (self.vue_right.length == 0)
break;
}
}
self.vue_categories.push({
'id': item['id'],
'name': '---'.repeat(self.vue_right.length) + ' ' + item['name']
});
self.vue_right.push(item['rgt'])
var str = "---";
});
}).catch(function (error) {
console.log(error);
});
axios.get('/vueDashboard/get/treatments?category=' + JSON.stringify(self.treatment_rates)).then(function (response) {
console.log(response.data);
self.vue_treatments = response.data;
}).catch(function (error) {
console.log(error);
});
},
addForm(event) {
var self = this;
self.vue_increment_id[self.vue_counter++]=self.vue_counter;
console.log(self.vue_increment_id);
self.treatment_rates.push(Vue.util.extend({}, self.treatment_rate));
},
}
}
</script>

Vue.js : How to iterate with v-for into a dynamic array

I want to display multiples html tables of tools (1 table = 1 tool's categorie / 1 tr = 1 tool).
data() {
return {
cats: '',
tools: [],
};
},
methods: {
getToolCats() {
var rez = getToolCats();
rez.then(data => this.receiveCats(data) )
},
receiveCats(_cats){
this.cats = _cats;
_cats.forEach(cat => {
getToolsByCat(cat.href).then(data => this.tools[cat.href] = data);
});
console.log(this.tools);
},
},
mounted() {
this.getToolCats();
},
cats (ie categories) is an array populated with an API call. Then for each cat, an API Call give me a tool list of that cat, that I place into the tools array (this.tools[cat.href] = data).
Here is the display code :
<div v-for="cat in cats" :key="cat.href" class="tbox col-xs-12 col-sm-6">
....
<table class="table table-hover">
<tr v-for="tool in tools[cat.href]" :key="tool.href">
<td>...</td>
</tr>
</table>
....
</div>
If i'm using a single var to store lthe tool list, all is OK. But while I don't know how many cats I'm going to have, I can't create a car for each category.
I think the problem could be there :
Using an array in v-for with a key not defined at mounted state :
v-for="tool in tools[cat.href]
I'll appreciate any help !
Vue can't detect dynamic property addition in this.tools[cat.href] = data, but it would detect the change with this.$set or Vue.set in this.$set(this.tools, cat.href, data):
new Vue({
el: '#app',
data() {
return {
cats: [],
tools: {}, // <-- make this an object (not an array)
};
},
mounted() {
this.getToolCats();
},
methods: {
getToolCats() {
// setTimeout to simulate delayed API calls...
setTimeout(() => {
this.cats = [
{ href: 'https://google.com' },
{ href: 'https://microsoft.com' },
{ href: 'https://apple.com' },
{ href: 'https://amazon.com' },
];
this.cats.forEach((cat, i) => {
setTimeout(() => {
const data = { href: cat.href };
this.$set(this.tools, cat.href, data); // <-- use this.$set for dynamic property addition
}, i * 1000);
})
}, 1000);
}
}
})
<script src="https://unpkg.com/vue#2.5.17"></script>
<div id="app">
<div v-if="!cats || cats.length == 0">Loading...</div>
<div v-for="cat in cats" :key="cat.href" v-else>
<table>
<tr v-for="tool in tools[cat.href]" :key="tool.href">
<td>cat.href: {{cat.href}}</td>
</tr>
</table>
</div>
<pre>tools: {{tools}}</pre>
</div>

Event default not triggering in jQuery module

I'm attempting to write a jQuery script to store an authentication token from a REST API service. I had a block of working code but decided to modularize to make the application more scalable. Now, it seems that the preventDefault portion is no longer working.
<form action="/" id="authorize">
<label for="username">Username:</label><br />
<input type="text" id="username" required /><br />
<label for="password">Password:</label><br />
<input type="password" id="password" required /><br />
<input type="submit" value="Authorize" /><span id="isValid" class="checkContainer"> </span>
</form><hr />
<label for="serviceType" class="fieldDisabled">Method: </label>
<select id="serviceType" disabled>
<option></option>
<option value="option1">Option 1</option>
<option value="option2">Option 2</option>
</select>
The script is saved separately as authorize.js and invoked in the module as follows:
<script src="js/authorize.js"></script>
<script>
$(document).ready(function() {
Authorize.init();
});
</script>
Here's the module itself:
var s;
var Authorize = {
token: null,
settings: {
username: $("#username"),
password: $("#password"),
form: $("#authorize"),
validationIcon: $("#isValid"),
selector: $("#serviceType"),
selectorLabel: $("label[for='serviceType']"),
serviceSelector: $(".methodFieldDisabled"),
url: "redacted"
},
init: function() {
s = Authorize.settings;
this.bindUIActions();
},
bindUIActions: function() {
s.form.submit(function(event) {
event.preventDefault();
data = Authorize.buildJSON(s.username.val(), s.password.val());
Authorize.getToken(json);
});
},
buildJSON: function(username, password) {
var data = {};
data['grant_type'] = password;
data['username'] = username;
data['password'] = password;
return data;
},
getToken: function(data) {
$.ajax({
type: "POST",
url: s.url,
data: data,
success: function(json) {
Authorize.success(json);
},
error: function(json) {
Authorize.error(json);
}
});
},
success: function(json) {
Authorize.token = json.accessToken;
Authorize.revealServiceSelector();
},
error: function(json) {
Authorize.hideServiceSelector();
},
revealServiceSelector: function() {
s.serviceSelector.hide();
if(s.validationIcon.hasClass("invalid")) {
s.validationIcon.removeClass("invalid");
}
selectorLabel.removeClass("fieldDisabled");
selector.prop("disabled", false);
s.validationIcon.addClass("valid");
},
hideServiceSelector: function() {
s.serviceSelector.hide();
if(s.validationIcon.hasClass("valid")) {
s.validationIcon.removeClass("valid");
}
selectorLabel.addClass("fieldDisabled");
selector.prop("disabled", "disabled");
s.validationIcon.addClass("invalid");
}
};
I've been toiling over this for about a day now and can't seem to locate the point of failure. When the form is submitted, it redirects to the root directory of the server instead of executing the script as intended.
Just a few typos which stopped the code in its tracks. The submission was the default behavior as your code failed to complete.
Use a debugger to see the errors at runtime (get to know and love your F12 debugging tools in Chrome etc!):
1) You have the wrong variable (json instead of data) on the line below so you get an error:
bindUIActions: function () {
s.form.submit(function (event) {
event.preventDefault();
data = Authorize.buildJSON(s.username.val(), s.password.val());
Authorize.getToken(data); // <<<<<<<<<<<<<<<<<<<<<<<
});
2) You also failed to put your scope (s) on a couple of variables:
revealServiceSelector: function () {
s.serviceSelector.hide();
if (s.validationIcon.hasClass("invalid")) {
s.validationIcon.removeClass("invalid");
}
s.selectorLabel.removeClass("fieldDisabled");
s.selector.prop("disabled", false);
s.validationIcon.addClass("valid");
},
hideServiceSelector: function () {
s.serviceSelector.hide();
if (s.validationIcon.hasClass("valid")) {
s.validationIcon.removeClass("valid");
}
s.selectorLabel.addClass("fieldDisabled");
s.selector.prop("disabled", "disabled");
s.validationIcon.addClass("invalid");
}
Your from action is pointed to "\" which is the root of your directory. Instead point it to the file that contains the code you want to fire.

Categories