This js-fiddle example is working as it should:
https://jsfiddle.net/qf089a0a/51/
But when I try to load this example on my own, the dropdown menu doesn't show anything -- even though it does in the js-fiddle example (try entering "wireless" in the input box.)
This is my html:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.18/vue.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<body>
<div id="app">
<input v-model="offer.tags"></input>
<select>
<option v-for="(key, value) in offer.units" v-bind:value="offer.units">
{{ key }}
</option>
</select>
</div>
</body>
<script src="./js/app.js"></script>
</html>
And here is the js:
var protocol = {
"wireless": {
"units": {
"bandwidth": "bit/s, Mb/s, Gb/s",
"distance": "kilometers, miles"
},
"children": [],
}
};
var vm = new Vue({
el: '#app',
data: {
offer: {
tags: '',
units: {}
},
protocol: protocol
},
watch: {
'offer.tags': {
handler: function() {
var tagList = this.offer.tags.split(',');
console.log(tagList);
for (var i = 0; i < tagList.length; i++) {
console.log(tagList[i]);
try {
var unitsObj = this.protocol[tagList[i]]["units"];
var unitKeys = Object.keys(unitsObj);
for (var i = 0; i < unitKeys.length; i++) {
if (!unitsObj[unitKeys[i]]) {
console.log("updating units");
// update dict only if it doesn't already contain key
this.offer.units[unitKeys[i]] = unitsObj[unitKeys[i]];
}
this.offer.units[unitKeys[i]] = unitsObj[unitKeys[i]];
}
console.log(this.offer.units);
} catch (e) {
return true
}
}
}
}
}
});
Any ideas as to what could be the problem?
Here's what the console prints out in the offline version - it's the same as the online version:
Array [ "wireless" ]
app.js:27:9
wireless
app.js:30:11
Object { bandwidth: "bit/s, Mb/s, Gb/s", distance: "kilometers, miles", 1 moreā¦ }
So, apparently the dictionary is being updated as I expect.
The Problem is the Version of Vue JS you are using. the one you mentioned here is different and the one you are using in jsfiddle is different.
Please remove the one u mentioned here and add the following.
<script type="text/javascript" src="https://unpkg.com/vue#2.0.3/dist/vue.js"></script>
It will work fine.
Related
i have a requirement where autocomplete comes from backend and it will have key called filedId based on that i want to show the label
if we click on dynamic resource 1 btn the label should be city
if we click on dynamic resource 2 btn the label should be pinCode
if we click on dynamic resource 3 btn the label should be countryCode
Note: i don't want to change the data structure / json
here is what i have tried
var app = new Vue({
el: '#app',
components: { Multiselect: window.VueMultiselect.default },
data () {
return {
value: [],
options: [],
infoData:{},
}
},
methods:{
dr1(){
let infoObj = {
resource:{
autocomplete:{
fieldId:'city',
},
data:[{
id:1,
city:'Bengaluru'
}],
}
}
this.infoData = infoObj;
this.options = infoObj.resource.data;
},
dr2(){
let infoObj = {
resource:{
autocomplete:{
fieldId:'pinCode',
},
data:[{
id:1,
pinCode:'560097'
}],
}
}
this.infoData = infoObj;
this.options = infoObj.resource.data;
},
dr3(){
let infoObj = {
resource:{
autocomplete:{
fieldId:'countryCode',
},
data:[{
id:1,
countryCode:'+91'
}],
}
}
this.infoData = infoObj;
this.options = infoObj.resource.data;
},
determineLabel(){
let labelName = this.infoData.resource.autocomplete.fieldId;
return labelName;
}
},
})
body { font-family: 'Arial' }
<!DOCTYPE HTML>
<html>
<head>
<title>Timeline</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-multiselect#2.1.0"></script>
<link rel="stylesheet" href="https://unpkg.com/vue-multiselect#2.1.0/dist/vue-multiselect.min.css">
<script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>
</head>
<body>
<div id="app">
<button #click="dr1()">dynamic resource 1</button>
<button #click="dr2()">dynamic resource 2</button>
<button #click="dr3()">dynamic resource 3</button>
<br/><br/>
<div>
<multiselect
v-model="value"
label="determineLabel"
:options="options"
:multiple="false"
:taggable="false"
></multiselect>
</div>
</div>
</body>
here is codepen link to play with: https://codepen.io/eabangalore/pen/MWmrOBb
Still i did not find solution, please help me thanks in advance
Label prop in <multiselect> doesn't execute determineLabel by itself. it only gets computed or data option or a simple string. so you should put determineLabel in the computed:
...
computed: {
determineLabel() {
let labelName = this.infoData.resource.autocomplete.fieldId;
return labelName;
}
}
...
I've been writing a code that uses ng-if to display a div with a message if an array is empty([]). The ng-if isn't displaying the div even though I have console.log the array and it shows up empty.
I am still new to angularjs so I am not sure if I am using the ng-if directive correctly. Here is my code, anything helps, thank you!
js:
(function () {
'use strict';
var data = [];
var shoppingList = [
{
name: "Donuts",
quantity: "10"
},
{
name: "Cookies",
quantity: "10"
},
{
name: "Drinks",
quantity: "10"
},
{
name: "Shrimp",
quantity: "10"
},
{
name: "Ice Cream tub",
quantity: "100"
}
];
console.log(data);
angular.module('shoppingListCheckOffApp', [])
.controller('toBuyListController', toBuyListController)
.controller('boughtListController', boughtListController)
.service('shoppingListService', shoppingListService);
toBuyListController.$inject = ['shoppingListService'];
function toBuyListController(shoppingListService) {
var buy = this;
buy.shoppingList = shoppingList;
buy.shoppingListBought = function (itemIndex) {
shoppingListService.dataTransfer(buy.shoppingList[itemIndex].name, buy.shoppingList[itemIndex].quantity);
shoppingListService.remove(itemIndex);
};
}
boughtListController.inject = ['shoppingListService'];
function boughtListController(shoppingListService) {
var bought = this;
bought.data = shoppingListService.getData();
console.log(bought.data);
}
function shoppingListService() {
var service = this;
service.dataTransfer = function (itemName, quantity) {
var item = {
name: itemName,
quantity: quantity
};
data.push(item);
}
service.remove = function (itemIndex) {
shoppingList.splice(itemIndex, 1);
};
service.getData = function () {
return data;
};
};
})();
html:
<!doctype html>
<html ng-app="shoppingListCheckOffApp">
<head>
<title>Shopping List Check Off</title>
<meta charset="utf-8">
<script src="angular.min.js"></script>
<script src="app.js"></script>
</head>
<body>
<div>
<h1>Shopping List Check Off</h1>
<div>
<!-- To Buy List -->
<div ng-controller="toBuyListController as buy">
<h2>To Buy:</h2>
<ul>
<li ng-repeat="item in buy.shoppingList">Buy {{item.quantity}} {{item.name}}(s)<button
ng-click="buy.shoppingListBought($index);" ng-click="myVar = true"><span></span>
Bought</button></li>
</ul>
<div ng-if="buy.shoppingList === []">Everything is bought!</div>
</div>
<!-- Already Bought List -->
<div ng-controller="boughtListController as bought">
<h2>Already Bought:</h2>
<ul>
<li ng-repeat="item in bought.data">Bought {{item.quantity}} {{item.name}}(s)</li>
</ul>
<div ng-if="bought.data === []">Nothing bought yet.</div>
</div>
</div>
</div>
</body>
</html>
You should use ng-if (for arrays) in this way:
<div ng-if="!bought.data.length">Nothing bought yet.</div>
This will show the message when the list is empty.
If you do this:
buy.shoppingList === []
You are comparing you buy.shoppingList array with a new empty array, then it will return false.
Here is the problem I am working on.
Attached is an index.html.
Implement the next and previous buttons to navigate to next/previous posts from the API provider (https://jsonplaceholder.typicode.com).
Create a new tag that displays the current post ID.
Bonus points: Create a new array to store all of the previously retrieved posts, and display them in a list.
The API is from jsonplaceholder.typicode.com, so you don't need to implement that. A jsfiddle would be immensely appreciated.
<!DOCTYPE html>
<html>
<head>
<title>Vue Test</title>
<link href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css' rel='stylesheet' type='text/css' />
<div id="app">
<h1>{{ message }}</h1>
<div>
<span>{{post.title}}</span>
</div>
<button v-on:click="previousPost">Previous Post</button> <!-- // new vue directive - v-on:click, also -->
<button v-on:click="nextPost">Next Post</button>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js"></script>
<script
src="https://code.jquery.com/jquery-3.1.1.min.js"
integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
***emphasized text***crossorigin="anonymous"></script>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Welcome to Vue!',
post: {},
page: 1
},
mounted: function() {
this.getPost()
},
methods: {
nextPost: function() {
this.page = this.page + 1
this.getPost()
// Implement me
},
previousPost: function() {
// Implement me
this.page = this.page - 1
this.getPost()
},
getPost: function() {
var root = 'https://jsonplaceholder.typicode.com';
$.ajax({
url: root + '/posts/' + this.page,
method: 'GET'
})
.then((data) => {
console.log(data);
this.post = data;
});
}
}
})
</script>
<style>
/* Add any additional styles here */
body {
padding: 20px;
}
div {
margin: 12px 0;
}
</style>
I would also like to know what is meant by the post id over there. I have completed one task which shows the next and previous posts, but the other two tasks I am a little confused.
When trying to update a chart in React using the sample given by FusionCharts, I can't get the chart to update. It is definitely changing the value, which I found out by adding this line:
console.log(revenueChartConfigs.dataSource.data[2].value);
The value is changing from 590000 to 420000 as desired, but the chart does not update. Does anyone have advice on this? I have pasted my code below. Thanks.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript" src="js/fusioncharts.js"></script>
<script type="text/javascript" src="js/fusioncharts.charts.js"></script>
<script type="text/javascript" src="js/fusioncharts.gantt.js"></script>
<script type="text/javascript" src="js/fusioncharts.maps.js"></script>
<script type="text/javascript" src="js/fusioncharts.powercharts.js"></script>
<script type="text/javascript" src="js/fusioncharts.ssgrid.js"></script>
<script type="text/javascript" src="js/fusioncharts.treemap.js"></script>
<script type="text/javascript" src="js/fusioncharts.widgets.js"></script>
<script type="text/javascript" src="js/fusioncharts.zoomscatter.js"></script>
<script src="https://unpkg.com/react#15/dist/react.js"></script>
<script src="https://unpkg.com/react-dom#15/dist/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script type="text/javascript" src="js/react-fusioncharts.min.js"></script>
<script type='text/babel'>
$(document).ready(function(){
var myDataSource = {
chart: {
caption: "Top 5 stores in last month by revenue",
subCaption: "Harry's SuperMart",
numberPrefix: "$",
theme: "fint"
},
data: [{
label: "Bakersfield Central",
value: "880000"
}, {
label: "Garden Groove harbour",
value: "730000"
}, {
label: "Los Angeles Topanga",
value: "590000"
}, {
label: "Compton-Rancho Dom",
value: "520000"
}, {
label: "Daly City Serramonte",
value: "330000"
}]
};
var RevenueChart = React.createClass({
/**
** `getInitialState()` method is used to initialize the state of the
** the `RevenueChart` component.
**/
getInitialState: function () {
return {
eventTarget: ''
};
},
/**
** The `handleClick()` function is defined in the `RevenueChart` component.
** This function is configured to store the state of the `eventTarget` using
** the `setState()` method of React. This is binded to button click.
**/
handleCLick: function () {
this.setState({
eventTarget: 'btn-update-data'
});
},
render: function () {
var revenueChartConfigs = {
id: "revenue-chart",
renderAt: "revenue-chart-container",
type: "column2d",
width:600,
height: 400,
dataFormat: "json",
dataSource: myDataSource,
eventTarget: this.state.eventTarget,
impactedBy: ['btn-update-data']
};
/**
** Using the state, we update the `label` and `value` for the third and
** fourth data plots in the `render()` method of RevenueChart. The configuration
** object that is passed as props is used to refer to the `label`
** and `value` attributes of the `data` object array.
**/
if (this.state.eventTarget && this.state.eventTarget.length != 0) {
revenueChartConfigs.dataSource.data[2].label = "Art Supply Store";
revenueChartConfigs.dataSource.data[2].value = "420000";
revenueChartConfigs.dataSource.data[3].label = "P.C. Richard & Son";
revenueChartConfigs.dataSource.data[3].value = "320000";
}
else {
revenueChartConfigs.dataSource = myDataSource;
}
console.log(revenueChartConfigs.dataSource.data[2].value);
return (
<div>
/** The `FusionCharts` React component is used to render the chart. **/
<react_fc.FusionCharts {...revenueChartConfigs} />
/** Create a button, which when clicked will call the `handleClick()` function. **/
<a id='btn-update-data'
onClick={this.handleCLick}
className="btn btn-default"
href="#">{'Click me to change data'}</a>
</div>
);
}
});
ReactDOM.render(
<RevenueChart />,
document.getElementById('chart-container')
);
});
</script>
</head>
<body>
Hello
<div id="chart-container"></div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<script src="js/vue.js"></script>
<meta charset="UTF-8">
<title>V-for example</title>
</head>
<body>
<script type="x/template" id="testTemplate">
<div><h1>{{name}}</h1>
<p>{{Age}}</p></div>
</script>
<div id="example">
<div id="filler">
<template v-for="person in people">
<test-component name="{{person.name}}"></test-component>
</template>
</div>
</div>
<script>
var newComponent = Vue.extend({
template: '#testTemplate',
props: ['name'],
data: function () {
return {
Age: 1010
}
}
});
Vue.component('test-component', newComponent);
new Vue({
el: '#example',
data: {
people: [{
name: 'jason',
age: 15,
complete: true
}, {
name: 'Jeremy',
age: 20,
complete: false
}]
},
ready: function () {
var divoutput = document.querySelector('#filler');
alert(divoutput.innerHTML);
len = this.$data.people.length;
for (i = 0; i < len; i += 1) {
var nameT = this.$data.people[i].name;
divoutput.innerHTML += '<test-component name="' + nameT + '"></test-component>';
}
},
});
</script>
</body> </html>
I'm trying to take all of the people in the Vue data array and inject it into a component and add it to a innerHTML of a div during the Vue.ready() function. I show that result is being injected in to the "filler" array but the components them selves are not being rendered properly. If I make a manual instance of my component it works fine.
You shouldn't try to add Vue component using innerHTML. That's managing the DOM yourself, just let Vue do that on its own. Here is a fiddle:
https://jsfiddle.net/xccjsp4b/
I changed the script template to a div because I'm not certain you can use the script tag like that (although I could be wrong). Then you just use a v-for to loop through the people and pass the relevant data as properties. If each person is going to have their own age, you want it to be a property not a data variable.
Also, use the shorthand binding of :name="person.name" rather than name="{{person.name}}". The : tells Vue to evaluate the expression.