I have JS script file.
In this file I have code that populate inputs with value from calendar
Here is code.
$(document).ready(function () {
columnSettings = $('#visibleColumns').val();
SetColumnCheckboxes();
$('#tableDetails').DataTable({
'columnDefs': columnDefs,
'sDom': '<"table-options"<"top length"l><"top paging"p><"top filtering"f>>rt<"bottom"i>',
'sScrollY': '1px',
'scrollX': true,
'autoWidth': true,
'lengthMenu': [[-1, 10, 25, 50, 100], [dictionary.find('all'), 10, 25, 50, 100]],
'language': dataTablesLanguage
});
//cultureTwoLetterName is a global variable from the view that contains the two letter iso language name
$.datepicker.setDefaults($.datepicker.regional[cultureTwoLetterName]);
$('#calendar').weekMonthDatepicker({
changeMonth: true,
dateFormat: 'yy-mm-dd',
showWeek: true,
firstDay: 1,
weekHeader: '<span class="glyphicon glyphicon-arrow-down"></span>',
minDate: -loggingRetention,
maxDate: '+0D',
weekSelection: true,
weekSelected: SelectionCallback,
monthSelection: true,
monthSelected: SelectionCallback
});
$('#startDate').datepicker({
changeMonth: true,
dateFormat: 'yy-mm-dd',
firstDay: 1,
minDate: -loggingRetention,
maxDate: '+0D'
});
$('#endDate').datepicker({
changeMonth: true,
dateFormat: 'yy-mm-dd',
firstDay: 1,
minDate: -loggingRetention,
maxDate: '+0D'
});
$('#selectGroups').on('change', function () {
PopulateSelectVehicles();
});
$('#selectVehicles').on('change', function () {
var imei = $(this).val();
var device = getDevice(imei);
configureReportpageForDevice(device);
var start = $('#calendar').weekMonthDatepicker('getStartDate');
var stop = $('#calendar').weekMonthDatepicker('getEndDate');
var ui;
if (start != null && stop != null) {
var ui = { 'startDate': start, 'endDate': stop };
}
PopulateTableDetails(null, ui);
});
$('#calendar').on('change', function () {
$('#startDate').val(moment($(this).val()).format('DD/MM/YYYY'));
$('#endDate').val(moment($(this).val()).format('DD/MM/YYYY'));
startdate = $('#startDate').val();
end = $('#endDate').val();
alert(end);
var start = $('#calendar').weekMonthDatepicker('getStartDate');
var stop = $('#calendar').weekMonthDatepicker('getEndDate');
var ui;
if (start != null && stop != null) {
ui = { 'startDate': start, 'endDate': stop };
}
PopulateTableDetails(null, ui);
});
$('#startDate').on('change', function () {
$(this).val(moment($(this).val()).format('DD/MM/YYYY'));
if ($('#endDate').val() == '' || moment($('#endDate').val(), 'DD/MM/YYYY') < moment($(this).val(), 'DD/MM/YYYY')) { //endDate niet ingevuld of < startDate --> endDate = startDate
$('#endDate').val($(this).val());
}
var start = moment($(this).val(), 'DD/MM/YYYY');
var stop = moment($('#endDate').val(), 'DD/MM/YYYY');
var ui = { 'startDate': start, 'endDate': stop };
PopulateTableDetails(null, ui);
});
$('#endDate').on('change', function () {
$(this).val(moment($(this).val()).format('DD/MM/YYYY'));
if ($('#startDate').val() == '' || moment($('#startDate').val(), 'DD/MM/YYYY') > moment($(this).val(), 'DD/MM/YYYY')) { //startDate niet ingevuld of > endDate --> startDate = endDate
$('#startDate').val($(this).val());
}
var start = moment($('#startDate').val(), 'DD/MM/YYYY');
var stop = moment($(this).val(), 'DD/MM/YYYY');
var ui = { 'startDate': start, 'endDate': stop };
PopulateTableDetails(null, ui);
});
});
I need to get values from startDate and endDate
I can do it writing startdate = $('#startDate').val(); in $('#calendar').on('change', function () { function.
But I have function out of document.ready block, that connected with map and cannot be used in document.ready block.
Here is code of this function
function getDriving() {
var startdatevalue = startdate;
alert(startdatevalue);
var url = $('#map').data('request-url2');
$.getJSON(url,
function (data) {
var marker = [];
$.each(data,
function (i, item) {
marker.push({
'location': new google.maps.LatLng(item.Latitude, item.Longitude),
'map': map,
'weight': item.Speed,
'radius': 10
});
});
var pointArray = new google.maps.MVCArray(marker);
heatmap = new google.maps.visualization.HeatmapLayer({
data: pointArray
});
heatmap.setMap(map);
});
};
And when I write var startdatevalue = startdate;
alert(startdatevalue); in it it is null.
How I can get value in this function correctly?
Here is full code of js Code
I tried to write initMap and other related functions in document.ready, but I get initMap not a function error. Because of this line in View <script async src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCea6mL2cqwVid2ESIjuJ0C31RbNVQNPY0&libraries=visualization&callback=initMap"> </script>
Thank's for help
This is a common problem. It's all about scope. Any var's you cast in the .ready event are only available in that scope (function).
So the work-around is to cast the var outside that function. (global scope)
If you have other modules/functions that need to read these vars your best bet is make your own app object and set the vars in that, you can then read those vars elsewhere in your app code.
var app = {};
..
$(document).ready(function () {
app.startdate = //some value
..
});
Now anywhere else in your app you can access that global object
console.log(app.startdate)
I have used a global object as you may need to have start, end date and other vars that can be accessed by the outside modules
You can just do
var startdate
Outside the ready function and that will also work.
The problem with this design method is that the var may not be set when the 2nd functions requests it.
This problem is solved by either passing the var in directly to the other function. Or using an event drive system, where by function 2 subscribes to an event on function 1 that passes the var as it is set, or changed.
Related
I have this simple datepicker jQuery, and in my application my users can go back to the past, but not future. I want to show the current day base on the date param in the url browser.
Let's say
var url_string = window.location.href;
var url = new URL(url_string);
var dateParam = url.searchParams.get("date"); <<----- current date
I have
$(".clock").click(function() {
$( "#expiryDate" ).datepicker('setDate', date); <<---- Note here
$("#expiryDate").datepicker({
dateFormat: 'yy-mm-dd',
defaultDate: date,
showAnim: "fold",
gotoCurrent: true,
maxDate: 0,
onSelect: function() {
var dateSelected = $(this).datepicker('getDate');
dateSelected = moment(dateSelected).format('YYYY-MM-DD');
// $( "#expiryDate" ).datepicker('setDate', dateSelected);
playSound('forward');
if(dateParam == null) {
var url = document.location.href+"&date="+dateSelected;
}else {
var url = document.location.href;
url = url.replace(dateParam,dateSelected);
}
document.location = url;
}
});
$('#expiryDate').datepicker('show');
});
Even if today is 05/06/2021, users can go back to the past, and see what happened on that day. So when user selected 02/03/2021. I want to highlight that date 02/03/2021. It seems working only if I clicked on my date twice.
Notice only second clicked 3 started to highlight!
How do I make it highlight on first clicked ?
I want to highlight that date 02/03/2021. It seems working only if I clicked on my date twice.
If removed the following code:
var dateSelected = $(this).datepicker('getDate');
dateSelected = moment(dateSelected).format('YYYY-MM-DD');
This can easily be replaces by the onChange function parameter, for more info, take a look at the documentation.
Replaced by:
onSelect: function(dateSelected) {
With that in mind, I've created some sort of [mre] from the code above. This seems to work as expected:
The url_string date is selected on load
On press, the new date is highlighted instantly
var url_string = 'https://example.com?date=2021-05-02'; // DEBUG
var url = new URL(url_string);
var dateParam = url.searchParams.get("date");
console.log('dateParam', dateParam);
$(".clock").click(function() {
$("#expiryDate").datepicker({
dateFormat: 'yy-mm-dd',
defaultDate: dateParam,
showAnim: "fold",
gotoCurrent: true,
maxDate: 0,
onSelect: function(dateSelected) {
console.log('onSelect', dateSelected);
if (dateParam == null) {
var url = document.location.href+"&date="+dateSelected;
} else {
var url = document.location.href;
url = url.replace(dateParam,dateSelected);
}
}
});
$('#expiryDate').datepicker('show');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<div class='clock'>🕑
<div id='expiryDate' />
</div>
Shooting a bit in the dark for now, since we have low info:
According to your snippets:
var dateParam = url.searchParams.get("date"); <<----- current date
And
$( "#expiryDate" ).datepicker('setDate', date); <<---- Note here
The problem is that you define dateParam while you use date.
It's hard to tell if other code define the date variable, but as a starter, I'd make sure that your date is correctly set...
console.log(date); // Make sure it logs the correct date.
$( "#expiryDate" ).datepicker('setDate', date); <<---- Note here
It is due to the lifecycle of the datepicker. The datepicker will be initialized as
$("#expiryDate").datepicker({});
If you call
$("#expiryDate").datepicker('setDate', date);
Before the datepicker be initialized, that will nothing to do with it at the first time.
At the second time, because of the datepicker was initialized. So, everything works fine. Moreover, once you set the date, it not needs to default date.
Due to reasons of above, the code should be modified as
$(".clock").click(function() {
$("#expiryDate").datepicker({
dateFormat: 'yy-mm-dd',
showAnim: "fold",
gotoCurrent: true,
maxDate: 0,
onSelect: function() {
var dateSelected = $(this).datepicker('getDate');
dateSelected = moment(dateSelected).format('YYYY-MM-DD');
// $( "#expiryDate" ).datepicker('setDate', dateSelected);
playSound('forward');
if(dateParam == null) {
var url = document.location.href+"&date="+dateSelected;
}else {
var url = document.location.href;
url = url.replace(dateParam,dateSelected);
}
document.location = url;
}
});
$("#expiryDate").datepicker('setDate', date); <<---- Note here
$("#expiryDate").datepicker('show');
});
I have the following function for pulling data from a php json_encode for use in FullCalendar.
eventDrop: function(info) {
$.get( "php/get-events.php", function( data ) {
// data is your result
// Find the value for editable where the event id = the event you are trying to move
rawdata = JSON.parse(data);
editable = rawdata.find(x => x.id === info.event.id).editable;
start= info.event.start.toISOString();
start = moment(info.event.start).format('Y-MM-DD HH:mm:ss');
end= info.event.end.toISOString();
end = moment(info.event.end).format('Y-MM-DD HH:mm:ss');
title = info.event.title;
id = info.event.id;
});
}
I will use very similar code for the eventResize function within fullcalendar, so I would like to extract this part
$.get( "php/get-events.php", function( data ) {
// data is your result
// Find the value for editable where the event id = the event you are trying to move
rawdata = JSON.parse(data);
into it's own function (not 100% sure I'm using the right terminology here?) I seen this answer jQuery - Passing variable within a function to another function about how to pass variables in the global scope, so I tried to move my above code out of eventDrop like so
$.get( "php/get-events.php", function( data ) {
// data is your result
// Find the value for editable where the event id = the event you are trying to move
rawdata = JSON.parse(data);
});
eventDrop: function(info) {
But this gives me an error
Uncaught SyntaxError: Unexpected token '.'
Ideally I would like to do the json extract using the $.get only one time throughout my page, and then reference the rawdata global variable to read the information, is this possible?
My full solution at current is
<script>
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var today = moment().day();
var calendar = new FullCalendar.Calendar(calendarEl, {
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
},
defaultDate: today,
editable: true,
$.get( "php/get-events.php", function( data ) {
// data is your result
// Find the value for editable where the event id = the event you are trying to move
rawdata = JSON.parse(data);
});
eventDrop: function(info) {
editable = rawdata.find(x => x.id === info.event.id).editable;
start= info.event.start.toISOString();
start = moment(info.event.start).format('Y-MM-DD HH:mm:ss');
end= info.event.end.toISOString();
end = moment(info.event.end).format('Y-MM-DD HH:mm:ss');
title = info.event.title;
id = info.event.id;
if (!confirm("Confirm you want to change " + info.event.title + " to " + info.event.start)) {
info.revert();
}
else{
if(editable === 'Y'){
$.ajax({
url: 'php/calendarupdate.php',
data: 'title=' + info.event.title + '&start='+ start +'&end=' + end + '&id=' + info.event.id ,
type: "POST"
});
}
else{
alert("Can only modify this calendar event if you created it. Please ask the event creator to modify.");
calendar.refetchEvents();
}
}
},
navLinks: true, // can click day/week names to navigate views
dayMaxEvents: true, // allow "more" link when too many events
events: {
url: '/php/get-events.php',
failure: function() {
document.getElementById('script-warning').style.display = 'block'
}
},
loading: function(bool) {
document.getElementById('loading').style.display =
bool ? 'block' : 'none';
}
});
calendar.render();
});
</script>
Problem solved, thanks to #Patrick Evans for the suggestion, I was adding the get call to the middle of my code, where I had to add it at the end, after the ";" to end the line. I can now reference "rawdata" variable within EventDrop.
<script>
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var today = moment().day();
var calendar = new FullCalendar.Calendar(calendarEl, {
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
},
defaultDate: today,
editable: true,
eventDrop: function(info) {
editable = rawdata.find(x => x.id === info.event.id).editable;
start= info.event.start.toISOString();
start = moment(info.event.start).format('Y-MM-DD HH:mm:ss');
end= info.event.end.toISOString();
end = moment(info.event.end).format('Y-MM-DD HH:mm:ss');
title = info.event.title;
id = info.event.id;
if (!confirm("Confirm you want to change " + info.event.title + " to " + info.event.start)) {
info.revert();
}
else{
if(editable === 'Y'){
$.ajax({
url: 'php/calendarupdate.php',
data: 'title=' + info.event.title + '&start='+ start +'&end=' + end + '&id=' + info.event.id ,
type: "POST"
});
}
else{
alert("Can only modify this calendar event if you created it. Please ask the event creator to modify.");
calendar.refetchEvents();
}
}
},
navLinks: true, // can click day/week names to navigate views
dayMaxEvents: true, // allow "more" link when too many events
events: {
url: '/php/get-events.php',
failure: function() {
document.getElementById('script-warning').style.display = 'block'
}
},
loading: function(bool) {
document.getElementById('loading').style.display =
bool ? 'block' : 'none';
}
});
$.get( "php/get-events.php", function( data ) {
// data is your result
// Find the value for editable where the event id = the event you are trying to move
rawdata = JSON.parse(data);
});
calendar.render();
});
</script>
I am developing a project with AngularJS and using Angular-UI UI-Calendar. In my code I initialize eventSources model for ui-calendar to empty array ([]) and set ui-config "events parameter" to a custom function. That function makes an $http request and then calls the callback function given to the events function.
However, I found out that when I load the page or change the month viewed by left or right buttons, events function called twice. How can I solve that?
Here is my code:
function CalendarCtrl($scope, Data){
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
// Stores all events
var events = [];
/* config object */
$scope.uiConfig = {
calendar:{
height: 450,
editable: true,
header: {
left: 'prev,next',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
buttonText: {
month: "Ay",
week: "Hafta",
day: "Gün",
list: "Ajanda"
},
allDayText: "Tüm gün",
eventLimitText: "daha fazla",
firstDay: 1,
timeFormat: 'H:mm',
axisFormat: 'H:mm',
lazyFetching: true,
// Here listen for calendar change events
events: getEvents
}
};
// For angular ui-calendar element
$scope.eventSources = [];
// Calendar event handlers
function getEvents(from, to, callback){
console.log(from); // For test purposes
// Request for data from server and when it comes, call callback to update calendar
Data.calendar.get(moment(from).unix(), moment(to).unix()).then(function(events){
angular.forEach(events, function(event){
event.start = moment.unix(event.start);
if(event.end){
event.end = moment.unix(event.end);
}
else{
delete event.end;
}
var d = event.start;
if(d.hour() == 0 && d.minute() == 0 && d.second() == 0){
event.allDay = true;
}
if(event.important){
event.className = "important-event";
}
event.editable = true;
});
callback(events);
});
}
I have the solution.
Instead of registering an event handler to $scope.uiConfig.calendar.events, register that same function to $scope.eventSources array. Like that:
$scope.eventSources = [getEvents];
Whenever view changes and calendar needs data it will look at the $scope.eventSources elements. And if an element is a function it will be called and results will be shown in calendar.
We ran into a similar problem in a project and our solution was also in the eventSource initialization putting an empty object inside the array.
$scope.eventSources = [{}];
I have a code here of my datetimepicker which will take away specific hours by date.
var specificDates = ['24/12/2014', '17/12/2014'];
var hoursToTakeAway = [[14, 15],[17]];
$('#from_date').datetimepicker({
format: 'd.m.Y H:i',
timepicker: true,
lang: 'en',
onGenerate: function (ct, $i) {
var ind = specificDates.indexOf(ct.dateFormat('d/m/Y'));
$('.xdsoft_time_variant .xdsoft_time').show();
if (ind !== -1) {
$('.xdsoft_time_variant .xdsoft_time').each(function (index) {
if (hoursToTakeAway[ind].indexOf(parseInt($(this).text())) !== -1) {
$(this).hide();
}
});
}
}
});
My problem is how to manipulate it dynamically like this:
if I select in my datetimepicker:
07/05/2015 -take away hours: 1,2
13/05/2015 -take away hours: 3,4,5
How would I do that?
I've developed a jQuery datepicker instance using the following code.
$(function() {
$('.datepicker').datepicker({
inline: true,
showButtonPanel: true, //Default Button Panel is customized in jQuery UI Soucre - Line Number : 9265
showOtherMonths: true,
showOn: "both",
buttonImage: "/images/calendar.png",//custom icon trigger -> positioned in CSS
buttonImageOnly: true,
//beforeShowDay:function(date){
//var blockDates = [""];
//var currentDateString = $.datepicker.formatDate(date);
//return [blockDates.indexOf(currentDateString) == -1 ];
//},
onSelect:function(date,inst){
if(inst.id != "to" && date != ""){
var numOfDays = 2;
var date = $.datepicker.parseDate('mm/dd/yy', date);
date.setDate(date.getDate('mm/dd/yy') + numOfDays);
setTimeout(function () {
$("#to").datepicker('option', 'minDate', date);
$("#to").datepicker('show');
$("#to").datepicker('setDate',date.toLocaleDateString());
}, 10);
}
}
});
});
I've got two inputs with datepicker instances. In the first I select a date and by using the date I populate the second date. When I test this on a desktop and I get the correct date. But the thing is I tested this on an iPad and the calculated date is not advanced by two days. the date is advanced by 7 months! I have no idea what's wrong with the code! any help?
I've tested in both safari + google chrome for ipad. the result is same.
Date.getDate() does not accept any parameters.
datepicker.setDate() happily accepts the JavaScript Date
Try revising your code like this:
onSelect: function (date, inst) {
if (inst.id != "to") {
var numOfDays = 2;
var date = $.datepicker.parseDate("mm/dd/yy", date);
date.setDate(date.getDate() + numOfDays);
$("#to").datepicker("option", "minDate", date);
$("#to").datepicker("setDate", date);
setTimeout(function () {
$("#to").datepicker("show");
}, 10);
}
}