I send some data and I wanna clear the content-editable div area.
The vaule of the div is empty but in the screen there is a text left.
It is a SPA Vue.js project.
<div id="chattingContents" class="chattingContents" contenteditable="true" :style="flexablePadding" #input="sync" v-html="innerContent"></div>
<input type="text" v-model="contents" style="display: none;">
export default {
data: function(){
return {
(...)
formShow: false,
contents: '',
innerContent:'',
(...)
}
},
methods: {
(...)
formToggle(){
this.stampShow= false
this.stampAreaShow= false
this.contents = ''
this.innerContent = this.contents
this.formShow = !this.formShow
},
createNotify(){
(...)
else if(!this.stampAreaShow&&this.contents&&!this.uploadedImage) {//text only
axios.post('/create_notify', {notify_type: 'text',contents: this.contents}).then((res)=>{
if (res.data != null){
alert("メッセージ送信完了!")
this.formToggle();
this.fetchNotifies();
}
}, (error) =>{
console.log(error)
})
}
}
okay, it was about ''.
If I change (this.contents = '') into (this.contents = ""), it works.
But I don't know why...
What's the difference between single quotation and double quotation?
Related
I have form data of:
const form = {
title: null,
content: null,
language: {
en: { title: null, content: null },
es: { title: null, content: null }
}
}
My Form inputs
<v-form ref="formEl" #submit.prevent="validate">
<div v-if="Object.keys(form.language).length > 0">
<div v-for="(language, langCode) in form.language" :key="langCode">
<v-text-field
v-model="form.language[langCode].title"
:label="$t('form.title')"
/>
<v-textarea
v-model="form.language[langCode].content"
:label="$t('form.content')"
/>
</div>
</div>
</form>
Now when I change the input of 1 form input, it updates both to be the same.
I tried placed a KEY on each input field, with the same result. Does anyone have any thoughts or direction on this? Much appreciated.
const form = ref(lodash.cloneDeep(state.pages.one))
// GET CONTENT
useFetch(async () => {
loading.value = true
try {
await dispatch('pages/getOne', route.value.params.id).then((res) => {
if (res !== false) {
form.value = lodash.cloneDeep(res)
}
})
} catch(e) {
$system.log({
comp: 'AdminPagesEdit', msg: 'useFetch', val: e
})
} finally {
loading.value = false
}
})
I have two input which both need to remove the space between the string
I used event.clipboardData.setData but it didn't work
After that, I used this.Name_of_my_state But it returns both pasted item and removed space Item.
Let's take a look at my code to make it clear
<template>
<span>
<input class="form-control inputHeight"
#keydown.space.prevent
#paste.space="remove_on_paste"
v-model="floatingData.from_id">
<input class="form-control inputHeight"
#keydown.space.prevent
#paste.space="remove_on_paste"
v-model="floatingData.to_id">
</span>
</template>
First I tried this but didn't work
new Vue({
data() {
return {
floatingData: {
from_id: "",
to_id: ""
}
}
},
methods: {
// Remove space on paste
remove_on_paste(event) {
let main_text = event.clipboardData.getData("text");
event.clipboardData.setData("text", main_text.replace(/\D/g, ""));
}
}
})
Result:
Then I tried this that pasted both copied and replaced value
new Vue({
data() {
return {
floatingData: {
from_id: "",
to_id: ""
}
}
},
methods: {
// Remove space on paste
remove_on_paste(event) {
let main_text = event.clipboardData.getData("text");
this.floatingData.from_id = main_text.replace(/\D/g, "");
}
}
})
Result:
I was able to get the behavior I think you requested, where you can paste in a string with tailing whitespace, and it will be trimmed. The trick is to prevent the browser from doing anything after the paste using event.preventDefault() and using main_text.trim() to remove whitespace. Please let me know if this is what you're looking for.
(Tested on Google Chrome 91, using this codesandbox)
<template>
<span>
<input class="form-control inputHeight"
#keydown.space.prevent
#paste.space="remove_on_paste"
v-model="floatingData.from_id">
<input class="form-control inputHeight"
#keydown.space.prevent
#paste.space="remove_on_paste"
v-model="floatingData.to_id">
</span>
</template>
<script>
export default {
data() {
return {
floatingData: {
from_id: "",
to_id: ""
}
}
},
methods: {
// Remove space on paste
remove_on_paste(event) {
let main_text = event.clipboardData.getData("text");
event.preventDefault();
this.floatingData.from_id = main_text.trim();
}
}
};
</script>
You should use watchers for this:
data()
{
return {
first_input: '',
second_input: '',
}
},
watch:
{
first_input()
{
this.$nextTick(() =>
{
this.first_input = this.first_input.replace(/\s+/g, '');
})
},
second_input()
{
this.$nextTick(() =>
{
this.second_input = this.second_input.replace(/\s+/g, '');
})
},
}
I'm working on a couponcode VueJS app, in which I want to check an array with different discountcodes on matching values. Below I have an array with two discountcodes. If the button is clicked, I want to check the array for any matches. I am not sure what would be the best solution for this..
<template>
<div class="container">
<input placeholder='type discount' v-model="discountInput">
<button #click="checkDiscount">check for discount</button>
<span class="alert" v-if="discountValid">
Code juist
</span>
<span class="alert" v-if="discountInvalid">
Code onjuist
</span>
</div>
</template>
<script>
export default {
props: {
},
data: () => {
return {
discountInput: '',
discountValid: false,
discountInvalid: false,
discountCodes: [
{ code: 'discount-code-1', message: '10% discount' },
{ code: 'discount-code-2', message: '5 dollar discount' }
]
}
},
components: {
},
methods: {
checkDiscount() {
if (this.discountInput === this.discountCode) {
return true;
} else {
return false;
}
}
},
watch: {
}
}
</script>
A find should work.
checkDiscount() {
if (this.discountCodes.find(x => x.code === this.discountInput)) {
return true;
} else {
return false;
}
}
or as comments pointed out could be reduced to:
checkDiscount() {
return !!this.discountCodes.find(x => x.code === this.discountInput);
}
Try to use array some method as follows :
checkDiscount() {
return this.discountCodes.some(dis => dis.code === this.discountInput)
}
I have created a settings page where users can update their email addresses. Everything worked fine but suddenly the validation is not updating anymore. Only the first change of the input field triggers validateState().
Any further changes will not trigger this function so the status of that field stays as it is.
I have compared the code with other components that use the same code and they still work fine.
I am using bootstrap-vue components for the form.
<template>
<div class="row">
<div class="col-md-12">
<b-form #submit="onSubmit">
<b-form-group :label="$t('general.email')"
label-for="settingsEmail"
:invalid-feedback="errors.first('email')">
<b-form-input id="settingsEmail"
type="text"
v-model="form.email"
:disabled="saving"
name="email"
:state="validateState('email')"
v-validate="{required: true, email: true}">
</b-form-input>
</b-form-group>
<b-button type="submit" variant="primary" :disabled="saving || !hasChanged() || errors.any()"><i class="fa fa-refresh fa-spin fa-fw" v-if="saving"></i> {{$t('general.save')}}</b-button>
</b-form>
</div>
</div>
</template>
<script>
import {UPDATE_USER} from '../config/actions'
export default {
name: 'settingsAccount',
data() {
return {
form: {},
saving: false
}
},
computed: {
user: function() {
return this.$store.getters.getUser;
}
},
created() {
this.init();
},
methods: {
init() {
this.form.email = this.user.email;
},
hasChanged() {
if(this.form.email !== this.user.email) {
return true;
}
return false;
},
onSubmit(event) {
event.preventDefault();
this.saving = true;
this.$validator.validateAll().then((result) => {
if (result) {
let data = {};
if(this.form.email !== this.user.email) {
data.email = this.form.email;
}
this.$store.dispatch(UPDATE_USER, data).then(() => {
this.saving = false;
this.$validator.reset();
}).catch(() => {
this.saving = false;
});
} else {
this.saving = false;
}
});
},
validateState(ref) {
if (this.veeFields[ref] && (this.veeFields[ref].dirty || this.veeFields[ref].validated)) {
return !this.errors.has(ref)
}
return null
},
}
}
</script>
The problem you're having is that the form data element is an empty object, so it will only trigger reactivity when the whole object changes. Either you need to change your data to be this:
data() {
return {
form: {email:''},
saving: false
}
},
Or in your init function, explicitly add the email property as reactive:
methods: {
init() {
this.$set(form,'email',this.user.email)
},
//...
If you're not clear on why, you can read the details here: https://v2.vuejs.org/v2/guide/reactivity.html
A working example (minus vuex) here: https://codesandbox.io/s/x4kp93w3o
PS, when writing questions about vue, it's very helpful to boil it down to a simpler example. Get rid of vuex, remove your translation stuff. Sometimes the answer will jump out at you once you have it as simple as possible.
all how i can watch changes in my component in data?
I need watch when user choose car brand to take from server models for that brand
this is my code
Templete
<template>
<div class="category-info">
<div v-for="input in inputs.text">
<label >{{ input.placeholder}}</label>
<input type="text" id="location" :name="input.name" v-model="input.value" #click="console">
</div>
<div class="select" v-for="select in inputs.select">
<label >{{ select.placeholder }}</label>
<my-select :data="select" v-model="select.value"></my-select>
</div>
<button #click="console">click</button>
</div>
Script
<script>
export default {
name: "profile-add-inputs",
props: ['category'],
data() {
return {
inputs: {
text : {},
select: {}
},
}
},
methods: {
getCategories(){
axios.get('/profile/inputs', {
params: {
category: JSON.stringify(this.category.href)
}
})
.then((response) => {
this.inputs.text = response.data.text;
this.inputs.select = response.data.select;
for(let key in this.inputs.text){
this.inputs.text[key].value = '';
}
for(let key in this.inputs.select){
this.inputs.select[key].value = '';
if(this.category.href.sub == 'car' && this.inputs.select[key].name == 'brand'){
console.log('CAR BREND');
this.$watch.inputs.select[key].value = function () {
console.log(this.inputs.select[key].value);
}
}
}
},this)
.catch(function (error) {
console.log(error);
});
},
console(){
console.log(this.inputs.select);
}
},
watch: {
category : function () {
this.getCategories();
console.log('categoty');
},
inputs : {
handler() {
console.log('watch inputs');
}
}
}
}
So, i tried to use watch and $watch but its not working, plz give me a reason why that not work, or maybe some another way to resolve this problem
this.$watch can i create dynamiclly watchers with this stement?
The correct syntax is
watch : {
inputs : function(val, oldVal){
//val : New value
//oldVal : Previous value.
}
}