Vue js - Add text and dropdown box to editable HTML content box
P粉288069045
2023-07-27 17:02:54
<p>I'm using Vue.js. I'm trying to add text and a dropdown box in an editable HTML div. </p><p>I want to add a dropdown box using a button. This dropdown box can be added anywhere in the text, just like where I place my cursor. </p><p>Now, it almost works, but I can't find a problem. </p><p>When I enter and add multiple dropdown boxes and then press the "Get Data Model" button, it always shows that the dropdown box option I selected is incorrect. I mean it always shows the first option. </p><p>Using this "Get Data Model" button, I am trying to get all the text selected options. </p><p>Here is my code:</p><p><br /></p>
<pre class="brush:php;toolbar:false;"><template>
<div>
<div class="content-editable" contenteditable="true" @input="onInput" ref="contentEditable"></div>
<button @click="addDropdown">Add Dropdown</button>
<button @click="getDataModel">Get Data Model</button>
<div>{{ dataModel }}</div>
</div>
</template>
<script>
export default {
data() {
return {
content: '',
dropdowns: [],
dropdownOptions: ['Option 1', 'Option 2', 'Option 3'],
dataModel: '',
};
},
methods: {
onInput(event) {
this.content = event.target.innerHTML.replace(/<div><br></div>/g, '');
},
addDropdown() {
const dropdown = {
selectedOption: this.dropdownOptions[0],
};
this.dropdowns.push(dropdown);
const editableDiv = this.$refs.contentEditable;
const dropdownSelect = document.createElement('select');
dropdownSelect.style.width = '100px';
this.dropdownOptions.forEach((option) => {
const dropdownOption = document.createElement('option');
dropdownOption.value = option;
dropdownOption.text = option;
dropdownSelect.appendChild(dropdownOption);
});
editableDiv.appendChild(dropdownSelect);
},
getDataModel() {
const editableDiv = this.$refs.contentEditable;
const clonedDiv = editableDiv.cloneNode(true);
const selectElements = clonedDiv.querySelectorAll('select');
this.dropdowns.forEach((dropdown, index) => {
const selectedOption = dropdown.selectedOption;
const selectedOptionText = Array.from(selectElements[index].options).find((option) => option.value === selectedOption)?.text;
const selectedOptionTextNode = document.createTextNode(` ${selectedOptionText}`);
selectElements[index].replaceWith(selectedOptionTextNode);
});
this.dataModel = clonedDiv.textContent;
},
},
};
</script>
<style scoped>
.content-editable {
border: 1px solid #ccc;
padding: 10px;
min-height: 100px;
margin-bottom: 10px;
}
</style></pre>
<p><br /></p>
Vue.js is data-driven and adopts MVVM thinking. If you want to create multiple "input" tags, it makes more sense to use v-for instead of dynamically creating the DOM.
hope this helps!