I'm not sure what I'm doing wrong here.
I set up my adapters like so
$(function () {
$.validator.addMethod("pastdate", function (value, element, params) {
if (value === "")
return true;
return Date.parse(value) <= new Date();
});
$.validator.unobtrusive.adapters.add("pastdate", function (options) {
options.rules["pastdate"] = "pastdate";
options.messages["pastdate"] = options.message;
});
});
and my rendered html is like so
<input
name="ReportedDate"
id="ReportedDate"
type="text"
data-val="true"
data-val-date="The field Reported Date must be a date."
data-val-pastdate="Reported Date must not be a future date."
value=""/>
But when I validate my form with a future date I do not get any errors.
Fiddle
http://jsfiddle.net/36dTM/3/
What am I doing wrong?
Related
I want made a validation for input to be number only, whenever someone input a string, the input box will be cleared.
First, I made a method function on $event like this (ps. I use props)
<BaseInput
:value="nama"
#update="nama = ruled($event)"
label="Nama"
type="type"
/>
and this is the method, I use RegExp to check if the $event value is number. When it's false then I return $event value to empty string.
ruled(event) {
console.log(event)
var intRegex = new RegExp(/[0-9]/);
var data = intRegex.test(event)
if(!data) {
alert("Value Must Number")
event = ""
console.log('masuk if' + data)
}
return event
}
but it didn't clear the input box, anyone know why it happened ?
As Creative Learner said, I must clearing input box in child component only, so I did this on my component child
<template>
<input
:value="value"
:placeholder="label"
#input="$emit('update', ruled($event))"
/>
</template>
And this is the methods:
methods: {
ruled(event) {
//console.log(event)
var val = event.target.value
if(event.target.type == "number"){
var intRegex = new RegExp(/[0-9]/);
var intdata = intRegex.test(val)
if(intdata == false) {
error = "Value must contain number"
//alert("Value must contain number")
return event.target.value = ""
}
}
return val
}
}
great thanks to Creative Learner who made me understand
Suggestions :
Instead of #update you have to use #keypress or #change.
You can use v-model for two-way data binding.
Working Demo :
new Vue({
el: '#app',
data: {
nama: ''
},
methods: {
ruled(event) {
var intRegex = new RegExp(/^\d+$/);
var data = intRegex.test(this.nama);
if (!data) {
alert("Value must contain number");
this.nama = "";
}
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<input
v-model="nama"
#change="ruled($event)"
label="Nama"
type="text"
/>
</div>
In the codepen below I have a Element-UI datepicker set up to show a dynamic disabled dates based on a random number.
The number of disabled dates change every time the datepicker input comes into focus.
My issue is the datepicker doesn't refresh the disabled dates until you click on a different month. The datepicker also shows the last month you were previously on when when you click off and back in.
Is there a way to force Element-UI Datepicker to refresh? I would like to make the datepicker refresh in the on focus event after the new disabled value is set.
https://codepen.io/anon/pen/rbXjLr
Element-UI Datepicker Documentation
<div id="app">
<template>
<div class="block">
<span class="demonstration">Picker with quick options</span>
<el-date-picker
v-model="value2"
type="date"
placeholder="Enter Date"
#focus="focus()"
:default-value="defaultValue"
:picker-options="pickerOptions">
</el-date-picker>
</div>
</template>
</div>
var is10Days = "";
var Randomizer = (function(){
var is10DaysSetter = function(){
if(is10Days === "") {
is10Days = Math.round(Math.random()) === 1;
}
//console.log("is10Days: " + is10Days);
return is10Days;
}
return {
Is10DaysSetter: is10DaysSetter
}
})()
var Main = {
data() {
return {
defaultValue: "",
pickerOptions: {
disabledDate(time) {
var self = this;
var date = moment()._d;
var mindate = moment().subtract(5,'d')._d;
var maxDate = moment()._d;
var isBeforeMinDate = time.getTime() < mindate;
var isAfterMaxDate = time.getTime() > maxDate;
if(is10Days !== "" && is10Days){
var alternateMinDate = date.setDate(date.getDate() - 10);
isBeforeMinDate = time.getTime() < alternateMinDate;
}
//console.log("disabledDate");
return isBeforeMinDate || isAfterMaxDate;
}
},
value2: '',
};
},
methods:{
focus: function() {
var self = this;
is10Days = "";
self.defaultValue = moment().format("YYYY-MM-DD");
Randomizer.Is10DaysSetter();
console.log("reset is10Days: " + (is10Days ? "10 days" : "5 days"));
}
}
};
var Ctor = Vue.extend(Main)
ELEMENT.locale(ELEMENT.lang.en)
new Ctor().$mount('#app')
I posted this as a feature request on Element UI's git hub and received a response:
https://github.com/ElemeFE/element/issues/15380
<el-date-picker
ref="picker" //Added this
v-model="value2"
type="date"
placeholder="Enter Date"
#focus="focus()"
:picker-options="pickerOptions">
</el-date-picker>
methods:{
focus: function() {
var self = this;
is10Days = "";
Randomizer.Is10DaysSetter();
//Added this
this.$nextTick(_ => {
this.$refs.picker.picker.date = new Date()
})
console.log("reset is10Days: " + (is10Days ? "10 days" : "5 days"));
}
}
Adding a reference to picker allowed me to override the unwanted feature of going back to the previously viewed month and solved my issue. This came with a warning that since this is not part of the public API, it could change in a future version.
Here is a link to a working code pen:
https://codepen.io/steveshore/pen/rbXjLr
I think it is about compomemt render. when your main vue app initialize, <el-date-picker>
rendered completly first.
The problem is when date-picker finished rendering, are the main vue datas ready?
It seems you pass a null into options, but select another month will force update options.
could you try this?
How to Initialize Data Properties with Prop Values
make a v-if="pickerOptions" in attr
I'm new to Bookshelf.js and hbs and would appreciate your help with the following:
I want to pre-fill a handlebars.js view form with data from a Bookshelf.js model.
hbs won't let me use the Bookshelf get method to get the desired attribute value: e.g. {{user.get(age)}}
I converted the model to JSON but am not able to query a specific json attribute in hbs e.g. {{user.age}}.
JSON
{"id":1,"fullName":"Mike","password":"password","email":"mike#email.com","age":38,"gender":"male","created_at":1432736718951,"updated_at":1432736718951}
Do I have to create a helper to extract the attribute value from the model?
function getUserModel(req, res, next) {
User.forge({id: req.user})
.fetch()
.then(function(user){
req.model = user;
return next()
})
.catch(function(err){
debug("Error loading userId[%s]", req.user);
return next(err);
});
}
router.use(ensureAuthenticated)
.use(getUserModel);
router.get('/', function handlePhotoUploadGet(req, res, next) {
var callback = "http://" + req.headers.host + "/cloudinary_cors.html";
var params = {return_delete_token: true, callback: callback,
timestamp: cloudinary.utils.timestamp()};
var dataFormData = cloudinary.utils.sign_request(params);
res.render('photos/upload',
{ title: 'Photo upload',
cloudinary: cloudinary,
dataFormData: JSON.stringify(dataFormData),
user: req.model }
);
});
<input type="text" name="age" aria-label="age" value="{{user.age}}" placeholder="age" class="radius {{#if errors.invalidAttributes.fullName}}error{{/if}}" />
<input type="radio" name="gender" value="male" aria-label="Male" id="male" {{#if_equal user.gender 'male'}}checked{{/if_equal}}><label for="male">Male</label>
In order to answer this question you need to provide the server-side code, to see what you push to response, and client side html as well. Please update your question.
Update:
Change this line:
req.model = user; to this: req.model = user.toJSON();
I have a super simple code I'm trying to validate:
<template>
<form role="form" submit.delegate="submit()" validate.bind="validation">
<div class="form-group">
<label>Test Field</label>
<input type="text" value.bind="testField" class="form-control" validate="Description" placeholder="What needs to be done?" />
<button type="submit">Submit</button>
</div>
</form>
</template>
With the following viewmodel
define(["require", "exports", "../scripts/HttpClient", "aurelia-validation", "aurelia-framework"], function(require, exports, HttpClient) {
var AureliaValidation = require('aurelia-validation').Validation;
var MyViewModel = (function () {
function MyViewModel(httpClient, aureliaValidation, isReadyCallback) {
this.httpClient = httpClient;
var self = this;
self.setupValidation(aureliaValidation);
}
MyViewModel.prototype.activate = function (params, queryString, routeConfig) {
};
MyViewModel.prototype.setupValidation = function (validation) {
this.testField = "";
this.validation = validation.on(this).ensure('testField');
//validation
// .on(this.serviceMetadata.ServiceData[0])
// .ensure('Value');
this.validation = this.validation.notEmpty().maxLength(3);
};
MyViewModel.prototype.submit = function () {
debugger;
if (this.validation.checkAll()) {
//Do Something
}
return null;
};
MyViewModel.inject = [HttpClient, AureliaValidation];
return MyViewModel;
})();
return MyViewModel;
});
Now I got it working for the most part, and the validation is showing false on submit check, the textbox outline color changes etc., however it's not injecting the validation error messages into the DOM. There's no script error message either, how can I troubleshoot this?
Yes, I can see the validation messages in the validationProperties, but they're not written to the UI.
If your browser allows it, find the JSPM packages in the sources and put a breakpoint here, it's the point where the view strategy looks for labels to append error messages to. If you'd have this code in the open, I'd be happy to have a look for you.
Also, what version of aurelia/aurelia-validation are you using?
And finally, did you modify your sample before posting?
`<input value.bind="testField" validate="Description" />`
These two attributes are contradictory. It binds the value to testField, but then you use the validate attribute to explicitly show validation messages for property "Description".
I'm using knockout validation and the error class is being added to the EndDate field but not the StartDate field when it't empty. the class caused the field to have a red background. I can't see any difference in the two fields. Something similar is happening on my other pages also.
Upon further investigation i realize it's always the first date field on the page that doesn't work. If I comment out the first one then the second stops working.
**Edit: as a hack I added this above the first date field
<input id="StartDate2" style="width: 140px;" type="hidden" data-bind="date: startDate">
and it works......but just feels really wrong.**
I have this at the beginning of my view model
ko.validation.init({
insertMessages: false,
decorateElement: true,
errorElementClass: "input-validation-error"
});
from my model
startDate: KnockoutObservable<Date> = ko.observable(null).extend({ required: { message: "Please enter a start date." }, simpleDate: { message: "Please enter a valid start date." } });
endDate: KnockoutObservable<Date> = ko.observable(null).extend({ required: { message: "Please enter an end date." }, simpleDate: { message: "Please enter a valid end date." } });
from the view
<li>
<label for="StartDate" class="required_label">Start Date</label>
<input id="StartDate" style="width: 140px;" type="text" data-bind="date: startDate, valueUpdate: 'afterkeydown', class:{'input-validation-error':(!startDate.isValid() && showErrors())}" ">
</li>
<li>
<label for="EndDate" class="required_label">End Date</label>
<input id="EndDate" style="width: 140px;" type="text" data-bind="date: endDate">
</li>
And here's our custome date binding handler
// mm/dd/yyyy format
ko.bindingHandlers.date = {
init: (element, valueAccessor) => {
$(element).mask("99/99/9999", { placeholder: "mm/dd/yyyy" });
ko.utils.registerEventHandler(element, "change", () => {
var value = valueAccessor();
if (moment(element.value).isValid()) {
value(element.value);
} else {
value(null);
}
});
ko.validation.makeBindingHandlerValidatable("date");
},
update: (element, valueAccessor, allBindingsAccessor) => {
var value = valueAccessor();
var allBindings = allBindingsAccessor();
var valueUnwrapped: any = ko.utils.unwrapObservable(value);
var pattern = allBindings.format || "MM/DD/YYYY";
var output = null;
if (valueUnwrapped !== null && valueUnwrapped !== undefined && valueUnwrapped.length > 0) {
output = moment(valueUnwrapped).format(pattern);
}
if ($(element).is("input") === true) {
$(element).val(output);
} else {
$(element).text(output);
}
}
};
You are making your date custom binding "validation compatible" only in its init function which will be only called when the binding is first used in the HTML. That is why the validation was only worked for the second input.
In order to fix this you have to move the ko.validation.makeBindingHandlerValidatable("date"); outside of your init function and have it after the whole binding handler declaration
ko.bindingHandlers.date = {
//...
};
ko.validation.makeBindingHandlerValidatable("date");