angular js input date on firefox - javascript

I've got these inputs and this model:
<input name="date" type="date" ng-model="model.date" />
<input name="time" type="time" ng-model="model.time" />
model{
date: "yyyy-mm-dd",
time: "hh24:mi"
}
I need the date and the time as a string and that format is ok for what I have to do. The problem is the input date and input time only work properly with Chrome. If I use Firefox these inputs become two simple input text.
What can I do?

As mentioned in W3Schools, the HTML5 input date is not supported in Firefox. Therefore, all input date will become simple input text in Firefox, as well as IE.
So if you only use IE and Firefox, you could use a jQuery datepicker. Use this for your timepicker.
Also, another way but not as nice, is using <select> tags.
Below I used JS (no jQuery) and HTML to create the datepicker and timepicker. Also, I have also created a "Validate" button to validate the values of the date, which means that "31 Feb 2012" and "29 Feb 2014" will be considered invalid.
HTML:
<table><tr><td>Event Date: </td><td> <select id="startday"></select><select id="startmonth">
<option value="01">Jan</option>
<option value="02">Feb</option>
<option value="03">Mar</option>
<option value="04">Apr</option>
<option value="05">May</option>
<option value="06">Jun</option>
<option value="07">Jul</option>
<option value="08">Aug</option>
<option value="09">Sep</option>
<option value="10">Oct</option>
<option value="11">Nov</option>
<option value="12">Dec</option>
</select> <select id="startyear"></select></td></tr>
<tr><td>Event Time:</td><td> <select id="starthrs"></select><select id="startmins"></select> [24 hrs clock]</td></tr>
</table><br><br>
<input type="button" id="validate" value="Validate"> <a style="color: Red;" id="error"></a>
JS:
for(var i = 0; i < 24; i++) {
var s = i.toString();
if(s.length == 1) {
s = "0" + s;
}
document.getElementById("starthrs").innerHTML += ("<option value='" + i + "'>" + s + " </option>");
}
for(var i = 0; i < 60; i++) {
var s = i.toString();
if(s.length == 1) {
s = "0" + s;
}
document.getElementById("startmins").innerHTML += ("<option value='" + i + "'>" + s + " </option>");
}
for(var i = 1; i < 32; i++) {
var s = i.toString();
if(s.length == 1) {
s = "0" + s;
}
document.getElementById("startday").innerHTML += ("<option value='" + s + "'>" + i + " </option>");
}
for(var i = new Date().getFullYear(); i < (new Date().getFullYear() + 11); i++) {
document.getElementById("startyear").innerHTML += ("<option value='" + i + "'>" + i + " </option>");
}
function ddlValue(id) {
var e = document.getElementById(id);
var strUser = e.options[e.selectedIndex].value;
return strUser;
}
// Validate date
function isDate(ExpiryDate) { // MM/DD/YYYY format
var objDate, // date object initialized from the ExpiryDate string
mSeconds, // ExpiryDate in milliseconds
day, // day
month, // month
year; // year
// date length should be 10 characters (no more no less)
if (ExpiryDate.length !== 10) {
return false;
}
// third and sixth character should be '/'
if (ExpiryDate.substring(2, 3) !== '/' || ExpiryDate.substring(5, 6) !== '/') {
return false;
}
// extract month, day and year from the ExpiryDate (expected format is mm/dd/yyyy)
// subtraction will cast variables to integer implicitly (needed
// for !== comparing)
month = ExpiryDate.substring(0, 2) - 1; // because months in JS start from 0
day = ExpiryDate.substring(3, 5) - 0;
year = ExpiryDate.substring(6, 10) - 0;
// test year range
if (year < 1000 || year > 3000) {
return false;
}
// convert ExpiryDate to milliseconds
mSeconds = (new Date(year, month, day)).getTime();
// initialize Date() object from calculated milliseconds
objDate = new Date();
objDate.setTime(mSeconds);
// compare input date and parts from Date() object
// if difference exists then date isn't valid
if (objDate.getFullYear() !== year ||
objDate.getMonth() !== month ||
objDate.getDate() !== day) {
return false;
}
// otherwise return true
return true;
}
document.getElementById("validate").onclick = function() {
var startday = parseInt(ddlValue("startday"));
var startmonth = parseInt(ddlValue("startmonth"));
var startyear = parseInt(ddlValue("startyear"));
var starthrs = parseInt(ddlValue("starthrs"));
var startmins = parseInt(ddlValue("startmins"));
// Invalid date
if(!isDate(ddlValue("startmonth") + "/" + ddlValue("startday") + "/" + ddlValue("startyear"))) {
document.getElementById("error").innerHTML = "Invalid date";
return;
}
document.getElementById("error").innerHTML = "";
}
Fiddle. Hope that helped.

