jQuery beforeShowDay function - javascript

Please can someone please explain how this code works? It's a trivial piece of code but I don't understand/appreciate how the Option
beforeShowDay
, that calls a function works.
The DisableDates Option calls function DisableDates(date) (that seemingly) takes in a date parameter - and I can't understand how this date parameter is being passed?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link
rel="stylesheet"
href="http://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"
/>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
<div id="date"></div>
<script>
$(function () {
var dates = ["08/11/2020", "09/11/2020", "10/11/2020", "12/11/2020"];
$("#date").datepicker({
changeYear: true,
changeMonth: true,
dateFormat: "yy/mm/dd",
minDate: new Date("2020/10/01"),
maxDate: "+3m",
beforeShowDay: DisableDates,
});
function DisableDates(date) {
var string = jQuery.datepicker.formatDate("dd/mm/yy", date);
return [dates.indexOf(string) == -1];
}
});
</script>
</body>
</html>

jQuery datepicker internally calling that function and passing parameter also.
Consider below small demo where you can assign your function to another variable and use that variable to call your function with parameter.
// plugin sample code with options
function demo(options) {
// assign option values to plugin variables.
this.date = options.date;
this.beforeShowDay = options.beforeShowDay;
// trigger function which invoke callback function with parameters
this.triggerBeforeShowDay = function() {
// as we have this.beforeShowDay = options.beforeShowDay;
// below code will be same as DisableDates(this.date)
this.beforeShowDay(this.date);
}
// return plugin object
return this;
}
// Your callback function with parameter
function DisableDates(date) {
console.log(date)
}
// pass options values in plugin
let d = new demo({
date: new Date("2020/10/01"),
beforeShowDay: DisableDates
});
// trigger function : Note - this part would be done internally on text change event from jquery datepicker.
// For demo only we are manually calling it.
d.triggerBeforeShowDay();

Related

Dynamic date blockouts jquery datepicker

