vue 2.0 how to manage the scope of vue instance - vuejs2
just a very new to Vue framework, and i have one strange thing just can not understand, as below screenshot you can see that i got two input, what i would like to accomplish is use first input to filter content in table, but when i try to move element with vue instant to cover it, i will got render error. should i use slot to pass data, seems not make sense. can anybody point out what is the issue with my code?
new Vue({
el:'#BookCard',
});
Vue.component('canvasComponent',{
template:'#canvasChart',
data:function () {
var sortOrders = {}; //定义sortOrders为空字典
//forEach为columns的每一个元素执行函数内部操作
this.columns.forEach(function (key) {
//将columns的元素设定为key值,value值都为1
sortOrders[key] = 1;
});
return {
sortKey: '',
sortOrders: sortOrders,
BookJson:{},
};
},
props:{
canvasData:Array,
columns:Array,
filterKey:String
},
methods: {
//sortBy[key]理解: 当click时执行该函数,sortBy为一个函数方法,接受key参数
sortBy: function (key) {
//并将参数赋值给内部变量
this.sortKey = key;
//更新排序序列,调用sortOrders将key代表的列反序
console.log(this.sortOrders[key]); // 1
this.sortOrders[key] = this.sortOrders[key] * -1;
console.log(this.sortOrders[key]); // -1
},
fetchBookData:function () {
var item;
var bookJson=$.getJSON('/api/book/getJson',function (data) {
format:"json",
item = data;
$.each(data,function (key,val) {
// item[key]= key;
// item[val]= val;
})
});
},
},
computed: {
filterI: function () {
return this.canvasData.filter((item) => {
return item.name.match(this.filterKey);
})
},
},
});
new Vue({
el:'#filterTest',
data:{
'keywords':[{"id":"9","name":"missy","phone":"21324234532"},
{"id":"3","name":"Mahama","phone":"345604542"},
{"id":"2","name":"Bernard","phone":"241242542"}],
canvasData:{"空间":34,"微博":30,"指导":29,"小明":28 , "图书馆": 27 , "PHP":26 , "项目" :25 ,"健康":24 , "JS" :23 ,'html' :22,'各镇': 22 ,'勋章' :21 ,'信息':20,'开发':19 , '设计':18 , '开幕式' :17 , '浏览器' :16 ,'身份':15,'图片': 14 , '中国' :13 , '伟大' :12 ,'地方':11 ,'噩梦' :10 ,'回复' :9 ,'空间' :8 , '请问' : 7 , '类库' : 6 , '激活' : 5 ,'规范' :4 ,'微软' :3 , '分割': 2 , '不错' :1 , '多个' :1, '斯蒂芬' :1, '分割' :1, '回过头' :1, '慈悲' :1, 'svg' :1, '三个' :1, '十多个' :1, '语句' :1, '写错' :1, '别冲动' :1, '请问' :1, '细长的' :1, '风光' :1, '梵蒂冈' :1, '成办' :1, '这些' :1, '是的' :1, '风格化' :1, '儿童歌' :1, '所得税' :1, '阿斯顿' :1, '斯蒂芬' :1, '电饭锅' :1, '很规范' :1, '车秩序' :1, '上网' :1, '过负荷' :1, '放到' :1, '电饭锅' :1, '东方红' :1, '风格化' :1, '请问' :1, '人头' :1, '让他' :1, '分隔' :1, '大概' :1, '福利' :1, '激活' :1, '断食' :1, '风格' :1, '瓦尔特' :1, '对方' :1, '请问' :1, '而' :1, '人头' :1, '统一' :1, '一份' :1, '放到' :1, '放到' :1, '放到' :1, '放到' :1, '上网' :1, '我是' :1, '的' :1, '耳朵' :1, '发热' :1, '乳房' :1, '跟他' :1, '通过' :1, '还好用' :1, '雅黑' :1, '聚聚' :1, '看过' :1, '似的' :1, '独' :1, '明年' :1, '手头紧' :1, '换个' :1, '数据' :1, '导入' :1, '回归' :1},
gridColumns:['id','name','phone'],
searchQuery:''
},
});
table {
border: 2px solid #42b983;
border-radius: 3px;
background-color: #fff;
}
th {
background-color: #42b983;
color: rgba(255,255,255,0.66);
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-user-select: none;
}
td {
background-color: #f9f9f9;
}
th, td {
min-width: 120px;
padding: 10px 20px;
}
th.active {
color: #fff;
}
th.active .arrow {
opacity: 1;
}
.arrow {
display: inline-block;
vertical-align: middle;
width: 0;
height: 0;
margin-left: 5px;
opacity: 0.66;
}
.arrow.asc {
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-bottom: 4px solid #fff;
}
.arrow.dsc {
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-top: 4px solid #fff;
}
<link href="https://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap.css" rel="stylesheet"/>
<script src="https://cdn.bootcss.com/vue/2.3.4/vue.js"></script>
<script type="text/x-template" id="canvasChart">
<table>
<thead>
<tr>
<!-- 指令(Directives)是特殊的带有前缀 v- 的特性.-->
<!-- 指令的值限定为绑定表达式.因此JavaScript表达式及过滤器规则在这里也适用.-->
<!-- 指令的职责就是当其表达式的值改变时把某些特殊的行为应用到DOM上.-->
<!-- v-for用于渲染列表-->
<!-- v-on的缩写用#表示,它用于监听DOM事件-->
<!-- v-bind的缩写用:表示,v-bind指令用于响应地更新HTML特性,v-bind:class的缩写是:class,sortKey == key表达式为True时class=active-->
<!-- 用管道符 | 来表示过滤器,capitalize表示首字母大写-->
<th v-for="key in columns" :class="{active: sortKey == key}">
#{{key}}
<span class="arrow" :class="sortOrders[key] > 0 ? 'asc' : 'dsc'"></span>
<!-- 这里用到js的判断表达式操作,sortOrders[key] > 0为真,class=asc,反之class=dsc-->
<!-- v-bind:class 指令可以与普通的 class 特性共存 -->
</th>
</tr>
</thead>
<tbody>
<!-- filterBy 返回过滤后的数组,第一个参数可以是字符串或函数,filterBy filterKey 输出满足条件的结果-->
<!-- orderBy sortKey为关键字 sortOrders[sortKey]升序或者降序 -->
<tr v-for="entry in filterI">
<td v-for="key in columns">{{entry[key]}}</td><!--单元格-->
</tr>
</tbody>
</table>
</script>
<div class="container-fluid">
<div class="row">
<div class="col-md-4 col-md-offset-4">
<div class="input-group">
<input type="text" class="form-control" v-model="filter-key" placeholder="Search for...">
<span class="input-group-btn">
<button class="btn btn-default" type="button">Go!</button>
</div>
</span>
</div><!-- /input-group -->
</div>
<div class="row">
<br>
<div class="span10">
<ul class="thumbnails">
</ul>
<blockquote class="pull-right">
<p>
Select the book what you want!
</p> <small>Keyword <cite>Opensource</cite></small>
</blockquote>
</div>
</div>
<div id="filterTest">
<div class="container">
<input type="text" class="input-lg" v-model=searchQuery></input>
<div class="row">
<canvas-component :canvas-data=keywords :columns=gridColumns :filter-key=searchQuery>
</canvas-component>
</div>
</div>
</div>
</div>
ok, i would like answer my question, it's true,just use slot tag internal in the template and added input script front of table, so i got a result what i want, but again, another question pop out, is this the only solution?
Related
Vue: Get data from parent in <slot>
I don't know if what I want is possible in the way I want to do it. I'm using this Vue plugin for modals: https://www.npmjs.com/package/vue-js-modal I have a component called ModalButton that is responsible for triggering the modal: <modal-button :modal-data="{{ collect(['account' => $account]) }}" modal-name="leave-account">Leave Account</modal-button> As you can see, I'm sending :modal-data as props. The ModalButton component is the following: <template> <button #click.prevent="show" type="button" class="px-3 py-2 bg-gray-200 font-bold text-gray-700 "> <slot></slot> </button> </template> <script> // # is an alias to /src export default { name: 'ModalButton', data() { return { } }, props: { modalName: String, modalData: Object }, methods: { show () { this.$modal.show(this.modalName, this.modalData); }, hide () { this.$modal.hide(this.modalName); } } } </script> You can see on the show method which comes from the plugin is sending that data to the modal this.$modal.show(this.modalName, this.modalData); In my blade template (i'm using laravel), I have the <modal>: <modal name="leave-account" class="text-center"> <div class="flex items-center justify-center h-full p-6"> <div> <div> <div class="text-3xl font-bold mb-2">Are you sure?</div> <p>If you leave this account, you won't be able to join back unless invited again. </p> </div> <footer class="flex items-center justify-end mb-24 mt-auto"> <button class="px-3 py-2 bg-gray-200 font-bold text-gray-700 mr-3">Cancel</button> <ajax-button class-list="px-3 py-2 bg-primary text-white font-bold" :route=#{{SOMEHOW ACCESS MODAL DATA}} method="delete"> Yes, leave account </ajax-button> </footer> </div> </div> </modal> Inside my modal, I have another component called AjaxButton which allows me to have a reusable button that handles ajax requests. I need a way of accessing the modal data that was passed to the modal. I'd like not to have to create an additional specific modal component to handle this. Is this possible? Specifically what the :route prop needs to send is the Account since my route requires model binding. i.e it'll look something like /accounts/leave/53 Edit: So I can do this: <button #click="$modal.hide('leave-account')" class="px-3 py-2 bg-gray-200 font-bold text-gray-700 mr-3">Cancel</button> (that's right above my <ajax-button>) So clearly I'm able to access the $modal properties / methods. So there has to be a way to accomplish what I want
You can use a simpler modal: <modal-button v-model="showModal"> Leave Account </modal-button> <modal v-model="showModal" caption="Leave Account"> {{ collect(['account' => $account]) }} </modal> Then modal-button will look like this: <template> <button #click.stop="$emit('input',true)" type="button" class="px-3 py-2 bg-gray-200 font-bold text-gray-700 "> <slot/> </button> </template> <script> export default { name: 'ModalButton', props: { value: { type: Boolean, default: false } } } </script> and the modal component will be: <template> <transition name="modal"> <div class="modal_overlay" #click="close" v-if="value"> <div class="modal_content" style="overflow: auto;" #click.stop> <div class="modal_title">{{ caption }} <div class="modal_close" #click="close">✖</div></div> <slot/> </div> </div> </transition> </template> <script> export default { props: { value: { type: Boolean, default: false }, caption: { type: String, default: '' }, created() { document.addEventListener('keydown', this.modal_escape, false); }, beforeDestroy() { document.removeEventListener('keydown', this.modal_escape, false); }, methods: { close() { this.$emit('input', false); }, modal_escape(event) { var e = event || window.event; if(this.value && e.keyCode == 27) { this.close(); // All good browsers… if (e.preventDefault) e.preventDefault(); // …and IE if (e.returnValue) e.returnValue = false; return false; } } } } </script> <style> .modal_overlay { position: fixed; left: 0; right: 0; top: 0; bottom: 0; z-index: 25; text-align: initial; background-color: rgba(0,0,0,0.75); } .modal_content { position: relative; display: inline-block; left: 50%; top: 50%; transform: translate(-50%,-50%); background-color: white; border: 2px solid #000; border-radius: 5px; max-width: 90vw; max-height: 90vh; } .modal_title { text-align: center; background-color: #F27935; color: white; line-height: 1.65; padding-left: 6px; } .modal_close { float: right; display: inline-block; cursor: pointer; padding: 0 5px 0 4px; } .modal_close:hover { color: white; background-color: #00B4FF; } .modal-enter-active { transition: all .4s ease; } .modal-leave-active { transition: all .2s cubic-bezier(1.0, 0.5, 0.8, 1.0); } .modal-enter, .modal-leave-to { transform: translateX(10px); opacity: 0; } </style>
How to handle transitions and animations in Gridsome
Currently i have been using this code in the inline CDN version of VueJS and it works fine, but when i add this to gridsome the click event on the animation to open the slide out doesn't work. I have looked up that animations for page enter is working but i am not sure how to handle component animations. Are animations working in Gridsome? <template> <nav class="navbar fixed-top navbar-expand-lg navbar-light bg-light"> <div class="row"> <div class="col"> <button #click="show = !show" class="navbar-toggler" type="button" > <span class="navbar-toggler-icon"></span> </button> </div> <div class="col"> <a class="navbar-brand" href="/">Navbar</a> </div> </div> <div> <transition name="slidein"> <div v-if="show" class="nav-bar"> <button #click="show = !show" class="btn-close pl-4 p-3" type="button" ></button> <span class="close-btn">X</span> <div class="d-flex flex-column"></div> </div> </transition> <transition name="fadein"> <div v-if="show = show" class="bck-close" #click="show = !show"></div> </transition> </div> </nav> </template> <script> export default { name: "headNav", data: { show: false }, }; </script> <style> .nav-bar { height: 100vh; width: 80vw; background: #fff; position: absolute; left: 0; z-index: 10000; overflow-x: hidden; overflow-y: auto; top: 0; } .btn-close { background: none; border: none; font-size: 1em; } .bck-close { height: 100vh; width: 100vw; background: rgba(0, 0, 0, 1); position: fixed; z-index: 9999; left: 0; top: 0; opacity: 0.1; cursor: pointer; } .slidein-enter-active { animation: slidein 0.2s; } .slidein-leave-active { animation: slidein 0.2s reverse; } #keyframes slidein { from { left: -100%; width: 0%; } to { left: 0; width: 80vw; } } .fadein-enter-active { animation: fadein 0.2s; } .fadein-leave-active { animation: fadein 0.2s reverse; } #keyframes fadein { from { opacity: 0; } to { opacity: 0.1; } } </style>
Got the data part wrong, animations do work! <script> export default { name: "headNav", data () { return { show: false } }, }; </script>
Error when trying to use ReactiveProp in vue-chartjs
I'm trying to use a component called "Vue-Chartjs" to create a LineChart.[ I'm passing some data from a MySql database to the 'chartData' prop, defined in the Chart.js file. But I'm getting this error. What I understood (I think), is that chartData doesn't get updated. Does anyone know why it doesn't work? Thank you very much!
This are my Chart.js file and my Forecast.vue file import { Line, mixins } from 'vue-chartjs' const { reactiveProp } = mixins export default { name: 'line-chart', extends: Line, mixins: [reactiveProp], props: { chartData: { type: Array, required: true }, chartLabels: { type: Array, required: true } }, data() { return { options: { scales: { yAxes: [{ display: true }], xAxes: [{ display: false }] }, legend: { display: true }, responsive: true, maintainAspectRatio: false } } }, mounted() { this.renderChart({ labels: this.chartLabels, datasets: [{ label: 'Temperature', colors: '#000000', backgroundColor: '#000000', data: this.chartData }] }, this.options) } } <template> <div class="FiveDaysForecast"> <div class="tabs is-fullwidth"> <ul> <li><router-link to="OneDayForecast"><span class="icon is-small"><i class="fas fa-cloud"></i></span>One day forecast</router-link></li> <li class="is-active"><router-link to="FiveDaysForecast"><span class="icon is-small"><i class="fas fa-cloud"></i></span>Five days forecast</router-link></li> <li><router-link to="FilterByDate"><span class="icon is-small"><i class="fas fa-calendar-alt"></i></span>Filter forecast by date</router-link></li> </ul> </div> <h1>FIVE DAYS FORECAST</h1> <form> <div class="box"> <div class="field"> <div class="control"> <input class="input is-rounded" type="text" placeholder="Place" v-model="place"> </div> <br> <div class="control"> <input class="input is-rounded" type="text" placeholder="Country" v-model="country"> </div> <br> <div class="control"> <input class="input is-rounded" type="text" placeholder="Unit of measure (Celsius = 'metric' | Fahrenheit = 'imperial')" v-model="unitOfMeasure" required> </div> <br> <div class="control"> <input class="input is-rounded" type="text" placeholder="Latitude" v-model="latitude"> </div> <br> <div class="control"> <input class="input is-rounded" type="text" placeholder="Longitude" v-model="longitude"> </div> </div> <button class="button is-medium is-rounded" #click="getFiveDaysForecast">Search</button> </div> </form> <br> <table class="table is-narrow"> <thead> <tr> <th>Temperature</th> <th>TemperatureMin</th> <th>TemperatureMax</th> <th>Humidity</th> <th>Pressure</th> <th>Time</th> </tr> </thead> <tbody> <tr v-for="forecast in forecastData" :key="forecast.Pressure"> <td>{{forecast.temperature}}</td> <td>{{forecast.temperatureMin}}</td> <td>{{forecast.temperatureMax}}</td> <td>{{forecast.humidity}}</td> <td>{{forecast.pressure}}</td> <td>{{forecast.timeStamp}}</td> </tr> </tbody> </table> <line-chart :chart-data="tempRows" :chartLabels="weatherDate" ></line-chart> </div> </template> <script> import axios from "axios"; export default { name: "FiveDaysForecast", data() { return { place: "", country: "", unitOfMeasure: "", latitude: "", longitude: "", forecastData: [], temperature: [], weatherDate: [], tempRows: [] }; }, methods: { getFiveDaysForecast() { axios({ method: "get", url: "http://localhost:55556/api/ForecastActions/fiveDaysForecast", params: { Place: this.place, Country: this.country, UnitOfMeasure: this.unitOfMeasure, Lat: this.latitude, Lon: this.longitude } }) .then(response => { console.log(response); this.forecastData = response.data; this.forecastData.forEach(item => { var tempArray = []; this.tempRows.push(item.temperature); this.weatherDate.push(item.timeStamp); }); }) .catch(error => { console.log(error); }); } } }; </script> <style scoped> .FiveDaysForecast { width: 1200px; margin: 30px auto; } .tabs { width: 600px; margin-left: auto; margin-right: auto; } h1 { font-size: 50px; } #forecast-params { margin-top: 30px; margin-bottom: 50px; text-align: left; font-size: 20px; } .param-names { font-weight: bold; color: black; font-size: 20px; } .box { background-color: transparent; width: 600px; margin: 0 auto; border: 3px solid royalblue; box-shadow: 0px 0px 30px royalblue; } ::placeholder { color: rgb(170, 170, 170); } input, button { background-color: #fcfcfc; border: 2px solid rgb(170, 170, 170); } input:focus { border: 2px solid royalblue; box-shadow: 0px 0px 30px royalblue; } input:hover { border: 2px solid royalblue; } button:focus { border: 2px solid royalblue; box-shadow: 0px 0px 30px royalblue; } button:hover { border: 2px solid royalblue; } .table { margin: 0 auto; width: 1000px; } td, th { text-align: center; } thead { font-size: 20px; display: table-header-group; vertical-align: middle; border-bottom: 3px solid royalblue !important; } tr { font-weight: 600; transition: background-color 0.5s ease; } tr:hover { background-color: rgb(153, 179, 255); } #chart { display: inline-block; padding: 0px; margin: 0px; } #tempChart { padding: 0 auto; } #charts { padding: 0px auto; } </style>
Well your "problem" is that your data is async. So the chart will be rendered without any data or without proper data. You have to put a v-if="loaded" on your chart component. And in your axios call you need to set it to true.
Method not executing inside another method using Vue.js event
I'm learning how to use vue.js to pull movie information and display it. Inside the main application mc I have a method getMovie which isn't being called when another method updateMovie is called. The updateMovie method is called from the event 'switch' which is emitted by a child component details-card I can see that the title on my application gets changed and the method updateMovie is working if you click on a director and then a movie under that director. The input field also changes value. Why won't the getMovie work? var mc = new Vue({ el: "#movie-card", data: { title: '', valid: false, loading: false, error: false, mc: {}, directorArray: [], actorArray: [], }, computed: { checkMulti: function(item) { if (Object.keys(item).length <= 1) { return false; } else { return true; } } }, methods: { getMovie: function() { this.cm = {}; console.log("getMovie called") if (this.title !== "") { this.loading = true; this.error = false; searchString = 'https://www.omdbapi.com/?t=' + this.title; var that = this; axios.get(searchString) .then(function(res) { that.cm = res.data; that.directorArray = res.data.Director.trim().split(/\s*,\s*/); that.actorArray = res.data.Actors.trim().split(/\s*,\s*/); that.valid = true; that.loading = false; }) .catch(function(error) { console.log(error.message); that.loading = false; that.error = true; }) } }, updateMovie: function(movie) { console.log(movie); this.title = movie; this.getMovie; } } }) Vue.component('details-card', { props: [ 'name', 'title' ], template: ` <div> <a href="" #click="handleShowDetails($event)" > {{ name }} </a> <div v-if="visible" class="detailsCard"> <h3 class="removeTopMargin">{{ name }}</h3> <img :src="picUrl"> <h4>Known for</h4> <p v-for="movie in knownForArray"> <a href="" #click="switchMovie(movie.original_title, $event)" >{{ movie.original_title }}</a> </p> </div> </div> `, data: function() { return { picUrl: "", knownForArray: [], visible: false } }, methods: { handleShowDetails: function($event) { this.visible = !this.visible; this.callPic($event); }, switchMovie( movie , $event) { if ($event) $event.preventDefault(); console.log("switching to...", movie); this.$emit('switch', movie); }, callPic: function(event) { if (event) event.preventDefault(); let that = this; let searchString = "https://api.themoviedb.org/3/search/person?api_key=9b8f2bdd1eaf20c57554e6d25e0823a2&language=en-US&query=" + this.name + "&page=1&include_adult=false"; if (!this.picUrl) { //only load if empty axios.get(searchString) .then(function(res) { let profilePath = res.data.results[0].profile_path; if (profilePath === null) { that.picUrl = "http://placehold.it/150x200" } else { that.picUrl = 'https://image.tmdb.org/t/p/w150/' + profilePath; } that.personPic = profilePath; that.knownForArray = res.data.results[0].known_for; }).catch(function(err){ console.log(err); }) } }, hideDetails: function () { this.visible= false; } } }) * { margin: 0; padding: 0; box-sizing: border-box; } *:focus { outline: none; } ul { padding-left: 1em; } .loading { margin: auto; max-width: 450px; } .details { display:block; margin: 1em auto; text-align: center; } .searchBar { padding: .5em; -webkit-box-shadow: 0px 2px 16px 2px rgba(168,168,168,0.45); -moz-box-shadow: 0px 2px 16px 2px rgba(168,168,168,0.45); box-shadow: 0px 2px 16px 2px rgba(168,168,168,0.45); text-align: center; } .searchBar input { padding: .5em; width: 300px; font-size: 1em; border: none; border-bottom: 1px solid gray; } .searchBar button { padding: .2em; border: 2px solid gray; border-radius: 8px; background: white; font-size: 1em; color:#333; } img { display: block; margin: auto; width: 150px; padding-bottom: .33em; } .card { max-width: 500px; margin: 2em auto; -webkit-box-shadow: 0px 6px 16px 2px rgba(168,168,168,0.45); -moz-box-shadow: 0px 6px 16px 2px rgba(168,168,168,0.45); box-shadow: 0px 6px 16px 2px rgba(168,168,168,0.45); padding: 2em; } .detailsCard { -webkit-box-shadow: 0px 6px 16px 2px rgba(168,168,168,0.45); -moz-box-shadow: 0px 6px 16px 2px rgba(168,168,168,0.45); box-shadow: 0px 6px 16px 2px rgba(168,168,168,0.45); padding: 1em; } /* ======= Typography */ html {font-size: 1em;} body { background-color: white; font-family: roboto; font-weight: 400; line-height: 1.45; color: #333; } p {margin-bottom: 1.3em;} h1, h2, h3, h4 { margin: 1.414em 0 0.5em; font-weight: inherit; line-height: 1.2; } h2, h3, h4 { border-bottom: 1px solid gray; } h1 { margin-top: 0; font-size: 3.998em; text-align: center; } h2 {font-size: 2.827em;} h3 {font-size: 1.999em;} h4 {font-size: 1.414em;} small, .font_small {font-size: 0.707em;} .removeTopMargin { margin-top: .5em; } <link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet"> <script src="https://unpkg.com/vue"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <div id="movie-card"> <div class="searchBar"> <input type="text" ref="input" v-model="title" placeholder="Enter a movie title here..." v-on:keyup.enter="getMovie"> <button type="submit" #click="getMovie">Search</button> </div> <div class="loading" v-if="loading"> <BR><BR> <h1>Loading...</h1> </div> <div class="loading" v-if="error"> <BR><BR> <h1>Something went wrong!</h1> </div> <div class="card" v-if="valid && !loading"> <h1> {{ cm.Title }}</h1> <div v-if="!(cm.Poster === 'N/A')" class="poster"> <img v-bind:src="cm.Poster"> </div> <div class="details"> <p>{{ cm.Year + " – " + cm.Rated + " – " + cm.Runtime }}</p> </div> <p>{{ cm.Plot }}</p> <div class="directors" v-if="cm.Director"> <h3 v-if="(directorArray.length > 1)">Director</h3> <h3 v-else>Director</h3> <p> <p v-for="(director, index) in directorArray"> <details-card :name="director" v-on:switch="updateMovie"></details-card> </p> </p> </div> <div class="actors" v-if="cm.Actors"> <h3 v-if="actorArray.length > 1">Actors</h3> <h3 v-else>Actor</h3> <p> <p v-for="(actor, index) in actorArray"> <details-card :name="actor"></details-card> </p> </p> </div> <div class="ratings" v-if="cm.Ratings"> <h3>Ratings</h3> <ul> <li v-for="rating in cm.Ratings">{{ rating.Source }}: {{ rating.Value }}</li> </ul> </div> </div> </div>
How to Submit Values from View to the Controller
I have a view with a partial view. In my main view there's a dropdown list, on selection of a value from dropdown list, WebGrid is populated according to the choice selected. Also in the main view I have a dropdown list, a datetime picker text box, and a Submit (Allocate) button. Webgrid has one check box for each row. On selecting a row from WebGrid, collected data needs to go the controller. But my button ain't working! Please help me with my controller, I'm not able to get selected values in my controller. My View is like: #model LipiProject.Models.Allocation #{ ViewBag.Title = "Call Allocation"; } <script src="~/Scripts/jquery-1.8.2.min.js"></script> <script src="~/Scripts/jquery.validate.min.js"></script> <script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script> <link href="~/StyleSheet1.css" rel="stylesheet" /> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> <script src="~/Scripts/Timepicker.js"></script> <script> $(function () { $("#datepicker").datetimepicker({ timeFormat: "hh:mm tt" }); });</script> <style> .webgrid-table { font-family: Arial,Helvetica,sans-serif; font-size: 14px; font-weight: normal; width: 650px; display: table; border-collapse: collapse; border: solid 1px #C5C5C5; background-color: white; } .webgrid-table td, th { border: 1px solid #C5C5C5; padding: 3px 7px 2px; } .webgrid-header, .webgrid-header a { background-color: #0094ff; color:#ffffff; text-align: left; text-decoration: none; } .webgrid-footer { } .webgrid-row-style { padding: 3px 7px 2px; } .webgrid-alternating-row { background-color:azure; padding: 3px 7px 2px; } .col1Width { width: 55px; } .col2Width { width: 220px; } .lineSep { border-bottom: 1px solid #000; display: block; margin: 10px 0; } </style> <h2>Index</h2> <div id="overlay" style="display: none"> <img id="loading" src="~/Images/ajax-loader.gif"> </div> #using (Html.BeginForm("CallAllocationSubmit", "Home", FormMethod.Post, new { id = "FrmCallAllocate", ReturnUrl = ViewBag.ReturnUrl })) { <table> <tr> <td> <div class="row"> <div class="col-sm-12"> <section class="panel default blue_title h5"> <div class="panel-heading">Select Call Category</div> <div class="panel-body"> #Html.DropDownList("CallNature", Model.CallNature, "Select Call Nature") </div> </section> </div> </div> </td> </tr> <tr> <td> <div id="GridView"> #Html.Partial("_CallAllocation",Model.CallTicketGrid) </div> </td> </tr> </table> <div class="row"> <div class="col-sm-12"> <section class="panel default blue_title h5"> <div class="panel-heading">Allocate Engineer</div> <div class="panel-body"> #Html.DropDownList("DefaultEngg", Model.DefaultEngg, "Select Engineer") ETA: <input type="text" id="datepicker"> <input type="submit" value="Allocate" class="btn btn-primary"> </div> </section> </div> </div> } <script type="text/javascript"> $('#CallNature').change(function (e) { e.preventDefault(); var url = '#Url.Action("Filter")'; $.get(url, { CallNatureId: $(this).val() }, function (result) { debugger; $('#GridView').html(result); }); }); </script> My Partial View is like: #model List<LipiProject.Models.Allocation> #{ ViewBag.Title = "_CallAllocation"; } <style> .webgrid-table { font-family: Arial,Helvetica,sans-serif; font-size: 14px; font-weight: normal; width: auto; display: table; border-collapse: collapse; border: solid 1px #C5C5C5; background-color: white; } .webgrid-table td, th { border: 1px solid #C5C5C5; padding: 3px 7px 2px; } .webgrid-header, .webgrid-header a { background-color: #0094ff; color:#ffffff; text-align: left; text-decoration: none; } .webgrid-footer { } .webgrid-row-style { padding: 3px 7px 2px; } .webgrid-alternating-row { background-color:azure; padding: 3px 7px 2px; } .col1Width { width: 55px; } .col2Width { width: 220px; } .lineSep { border-bottom: 1px solid #000; display: block; margin: 10px 0; } </style> #{ var grid = new WebGrid(source: Model, canPage: true, rowsPerPage: 10, ajaxUpdateContainerId: "gridContent", columnNames: new[] { "CallTicketNumber", "TicketDate", "SerialNumber", "CustomerName", "City", "State", "DefaultEngg" }, defaultSort: "DateCreated"); <div class="row" id="GridView"> <div class="col-sm-12"> <section class="panel default blue_title h5"> <div class="panel-heading">Allocate Calls</div> <div class="panel-body"> <div class="col-sm-12">#grid.GetHtml(mode:WebGridPagerModes.All, tableStyle: "webgrid-table", htmlAttributes: new {id = "checkableGrid"}, headerStyle: "webgrid-header", footerStyle: "webgrid-footer", alternatingRowStyle: "webgrid-alternating-row", selectedRowStyle: "webgrid-selected-row", rowStyle: "webgrid-row-style", columns: grid.Columns( grid.Column(columnName: "CallTicketNumber", header: "CallTicketNumber"), grid.Column(columnName: "TicketDate", header: "Ticket Logged On"), grid.Column(columnName: "SerialNumber", header: "Serial Number"), grid.Column(columnName: "CustomerName", header: "Customer Name"), grid.Column(columnName: "City", header: "City"), grid.Column(columnName: "State", header: "State"), //grid.Column("DefaultEngg", "Engineer", format:item => Html.DropDownList(((string)item.DefaultEngg).ToString(), (List<SelectListItem>)Model[0].DefaultEngg)) //grid.Column(header:"Default Engineer", format: item =>Html.DropDownList(((long)item.CallTicketNumber).ToString(), (IEnumerable<SelectListItem>)Model[0].DefaultEngg)) grid.Column(format: #<text> <input type="checkbox" value="#item.CallTicketNumber" name="ids" /> </text>, header: "SelectAll") )) </div> </div> </section> </div> </div> } <script> $(document).ready(function () { // 1st replace first column header text with checkbox $("#checkableGrid th").each(function () { if ($.trim($(this).text().toString().toLowerCase()) === "SelectAll") { $(this).text(''); $("<input/>", { type: "checkbox", id: "cbSelectAll", value: "" }).appendTo($(this)); $(this).append("<span>Select All</span>"); } }); //2nd click event for header checkbox for select /deselect all $("#cbSelectAll").live("click", function () { var ischecked = this.checked; $('#checkableGrid').find("input:checkbox").each(function () { this.checked = ischecked; }); }); //3rd click event for checkbox of each row $("input[name='ids']").click(function () { var totalRows = $("#checkableGrid td :checkbox").length; var checked = $("#checkableGrid td :checkbox:checked").length; if (checked == totalRows) { $("#checkableGrid").find("input:checkbox").each(function () { this.checked = true; }); } else { $("#cbSelectAll").removeAttr("checked"); } }); }); </script> My Controller is like: [HttpPost] [ValidateAntiForgeryToken] public ActionResult CallAllocationSubmit(Allocation allocate, FormCollection frmCollection) { string CallTicketNumber = frmCollection["CallTicketNumber"].ToString(); string CallNature = frmCollection["CallNature"].ToString(); var Defengg = frmCollection["DefaultEngg"].ToList(); var ETA = frmCollection["ETA"].ToString(); return RedirectToAction("CallAllocation"); }