AFAIK, 'date' input type is supported only by chrome at the moment. May be this answer will help with your need.

Related

When we select todays date time is not showing

When we select todays date time is not showing. if we select the next days date the below mentioned times are showing. When we select todays date time is not showing. if we select the next days date the below mentioned times are showing.
var todaydate = new Date();
let yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
$('#datepicker').datepicker({
uiLibrary: 'bootstrap4',
minDate: yesterday
});
var old_data = '';
var current_date = '{{date("m/d/Y")}}';
var time = "{{date('h a')}}";
$(".datepicker").change(function() {
var selected_date = $(this).val();
if (selected_date != old_data) {
old_data = selected_date;
if (current_date == selected_date) {
var html_data = '<option value="">Select Time</option>';
if (time <= '01 pm') {
html_data += '<option value="9am - 2pm">9am - 2pm</option>';
}
if (time <= '05 pm') {
html_data += '<option value="2pm - 6pm">2pm - 6pm</option>';
}
if (time <= '08 pm') {
html_data += '<option value="6pm - 11pm">6pm - 9pm</option>';
}
} else {
var html_data = '<option value="">Select Time</option>' +
'<option value="9am - 2pm">9am - 2pm</option>' +
'<option value="2pm - 6pm">2pm - 6pm</option>' +
'<option value="6pm - 11pm">6pm - 11pm</option>';
$(".delivery_time").html(html_data);
}
}
});

Ignore Sundays from jQuery date range picker

