TrandingView Widget in Vue view - vue.js

I'm doing a view which shows a Vue component, this view has to display 4 tradingview graphs corresponding to 4 cryptocurrencies (BTC, ETH, EOS and XRP). The problem is that I can only show a single graphic of the four and only shows me the graph of the last cryptodivisa of the array.
The view should show this:
But it only shows me a single graphic:
This is the component code that does everything:
<template>
<div class="container">
<br>
<form class="form-inline" action="POST" v-on:submit.prevent>
<table>
<tr>
<td style="font-weight:bold; width:200px;">Exchange</td>
<td style="width:250px;">
<input class="form-check-input"
type="radio"
id="bittrex"
name="bittrex"
value="bittrex"
v-model="queryExchange.picked"/> Bittrex
<input class="form-check-input"
type="radio"
id="binnace"
name="binance"
value="binance"
v-model="queryExchange.picked"
checked> Binance
</td>
</tr>
<tr><td colspan="4" style="height:20px"></td></tr>
<tr>
<td style="font-weight:bold; width:200px;">Intervalo:</td>
<td>
<select id="Intervalo" name="Intervalo" v-model="queryExchange.interval">
<option value="W">1 Semana</option>
<option value="D">1 Día</option>
<option value="240">4 Hrs</option>
<option value="60">1 Hr</option>
<option value="30">30 min</option>
<option value="15">15 min</option>
<option value="5">5 min</option>
</select>
</td>
</tr>
<tr><td colspan="4" style="height:20px"></td></tr>
<tr>
<td style="font-weight:bold; width:200px;">
<button type="button" class="btn btn-primary"
v-on:click="queryForm()">
Mostrar
</button>
</td>
</tr>
<tr><td colspan="4" style="height:20px"></td></tr>
</table>
</form>
<div id="contenedor">
</div>
</div>
<script>
export default {
data () {
return {
queryExchange: {
picked: 'binance',
interval: '60',
},
cryptoCurrency: ['BTC', 'ETH', 'EOS', 'XRP']
}
},
methods: {
queryForm(){
let exchangeSelect = this.queryExchange.picked.toUpperCase();
let intervalSelect = this.queryExchange.interval;
this.cryptoCurrency.forEach(element => {
new TradingView.widget(
{
"width": 400,
"height": 300,
"symbol": exchangeSelect+':'+element+'BTC',
"interval": intervalSelect,
"timezone": "Etc/UTC",
"theme": "Dark",
"style": "1",
"locale": "en",
"toolbar_bg": "#f1f3f6",
"allow_symbol_change": true,
"enable_publishing": false,
"save_image": false,
"hideideas": true,
"container_id": "contenedor"
}
);
});
}
}
}
</script>
So far I can not find the mistake, I occupy Laravel 5.6 and Vuejs 2

Related

Validating dynamic array in vuelidate

