I have a simple component that I use as a 'wrapper' for another component that displays a form for each object.
When I try to edit any of the forms, when I submit the form it's not picking up the values for the inputs.
Here is the wrapper component template:
<script id="evidenceFormsContainerTemplate" type="text/x-template">
<div>
<evidence-form
v-for="(element, index) in evidence"
ref="form"
:shared-store="sharedStore"
:element="element"
:key = "element.id"
:index="index"
:subdomains="subdomains"
>
</evidence-form>
</div>
</script>
Here is the evidenceFormTemplate
:
<script type="text/x-template" id="evidenceFormTemplate">
<div>
<div class="mt-4 mb-4 row" :class="(sharedStore.state.activeForm != index) ? 'bg-white text-secondary border border-secondary rounded':'bg-light text-dark border border-primary rounded'">
<form class="col" :id="'form'+element.id" v-on:submit.prevent="submitForm(element.absolute_url, sharedStore.state.evaluationId)">
<fieldset :disabled="(sharedStore.state.activeForm != index && element.id)">
<input type="hidden" id="evidenceId" v-model="element.id">
<div class="form-row">
<div class="form-group col-sm-4">
<label class="" for="subdomain">Subdomain</label>
<select name="subdomain" id="subdomain" class="form-control" v-model="element.subdomain">
<option v-for="choice in subdomains" :value="choice.id" >{{ choice.character_code }}</option>
</select>
</div>
<div class="form-group col">
<label class="" for="comments">Comments</label>
<textarea id="comments" class="form-control" v-model="element.comments" rows="5"></textarea>
</div>
</div>
<div class="form-row mb-4">
<label class="sr-only" for="published">Publish Status</label>
<div class="btn-group btn-group-toggle" data-toggle="buttons">
<label :class="{ active: element.published,}" class="btn btn-outline-success form-check-label" for="publishedTrue">Published
<input v-model="element.published" :active='element.published' :class="{ active: element.published, 'form-check-input': true}" type="radio" name="published" id="publishedTrue" value="true"> </label>
<label :class="{ active: !element.published,}" class="btn btn-outline-secondary form-check-label" for="publishedFalse">Unpublished
<input v-model="element.published" :active='!element.published' :class="{ active: !element.published, 'form-check-input': true}" type="radio" name="published" id="publishedFalse" value="false"> </label>
</div>
</div>
<div class="form-row">Created By: {{ element.created_by_name }}</div>
<div class="form-row">Last Updated: {{ element.updated_at}} by {{ element.updated_by_name }}</div>
</fieldset>
<div v-show="!hideControls" class="form-row mt-4 mb-4">
<button type="button" v-if="!isEditing" class="btn btn-primary ml-2 mr-2 text-white" @click="editForm(element, sharedStore.state.activeForm, index)"> <i class="far fa-edit"></i> EDIT </button>
<div v-show="!hideControls && isEditing">
<button :id="'saveButton'+element.id" :disabled="(sharedStore.state.activeForm != null && sharedStore.state.activeForm != index)" class="btn btn-primary text-white ml-2 mr-2"> <i class="far fa-save"></i> SAVE </button>
<button type="button" class="btn bg-secondary text-white ml-2 mr-2" @click="cancelEdit(element, index)"> <i class="fas fa-minus"></i> CANCEL </button>
</div>
</div>
</form>
</div>
</div>
</script>
The component JS looks like this:
const evidenceFormComponent = Vue.component("evidence-form", {
template: "#evidenceFormTemplate",
props: [
"element",
"sharedStore",
"index",
"subdomains",
],
data: function (element) {
console.log('we are in data setup for : ' + element);
return {
isEditing: false,
evaluation_id: null,
subdomain: null,
comments: '',
published: null,
};
},
created: function () {
return {
};
},
computed: {
hideControls: function() {
if (this.sharedStore.state.addingEvidence) {
return true;
}
if ((this.sharedStore.state.activeForm != null) && !this.isEditing) {
return true;
} else {
return false;
}
},
},
watch: {},
methods: {
editForm: function (element, activeForm, index) {
this.sharedStore.setOriginalElement(element);
this.sharedStore.setActiveForm(index);
this.isEditing = true;
},
cancelEdit: function (element, index) {
this.sharedStore.clearOriginalElement(element);
this.sharedStore.clearActiveForm();
this.isEditing = false;
},
submitForm: function(absolute_url, evaluationId) {
var vm = this
url = absolute_url + "?evaluation_id=" + evaluationId
console.log($('#subdomain').val());
console.log($('input[id="subdomain"]').val());
$.ajax({
url: url,
type: 'PATCH',
data: {
evaluation : evaluationId,
subdomain : $('#subdomain').val(),
comments : $('#comments').val(),
published: $('input[name=published]:checked').val(),
csrfmiddlewaretoken: vm.sharedStore.state.csrftoken,
},
beforeSend: function (xhr, settings) {
xhr.setRequestHeader("X-CSRFToken", vm.sharedStore.state.csrftoken);
},
success: function (element) {
console.log('SUCCESS! Update to element is good.');
vm.isEditing = false;
vm.sharedStore.clearOriginalElement(element);
vm.sharedStore.clearActiveForm();
}
})
},
},
});
When the template loads up - I see all the values displaying correctly with the right data. When I click 'edit', the form becomes editable as expected.
Once I click submit, there are no values being passed, but I'm using the v-model
on the inputs.
Any idea why that would occur?