My JSON is:
[{
"name": "Health care",
"cat_id": 1
}, {
"name": "Education",
"cat_id": 2
}, {
"name": "Bakery",
"cat_id": 3
}, {
"name": "Software company",
"cat_id": 4
}]
My vue js script is.
<script>
new Vue({
el: '#categories' ,
data: {
articles: [],
},
mounted() {
this.$nextTick(function() {
var self = this;
$.ajax({
url: "https://",
method: "GET",
dataType: "JSON",
success: function (e) {
self.articles = e.articles;
console.log(e.articles)
},
});
})
},
})
</script>
The html code used is
<div v-for="post in articles" id="categories">
<div class="top">
<h4>Top Categories</h4>
<ul class="mov_list">
<li><i class="fa fa-star"></i></li>
<li>77</li>
<li>{{post.name}}</li>
</ul>
</div>
</div>
This is where I am trying to display the different categories. But I am getting some errors. Can anybody please help me to display the same. I am weak in js
It looks like a scope issue. self has to be declared outside of the function. Still I believe you do not need to specify the callback. Something like this should be sufficient:
<script>
new Vue({
el: '#app',
data: {
articles: [],
},
mounted() {
var self = this;
$.ajax({
url: "https://n2s.herokuapp.com/api/post/get_all_category/",
method: "GET",
dataType: "JSON",
success: function(e) {
self.articles = e.articles;
console.log(e.articles)
},
});
},
})
</script>
html:
<div id="app">
<div v-for="post in articles">
<div class="top">
<h4>Top Categories</h4>
<ul class="mov_list">
<li><i class="fa fa-star"></i></li>
<li>77</li>
<li>{{post.name}}</li>
</ul>
</div>
</div>
</div>
Cheers!
Related
I have a basic table with an id column and a location name column. I also have an html form where a user can insert a new location into the table. Before inserting I want to check if my locations table already includes a location name and if it does exist I want to alert the user. If not it will be inserted into the table. First I query the locations table and then I try to use an if statement to see if the input value already matches a location name in my table. But I can't get it to work. My insert code works fine on it's own but I just can't get the conditions working. Any help would be greatly appreciated.
// add a new location
$("#btn-locationAdd").on("click", function() {
var addLocationName = $("#addLocationName");
$.ajax({
url: 'libs/php/getAllLocations.php',
method: 'POST',
dataType: 'json',
success: function (result) {
for (let i = 0; i < result.data.length; i++) {
if (result.data[i].name === addLocationName.val()) {
alert('This location aready exists')
} else {
$.ajax({
url: 'libs/php/insertLocation.php',
method: 'POST',
dataType: 'json',
data: {
addLocationName: addLocationName.val(),
},
success: function (result) {
$("#addNewLocationModal").modal('hide');
const newLocation = $("#alertTxt").html('New Location Record Created');
alertModal(newLocation);
}
});
}
this is the array I get after I query the locations table and get all locations in the table:
{
"status": {
"code": "200",
"name": "ok",
"description": "success",
"returnedIn": "1.5790462493896E-6 ms"
},
"data": [
{
"id": "1",
"name": "London"
},
{
"id": "2",
"name": "New York"
},
{
"id": "3",
"name": "Paris"
},
{
"id": "4",
"name": "Munich"
},
{
"id": "5",
"name": "Rome"
}
]
}
my html:
<!-- Add Location Modal -->
<div id="addNewLocationModal" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title">Add New Location</h2>
</div>
<div class="modal-body">
<input type="text" class="form-control" placeholder="Location Name" id="addLocationName"><br>
</div>
<div class="modal-footer">
<input type="button" id="btn-locationAdd" value="Add Location" class="btn btn-success">
<input type="button" id="btn-addLocationCancel" value="CANCEL" data-bs-dismiss="modal" class="btn btn-secondary">
</div>
</div>
</div>
</div>
$("#btn-locationAdd").on("click", function () {
var addLocationName = $("#addLocationName");
$.ajax({
url: 'libs/php/getAllLocations.php',
method: 'POST',
dataType: 'json',
success: function (result) {
let existed = false;
for (let i = 0; i < result.data.length; i++) {
if (result.data[i].name === addLocationName.val()) {
existed = true
break
}
}
if(existed){
alert('This location aready exists')
return
}
$.ajax({
url: 'libs/php/insertLocation.php',
method: 'POST',
dataType: 'json',
data: {
addLocationName: addLocationName.val(),
},
success: function (result) {
$("#addNewLocationModal").modal('hide');
const newLocation = $("#alertTxt").html('New Location Record Created');
alertModal(newLocation);
}
});
}
})
})
I have an API response like this:
{
"status": 200,
"message": "OK",
"data": {
"total": 5
}
}
I want to write the total value from the response above, 5, to my HTML. When I create the js file to get the response the result in HTML is empty.
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript" src="script.js"></script>
<div class="inner">
<h3 id="total"></h3>
<p>Total</p>
</div>
$(function() {
$.ajax({
url: 'https://api-url',
type: 'GET',
dataType: 'json',
success: function(data) {
$.each(data, function(value) {
//append each row data to datatable
var row = value.total
$('#total').append(row);
});
}
})
})
Do you know how to show the total that I want from the API in HTML? Thank you
You don't need an each() loop here as the response is a single object, not an array. As such you can access the data.value and set it as the text() of #total, like this:
$(function() {
$.ajax({
url: 'https://api-url',
type: 'GET',
dataType: 'json',
success: function(response) {
var total = response.data.total;
$('#total').text(total);
}
})
})
Use innerHTML to insert value
var a= {
"status": 200,
"message": "OK",
"data": {
"total": 5
}
};
document.querySelector('#total').innerHTML=a.data.total
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript" src="script.js"></script>
<div class="inner">
<h3 id="total"></h3>
<p>Total</p>
</div>
/* $(function() {
$.ajax({
url: 'https://api-url',
type: 'GET',
dataType: 'json',
success: function(response) {
var total = 0;
for (var i = 0; i < response.length; i++) {
total = total + response[i].data.total;
}
$('#total').text(total);
}
})
}) */
// for ex.: -
const data = [{
"status": 200,
"message": "OK",
"data": {
"total": 5
}
}, {
"status": 200,
"message": "OK",
"data": {
"total": 5
}
}, {
"status": 200,
"message": "OK",
"data": {
"total": 5
}
}];
var total = 0;
for (var i = 0; i < data.length; i++) {
total = total + data[i].data.total;
}
$('#total').text(total);
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript" src="script.js"></script>
<div class="inner">
<h3 id="total"></h3>
<p>Total</p>
</div>
try this I think it should be work
$('#total').append(`<p>${row}</p>`)
{
"status": 200,
"message": "OK",
"data": {
"total": 5
}
}
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript" src="script.js"></script>
<div class="inner">
<h3 id="total"></h3>
<p>Total</p>
</div>
$(function() {
$.ajax({
url: 'https://api-url',
type: 'GET',
dataType: 'json',
success: function(data) {
var row = data.data.total
$('#total').text(row);
});
}
})
})
I am trying to pass an array that inside an object from a parent component to a child component but answers is coming up undefined. When checking the prop in the parent component the data is there, but when it gets past to the child it is undefined.
Vue.component('single-question', {
props: ['question'],
data: function () {
let vm = this
return {
answers: vm.question.answers
}
},
template: `<div class="question mb-3">
<div class="card">
<div class="card-body">
<h5 class="class-title">{{question.questionId}}</h5>
<p class="card-text">{{question.questionText}}</p>
<a class="btn btn-primary" data-toggle="collapse" v-bind:href="'#answerArea' + question.questionId" role="button" aria-expanded="false" aria-controls="answerArea">List answers</a>
</div>
</div>
<answer-area v-bind:id="'answerArea' + question.questionId" v-bind:answers="question.answers"></answer-area>
</div>`
})
Vue.component('answer-area', {
data: function() {
return {
show: false
}
},
props: ['answers'],
template: `<div class="collapse" id="">
<div class="card card-body">
<ol>
<li v-for="answer in answers" v-bind:key="answer.answerId"></li>
</ol>
</div>
</div>`
})
edit: Here is where the parent is declared
<div id="question-area">
<single-question v-for="question in questions" v-bind:key="question.questionId" v-bind:question="question"
v-bind:id="question.questionId"></single-question>
</div>
Parent data:
new Vue ({
el: '#question-area',
data: {
questions: [{
"answers": [{
"answerId": 21,
"questionId": 1,
"answerText": "One",
"iscorrect": false
},
{
"answerId": 40,
"questionId": 1,
"answerText": "In",
"iscorrect": false
}],
"questionId": 1,
"classCode": "123",
"questionText": "Result",
}],
},
})
Query:
$.getJSON(prestring + "/api/v1/classes/"+parsed.classcode+"/questions", function(json) {
vm.questions = json
vm.questions.forEach(question => {
$.ajax({
url: prestring + "/api/v1/questions/" + question.questionId + "/answers",
dataType: 'json',
//async: false,
success: function (json) {
question["answers"] = json
// question["answers"].push(json)
}
})
})
})
We would have to check what's in your data to be sure, but you are probably facing one of the Change Detection Caveats.
Try using Vue.set() to create your answers property, as below:
$.getJSON(prestring + "/api/v1/classes/"+parsed.classcode+"/questions",
function(json) {
vm.questions = json
vm.questions.forEach(question => {
$.ajax({
url: prestring + "/api/v1/questions/" + question.questionId + "/answers",
dataType: 'json',
//async: false,
success: function (json) {
// question["answers"] = json
Vue.set(question, 'answers', json); // changed this line
// question["answers"].push(json)
}
})
})
})
I have a problem with binding checkboxes using Vuex. On checkbox I use v-model with variable which has getter and setter to set or get value in store, the problem is that I get wrong data in store and I don't understand what cause the problem. Checkboxes bind to store property and this property must contain array of id's from checkboxes, but when I click checkbox more than one time it rewrite or remove store values. Can anyone help me to understand why does this happens? Link to jsFiddle.
The code
const store = new Vuex.Store({
state: {
checkboxes: {},
checked: {}
},
mutations: {
setCheckboxes(state, dataObj){
console.log(dataObj);
state.checkboxes = dataObj.data;
let firstElem = dataObj.data[Object.keys(dataObj.data)[0]];
state.checked[firstElem.parent_id] = [firstElem.id];
console.log(state.checked);
},
setTreeState(state, dataObj){
state.checked[dataObj.id] = dataObj.value;
console.log(state.checked);
}
}
});
Vue.component('checkboxTree', {
template: "#checkboxTree",
});
Vue.component('checkboxToggle', {
template: "#checkboxToggle",
data(){
return {
store
}
},
computed: {
value:{
get(){
return store.state.checked[this.checkbox.parent_id];
},
set(val){
store.commit({
type: 'setTreeState',
id: this.checkbox.parent_id,
value: val
});
},
},
},
props: ['checkbox']
});
const app = new Vue({
el: "#app",
store,
data: {
checkboxData: {
...
},
},
mounted(){
this.$store.commit({
type: 'setCheckboxes',
data: this.checkboxData
});
}
})
Template
<div id="app">
<checkbox-tree :checkboxData="checkboxData"></checkbox-tree>
</div>
<template id="checkboxTree">
<div>
<p>checkbox tree</p>
<form>
<ul>
<li v-for="checkbox in $store.state.checkboxes">
<checkbox-toggle :checkbox="checkbox"></checkbox-toggle>
</li>
</ul>
</form>
</div>
</template>
<template id="checkboxToggle">
<div>
<label>{{ checkbox.id }}</label>
<input type="checkbox"
:value="checkbox.id"
:id="'checkbox-' + checkbox.id"
:name="'checkbox-' + checkbox.id"
v-model="value"
>
</div>
</template>
Okay, assuming you want checked to contain ids of selected objects, I had to restructure your code significantly:
const removeFromArray = (array, value) => {
const newArray = [...array];
const index = newArray.indexOf(value);
if (index > -1) {
newArray.splice(index, 1);
return newArray;
}
return array;
}
const store = new Vuex.Store({
state: {
checkboxes: {},
checked: [],
},
mutations: {
addToChecked(state, id) {
state.checked.push(id);
},
removeFromChecked(state, id) {
const newArray = removeFromArray(state.checked, id);
state.checked = newArray;
},
setCheckboxes(state, data) {
state.checkboxes = data;
},
}
});
Vue.component('checkboxTree', {
template: "#checkboxTree",
computed: {
checkboxes() {
return this.$store.state.checkboxes;
},
},
});
Vue.component('checkboxToggle', {
template: "#checkboxToggle",
computed: {
value:{
get(){
return this.$store.state.checked.indexOf(this.checkbox.id) > -1;
},
set(val){
const mutation = val ? 'addToChecked' : 'removeFromChecked';
this.$store.commit(mutation, this.checkbox.id);
},
},
},
props: ['checkbox'],
});
const app = new Vue({
el: "#app",
store,
data: {
checkboxData: {
"5479": {
"id": 5479,
"title": "Место оказания услуг",
"type": "checkbox",
"dependencies": "",
"description": "",
"parent_id": 5478,
"npas": ""
},
"5480": {
"id": 5480,
"title": "Способы оказания услуг",
"type": "checkbox",
"dependencies": "",
"description": "",
"parent_id": 5478,
"npas": "50"
},
"5481": {
"id": 5481,
"title": "Объем и порядок содействия Заказчика в оказании услуг",
"type": "checkbox",
"dependencies": "",
"description": "",
"parent_id": 5478,
"npas": "54"
},
}
},
computed: {
stateRaw() {
return JSON.stringify(this.$store.state, null, 2);
},
},
mounted() {
this.$store.commit('setCheckboxes', this.checkboxData);
const firstElementKey = Object.keys(this.checkboxData)[0];
const firstElement = this.checkboxData[firstElementKey];
this.$store.commit('addToChecked', firstElement.id);
}
})
<script src="https://unpkg.com/vue"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.0.1/vuex.js"></script>
<div id="app">
<checkbox-tree :checkboxData="checkboxData"></checkbox-tree>
<pre v-text="stateRaw"></pre>
</div>
<template id="checkboxTree">
<div>
<p>checkbox tree</p>
<form>
<ul>
<li v-for="checkbox in checkboxes">
<checkbox-toggle :checkbox="checkbox"></checkbox-toggle>
</li>
</ul>
</form>
</div>
</template>
<template id="checkboxToggle">
<div>
<label>{{ checkbox.id }}</label>
<input
type="checkbox"
:value="checkbox.id"
:id="'checkbox-' + checkbox.id"
:name="'checkbox-' + checkbox.id"
v-model="value">
{{value}}
</div>
</template>
Using this code as an example, you can populate checked however you want to.
Also, a jsfiddle link for you: https://jsfiddle.net/oniondomes/ckj7mgny/
I try to add shopping cart,but I do not know how to do it. When count = 0,- is hidden.And when count > 0,- is show.When i try to click +, automatically increase 1, click - automatically reduced by 1. But can not be displayed.jsfiddle
Look at the Javascript file:
const goods = [{
id: "1",
goods_name: "水立方",
goods_price: "30.00",
goods_num: "15",
count:"0"
}, {
id: "2",
goods_name: "农夫山泉",
goods_price: "28.00",
goods_num: "10",
count:"0"
}]
var app = new Vue({
el: "#app",
data: {
list: goods,
},
methods: {
addCart(item,event) {
if (!this.item.count) {
Vue.set(this.item, 'count', 1);
} else {
this.item.count++;
}
},
lessCart(event) {
this.item.count--;
}
}
})
HTML file:
<div id="app">
<ul>
<li v-for="item in list">
<p>{{item.goods_name}}</p>
<p>{{item.goods_price}}</p>
<a v-show="item.count > 0" #click.stop.prevent="lessCart(item,$event)">-</a>
<input v-show="item.count > 0" v-model="item.count">
<a #click.stop.prevent="addCart(item,$event)">+</a>
</li>
</ul>
</div>
You are mutating the same state each time and not the state from the list.
You should simply do:
const goods = [{
id: "1",
goods_name: "水立方",
goods_price: "30.00",
goods_num: "15",
count:"0"
}, {
id: "2",
goods_name: "农夫山泉",
goods_price: "28.00",
goods_num: "10",
count:"0"
}]
var app = new Vue({
el: "#app",
data: {
list: goods,
},
methods: {
addCart(item) {
item.count++;
},
lessCart(item) {
item.count--;
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<div id="app">
<ul>
<li v-for="item in list">
<p>{{item.goods_name}}</p>
<p>{{item.goods_price}}</p>
<a v-show="item.count > 0" #click.stop.prevent="lessCart(item)">-</a>
<input v-show="item.count > 0" v-model="item.count">
<a #click.stop.prevent="addCart(item)">+</a>
</li>
</ul>
</div>
Note that you do not need the event argument in your method.