I am very new to vue and I am trying to validate an array using vuelidate which is used to render a dynamic table. The problem is with the validation() method as I can comprehend.
According to vuelidate docs, https://vuelidate.js.org/#sub-collections-validation, the $each method supports array. When I use it, the validation never fails. However, when I omit $each, and, try to validate first index of the array, it returns as corrected - validation fails.
To be more precise, I am trying to validate each added row(s), and if there's a problem with the validation, it'd add a class to the affected row.
Component App.vue,
This is the HTML code:
<template>
<div>
<br>
<div class="text-center">
<button type="button" class="btn btn-outline-primary" #click="addRow()">Shto</button>
</div>
<br>
<p
v-for="error of v$.$errors"
:key="error.$uid"
>
<strong>{{ error.$validator }}</strong>
<small> on property</small>
<strong>{{ error.$property }}</strong>
<small> says:</small>
<strong>{{ error.$message }}</strong>
</p>
<form name="articles" #submit.prevent="submitForm">
<table class="table table-hover table-responsive">
<thead class="thead-inverse">
<tr>
<th>Nr.</th>
<th class="col-3">Numri</th>
<th class="col-4">Përshkrimi</th>
<th class="col-1">Sasia</th>
<th class="col-1">Çmimi</th>
<th class="col-2">Shuma</th>
<th></th>
</tr>
</thead>
<tbody>
<tr v-for="(item, idx) in items_table" :key="item">
<td>
{{idx+1}}
</td>
<td>
<input v-model="item.part_no" name="part_no[]" class="form-control" type="text" />
</td>
<td>
<textarea v-model="item.part_name" name="part_name[]" class="form-control" type="text"></textarea>
</td>
<td>
<input v-model="item.part_qty" name="part_qty[]" class="form-control " type="number" step="0.01">
</td>
<td>
<input v-model="item.part_price" name="part_price[]" class="form-control" type="number" step="0.01">
</td>
<td>
<input :value="item.part_total" name="part_total[]" class="form-control text-center border-0" style="background-color: transparent; font-size: 18 px;" type="text" disabled>
</td>
<td>
<button type="button" #click="deleteRow(idx)" class="btn btn-danger btn-md btn-block">X</button>
</td>
</tr>
</tbody>
</table>
<div class="text-center">
<button type="submit" name="" id="" class="btn btn-primary btn-lg btn-block">Valido</button>
</div>
</form>
<div class="text-center">
<textarea name="" id="verbose_log" cols="70" rows="15" refs="logg"></textarea>
</div>
</div>
</template>
This is the content from script tag:
<script>
import useVuelidate from '#vuelidate/core'
import { required } from '#vuelidate/validators'
export default {
name: 'App',
setup: () => ({ v$: useVuelidate() }),
validation() {
return {
items_table: {
$each: {
part_no: {
required,
}
}
},
}
},
data() {
return {
items_table: [
{
part_no: '', part_name: '', part_qty: '', part_price: '', part_total: ''
}
],
items_subtotal: 0.00,
items_total: 0.00,
}
},
methods: {
deleteRow(index) {
if(this.items_table.length == 1) {
this.items_table.splice(index, 1);
this.items_subtotal = 0.00;
this.items_total = 0.00;
this.addRow();
} else if(this.items_table.length > 0) {
this.items_table.splice(index, 1);
}
},
addRow() {
this.items_table.push({part_no: '', part_name: '', part_qty: '', part_price: '', part_total: ''});
},
submitForm() {
this.v$.$touch();
//if (this.v$.$error) return;
console.log(this.v$);
document.getElementById('verbose_log').innerHTML = JSON.stringify(this.$data, null, 4);
}
},
computed: {
//
}
}
</script>
For the sake of clarity, I have excluded two methods which calculate line total and the total itself.

Getting a NaN when typing a value

I'm trying to calculate a value from 2 input boxes and then get the total of those input boxes. I'm then trying to get the all my amounts and total them and add them to the subtotal but the issue I'm having is that when I type in a number in the first box my output is NaN instead of 0 and I would like for it to show me a 0 instead.
Here is my code
<template>
<div class="content-header">
<div class="container">
<div class="row">
<div class="col-sm-12">
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-lg-12">
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Unit</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr v-for="product in products">
<td>{{ product['name'] }}</td>
<td>
<input type="text" class="form-control" v-model="unit[product['unit']]" #change="calculateCost(product['name'])">
</td>
<td>
<input type="text" class="form-control" v-model="price[product['price']]" #change="calculateCost(product['name'])">
</td>
<td>
{{ cost[product['name']] }}
</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td>
Subtotal: {{ subTotal }}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default{
props: [],
data(){
return {
products: [],
unit: {},
price: {},
cost: []
}
},
computed:{
subTotal(){
if(this.cost!== null)
{
if(Object.keys(this.cost).length !== 0){
return Object.keys(this.cost).reduce((carry, item) => {
carry+= Number(this.cost[item])
return carry;
}, Number(0))
}else{
return 0;
}
}
}
},
methods: {
getProducts(){
axios.get(`/api/product/all`).then(response => {
this.products = response.data.products;
});
},
calculateCost(item){
this.cost[item] = Number(this.unit[item]) * Number(this.price[item]);
},
},
mounted() {
this.getProducts();
}
}
</script>
Almost all type of inputs return a string. You can use
<input type="number" class="form-control" v-model="unit[product['unit']]" #change="calculateCost(product['name'])">
or
<input type="text" class="form-control" v-model.number="unit[product['unit']]" #change="calculateCost(product['name'])">
The problem is the v-model for unit and price are set to the different keys than the one given to calculateCost(), which causes the lookups to fail and results in NaN:
<input v-model="unit[product['unit']]" #change="calculateCost(product['name'])"> ❌
^^^^^^ ^^^^^^
<input v-model="price[product['price']]" #change="calculateCost(product['name'])"> ❌
^^^^^^^ ^^^^^^
<input v-model="unit[product['name']]" #change="calculateCost(product['name'])"> ✅
<input v-model="price[product['name']]" #change="calculateCost(product['name'])"> ✅
Setting the keys to product['name'] ensures the correct lookup for unit and price in calculateCost(). Since the user could enter invalid values (non-numeric strings) or omit a value, it's possible to get NaN, so it would be a good idea to add a NaN-check in calculateCost():
calculateCost(item) {
const unit = Number(this.unit[item]);
const price = Number(this.price[item]);
if (Number.isNaN(unit) || Number.isNaN(price)) return;
this.cost[item] = unit * price;
},
Also, you probably want the cost to react to user input, so switch from #change to #input:
<input v-model="unit[product['name']]" #input="calculateCost(product['name'])">
<input v-model="price[product['name']]" #input="calculateCost(product['name'])">
demo