I'm using the following jQuery date range picker library : http://longbill.github.io/jquery-date-range-picker/
I would like to remove / hide all Sundays from all date range pickers while keeping a normal behavior on the date range pickers.
I tried to do something with beforeShowDay option :
beforeShowDay: function(t) {
var valid = t.getDay() !== 0; //disable sunday
var _class = '';
// var _tooltip = valid ? '' : 'weekends are disabled';
return [valid, _class];
}
but it only "disables" all Sundays whereas I want to remove / hide them:
Here's the fiddle I'm working on : https://jsfiddle.net/maximelafarie/dnbd01do/11/
EDIT:
Updated fiddle with #Swanand code: https://jsfiddle.net/maximelafarie/dnbd01do/18/
You could do it with just a little CSS but it does leave a gap:
.week-name th:nth-child(7),
.month1 tbody tr td:nth-child(7) {
display: none;
}
Hope this helps a little.
You need do changes in two functions in your daterangepicker.js file:
createMonthHTML()
function createMonthHTML(d) { var days = [];
d.setDate(1);
var lastMonth = new Date(d.getTime() - 86400000);
var now = new Date();
var dayOfWeek = d.getDay();
if ((dayOfWeek === 0) && (opt.startOfWeek === 'monday')) {
// add one week
dayOfWeek = 7;
}
var today, valid;
if (dayOfWeek > 0) {
for (var i = dayOfWeek; i > 0; i--) {
var day = new Date(d.getTime() - 86400000 * i);
valid = isValidTime(day.getTime());
if (opt.startDate && compare_day(day, opt.startDate) < 0) valid = false;
if (opt.endDate && compare_day(day, opt.endDate) > 0) valid = false;
days.push({
date: day,
type: 'lastMonth',
day: day.getDate(),
time: day.getTime(),
valid: valid
});
}
}
var toMonth = d.getMonth();
for (var i = 0; i < 40; i++) {
today = moment(d).add(i, 'days').toDate();
valid = isValidTime(today.getTime());
if (opt.startDate && compare_day(today, opt.startDate) < 0) valid = false;
if (opt.endDate && compare_day(today, opt.endDate) > 0) valid = false;
days.push({
date: today,
type: today.getMonth() == toMonth ? 'toMonth' : 'nextMonth',
day: today.getDate(),
time: today.getTime(),
valid: valid
});
}
var html = [];
for (var week = 0; week < 6; week++) {
if (days[week * 7].type == 'nextMonth') break;
html.push('<tr>');
for (var day = 0; day < 7; day++) {
var _day = (opt.startOfWeek == 'monday') ? day + 1 : day;
today = days[week * 7 + _day];
var highlightToday = moment(today.time).format('L') == moment(now).format('L');
today.extraClass = '';
today.tooltip = '';
if (today.valid && opt.beforeShowDay && typeof opt.beforeShowDay == 'function') {
var _r = opt.beforeShowDay(moment(today.time).toDate());
today.valid = _r[0];
today.extraClass = _r[1] || '';
today.tooltip = _r[2] || '';
if (today.tooltip !== '') today.extraClass += ' has-tooltip ';
}
var todayDivAttr = {
time: today.time,
'data-tooltip': today.tooltip,
'class': 'day ' + today.type + ' ' + today.extraClass + ' ' + (today.valid ? 'valid' : 'invalid') + ' ' + (highlightToday ? 'real-today' : '')
};
if (day === 0 && opt.showWeekNumbers) {
html.push('<td><div class="week-number" data-start-time="' + today.time + '">' + opt.getWeekNumber(today.date) + '</div></td>');
}
if(day == 0){
html.push('<td class="hideSunday"' + attributesCallbacks({}, opt.dayTdAttrs, today) + '><div ' + attributesCallbacks(todayDivAttr, opt.dayDivAttrs, today) + '>' + showDayHTML(today.time, today.day) + '</div></td>');
}else{
html.push('<td ' + attributesCallbacks({}, opt.dayTdAttrs, today) + '><div ' + attributesCallbacks(todayDivAttr, opt.dayDivAttrs, today) + '>' + showDayHTML(today.time, today.day) + '</div></td>');
}
}
html.push('</tr>');
}
return html.join('');
}
In this function i have added class hideSunday while pushing the element.
The 2nd function is getWeekHead():
function getWeekHead() {
var prepend = opt.showWeekNumbers ? '<th>' + translate('week-number') + '</th>' : '';
if (opt.startOfWeek == 'monday') {
return prepend + '<th>' + translate('week-1') + '</th>' +
'<th>' + translate('week-2') + '</th>' +
'<th>' + translate('week-3') + '</th>' +
'<th>' + translate('week-4') + '</th>' +
'<th>' + translate('week-5') + '</th>' +
'<th>' + translate('week-6') + '</th>' +
'<th class="hideSunday">' + translate('week-7') + '</th>';
} else {
return prepend + '<th class="hideSunday">' + translate('week-7') + '</th>' +
'<th>' + translate('week-1') + '</th>' +
'<th>' + translate('week-2') + '</th>' +
'<th>' + translate('week-3') + '</th>' +
'<th>' + translate('week-4') + '</th>' +
'<th>' + translate('week-5') + '</th>' +
'<th>' + translate('week-6') + '</th>';
}
}
In this file, I have added class to week-7 header.
CSS:
.hideSunday{display:none;}
Please note, I have not checked all the scenario but it will do trick for you.
I finally ended up by letting the Sundays appear (but completely disabling them).
These questions inspired me :
Moment.js - Get all mondays between a date range
Moment.js: Date between dates
So I created a function as follows which returns an array that contains the "sundays" (or whatever day you provide as dayNumber parameter) in the date range you selected:
function getDayInRange(dayNumber, startDate, endDate, inclusiveNextDay) {
var start = moment(startDate),
end = moment(endDate),
arr = [];
// Get "next" given day where 1 is monday and 7 is sunday
let tmp = start.clone().day(dayNumber);
if (!!inclusiveNextDay && tmp.isAfter(start, 'd')) {
arr.push(tmp.format('YYYY-MM-DD'));
}
while (tmp.isBefore(end)) {
tmp.add(7, 'days');
arr.push(tmp.format('YYYY-MM-DD'));
}
// If last day matches the given dayNumber, add it.
if (end.isoWeekday() === dayNumber) {
arr.push(end.format('YYYY-MM-DD'));
}
return arr;
}
Then I call this function in my code like that:
$('#daterange-2')
.dateRangePicker(configObject2)
.bind('datepicker-change', function(event, obj) {
var sundays = getDayInRange(7, moment(obj.date1), moment(obj.date1).add(selectedDatesCount, 'd'));
console.log(sundays);
$('#daterange-2')
.data('dateRangePicker')
.setDateRange(obj.value, moment(obj.date1)
.add(selectedDatesCount + sundays.length, 'd')
.format('YYYY-MM-DD'), true);
});
This way, I retrieve the amount of sundays in the date range I selected. For example, if there's two sundays in my selection (with sundays.length), I know I have to set two additional workdays to the user selection (in the second date range picker).
Here's the working result:
With the above screenshot, you can see the user selected 4 workdays (5 with sunday but we don't count it). Then he click on the second calendar and the 4 workdays automatically apply.
Here's the result if the period apply over a sunday (we add one supplementary day and Xfor X sundays in the period):
Finally, here's the working fiddle: https://jsfiddle.net/maximelafarie/dnbd01do/21/
I want to thank any person that helped me. The question was hard to explain and to understand.
You can also do it by setting a custom css class and use it in beforeShowDay like below
.hideSunDay{
display:none;
}
beforeShowDay: function(t) {
var valid = t.getDay() !== 0; //disable sunday
var _class = t.getDay() !== 0 ? '' : 'hideSunDay';
// var _tooltip = valid ? '' : 'weekends are disabled';
return [valid, _class];
}
But it only hides the sundays beginning from current day.
Here is a working fiddle
https://jsfiddle.net/dnbd01do/16/

Get Date string value from Date and Time field in CRM using JavaScript

I am trying to get the date string value(mm/dd/yyyy)from a custom date and time field and set the returned value back into the custom field. I found this script and modified it but it does not seem to work. When I step through the code it breaks on var year = startDate.getFullYear() + ""; Any ideas what I am doing wrong? Thanks.
function ConcatChainsAuth() {
var startDate = Xrm.Page.getAttribute("new_dateauthorized").getValue();
if (startDate != null) {
var year = startDate.getFullYear() + "";
var month = (startDate.getMonth() + 1) + "";
var day = startDate.getDate() + "";
var dateFormat = month + "-" + day + "-" + year;
Xrm.Page.getAttribute("new_dateauthorized").setValue(dateFormat);
}
var lookupObject = Xrm.Page.getAttribute("new_chain");
if (lookupObject != null) {
var lookUpObjectValue = lookupObject.getValue();
if ((lookUpObjectValue != null)) {
var Chain = lookUpObjectValue[0].name;
}
}
var lookupObject = Xrm.Page.getAttribute("new_package");
if (lookupObject != null) {
var lookUpObjectValue = lookupObject.getValue();
if ((lookUpObjectValue != null)) {
var Package = lookUpObjectValue[0].name;
}
}
var concatedField = Chain + "-" + Package + "-" + dateFormat;
Xrm.Page.getAttribute("new_name").setValue(concatedField);
Xrm.Page.data.entity.save();
}
Assuming that new_dateauthorized is a CRM date field, then Xrm.Page.getAttribute("new_dateauthorized").getValue() will return a Date object.
In which case you can just manipulate the Date object, like so:
var currentDate = Xrm.Page.getAttribute("new_dateauthorized").getValue();
currentDate.setMonth(currentDate.getMonth() + 1);
Xrm.Page.getAttribute("new_dateauthorized").setValue(currentDate);
However, adding months in this fashion fails in some cases, check out the comments here for more info.

How to reset drop down if value change?

I'm working on my project where I have three drop down boxes. User can pick Start time, Meeting Length and End time. My function works fine but I'm missing one more thing, so If user select all of three drop downs they will get all end times in last drop down but now I want if they change meeting length or start time, my end time drop box should give them values with the valid records. Current code works fine if they select everything once but if they change start time or meeting length my end time is still the same.
Here is my jsfiddle with the working example:
https://jsfiddle.net/dmilos89/vy0yy7h9/4/
I tried to reset my function with something like this:
$('#meet_leng').on('chnage');
inside of my existing function but that did not help. If anyone knows how I can refresh my function each time after I change values in my start time and meeting length drop downs please let me know.
$(function() {
//This loop populate values fro meeting length dropdown
for (var i = 5; i <= 60; i += 5) {
$('#meet_leng').append('<option value="' + i + '">' + i + ' min' + '</option>')
}
//Populate start time dropdown with values
for (var i = 700; i <= 1700; i += 15) {
var mins = i % 100;
var hours = parseInt(i / 100);
if (mins > 45) {
mins = 0;
hours += 1;
i = hours * 100;
}
var AmPm = " AM";
//set hours 12 to PM
if (hours == 12) {
AmPm = " PM";
}
//format all hours greater than to PM
if (hours > 12) {
hours = hours - 12;
AmPm = " PM";
}
//populate stime with values
$('#stime').append('<option value="' + ('0' + (hours)).slice(-2) + ':' + ('0' + mins).slice(-2) + AmPm + '">' + ('0' + (hours)).slice(-2) + ':' + ('0' + mins).slice(-2) + AmPm + ' </option>')
}
//onChange function set end time based on start time and meeting length
$('#meet_leng').on('change', function() {
if ($('#stime').val() == '0') {
alert('You have to pick start time first.')
} else {
if ($('#meet_leng').val() == '0') {
$('#hideSlots').hide();
} else {
//convert variables for start and end time to new Date
var time1 = new Date();
var time2 = new Date();
//meeting length converts to int
var meetingLength = parseInt($('#meet_leng').val());
//start time split into hours and minutes
var startTime = $('#stime').val();
var startHour = startTime.split(':')[0];
var startMin = startTime.split(':')[1].replace(/AM|PM/gi, '');
//end time split into hours and minutes
var endTime = '05:00 PM';
var endHour = endTime.split(':')[0];
var endMin = endTime.split(':')[1].replace(/AM|PM/gi, '');
//Check if start time is PM and adjust hours to military
if (startTime.indexOf('PM') > -1) {
if (startHour != 12) {
startHour = parseInt(startHour) + 12;
} else {
startHour = parseInt(startHour);
}
}
//Check if end time is PM and adjust hours to military
if (endTime.indexOf('PM') > -1) {
endHour = parseInt(endHour) + 12;
}
//Date API start time set hours and minutes
time1.setHours(parseInt(startHour));
time1.setMinutes(parseInt(startMin));
//Date API end time set hours and minutes
time2.setHours(parseInt(endHour));
time2.setMinutes(parseInt(endMin));
//Adding meeting length to start time
time1.setMinutes(time1.getMinutes() + meetingLength);
//while loop checks for time values and increment end time for meeting interval
while (time1 <= time2) {
var amPm = " AM";
var hourEnd = time1.getHours();
var minEnd = time1.getMinutes();
if (hourEnd >= 12) {
hourEnd = (hourEnd == 12) ? hourEnd : hourEnd - 12;
amPm = " PM";
}
if (hourEnd == 24) {
hourEnd = 12;
}
minEnd = ('' + minEnd).length > 1 ? minEnd : '0' + minEnd;
$('#etime').append('<option value="' + hourEnd + ':' + minEnd + ' ' + amPm + '">' + hourEnd + ':' + minEnd + ' ' + amPm + '</option>');
time1.setMinutes(time1.getMinutes() + meetingLength);
}
}
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<tr>
<th>Start Time:</th>
<td>
<select name="stime" id="stime">
<option value="0">--Select start time--</option>
</select>
</td>
</tr>
<br/>
<tr>
<th>Metting Length:</th>
<td>
<select name="meet_leng" id="meet_leng">
<option value="0">--Select length--</option>
</select>
</td>
</tr>
<br/>
<tr>
<th>End Time:</th>
<td>
<select name="etime" id="etime" />
<option value="0">--Select end time--</option>
</select>
</td>
</tr>
You want to either set the value:
$('#etime').val("new value");
or select the index:
$('#etime').get(0).selectedIndex = 1;
remember that indexes start at 0.
you would do this after the while loop that populates all the end time options.
Please try below code
$('#meet_leng').on('chnage',function(){
$('#etime').val("FirstIndexValue")
});
//FirstIndexValue= #etime default value

how to make options based on the current year

I want to have options of this year and next year, but I can't figure out how to integrate the JavaScript variable into the value = "" and the text inside the option tags. This code demonstrates what I mean (obviously it is not valid, but shows what I mean). so today the first option would be 2013 and the next, 2014. Thanks.
var date = new Date(),
y = date.getFullYear();
<html>
<select id = "year">
<option value = "y" >y</option>
<option value = "(y + 1)">(y + 1)</option>
</select>
</html>
With jQuery:
var sel = $("#year"),
date = new Date(),
y = date.getFullYear(),
newOptions = "";
newOptions += "<option value='" + y + "'>" + y + "</option>";
newOptions += "<option value='" + (y + 1) + "'>" + (y + 1) + "</option>";
sel.append(newOptions);
DEMO: http://jsfiddle.net/YxqcT/
Since you mentioned that you're using jQuery, you can use this:
var currentYear = (new Date).getFullYear();
var opts;
$('#year').append(function () {
for (var i = currentYear; i <= currentYear + 1; i++) {
opts += "<option value='" + i + "'>" + i + "</option>";
}
return opts;
})
jsFiddle example
No need for jQuery. Simple HTML DOM can do the work for you.
Sample >> http://jsfiddle.net/47dDu/
<!DOCTYPE html>
<html>
<body>
<select id="MySelectBox">
<option value="1" id="this_year"></option>
<option value="2" id="next_year"></option>
</select>
<script type="text/javascript">
var d = new Date();
var x = document.getElementById("this_year");
x.innerHTML=d.getFullYear(); //get this year
var y = document.getElementById("next_year");
y.innerHTML=d.getFullYear()+1; //get next year
</script>
</body>
</html>

Categories