I have a custom appointment form with multiple locations. On Sundays all locations are closed. On Saturdays only a few locations are open. One location is so busy that all appointments need to be 1 week in advance at the very least.
I was finding answers saying, "You cannot update the current picker. You need to destroy it, set the reserved dates in an array, and rebuild the datepicker with those options.", which meant duplicating the datepicker that's on the custom form with all it's odd regional formats and options.
Then, after telling everyone it's going to be more work than it's worth I found out you can just out the next 7 days dynamically with:
$('input.datepicker').datepicker( 'option', 'minDate', '+7d');
That works! Then also found you could tell the current datepicker to switch to today's date with this:
$('input.datepicker').datepicker('setDate', 'today');
So can I get a live datepicker to hide weekends? I should be able to but the option I found fails:
$('input.datepicker').datepicker({ beforeShowDay: jQuery.datepicker.noWeekends });
I really want to be able to say, "no weekends" or "no sundays", without destroying and rebuilding, but it's not a popular topic since most forms don't need to update the datepicker dynamically.
Here's a simple fiddle of what I'd like to accomplish: https://jsfiddle.net/56qsau34/
EDIT: So I was really close but I had the wrong method(?) for applying an update to the live datepicker. If you take the last guess and write it properly it works!
$('input.datepicker').datepicker( 'option', 'beforeShowDay', jQuery.datepicker.noWeekends );
EDIT #2: Just for the poor soul that finds this without the final solution. When you realize that you need to 'toggle' the noWeekends feature this function that returns all the dates with 'true' will come in real handy:
$('input.datepicker').datepicker('option', 'beforeShowDay', function(d) {
var year = d.getFullYear(),
month = ("0" + (d.getMonth() + 1)).slice(-2),
day = ("0" + (d.getDate())).slice(-2);
var formatted = year + '-' + month + '-' + day;
//is it a sunday - this was the missing bit for all my specs
if (d.getUTCDay() != 0) {
return [true, "",""];
}else{
return [false, "",""];
}
}
Yes, you can change the options without destroying the widget.
$.datepicker.noSundays = function (date) {
return [ date.getDay() != 0, "" ];
}
$("#foo").click(function() {
$("input").datepicker();
});
$("#nowknd").click(function() {
$("#datepicker").datepicker('option', 'beforeShowDay', $.datepicker.noWeekends);
});
$("#okwknd").click(function() {
$("#datepicker").datepicker('option', 'beforeShowDay', '');
});
$("#nosuns").click(function() {
$("#datepicker").datepicker('option', 'beforeShowDay', $.datepicker.noSundays);
});
$("#weekblock").click(function() {
$("#datepicker").datepicker('option', 'minDate', '+7d');
});
<link href="https://code.jquery.com/ui/1.12.1/themes/smoothness/jquery-ui.css" rel="stylesheet" type="text/css" />
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<p>Date:<input type="text" id="datepicker"></p>
<p>
<button id="foo">Make it a datepicker</button>
<button id="nowknd">Block weekends</button>
<button id="okwknd">Allow weekends</button>
<button id="nosuns">Block Sundays</button>
<button id="weekblock">Block off a week</button>
</p>
Does this help?
Can the jQuery UI Datepicker be made to disable Saturdays and Sundays (and holidays)?
weekends visible but not selectable.
<!doctype html>
<html class="no-js" lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!--
want to hide weekends from calendar
https://stackoverflow.com/questions/501943/can-the-jquery-ui-datepicker-be-made-to-disable-saturdays-and-sundays-and-holid
-->
<title>jQuery UI Datepicker - Disable the Selection of some days </title>
<link href="jquery-ui-1.10.3.css" rel="stylesheet">
<script
src="https://code.jquery.com/jquery-2.2.0.min.js"
integrity="sha256-ihAoc6M/JPfrIiIeayPE9xjin4UWjsx2mjW/rtmxLM4="
crossorigin="anonymous"></script>
<script
src="https://code.jquery.com/ui/1.10.3/jquery-ui.min.js"
integrity="sha256-lnH4vnCtlKU2LmD0ZW1dU7ohTTKrcKP50WA9fa350cE="
crossorigin="anonymous"></script>
<script type="text/javascript">
$(function () {
$(".datepicker1").datepicker({
beforeShowDay: $.datepicker.noWeekends
});
});
</script>
</head>
<body>
<h3>Click in the TextBox to select a date :</h3>
<p>weekends are not selectable</p>
<input type="text" class="datepicker1" />
</body>
</html>

passing variables to function with jquery

I'm new to javascript although I do use PHP.
I'm having issues passing variables using javascript/jquery on an onclick event on a href.
I'm pulling json data from a remote URL and there are 3 parameters that need to go with each request.
Date, price and currency.
I have a function to build the URL that looks like this:
function getIndexData(date, price, currency){
ajaxURL = "/data/"+date+"/"+price+"/"+currency+"";
}
This works well and builds the URL I need.
However, I have a jquery datepicker on the page to change the date to whatever I want which looks like:
$(function () {
$("#datepicker").datepicker(
{
dateFormat: 'yymmdd',
onSelect: function (date) {
getIndexData(date, price, currency )
}
}
);
});
Even if price and currency have previously been set they are now 'undefined'.
I have the same issue with the onclick events - if I try to send the price or the currency using (for example):
NET</span>
price and currency are undefined.
Is there a way I can send only one of the variables to my function whilst retaining the already existent values?
Apologies for what must be a really basic question. I'm just new to this and I've obviously misunderstood something along the way.
Ok so here is the updated answer. As you can see, if variables are declared in the global scope of the code, the date picker function will have access to it. I think it previously did not work because the html was wrong. I deleted all of the html and included only the date picker and if you test it in the browser, you will see that in the console the price, currency variables are available inside date picker onSelect function and you can also execute the function getIndexData inside it. I've assigned the function to a variable that way you can use the variable getIndexData if you want to use the function.
<html>
<head>
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
<div class="col-sm-5 index-grid">
<span class="grid-label">Price</span>
<span class="btn btn-grid">CLOSE</span>
<span class="btn btn-grid">RETURN</span>
<span class="btn btn-grid">NET</span>
</div>
<p>Date: <input type="text" id="datepicker"></p>
</body>
</html>
<script>
var ajaxURL;
var indexDate = "2017-08-20"
var indexPrice = "closeprice";
var indexCurrency = "EUR";
var getIndexData = function (indexDate, indexCurrency, indexPrice) {
ajaxURL = "/data/" + indexDate + "/" + indexPrice + "/" + indexCurrency + "";
alert(ajaxURL);
}
$(document).ready(function() {
$(function() {
$("#datepicker").datepicker({
dateFormat: 'yymmdd',
onSelect: function(date) {
console.log(date);
console.log(indexPrice);
console.log(indexCurrency);
console.log(getIndexData);
}
});
});
});
</script>
If you declared price and currency outside of :
$(function () {
$("#datepicker").datepicker(
{
dateFormat: 'yymmdd',
onSelect: function (date) {
getIndexData(date, price, currency )
}
}
);
});
Then what you need to do is use the "this" keyword to access the values of price and currency. Just like the example below.
You may also want to check this link for more insight : https://javascriptplayground.com/blog/2012/04/javascript-variable-scope-this/
$(function () {
$("#datepicker").datepicker(
{
dateFormat: 'yymmdd',
onSelect: function (date) {
getIndexData(date, this.price, this.currency )
}
}
);
});

Fullcalendar dynamic data parameter and elaborate response

I'm using fullcalendar with events retrieved by ajax call. The URL has a dynamic parameter that is the room id because I would like to show the calendar based on room choice. I have two problems:
events is called before the user can choose the room (room selection and calendar is loaded at the same time), so the ajax URL is not valid because there isn't the room id. Is it possible to avoid the first loading?
The ajax response is in a particolar format like this:
{
"status":true,"success":true,"result":
[
{
"id":2,"title":"test","start":"2017-07-06T10:30:00","end":"2017-07-06T11:30:00"
},
{
"id":3,"title":"test","start":"2017-07-07T16:30:00","end":"2017-07-07T17:30:00"
}
],
"error":null
}
so I have to use only result field but eventDataTransform doesn't work with a JSON different from event format. Do you know if is it possible to elaborate the response before using it for the event?(I also use status and error to show message)
This is my actual code:
var calendar = $('#calendar').fullCalendar({
selectOverlap: false,
height: 600,
defaultView: 'agendaDay',
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaDay'
},
slotMinutes: 30,
minTime: '08:00:00',
maxTime: '18:00:00',
firstDay: 1,
editable: true,
weekends: false,
//this allow the click on month agenda and go to day agenda
dayClick: function(date, jsEvent, view) {
if(view.name == 'month') {
$('#calendar').fullCalendar('changeView', 'agendaDay');
$('#calendar').fullCalendar('gotoDate', date);
}
},
eventDataTransform: function(eventData){
return eventData.result;
},
//load room reservation
events: {
url: '/booking/reservation/',
data: function () { // a function that returns an object
return {
idRoom: bookingForm.room,
};
}
}
});
bookingForm.room is loaded on select event:
roomTable.off('select')
.on( 'select', function ( e, dt, type, indexes ) {
bookingForm.room = roomTable.rows( indexes ).data().toArray()[0].idRoom;
$("#calendar").fullCalendar("refetchEvents");
} );
It is possibile to avoid the first loading?
Sure, simply don't set the events property and load the events later with addEventSource
See following example please:
var source =
[
{
title : 'event1',
start : '2017-07-01'
},
{
title : 'event2',
start : '2017-07-05',
end : '2017-07-07'
},
{
title : 'event3',
start : '2017-08-09T12:30:00',
allDay : false
}
];
$(document).ready(function() {
$("#calendar").fullCalendar();
});
$("#btnLoadEvents").click(function(){
$("#calendar").fullCalendar("addEventSource", source);
});
<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.6.1/fullcalendar.min.css">
<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.6.1/fullcalendar.print.css">
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.12.0/moment.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.6.1/fullcalendar.min.js"></script>
<button type="button" id="btnLoadEvents">Load events</button>
<div id="calendar" />
Do you know if is it possible to elaborate the response before use it for the event?
Yes, get the events from your custom ajax response:
var customAjaxResponse = {"status":true,"success":true,"result":[{"id":2,"title":"test","start":"2017-07-06T10:30:00","end":"2017-07-06T11:30:00"},{"id":3,"title":"test","start":"2017-07-07T16:30:00","end":"2017-07-07T17:30:00"}],"error":null};
var source = customAjaxResponse.result;
Then add the source to the calendar:
$("#calendar").fullCalendar("addEventSource", source);
See the final result:
var customAjaxResponse = {"status":true,"success":true,"result":[{"id":2,"title":"test","start":"2017-07-06T10:30:00","end":"2017-07-06T11:30:00"},{"id":3,"title":"test","start":"2017-07-07T16:30:00","end":"2017-07-07T17:30:00"}],"error":null};
var source = customAjaxResponse.result;
$(document).ready(function() {
$("#calendar").fullCalendar();
});
$("#btnLoadEvents").click(function(){
$("#calendar").fullCalendar("addEventSource", source);
});
<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.6.1/fullcalendar.min.css">
<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.6.1/fullcalendar.print.css">
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.12.0/moment.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.6.1/fullcalendar.min.js"></script>
<button type="button" id="btnLoadEvents">Load events</button>
<div id="calendar" />
Note: You could add events dynamically whenever you want, although other events are already present on the calendar (try to click many times on the buttons in the above example).
I hope it helps you, ciao Luca.
Updated: How to hide/show events with a specific filter:
For each single event you can check whether it's to be displayed or not, with a function on eventRender, like following:
eventRender: function (event, element, view) {
var roomId = getRoomIdFromEvent(event.id);
return $("#chkRoom" + roomId).is(':checked');
},
So, when the function returns true the event will be displayed otherwise it will be hidden.
Finally, when the filters change you have to refresh the calendar:
$(mySelector).click(function(){
$("#calendar").fullCalendar("refetchEvents");
};
See following please:
var customAjaxResponse = {"status":true,"success":true,"result":[{"id":2,"title":"test","start":"2017-07-06T10:30:00","end":"2017-07-06T11:30:00", "room": 1},{"id":3,"title":"test","start":"2017-07-07T16:30:00","end":"2017-07-07T17:30:00", "room": 2}],"error":null};
var source = customAjaxResponse.result;
$(document).ready(function() {
$("#calendar").fullCalendar({
eventRender: function (ev, el, v) {
console.log(ev);
var roomId = ev.room;
return $("#cmdRoom").val()==roomId;
}
});
$("#calendar").fullCalendar("addEventSource", source);
});
$("#cmdRoom").change(function(){
$("#calendar").fullCalendar("refetchEvents");
})
<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.6.1/fullcalendar.min.css">
<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.6.1/fullcalendar.print.css">
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.12.0/moment.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.6.1/fullcalendar.min.js"></script>
<select id="cmdRoom">
<option value="1">Room one</option>
<option value="2">Room two</option>
</select>
<div id="calendar" />
I resolved with Fullcalendar events as a function where I can elaborate each single event field. This is my final code
success: function(doc) {
if (doc.status && doc.success && bookingForm.room){
var events = [];
var color = [];
for (index = 0; index < doc.result.length; ++index) {
//change the color if user is the owner of event
if (doc.result[index].owner == document.getElementById('username').innerHTML)
color = '#3c8dbc';
else
color = '#FF0000';
events.push({
editable: false,
id: doc.result[index].id,
title: doc.result[index].title,
start: doc.result[index].start,
end: doc.result[index].end,
color: color,
});
}
callback(events);
}
}
instead the first call to web service has done with a roomId initialize with -1 so it return no result

Using a Javascript Date Selector in Qualtrics survey - carry date to the survey field

I'm trying to input a date selector tool so that a survey respondent can input a date by clicking on the field, a calendar will pop up, they can select the date, and the date will be inputted to the Qualtrics question text box.
Qualtrics has their own calendar tool available, but the issue is that the calendar is always visible. I only want the calendar to be visible when they either click the text box itself or a calendar icon (either would be fine). Here's the Qualtrics code:
Enter a date:
<link href="https://ajax.googleapis.com/ajax/libs/yui/2.9.0/build/calendar/assets/skins/sam/calendar.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/yui/2.9.0/build/yahoo-dom-event/yahoo-dom-event.js"></script> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/yui/2.9.0/build/calendar/calendar-min.js"></script> <script>
Qualtrics.SurveyEngine.addOnload(function ()
{
var qid = this.questionId;
var calid = qid + '_cal';
var y = QBuilder('div');
$(y).setStyle({clear:'both'});
var d = QBuilder('div',{className:'yui-skin-sam'},[
QBuilder('div', {id:calid}),
y
]);
var c = this.questionContainer;
c = $(c).down('.QuestionText');
c.appendChild(d);
var cal1 = new YAHOO.widget.Calendar(calid);
cal1.render();
var input = $('QR~' + qid);
$(input).setStyle({marginTop: '20px',width: '150px'});
var p =$(input).up();
var x = QBuilder('div');
$(x).setStyle({clear:'both'});
p.insert(x,{position:'before'});
cal1.selectEvent.subscribe(function(e,dates){
var date = dates[0][0];
if (date[1] < 10)
date[1] = '0' + date[1];
if (date[2] < 10)
date[2] = '0' + date[2];
input.value = date[1] +'-'+date[2]+'-'+date[0];
})
});
</script>
Here's the calendar tool that I'd like to use, but I can't figure out how to get the date to feed into the Qualtrics field text box.
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Datepicker - Default functionality</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script>
$( function() {
$( "#datepicker" ).datepicker();
} );
</script>
</head>
<body>
<p>Date: <input type="text" id="datepicker"></p>
</body>
</html>
Your problem is that in Qualtrics $ refers to prototypejs, not jQuery. So, you need to do something like:
$j = jQuery.noconflict();
$j( function() {
$j( "#datepicker" ).datepicker();
} );
However, that may not work if the datepicker code is itself using $ to refer to jQuery.
I've used https://github.com/joshsalverda/datepickr successfully with Qualtrics.
EDIT:
To implement datepickr in Quatrics:
Add datepickr script to Qualtrics header (you can upload the file to Qualtrics then get the url of the file to add to the header in a script tag)
Add datepickr CSS to Qualtrics custom CSS
Add JavaScript to your question to add datepickr to an input element (e.g., datepickr($(this.questionId).down('.InputText')), {dateFormat: 'm/d/Y'});
Add this JavaScript to the field to use a plain HTML date input (no jQuery required).
Qualtrics.SurveyEngine.addOnload(function() {
var textInputs = this.questionContainer.querySelectorAll('input[type="text"]');
if (typeof textInputs[0] !== 'undefined') {
textInputs[0].type = 'date';
}
});

the 1st click of button validates data in a CKeditor, for the second click it does not take the modified data

I am validating data present in CKeditor on a button click event using jquery. After the button click it separates the list of correct answers and wrong answers. This works fine. But after modifying the wrong answers and hit the button, it again takes the initially entered values. How to make it take the modified data on the 2nd button click.
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type="text/javascript" src="../ckeditor/ckeditor.js"></script>
<script src="../ckeditor/jquery.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
CKEDITOR.replace('Field');
var correctZips = new Array;
var wrongZips = new Array;
var CorZip;
var WorZip;
$('#save').click(function () {
var editor_data = CKEDITOR.instances['Field'].getData();
var element = $(editor_data).text().split(",");
$.each((element), function (index, value) {
if(this.length=5 && jQuery.isNumeric(this)) {
correctZips= correctZips+"<span>"+this+"</span>"+",";
}else {
wrongZips= wrongZips+"<span id='flip' style=\"background-color: yellow; \">"+this+"</span>"+",";
}
}
)
CKEDITOR.instances.Field.setData((correctZips + wrongZips), function (index, value){
})
//$("#save").attr("disabled", "disabled");
});
});
</script>
</head>
<body>
<textarea id="Field"></textarea>
<button id ="save">Verify the ZipCodes</button>
</body>
</html>
Regards,
Steven
You are deinfing the 2 ZIPS variables as arrays outside of the click handler. You need to reset them for each time a click occurs so they need to be defined inside the handler and they shouldn't be defined as arrays since you are using them to concatenate strings
$('#save').click(function () {
var correctZips = '', wrongZips='';/* start with empty strings*/
/* remainder of your handler code*/
});

Categories

Resources