Setting a Form Value in Vue Js

I am using Struts 1.x in my application. Recently i used Vue js.So, I use the same jsp page for Adding and updating (in this case company). So When i click edit, the details are fetched the page is redirected to that page and form values are set from the action class.
Here is the html portion
<form action="company.do" method="post" name="companyForm">
<html:hidden property="method" value="doAddUpdateCompany" />
<html:hidden property="companyId" value="${companyForm.companyId}" />
<div class="row" >
<div class="col-md-9">
<div class="grid simple">
<div class="grid-title ">
<h4>
<logic:equal value="addCompany" property="method" name="companyForm">
New <span class="semi-bold">Company</span>
</logic:equal>
<logic:equal value="updateCompany" property="method" name="companyForm">
Edit <span class="semi-bold">Company</span>
</logic:equal>
</h4>
<div class="tools"> </div>
</div>
<div class="grid-body">
<table class="tbl_wall" style="width: 100%" >
<tr >
<td class="fi_wall" >Company Name<span class="notify style16"> *</span></td>
<td class="fi_wall" ><html:text property="companyName" name="companyForm" styleClass="med_txt" /></td>
<td> </td>
</tr>
<tr>
<td class="fi_wall" valign="top" >Company Code<span class="notify style16"> *</span> (3 Letter)</td>
<td class="fi_wall" valign="middle" ><html:text property="companyCode" maxlength="3" styleClass="med_txt" name="companyForm" /></td>
<td> </td>
</tr>
<tr id="cmp">
<td class="fi_wall">Company Type </td>
<td class="fi_wall"><select name="companyType" v-model="companyType">
<option value="-1">select</option>
<option v-for=" result in results " v-bind:value="result.commonId">
{{ result.name}}</option>
</select></td>
</tr>
<tr>
<td colspan="3" align="center">
<button type="button" class="btn btn-success" onclick="doSave()" ><i class="fa fa-save"></i> Save</button>
</td>
</tr>
</table> </form>
and the vue Portion
<script type="text/javascript">
new Vue({
el: '#cmp',
data: {
results: [],
companyType : '-1'
},
mounted() {
axios.get('/easyoffice/companyType.do?method=getCompanyTypeAjax').then(response => {
this.results = response.data,
this.companyType = document.forms['companyForm'].companyType.value
})
.catch(e => {
this.errors.push(e)
})
}
});</script>
i used this.companyType = document.forms['companyForm'].companyType.value to set form value but it is not working. Any Thoughts?

Setting a value to true for v-for generated radio buttons

