I have a form_for form. Some of my fields are for selecting dates, which I'm using flatpickr for. I'm having trouble making the field required using form validation on the client side.
I have the following basic flatpickr code in application.js:
flatpickr("[data-behavior='flatpickr']", {
altInput: true,
altFormat: "F j, Y",
dateFormat: "Y-m-d"
});
In my view, I've tried making a field like this (with many variations):
<%= f.text_field :attribute_name,
{ label: "Description of attribute", data: { behavior: "flatpickr" }, required: true } %>
which produces this HTML:
<label class="required" for="model_name_attribute_name">Description of attribute</label>
<input data-behavior="flatpickr" required="required" class="form-control flatpickr-input" type="hidden" name="model_name[attribute_name]" id="model_name_attribute_name">
<input class="form-control form-control input" placeholder="" required="" tabindex="0" type="text" readonly="readonly">
Everything works, except I can't figure out how to make the field required. Flatpickr creates a hidden field that holds the actual date value selected in their javascript pop-up and then it displays it using whatever format you like in the visible field which is readonly because it's set by flatpickr. It seems like my attempts to make the field "required" have made the label have the "required" class and made the hidden field "required" while leaving my visible field with required='' which is not sufficient enough to halt submission when nothing has been selected and the field is empty. I have a server-side validation catching it but I want to find a way for the client-side validation to work also.
Apparently it's a known bug in flatpickr which has not been fixed yet, at least as of writing this, but it looks like it's been around several years. As a workaround, I ended up successfully solving this by adding allowInput: true in my flatpickr config like in the following example:
flatpickr("[data-behavior='flatpickr']", {
allowInput: true,
altInput: true,
altFormat: "F j, Y",
dateFormat: "Y-m-d"
});
I then wanted to automatically select all the text in the field when the user focuses (through clicking or the tab button) on flatpickr fields and inspired by this, I settled on this solution using jQuery:
$("[data-behavior='flatpickr']").next().focus(function() {
$(this).on("click.a keyup.a", function(e){
$(this).off("click.a keyup.a").select();
});
});
The key difference from the original code that was necessary to get it working was the .next(). As I noted earlier, flatpickr creates a hidden field to store the date selected with the pop-up picker and technically it's that hidden field which has the id and the data-behavior attribute. So with next(), we are listening to the visible field, which is the next element.
Many alternative approaches are discussed on the flatpickr GitHub issue page for those wanting a different approach, depending on your needs.
Related
I'm using this datepicker. As of now, the user can write anything he likes in the input field which is not what I want.
My code:
session.js
session.getDateFormat = function() {
return 'yyyy-MM-dd';
};
session.formatDate = function(date) {
return $filter('date')(date, session.getDateFormat());
};
Controller.js
vm.dateFormat = session.getDateFormat();
function submit() {
date : session.formatDate(vm.data.date)
}
The code is much longer but that basically the part concerning the date. And HTML
<input type="text" class="form-control" uib-datepicker-popup="{{vm.dateFormat}}" placeholder="{{vm.dateFormat}}" ng-model="vm.data.date" is-open="vm.dateOpened" ng-required="true" ng-disabled="disabled" />
The admin can choose if he wants getDateFormat to accept yyyy-mm-dd or dd-mm-yyyy etc.
What I want:
To verify that the user has input the date is the right format, otherwise to clear the field automatically and display an error message along with the right date format as a hint to the user. All that must be done before pressing submit.
Not allowing the user to enter letters obviously
No hard coded html regex, I want something to check if the input is the same as getDateFormat, otherwise clear the field and display an error.
No Jquery, I don't use Jquery in the entire project.
If you have any other datepicker in mind that works with angular and bootstrap without using Jquery, let me know.
I had to update to angular-ui 1.3.3 and then I had to give the date input a name 'datepicker' and the form a name 'frm' and then
<div ng-if="!frm.datepicker.$error.required"">
<div class="datepicker-error" ng-if="frm.datepicker.$invalid">
some error message
</div></div>
I didn't clear the field since if the user didn't finish typing it's going to be invalid and hence might be cleared. If anyone has a better solution let me know.
I have a login Form that is validated using Angular validation as follows:
HTML for Input fields:
<input id="loginName" name="loginName" type="text" class="form-control" placeholder="Username" data-ng-model="loginName" data-ng-maxlength="246" required>
<input id="password" name="password" type="password" class="form-control" placeholder="Password" data-ng-model="password" data-ng-maxlength="246" required>
'Login' button is validated against loginName and password fields using angular validation.
In Google Chrome (other browsers behave as intended) when these fields are saved (with do you want to save username and password feature) when the page is refreshed, the model for input type 'text' -> $scope.loginName gets updated with the saved value on the other hand the model for input type 'password' -> $scope.password is always empty) and according to the validation logic form is declared invalid and the 'Login' button stays disabled even though both the input fields are populated with saved information (See first attached image).
The moment a keypress or mouse click even occurs(not necessarily on the input fields but anywhere on the web page), somehow the model for password is updated and form is validated as shown in the second image attached.
I tried using autofocus, custom autofocus directives, timeouts but it doesn't seem to work as intended.
any suggestions, probably moving the cursor to the end of the text field so that the form knows that the text has been entered in the password field by the browser?
Came across this: AngularJS browser autofill workaround by using a directive
NOTE: All he answers in above solution talk about input elements value, got by either .val() or .value methods but the tricky part is both return undefined in case of password input field.
But no luck!
Thanks.
You may use
$scope.$watch('modelValue',function(newVal,oldVal){
//your code action
});
which will keep on tracking the model value. Whenever the model has value, your code inside $scope.$watch will be triggered.
As suggested by Ziv Weissman (in the comments section above) and after wasting quite a few hours on this, I have abandoned the AngularJs style validation process for the Login button and the input type password as well.
Chrome pretends it does not have a value for the field as a security measure. There's no way to hack around that. from: here
I found a potential solution to this behaviour which involves re-capturing the password value after a delay.
Just add this directive,and call the directive from the input's
Directive code
Modeule.directive('autoComplete', function ($timeout) {
return function (scope, iElement, iAttrs) {
iElement.autocomplete({
source: scope[iAttrs.uiItems],
select: function () {
$timeout(function () {
iElement.trigger('input');
}, 0);
}
});
};
});
HTML code
<input type="text" ng-model="username" auto-complete />
In my ASP.NET MVC 4 app, I am using the jquery.ui.datepicker.css to implement the datepicker for an input field as follows:
#Html.TextBox("txtDate", new { #class = "date", #title = "(mm/dd/yyyy)"})
When user clicks the textbox, the datepicker (calendar) popups where user can select a date. Some users just prefer to start typing the date instead. How can I force user to use the datepicker instead. I added the attribute #readonly = "readonly" into the textbox but the browsers then make the color of the textbox grayed out making user think that he/she cannot do anything there.
Please help.
I think you should add
style="background:white;"
to make looks like it is writable
<input type="text" id="txtDate" class="date" readonly="readonly" style="background:white;"/>
I've been trying to add a date picker to my site that allows users to pick multiple non-concurrent dates. Multidatespicker appears to do what I want but i've got to a point where I think I have discovered a bug, particularly with it's AltField, which is confirmed here. The bug seems to stop the altfield's values showing. If you visit the Multidatespicker demo and inspect the altfield you'll see that while it appears empty the values are showing in the code.
The issue this presents for me is that I can't edit previously selected dates when returning a record from my App/DB. When passing the value of altfield back to my Rails App for database storage I only receive the hidden values shown in the code.
If I can get the altfield to correctly show these values and allow me to edit them via the date selector, then I should be amend within my app's backend.
Note the suggested fix on the github link above does not solve this issue - it only enables rendering dates in 'dateVar' as being selected in the picker....it does nothing to show values in altField.
Has anyone used this and had the same problem and solved it?
Does anyone know how to fix it?
OR
Can anyone suggest a good alternative that will work nicely with a Rails 3 App using Twitter Bootstrap. It's very important that i'm able to select multiple non-concurrent dates. I've searched quite extensively but MultiDatesPicker seems to be one of the only options I can find.
The problem is that Multidatespicker is not listening #altField so we need to create our own listener to add/remove dates.
The idea is to add values to a hidden or readonly input and add/remove dates by an other. This prevent the customer to add dates in #altField and getting them overwritten by the plugin.
HTML
<input type="text" id="date">
<button type="button" id="addDate">Add dates</button>
<button type="button" id="removeDate">Remove dates</button>
<div class="ui-state-error" id="error"></div>
<br />
<input type="text" id="altField" readonly value="2013-08-30,2013-08-31">
JAVASCRIPT
And with javascript we simply add the date with a button (could be on keyup or anything your imagination can imagine :)
var dates = $('#altField').val().split(',');
$('#datepicker').multiDatesPicker({
dateFormat: "yy-mm-dd",
addDates: dates,
altField: '#altField'
});
$('#addDate, #removeDate').on('click', function() {
try {
var $date = $('#date');
var addOrRem = $(this).attr('id') === "addDate" ? 'addDates' : 'removeDates';
$('#datepicker').multiDatesPicker(addOrRem, $date.val());
$date.val('');
} catch (e) {
var $error = $('#error');
$error.html(e).slideDown();
setTimeout(function() {
$error.slideUp();
}, 2000);
}
});
jsFiddle
I have scanned the source of MultiDatesPicker. I don't find any method which set the date from the #altfield. So it is not a bug it is missing.
I also do not understand the difference between the preselected dates and the altfield.
I think you can do what you want with a combination of preselect and the altfield:
html
<div id="with-altField"></div>
<input type="text" id="altField" value="08/22/2013,08/21/2013">
</div>
javascript
//first read the values of the #altfield
var dates = $('#altField').val().split(',');
//second set your multiDatesPicker with the dates of step 1 and an altfield
$('#with-altField').multiDatesPicker({
dateFormat: "mm/dd/yy",
addDates: dates,
altField: '#altField'
});
nb load the javascript on document ready
I'm brand new to javascript and knockout. I'm working on client side validation using knockout-validation and am having some trouble. I want textboxes that require some user input to show their error messages on blur (even if the user didn't enter anything). A problem I ran into is that I don't want the error messages to show up right away. I was able to get this working but was wondering if someone had a more elegant way to do this. The pseudo code for what I do is set a textbox's value as an observable and then subscribe that to hasfocus of the textbox. Here is the sample code of the view model and the fiddle to go with it:
self.firstName = ko.observable().extend({
required: true,
notify: 'always'
});
self.firstName.focused = ko.observable();
self.firstName.focused.subscribe(function(newVal) {
if(not the first time in the function and the value hasn't changed)
{
update the value to itself;
//if this is empty then it will trigger the "required" error message
}
});
http://jsfiddle.net/sderico/qAnxw/
I want to know if there's a nicer way to implement this functionality (or any other ways that aren't too convoluted). Thanks in advance!
You just need to specify the valueUpdate option to 'blur' on in your value binding. Then knockout will also update the value of firstName on the blur event which triggers the validation:
<input type="text" runat="server" ID="FirstName"
data-bind="value: firstName, valueUpdate: 'blur'"/>
Demo JSFiddle.