#*<select id="attr-code-dropdown" class="ms-TextField-field detail-input"></select>*#
#(Html.Kendo().DropDownList()
.Name("AttributeCode")
.DataTextField("AttributeCode")
.DataValueField("AttributeCodeId")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("AttributeSecurityCode_Read", "AttributeCode")
.Data("filterCode");
})
.ServerFiltering(true);
})
.Enable(false)
.AutoBind(false)
.CascadeFrom("AttributeName")
)
<script>
function filterCode() {
return {
AttributeName: $("#AttributeName").val()
};
}
</script>
What is wrong with my code it gives me this error.
kendo.all.js:198 Uncaught Error: Invalid template:' Attribute Type * kendo.syncReady(function(){jQuery("#AttributeName").kendoDropDownList({"dataTextField":"AttributeTypeName","dataValueField":"AttributeTypeId","dataSource":{"transport":{"read":{"url":"/AttributeType/AttributeTypesSecurity_Read"},"prefix":""},"schema":{"errors":"Errors"}}});});
If that is within a template, try using deferred scripts:
#(Html.Kendo().DropDownList()
.Name("AttributeCode")
.DataTextField("AttributeCode")
.DataValueField("AttributeCodeId")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("AttributeSecurityCode_Read", "AttributeCode")
.Data("filterCode");
})
.ServerFiltering(true);
})
.Enable(false)
.AutoBind(false)
.CascadeFrom("AttributeName")
.Deferred() // tell kendo to do scripts below
)
<script>
function filterCode() {
return {
AttributeName: $("#AttributeName").val()
};
}
#Html.Kendo().DeferredScripts()
</script>
Related
I'm trying to create a select option that will show the category when it's been saved. The problem I'm having is that I'm getting this error in my console
[Vue warn]: Error in render: "TypeError: _this2.categoryOptions.find is not a function"
Here is my code
<template>
<div>
<select class="form-control" v-model="addCategory" name="category">
<option v-for="category in categoryOptions" :value="category.id">{{ category.name }}</option>
</select>
</div>
</template>
<script>
export default {
props: ['product', 'categories'],
data() {
return {
addCategory: null,
categoryOptions: []
}
},
mounted() {
axios.get('/admin/products/'+this.product.id+'/category').then((response) => {
this.categoryOptions = response.data;
});
},
computed: {
categoryOptions(){
let options = [];
options.push({id:0, text: "Please select one"});
let filteredCategory = this.categories.filter(category => {
return this.categoryOptions.find(selected => categoryOptions.category_id === category.id) == null;
});
filteredCategory.forEach(sc => {
options.push({id: sc.id, text: sc.name});
});
return options;
}
},
}
</script>
Replace:
let filteredCategory = this.categories.filter(category => {
return this.categoryOptions.find(selected => categoryOptions.category_id === category.id) == null;
});
per
let filteredCategory = this.categories.filter(category => {
return this.categoryOptions.find(selected => selected.category_id === category.id) == null;
});
note that you just forgot to replace categoryOptions with selected. But to ensure that the component is loaded, I advise you to make the props categories required, and ensure that it is persisted for the component before rendering.
<script>
export default {
props: {
'product',
'categories': {
type: [Array, Object],
required: true,
},
},
...
}
</script>
Another tip if you use the chrome browser, is to use a very cool extension which is Vue.js devtools to follow the status of your application.
I work with constantly changing api data. I use Laravel and Vue.js. There is a steady stream of data when I control the network with F11. But it has no effect on the DOM.
Here are sample codes. I would be glad if you help.
HTML code;
<div class="row">
<div class="col-md-12">
<p class="tv-value" v-html="totalMeetings"></p>
</div>
</div>
Script Code;
<script>
export default {
data() {
return {
totalMeetings: null
}
},
created() {
this.getPosts();
},
methods: {
getPosts() {
axios
.get("/get-total-meetings")
.then(response => (this.totalMeetings = response.data))
.catch(error => {
this.errors.push(error);
});
}
},
mounted() {
setInterval(function () {
axios
.get("/get-total-meetings")
.then(response => (this.totalMeetings = response.data))
.catch(error => {
this.errors.push(error);
});
}, 2000)
}
}
</script>
Change your setInterval function to arrow function like this.
setInterval(() => {
axios
.get("/get-total-meetings")
.then(response => (this.totalMeetings = response.data))
.catch(error => {
this.errors.push(error);
});
}, 2000);
You could put a watcher for that to be able vue to watch the changes of your data. like this.
watch: {
totalMeetings(val) {
this.totalMeetings = val
}
}
Or create a computed property for it to update the value when it changes.
computed: {
total_meetings() {
return this.totalMeetings
}
}
then your component should look like this
<p class="tv-value" v-html="total_meetings"></p>
I created a component that can add additional fields by pressing a button. I don't know how would I submit this in the database with axios.post and laravel controller. I was able to achieve it in the past with the use of jquery and pure laravel, but I'm confused how to implement it in vue and axios.
Component.vue
<template>
<v-app>
<table class="table">
<thead>
<tr>
<td><strong>Title</strong></td>
<td><strong>Description</strong></td>
<td><strong>File</strong></td>
<td></td>
</tr>
</thead>
<tbody>
<tr v-for="(row, index) in rows" :key="row.id">
<td><v-text-field outlined v-model="row.title" /></td>
<td><v-text-field outlined v-model="row.description" /></td>
<td>
<label class="fileContainer">
<input type="file" #change="setFilename($event, row)" :id="index">
</label>
</td>
<td><a #click="removeElement(index);" style="cursor: pointer">X</a></td>
</tr>
</tbody>
</table>
<div>
<v-btn #click="addRow()">Add row</v-btn>
<v-btn class="success" #click="save()">Save</v-btn>
<pre>{{ rows | json}}</pre>
</div>
</v-app>
</template>
<script>
export default {
data: ()=> ({
rows: []
}),
methods: {
addRow() {
var elem = document.createElement('tr');
this.rows.push({
title: "",
description: "",
file: {
name: 'Choose File'
}
});
},
removeElement(index) {
this.rows.splice(index, 1);
},
setFilename(event, row) {
var file = event.target.files[0];
row.file = file
},
save() {
// axios.post
}
}
}
</script>
Controller.php
public function store(Request $request)
{
// store function
}
save() {
let data = this.rows
axios
.post("Url", {
data
})
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err)
});
}
ref link https://github.com/axios/axios
save() {
axios
.post("/your/uri", {
user_id: 1,
user_name:'jhone doe',
email:'test#test.com'
})
.then(response => {
console.log(response);
})
.catch(error => {
console.log(error)
});
}
You can retrieve your data from your controller $request->user_id,...,$request->email
Tip: if you post any object,you must JSON.stringify(your_json) them and in a response data from controller json_decode($your_json,true) or you need to modify your header file.
Always use '/your/uri' instead of /your/uri/ without trailing '/'
It now works. I'll be posting my code just in case someone encounter the same hurdle. Than you very much to #kamlesh-paul and #md-amirozzaman
Component.vue
<script>
export default {
data: ()=> ({
rows: [],
}),
methods: {
addRow() {
this.rows.push({
corporate_objective_id: '',
kpa: '',
kpi: '',
weight: '',
score: '',
equal: '',
file: {
name: 'Choose File'
}
});
},
removeElement(index) {
this.rows.splice(index, 1);
},
setFilename(event, row) {
var file = event.target.files[0];
row.file = file
},
save() {
const postData = {
data: this.rows
}
console.log(postData)
axios
.post('/api/employee-objective', {postData})
.then(res => { console.log(res) })
.catch(err => { console.log(err) });
}
}
}
</script>
Controller.php
public function store(Request $request) {
foreach($request->data as $data) {
$container = EmployeeObjective::updateOrCreate([
'kpa_info' => $data['kpa'],
'kpi_info' => $data['kpi'],
'kpa_weight' => $data['weight'],
'kpa_score_1' => $data['score'],
'kpa_equal' => $data['equal'],
]);
$container->save();
}
}
I'm trying to get data from an API in a Laravel Vue component.
I get this error in the console:
TypeError: Cannot set property 'continents' of undefined
What am I missing?
This is my code:
<script>
export default {
mounted() {
console.log('Component mounted.');
},
created(){
this.loadData();
},
data() {
return {
continents: [],
}
},
methods: {
loadData: function() {
axios.get('/api/continents')
.then(function (response) {
// handle success
console.log(response.data);
this.continents = response.data;
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});
},
},
}
</script>
Here is the simple working demo of axios.get request
var app = new Vue({
el: '#app',
data: {
users:[]
},
mounted(){
this.loadData();
},
methods:{
loadData:function(){
axios.get('https://jsonplaceholder.typicode.com/users').then(res=>{
if(res.status==200){
this.users=res.data;
}
}).catch(err=>{
console.log(err)
});
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<div id="app">
<ol>
<li v-if="users.length>0" v-for="user in users">
{{ user.name }}
</li>
</ol>
</div>
In methods you have to use arrow functions syntax in callback functions, to keep your data property accessible.
When you declare the function with normal syntax, you add a "child scope" and this.components in your callback refers to "this" inside you callback function.
Change your method to:
loadData() {
axios.get('/api/continents')
.then((response) => {
// handle success
console.log(response.data);
//now this refers to your vue instance and this can access you data property
this.continents = response.data;
})
.catch((error) => {
// handle error
console.log(error);
})
.then(() => {
// always executed
});
},
You should use arrow function in your call as instance of this is not available in your .then function of promise.Hence try as below.
Read more about arrow functions here
.
methods: {
loadData: function() {
axios.get('/api/continents')
.then((response) => {
// handle success
console.log(response.data);
this.continents = response.data;
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});
},
},
I would like to bind data to a kendoui multiselect at runtime.
for example suppose that I want to bind it as a cascade of a drobdownlist.
any idea?
<p>
<label for="categories">Catergories:</label>
#(Html.Kendo().DropDownList()
.Name("categories")
.HtmlAttributes(new { style = "width:300px" })
.OptionLabel("Select category...")
.DataTextField("CategoryName")
.DataValueField("CategoryId")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetCascadeCategories", "CoreParam");
});
})
.Events(e =>e.Select("select"))
)
</p>
<p>
<label for="parameters">Parameters:</label>
#(Html.Kendo().MultiSelect()
.Name("parameters")
.HtmlAttributes(new { style = "width:400px" })
.DataTextField("ParamDesc")
.DataValueField("ParamCode")
.Placeholder("Select products...")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetCascadeParams", "CoreParam")
.Data("filterParams");
})
.ServerFiltering(true);
})
.AutoBind(false)
)
</p>
<script type="text/javascript">
function filterParams() {
return {
categories: $("#categories").val()
};
}
function select(e) {
var dropdownlist = $("#categories").data("kendoDropDownList");
dropdownlist.select(e.item.index());
var multiselect = $("#parameters").data("kendoMultiSelect");
multiselect.dataSource.read();
};
</script>
You could create a custom MVVM binder which will get the text of the dropdownlist and will set a property of the ViewModel. This property can be bound to the hidden field. Check out the link below for more information.