Observe Change in Vue js model when input updated by javascript function - vue.js

I am using Date Range Picker to select to dates now when I select the dates, I update the inputs with dates value respectively.
The inputs I have binded with v-model and created a function in watch attribute of component to observe the change in model.
But when the inputs are updated with the javascript function no change can be observed in the model but the value of my input fields are updated.
// My Input Fields
<input type="text" name="updateStartDate" v-model="updateDateRange.start">
<input type="text" name="updateEndDate" v-model="updateDateRange.end">
//My javascript Function
$('input[rel=dateRangePickerX]').daterangepicker({
'autoApply': true,
'drops': 'up',
'startDate': moment().add(90, 'days').calendar(),
'endDate': moment().add(97, 'days').calendar(),
locale: { cancelLabel: 'Clear' }
},
function (start, end, label) {
$('input[name="updateStartDate"]').val(start.format('MM/DD/YYYY'));
$('input[name="updateEndDate"]').val(end.format('MM/DD/YYYY'));
});
// My watch attribute in Component
watch : {
'updateDateRange.end' : function (val) {
console.log('In Watch Function');
console.log(this.dateRanges);
if(val != '' && this.updateDateRange.start != '' && this.updateDateRangeIndex != ''){
console.log(val);
console.log(this.updateDateRange.start);
console.log(this.updateDateRangeIndex);
this.dateRanges[this.updateDateRangeIndex] = this.updateDateRange;
this.updateDateRangeIndex = '';
this.updateDateRange.start = '';
this.updateDateRange.end = '';
console.log(this.dateRanges);
}
}
}

I don't like to mix jQuery and Vue because jQuery messes up the DOM. Even more, I find it completely unnecessary.
Simple only with native Vue you can do it like this:
<input type="text" name="updateStartDate" v-model="startDate" #input="onInput()">
<input type="text" name="updateStartDate" v-model="endDate" #input="onInput()">
methods: {
onInput(e): function () {
// this will be called on change of value
}
}
Further to set the value and update the DOM simply update startDate and/or endDate variables and DOM will update accordingly.

You need to work with your model and not fiddle with the bound DOM element. You have bound the elements to viewmodel items:
<input type="text" name="updateStartDate" v-model="updateDateRange.start">
<input type="text" name="updateEndDate" v-model="updateDateRange.end">
then you use jQuery to set the field values
$('input[name="updateStartDate"]').val(start.format('MM/DD/YYYY'));
$('input[name="updateEndDate"]').val(end.format('MM/DD/YYYY'));
but you should be setting the bound values instead:
updateDateRange.start = start.format('MM/DD/YYYY');
updateDateRange.end = end.format('MM/DD/YYYY');

Related

Computed property not disabling input

