我想在detail_index.js(文档表)中呈现documents_index.js内的元素。 Detail.cshtml打开detail_index.js,这将打开一个模式。模态可以做其他事情,但是我希望文档列表也出现在模态内部。最终,文件也会被推送到其他地方。
我已经看到将script标记放在结束body标记之前会有所帮助,我还看到将eventlistener放置可以解决问题。使用现有的chstml,我尝试将其移出脚本部分,并在不同div的多个位置内联。错误仍然存在:
[Vue warn]: Cannot find element: #documents
。我不确定在哪里放置eventListener,以及具体如何调用。
detail.cshtml
@model Project.Controllers.CareerController
@{
ViewData["Title"] = "Job Details";
}
@section css {
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css" />
<link href="~/lib/slick/slick.css" rel="stylesheet" />
<link href="~/lib/slick/slick-theme.css" rel="stylesheet" />
}
<div id="job-detail" v-cloak>
<div class="columns">
<div class="colum is-12">
<!--
Some stuff that isnt necessary
-->
</div>
</div>
<div class="columns">
<div class="column is-9">
<div v-if="jobDetail">
<!--
more unnecessary stuff
-->
<button class="button is-fullwidth is-primary" v-if="!jobDetail.externalApplyLink && !jobDetail.externalHostLink && !applied" v-on:click="apply()"><b>Apply</b></button>
<a class="button is-fullwidth is-primary" v-if="jobDetail.externalApplyLink || jobDetail.externalHostLink && !applied" :href="jobDetail.externalApplyLink ? jobDetail.externalApplyLink : jobDetail.externalHostLink" target="_blank"><b>Apply</b></a>
</div>
<section class="job-response" v-show="!jobDetail">
<div class="image is-96x96 is-centered">
<img src="/images/loaderPrimary.svg">
</div>
</section>
</div>
</div>
</div>
@section Scripts {
<script src="~/lib/slick/slick.min.js"></script>
<script src="https://unpkg.com/vue-the-mask@0.11.1/dist/vue-the-mask.js"></script>
<script src="https://unpkg.com/vee-validate@2.0.0-rc.14/dist/vee-validate.js"></script>
<script src="~/dist/career/detail.js"></script>
}
detail_index.js
import { documents, components } from '../documents/index.js';
documents();
components();
//modal component
var modal = {
props: {
title: String,
subtitle: String,
content: String,
redirectUrl: String,
buttonName: String,
jobID: String,
isLoading: Boolean = false,
data: {
type: Object,
default: null
},
container: {
type: String,
default: '.simple-modal'
}
},
//add transistion see results
template: '<div class="modal" v-if="show" style="display:flex;">' +
'<div class="modal-background" v-on:click="close()"></div>' +
'<div class="modal-card">' +
'<header class="modal-card-head">' +
'<p class="modal-card-title has-text-centered">{{title}} - {{subtitle}}</p>' +
'<button class="delete" v-on:click="close()"></button>' +
'</header>' +
'<section class="modal-card-body">' +
'<div v-if="status == 1">' +
//'irrelevant stuff'
'<div id="documents" class="field">' +
'<label class="label">CareerDocs</label>' +
//'<p>The ability to include documents you\'ve uploaded into CareerDocs with your application is coming soon!</p>' +
'<table class="table is-narrow">'+
'<thead>'+
'<tr>'+
'<th><input type="checkbox" :records="recordList()" v-on:click="selectAllChecked.records = !selectAllChecked.records; selectAllRecords(recordData.Children[0].Children, showDeleted, selectAllChecked.records);"></th>'+
'<th>Name</th>'+
'<th>Date & Time</th>'+
'<th>Type</th>'+
'<th></th>'+
'</tr>'+
'</thead>'+
'<tbody>'+
'<tr v-for="child in recordList" v-if="showDeleted == child.Hidden">'+
'<td><input v-if="!child.Hidden" type="checkbox" :id="child.ItemID" v-on:click="recordSelected(child,selectedRecords)"></td>'+
'<td><a v-if="!child.Hidden" v-on:click="routeEdit(child, \'detail\')">{{child.Content.name}}</a></td>'+
'<td>{{child.Content.startDate}}</td>'+
'<td>{{child.Content.type}}</td>'+
'<td class="has-text-centered">'+
'</td>'+
'</tr>'+
'<tr v-if="recordList.length < 1">'+
'<td colspan="5" rowspan="2" class="has-text-centered">No Records.</td>'+
'</tr>'+
'</tbody>'+
'</table>'+
'</div>' +
'</div>' +
//'a whole bunch of irrelevant stuff',
data: function () {
return {
$_parent_: null,
show: true,
coverLetter: null,
showError: false,
fileBlob: null,
errorMessasge: null,
file: null,
status: 1,
tooLarge: false,
wrongType: false,
phoneProp: "required|numeric|min:10",
profile: {
name: "",
phone: "",
email: "",
city: "",
state: ""
},
catId: 3,
userID: userViewId,
};
},
created() {
let $parent = this.$parent
if (!$parent) {
let parent = document.querySelector(this.container)
if (!parent) {
// Lazy creating `div.modal` container.
const className = this.container.replace('.', '')
const Modal = Vue.extend({
name: 'Modal',
render(h) {
return h('div', {
'class': {
[`${className}`]: true
}
})
}
})
$parent = new Modal().$mount()
document.body.appendChild($parent.$el)
} else {
$parent = parent.__vue__
}
// Hacked.
this.$_parent_ = $parent
}
},
mounted() {
if (this.$_parent_) {
this.$_parent_.$el.appendChild(this.$el)
this.$parent = this.$_parent_
delete this.$_parent_
}
if (this.duration > 0) {
this.timer = setTimeout(() => this.close(), this.duration)
}
},
destroyed() {
this.$el.remove()
},
methods: {
}
};
const modalComponent = Vue.extend(modal);
const openModal = function openModal(propsData) {
return new modalComponent({
el: document.createElement('div'),
propsData: propsData
});
};
var app = new Vue({
el: '#job-detail',
data: {
jobID: null,
jobDetail: null,
applied: null
},
created: function () {
this.jobID = getParam("id");
this.getJobDetail(this.jobID);
},
mounted: function () {
},
methods: {
apply: function () {
openModal({
title: this.jobDetail.title,
subtitle: this.jobDetail.employer.name,
content: '<svg class="checkmark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52"><circle class="checkmark__circle" cx="26" cy="26" r="25" fill="none"/><path class="checkmark__check" fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8"/></svg>',
redirectUrl: "#",
buttonName: "Manage Your Jobs",
jobID: this.jobID
});
},
...
});
function getParam(param) {
var vars = {};
window.location.href.replace(location.hash, '').replace(
/[?&]+([^=&]+)=?([^&]*)?/gi, // regexp
function (m, key, value) { // callback
vars[key] = value !== undefined ? value : '';
}
);
if (param) {
return vars[param] ? vars[param] : null;
}
return vars;
}
var el = document.getElementById("documents");
el.addEventListener('load');
documents_index.js
import { getParam, readImage, resizeImg, getFile, downloadFile, deleteFile, saveObject, createLocalData, bindLocalData, clearLocalData, createValidationObj, guid } from './global.js';
import components from './components.js';
components();
var recordTemplate = {
name: '',
startDate: '',
type: '',
notes: ''
};
var userObjectTemplate = {
ItemID: null,
Name: null,
ParentId: null,
Hidden: false,
TypeID: null,
Type: null,
Content: null,
Children: [],
OwnerID: null,
CreationDate: null,
CanRead: null,
CanWrite: null
};
// Vue.component('flat-pickr', VueFlatpickr.default);
Vue.component('healthRecord', {
props: ['currentRecord', 'onSave', 'onCancel', 'selectTab'],
template: '<div>' +
'<div class="field">' +
'<label class="label">Document Name</label>' +
'<p class="control has-icon has-icon-right">' +
'<input name="name" data-vv-name="name" v-validate="\'required\'" data-vv-delay="500" :class="{\'input\': true, \'is-danger\': errors.has(\'name\') }" type="text" v-model="name">' +
'<span class="icon is-small is-right">' +
'<i v-show="errors.has(\'name\')" class="fa fa-warning"></i>' +
'</span>' +
'<span v-show="errors.has(\'name\')" class="help is-danger">{{ errors.first(\'name\') }}</span>' +
'</p>' +
'</div>' +
'<div class="field">' +
'<label class="label">Type:</label>' +
'<p class="control">' +
'<span class="select">' +
'<select v-model="type">' +
'<option>Resume</option>' +
'<option>Cover Letter</option>' +
'<option>Reference Letter</option>' +
'<option>Credentials/Certification</option>' +
'<option>Diploma/Certificate</option>' +
'<option>License</option>' +
'<option>Offer Letter</option>' +
'<option>Work Agreement/Employment Contract</option>' +
'<option>Misc / Other</option>' +
'</select>' +
'</span>' +
'</p>' +
'</div>' +
'<div class="field">' +
'<label class="label">Notes</label>' +
'<p class="control">' +
'<textarea class="textarea" v-model="notes"></textarea>' +
'</p>' +
'</div>' +
'<br />' +
'<div class="columns">' +
'<div class="column">' +
'<p class="control inline-flex"><button class="button is-primary" v-on:click="selectTab(\'tab-2\')">Next</button></p>' +
'<p class="is-pulled-right control"><button class="button is-primary" v-on:click="save(true)">Save</button></p>' +
'<p class="is-pulled-right control" style="padding-right:10px"><button class="button is-link" v-on:click="cancel">Cancel</button></p>' +
'</div>' +
'</div>' +
'</div>',
data: function() {
this.currentRecord.Content.startDate = moment().format('lll');
return createLocalData(this.currentRecord.Content);
},
methods: {
save: function(redirect) {
bindLocalData(this, this.currentRecord.Content);
this.onSave(this.currentRecord, redirect);
},
cancel: function() {
clearLocalData(this, this.currentRecord.Content);
this.onCancel();
},
}
});
var app = new Vue({
el: '#documents',
data: {
recordTitle: "Documents",
recordName: "Document",
urlRoot: "career/documents",
catId: 19,
userID: userViewId,
accountData: null,
showModal: false,
recordData: null,
showOverview: false,
showDetail: false,
showEdit: false,
showAdd: false,
currentRecord: null,
showDeleted: false,
selectedRecords: [],
selectedFiles: [],
selectAllChecked: { records: false, files: false },
currentTab: 'Info'
},
created: function() {
this.getAccount();
},
mounted: function() {
var that = this;
window.onpopstate = function(event) {
that.processUrl();
};
},
computed: {
recordList: function() {
return this.recordData.Children[0].Children;
}
},
methods: {
}
});
export {
documents,
VueFlatpickr,
}
documents.cshtml
@model Project.Controllers.CareerController
@{
ViewData["Title"] = "Career Documents";
}
@section css{
<link rel="stylesheet" href="https://unpkg.com/flatpickr@4.1.2/dist/flatpickr.min.css" />
}
<div id="documents" v-cloak>
<h3 class="title is-3 no-print"><strong>{{recordTitle}}</strong></h3>
<!--Overview-->
<div id="overview" class="columns" v-if="showOverview">
<div class="column is-9">
<div class="card">
<div class="card-content">
<div class="right-scroll">
<table class="table is-narrow" v-if="recordData">
<thead>
<tr>
<th><input type="checkbox" v-on:click="selectAllChecked.records = !selectAllChecked.records; selectAllRecords(recordData.Children[0].Children, showDeleted, selectAllChecked.records);"></th>
<th>Name</th>
<th>Date & Time</th>
<th>Type</th>
<th>Files</th>
<th></th>
</tr>
</thead>
<tbody>
<tr v-for="child in recordList" v-if="showDeleted == child.Hidden">
<td><input v-if="!child.Hidden" type="checkbox" :id="child.ItemID" v-on:click="recordSelected(child,selectedRecords)"></td>
<td><a v-if="!child.Hidden" v-on:click="routeEdit(child, 'detail')">{{child.Content.name}}</a></td>
<td>{{child.Content.startDate}}</td>
<td>{{child.Content.type}}</td>
<td>{{fileCount(child.Children)}}</td>
<td class="has-text-centered">
<a v-on:click="routeEdit(child, 'edit')"><span class="icon"><i class="fa fa-pencil-square-o"></i></span></a>
<a v-on:click="deleteRecords([child])" class="is-negative"><span class="icon"><i class="fa fa-trash-o"></i></span></a>
</td>
</tr>
<tr v-if="recordList.length < 1">
<td colspan="5" rowspan="2" class="has-text-centered">No Records.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="column is-3">
<button class="button is-primary is-marginless is-fullwidth" v-on:click="routeEdit(false,'add')"><b>Add</b></button>
<button class="button is-negative no-label is-fullwidth" v-on:click="deleteRecords(selectedRecords)"><b>Delete</b></button>
<!-- <button class="button is-primary no-label is-fullwidth" v-on:click="(showDeleted = !showDeleted)"><b><span v-if="!showDeleted">Show</span><span v-if="showDeleted">Hide</span> Deleted Files</b></button> -->
</div>
</div>
<section v-show="!recordData">
<br />
<div class="image is-96x96 is-centered">
<img src="/images/loaderPrimary.svg">
</div>
<br />
</section>
<!--Detail-->
<div id="detail" class="columns" v-if="showDetail">
<div class="column is-9 print-fullwidth">
<div class="card">
<div class="card-content">
<h3 class="title is-3">{{currentRecord.Content.name}}</h3>
<h5 class="title is-5 has-text-weight-semibold">Date and Time</h5>
<p class="subtitle is-6">{{currentRecord.Content.startDate}}</p>
<h5 class="title is-5 has-text-weight-semibold">Notes</h5>
<p class="subtitle is-6">{{currentRecord.Content.notes}}</p>
<h5 class="title is-5 has-text-weight-semibold">Files</h5>
<file-gallery :file-num="currentRecord.Children.length">
<thumbnail v-for="file in filterHidden(currentRecord.Children, showDeleted)" :file-data="file" :key="currentRecord.lastModified" :show-deleted="showDeleted" :record-selected="recordSelected" :selected-files="selectedFiles" :edit="false"></thumbnail>
</file-gallery>
</div>
</div>
</div>
<div class="column is-3 no-print">
<button class="button is-primary is-marginless is-fullwidth" v-on:click="routeEdit()"><b>Back</b></button>
<button class="button is-primary no-label is-fullwidth" v-on:click="routeEdit(currentRecord,'edit')"><b>Edit</b></button>
<button class="button is-negative no-label is-fullwidth" v-on:click="deleteRecords([currentRecord]); routeEdit();"><b>Delete</b></button>
</div>
</div>
<!--Edit-->
<div id="edit" class="columns" v-if="showEdit || showAdd">
<div class="column is-9">
<div class="card">
<div class="card-content">
<h3 v-if="showEdit" class="title is-3">Edit {{recordName}}</h3>
<h3 v-if="showAdd" class="title is-3">New {{recordName}}</h3>
<tabs @@change="changeTab">
<tab ref="tab-1" name="Info" :selected="true">
<health-record :current-record="currentRecord" :on-save="saveRecord" :on-cancel="routeEdit" :select-tab="selectTab"></health-record>
</tab>
<tab ref="tab-2" name="Files">
<uploader :file-data="currentRecord" :parent-object="recordData" :path="urlRoot">
<label class="label">Files</label>
<file-gallery :file-num="currentRecord.Children.length">
<thumbnail v-for="file in filterHidden(currentRecord.Children, showDeleted)" :file-data="file" :key="currentRecord.lastModified" :show-deleted="showDeleted" :record-selected="recordSelected" :selected-files="selectedFiles" :edit="true"></thumbnail>
</file-gallery>
</uploader>
<br />
<div class="columns">
<div class="column">
<p class="control inline-flex"><button class="button is-primary" v-on:click="selectTab('tab-1')">Previous</button></p>
<p class="is-pulled-right control"><button class="button is-primary" v-on:click="routeEdit()">Done</button></p>
</div>
</div>
</tab>
</tabs>
</div>
</div>
</div>
<div class="column is-3">
<button class="button is-primary is-marginless is-fullwidth" v-on:click="routeEdit()"><b>Back</b></button>
<button class="button is-primary no-label is-fullwidth" v-if="selectedFiles.length > 0" v-on:click="downloadFiles(selectedFiles)"><b>Download</b></button>
<button class="button is-primary no-label is-fullwidth" v-if="currentRecord.Children.length > 0 && currentTab == 'Files'" v-on:click="selectAllChecked.files = !selectAllChecked.files; selectAllRecords(currentRecord.Children, showDeleted, selectAllChecked.files);"><b>Select All</b></button>
<button class="button is-negative no-label is-fullwidth" v-if="currentTab == 'Files'" v-on:click="deleteRecords(selectedFiles)"><b>Delete</b></button>
<!-- <button class="button is-primary no-label is-fullwidth" v-if="currentTab == 'Files'" v-on:click="(showDeleted = !showDeleted)"><b><span v-if="!showDeleted">Show</span><span v-if="showDeleted">Hide</span> Deleted Files</b></button> -->
</div>
</div>
</div>
@section Scripts {
<script src="https://unpkg.com/flatpickr@4.1.2/dist/flatpickr.js"></script>
<script src="https://unpkg.com/vue-flatpickr-component@4.0.0/dist/vue-flatpickr.min.js"></script>
<script src="https://unpkg.com/vee-validate@2.0.0-rc.14/dist/vee-validate.js"></script>
<script src="~/dist/career/documents.js"></script>
}
我希望在document.cshtml页面上呈现的表也出现在detail_index.js的模式内