The rows of a table are generated using a v-for loop over an array of objects in graphicState. I am trying to create a column of radio buttons. When a radio button is checked, this should set graphicState[index].selected to true.
This post is interesting, but how can I use it set graphicState[index].selected to true?
<form>
<div class="row">
<div class="col-md-12 " align="center">
<table class="table-striped" v-on:mouseleave="mouseleave()">
<thead>
<tr>
<th></th>
<th>Show</th>
<th>Select</th>
<th>Shape</th>
</tr>
</thead>
<tbody>
<tr v-for="(form, index) in graphicState" :key="index">
<td #click="removeDate(index)"><i class="far fa-trash-alt"></i></td>
<td>
<input type="checkbox" v-model="form.show">
</td>
<td>
<input type="radio" name="grp" id="grp" value="true" v-model="form.selected">
</td>
<td v-on:click="toggleShape(index)">
{{ form.shape }}
</td>
</tr>
</tbody>
</table>
<div v-for="(form, index) in graphicState " :key="index">
</div>
</div>
</div>
</form>
You can use #change event handler:
<input type="radio" name="grp" id="grp" value="true" v-model="form.selected" #change="onChange($event, index)">
then handle in method:
methods: {
onChange (event, index) {
this.graphicState[index].selected = event.target.value
this.graphicState = JSON.parse(JSON.stringify(this.graphicState))
}
}
The code you have already should set the graphicState[index].selected to true for the radio inputs, but the input values (and thus graphicState[index].selected through v-model) are never set to false, which is a problem if the user is allowed to change their mind to select a different input. This occurs because the radio input's change-event is only fired when the its checked property is set to a truthy value (upon selection).
One solution is to add a change-event handler that clears the .selected value for the non-selected inputs.
// template
<tr v-for="(form, index) in graphicState">
<input #change="onRadioChange(index)" ...>
</tr>
// script
onRadioChange(selectedIndex) {
this.graphicState
.filter((x,i) => i !== selectedIndex) // get non-selected inputs
.forEach(x => x.selected = false)
}
But there's still another problem if you're using HTMLFormElement's native submit. In the following template, when the v-model value is true, Vue sets the radio input's checked property to true, which tells the HTMLFormElement to use this particular input's value as the group value...
<input type="radio"
name="grp"
v-model="form.selected"
value="true">
All the radio inputs have the same value, so the receiver of the form data won't be able to tell which input is selected. To address this, assign a unique value to each input based on the iterator item. For example, you could use ID:
<input type="radio"
name="grp"
v-model="form.selected"
value="form.id">
new Vue({
el: '#app',
data() {
return {
graphicState: [
{id: 'A', selected: false, show: false},
{id: 'B', selected: false, show: false},
{id: 'C', selected: false, show: false},
]
}
},
methods: {
mouseleave() {},
removeDate() {},
toggleShape() {},
onRadioChange(selectedIndex) {
this.graphicState
.filter((x,i) => i !== selectedIndex)
.forEach(x => x.selected = false)
},
}
})
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
<script src="https://unpkg.com/vue#2.6.8/dist/vue.min.js"></script>
<div id="app">
<form method="post" action="//httpbin.org/post">
<div class="row">
<div class="col-md-12" align="center">
<table class="table-striped" v-on:mouseleave="mouseleave()">
<thead>
<tr>
<th></th>
<th>Show</th>
<th>Select</th>
<th>Shape</th>
</tr>
</thead>
<tbody>
<tr v-for="(form, index) in graphicState" :key="form.id">
<td #click="removeDate(index)"><i class="far fa-trash-alt"></i></td>
<td>
<input type="checkbox" v-model="form.show">
</td>
<td>
<input type="radio" name="grp" :value="form.id" v-model="form.selected" #change="onRadioChange(index)">
</td>
<td v-on:click="toggleShape(index)">
{{ form.shape }}
</td>
</tr>
</tbody>
</table>
<pre>{{graphicState}}</pre>
</div>
</div>
<button>Submit</button>
</form>
</div>

How to filter multiple form fields and display in table in angular 5?