I am trying to set the disabled property on a text field via checkbox. I'm referencing this item, but none of the solutions are working for me.
My text field and checkbox are as follows:
<input
type="checkbox"
class="form-check-input"
v-model="formData.useSystemSetting"
>
<input
type="text"
class="form-control"
:class="hasError('maxCount') ? 'is-invalid' : ''"
placeholder="Enter the Maximum Count"
v-model="formData.maxCount"
:disabled = "isDisabled"
>
My computed property is:
computed:{
isDisabled: function() {
this.useSystemSetting = this.useSystemSetting == true?false:true
return this.useSystemSetting;
},
I'm also setting useSystemSettings in the data section to true because if I don't it doesn't get populated. When I add a breakpoint to the computed property, it's only getting hit on the page load, but not after.
It's not allowed to mutate other properties inside the computed property, you should only do some process and return a value:
computed:{
isDisabled: function() {
return this.useSystemSetting ? false : true;
}
}
You shouldn't mutate data inside a computed property.
A computed property is used whenever you need to use logic for getting a value which includes reactive data, as you'd find here.
You could try something like:
computed:{
isDisabled: function() {
return !this.formData.useSystemSetting;
}
}
Presuming that the formData object will not be null at this point.
To prevent that, you could also use something like:
return ((this.formData || {}).useSystemSetting || true) ? false : true;

Vue Js - How to disable all inputs after loaded data

I have many inputs on my forms. After I got data from API, I looped to display all inputs. Then I want to disable them. I do not want to disable all inputs one by one on my loop, because I had many loops and inputs on my forms. I want to write a block of code can solved my problem.
I try to use this code for disable them, but it can only disabled on input that created before load data.
let inputs = document.getElementsByTagName('input')
for(let i = 0; i < inputs.length; i++) {
inputs[i].disabled = true;
}
Thanks!
if you are using vue.js then you can set a veriable like disable and set it like this
<template>
<input type="text" :disabled="disable">
<input type="text" :disabled="disable">
<input type="text" :disabled="disable">
.
.
.
</template>
and in vue script
data() {
return {
// other vars,
disable: false,
}
},
methods: {
methodToLoadData() {
// Load data
this.disable = true;
},
},

How to prevent reactivity in form placeholder

I have an input field set up as
<input #input="e => machineCIDR = e.target.value" type="text" name="machine" class="form-control form-control-lg" :placeholder="machineCIDR">
The problem is, whenever someone fills out the form and then deletes it all, the placeholder is left with the last character that was filled out.
How can I setup :placeholder="machineCIDR" so that it shows the initial value, and then never gets updated again??
Assuming machineCIDR is set up already (as a prop or in data), you could create an object for storing all of your initial values:
data() {
return {
...
initial: {}
}
}
And set up the values in created:
created() {
this.initial['machineCIDR'] = this.machineCIDR;
}
Then bind to that instead in the placeholder:
:placeholder="initial['machineCIDR']"

Render form after method completion in VueJS

I am facing a problem with my page with VueJS. It's a page for different translations of the website. It has a dropdown on the top for the language selection that once switched will update the fields with the current language.
The problem starts when it loads, because my form is like this:
<form id="trForm">
...
<input type="text" name="header_title" class="form-control" v-model="translations.header.header_title" />
...
</form>
It's trying to access these attributes before the method returns any data, but somehow it will still show the data once it is complete, but it becomes troublesome when I try to switch the language, it won't because of this problem and also, if I do the following:
<form id="trForm">
...
<input type="text" name="header_title" v-if="translations.header" class="form-control" v-model="translations.header.header_title" />
...
</form>
on each field, those that aren't populated will display no field at all for a new input value. I tried something like translations.features || '', but no success.
I also tried to put on the parent block a condition that if the loading is false will display the form, but since the page is loaded first than the method is executed, it will always be false for the first microsecond.
methods: {
fetchTranslations(e) {
let vm = this;
vm.loaded = false;
$.get('/ajax/admin/translations', { 'locale': e }).done((data) => {
if (data.success) {
vm.translations = JSON.parse(data.translations.translation);
vm.loaded = true;
} else {
toastr.error('Something went wrong');
}
});
},
Please, what do I do? It'd be good to show the form after there is data.
Introduce a new variable, e.g. loaded that defaults to false
Use this variable as a v-if condition on the form
In the callback of your data fetch, set loaded to true.

aurelia-validation with custom element

I created an input form with aurelia-validation plugin which worked perfectly.
Now I created a custom element to replace the input type textbox.
I'm trying to validate the new custom element value, by setting the value attribute with the "validate" keyword - but the custom element input value isn't validated.
It seems like the Validation Controller is not binded to the custom element.
The bindings array of the Validation Controller doesn't contains the custom element.
Maybe this is related to the actions that should trigger the validation (blur\focus out), so I added dispatching of blur event, but it still doesn't work. As mentioned - it worked perfectly when it was a regular element.
Here is the relevant code (un-needed code was removed):
custom element template:
<template>
<label>
${title}<input name.bind="fieldName"
title.bind="title" focusout.trigger="focusoutAction()" />
</label>
</template>
custom element relevant viewmodel code:
#bindable onFocusout;
...
bind(bindingContext) {
var input = this.element.getElementsByTagName("input")[0];
input.type = this.customType || "text";
input.placeholder = this.placeHolder || "";
//input.value.bind = bindingContext.registration.firstName & validate;
}
...
focusoutAction() {
var customEvent = new CustomEvent("blur");
this.element.dispatchEvent(customEvent);
this.onFocusout();
}
Relevant container(parent) view code:
<form-input name="firstName" id="firstName" title="First Name" bind-
value="registration.firstName & validate" field-name="firstName" on-
focusout.call="validateInput()" />
And the relevant viewmodel code:
ValidationRules
.ensure(r => r.firstName).displayName('first
name').required().withMessage(`\${$displayName} cannot be blank`)
.satisfiesRule('FirstNameValidation')
.ensure(r => r.lastName).displayName('last
name').required().withMessage(`\${$displayName} cannot be blank`)
.satisfiesRule('LastNameValidation')
validateInput() { this.getValidationError(event.target.name); }
getValidationError(propertyName) {
let error = this.getValidationFirstError(propertyName);
....
}
getValidationFirstError(propertyName)
{
if (this.controllerToValidate.errors !== null &&
this.controllerToValidate.errors.length > 0) //This is 0 !!!!!
}