I have a form which has checkbox and dropdowns and the data which is present in dropdowns is fetched from json. I have to select the dropdowns option , text written in text box on click of submit i have to filter and show the filtered data in table.
<form [formGroup]="reportsForm" (ngSubmit)=onSubmit(reportsForm.value)>
<label> Task Status</label>
<div>
<label class="checkbox-inline"></label>
<input type="checkbox" formControlName="whole" id="whole" value="whole"> a
<label class="checkbox-inline"></label>
<input type="checkbox" formControlName = "progress" id= "progress" value="progress"> b
</div>
<label>Date Time (GMT)</label>
<div class="">
<div class="col-md-6">
<label>FROM</label>
<input type="date" formControlName = "bfrom" id= "from" class="form-control">
</div>
<div class="col-md-6">
<label>TO</label>
<input type="date" formControlName = "to" id= "to" class="form-control">
</div>
</div>
<label>Group Name</label>
<div class="input-group-btn">
<select class="form-control" formControlName="groupname" id="groupname">
<option>Select</option>
<option *ngFor="let x of y" >{{x.grouping}}</option>
</select>
</div>
<label>Task Name</label>
<div class="input-group-btn">
<input type="text" formControlName="taskname" id="taskname" class="form-control">
</div>
<label>ASSIGNEE</label>
<div class="input-group-btn">
<select class="form-control" formControlName="assignee" id="assignee">
<option>Select</option>
<option *ngFor="let x of y" >{{x.assignee}}</option>
</select>
</div>
<label>Frequency</label>
<div class="input-group-btn">
<select class="form-control" formControlName="frequency" id= "frequency">
<option>Select</option>
<option *ngFor="let x of y">{{x.frequency}}</option>
</select>
</div>
<div class="buttons">
<button type="submit" class="btn">Submit</button>
</div>
</form>
<table class="table table table-bordered">
<thead>
<tr>
<th scope="col ">GroupName</th>
<th scope="col ">Assignee</th>
<th scope="col ">frequency</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let x of y">
<td scope="col">{{x.grouping}}</td>
<td scope="col">{{x.assignee}}</td>
<td scope="col">{{x.frequency}}</td>
</tr>
</tbody>
</table>
I have created a form in my component I have created all form data which is populating on submit of my form based on my selections of dropdowns and checkbox. And I have to filter those data and display on the table on form submit
#Component({
selector: 'app-rep',
templateUrl: './rep.component.html',
styleUrls: ['./rep.component.css']
})
export class RepComponent implements OnInit {
y;
users;
reportsForm: FormGroup;
constructor(private service: RepositoryService) { }
ngOnInit() {
this.reportsForm = new FormGroup({
whole: new FormControl(''),
progress: new FormControl(''),
bfrom: new FormControl(''),
to: new FormControl(''),
groupname: new FormControl(''),
taskname: new FormControl(''),
assignee: new FormControl(''),
frequency: new FormControl(''),
});
this.getTasks();
this.getUsers();
}
public getUsers() {
this.service.getData(usersUrl).subscribe(res =>{this.users = res.data.items});
}
public getTasks() {
this.service.getData(reportsUrl).subscribe(res =>{this.y= res.data.items});
}
onSubmit(filterValue:any) {
console.log(this.reportsForm);
}
}
Finally I came up with one solution which is working for multiple filters and on submit data should be filtered in a table. But it needs optimization if you have many conditions.
onSubmit() {
this.filteredtasks=[];
let grp = this.reportsForm.value.groupname;
let fre = this.reportsForm.value.frequency;
let as= this.reportsForm.value.assignee;
let tsknm = this.reportsForm.value.taskname;
for(let i=0; i< this.y.length; i++) {
if(
(grp == "" || grp == this.tasks[i].groupname) &&
(fre == "" || fre == this.tasks[i].frequency) &&
(as== "" || as== this.tasks[i].assignee) &&
(tsknm == "" || tsknm == this.tasks[i].taskname)
) {
this.filteredtasks.push(this.y[i]);
}
}
The filteredtasks array is having the filtered list..
<table class="table table table-bordered">
<thead>
<tr>
<th scope="col ">GroupName</th>
<th scope="col ">Assignee</th>
<th scope="col ">frequency</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let x of filteredtasks">
<td scope="col">{{x.groupname}}</td>
<td scope="col">{{x.assignee}}</td>
<td scope="col">{{x.frequency}}</td>
</tr>
</tbody>
</table>