How do I pick the time in an MUI DateTimePicker using #testing-library/react and #testing-library/user-event? - material-ui

I'm trying to write a test involving the DateTimePicker using #testing-library/react/#testing-library/user-event.
This is how I'm opening the picker and picking a date:
it('test picker', () => {
jest.useFakeTimers().setSystemTime(new Date('2022-12-15T14:03:23Z'));
render((
<LocalizationProvider dateAdapter={AdapterDateFns as any}>
<MyComponentContainingADateTimePicker />
</LocalizationProvider>
));
// Open the picker
userEvent.click(screen.getByRole('button', {name: 'Choose date'}));
// Pick a day in the current month
userEvent.click(screen.getByRole('gridcell', {name: '16'}));
// Pick hours
userEvent.selectOptions(
screen.getByRole('listbox'),
screen.getByRole('option', {name: '20 hours'}),
undefined,
{skipPointerEventsCheck: true},
);
// Pick minutes
userEvent.selectOptions(
screen.getByRole('listbox'),
screen.getByRole('option', {name: '00 minutes'}),
undefined,
{skipPointerEventsCheck: true},
);
});
Problem 1: I have to use skipPointerEventsCheck: true because the listbox and options aren't clickable.
Problem 2: The picker doesn't advance to the minutes when I pick the hours (probably because of problem 1)

Related

applyTransaction remove not working with id

I'm using ag-grid in Angular9 project. I'm using Transactions to do CRUD operations in grid when my backend request resolve. I need to provide RowNodeId myself, i dont want to use object-references as i have large data set.
Thing is, i've provided the ID and i can add/update item in the grid but i'm unable to delete the item. In Doc it mentions, you only need to provide id to remove the item but i'm getting the following error.
Here's the code.
class HostAppListPage
{
#ViewChild('agGrid', {static: true}) grid:AgGridAngular;
constructor()
{
}
ngOnInit()
{
this.grid.getRowNodeId = (data) => {
return data.entityId;
};
this.columns = [
{headerName: 'App Name', field: 'name', rowDrag: true, headerCheckboxSelection: true, checkboxSelection: true},
{headerName: 'App Id', field: 'id'},
{headerName: 'Compatibility', field: COMPATIBILITY'},
{headerName: 'Creation', field: 'createdAtToString'},
{headerName: 'Last Update', field: 'updatedAtToString'}
];
}
deleteRow()
{
let ids = this.gridApi.getSelectedNodes()
// .map((row) => {
// return {id: row.entityId}
// return row.entityId;
// });
console.log(ids);
this.grid.api.applyTransaction({remove: ids});
}
I tried both with and without map statement, nothing worked
but my Add and Update works fine.
Replace map with following code.
.map((row) => {
return {entityId: row.data.entityId};
});
it should be the the same field (entityId) which i set in getRowNodeId function.
In a typical situation, where one does not define a getRowNodeId, one should be able to do:
const removeData: any[] = [{id: rowNode0.id}, {id: rowNode1.id}, ...];
applyTransaction({remove: removeData});
where rowNode0, rowNode1, etc. are the nodes you want to remove.
However when you provide your own getRowNodeId callback, ag-grid will fetch the id's by applying your callback on the data you provided. Therefore, the name(s) in the data must match those used in your callback. That's why return {id: row.entityId} doesn't work, but return {entityId: row.entityId} does.
In other words, if one defines:
this.grid.getRowNodeId = (data) => {
return data.column1 + data.column5 + data.column2;
};
Then one would need to provide
const removeData: any[] = [
{column1: 'a1', column2: 'b1', column5: 'c1'},
{column1: 'a2', column2: 'b2', column5: 'c2'},
{column1: 'a3', column2: 'b3', column5: 'c3'},
];
so that ag-grid would have all the names it needs to find the id's via the given getRowNodeId.

Google Timeline Chart with more than one column role

I am trying to draw a timeline chart and add two column roles, one for an HTML link (tooltip column role) and another for styling (style).
I can use either one of them successfully but not both at the same time.
For example, here's a sample of my code:
var container = document.getElementById('mychart');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'string', id: 'Position' });
dataTable.addColumn({ type: 'string', id: 'Name' });
dataTable.addColumn({ type: 'string', role: 'style' });
dataTable.addColumn({ type: 'date', id: 'Start' });
dataTable.addColumn({ type: 'date', id: 'End' });
dataTable.addColumn({ type: 'string', role: 'tooltip', id: 'link', 'p': {'html': true} });
I believe it has to do with the placement of the columns. In the example above, styling is done correctly but the hyperlink is being formed with the tooltip content instead of the actual column role data I'm passing.
If I remove the style column role the hyperlink works fine, even when placed last in the columns. It's leading me to think that I can't have more than one column role but that's not what the documentation says.
Any clues would be appreciated.
In order to have a column have a clickable hyperlink you an extra piece of code:
google.visualization.events.addListener(chart, 'select', function () {
var selection = chart.getSelection();
if (selection.length > 0) {
window.open(dataTable.getValue(selection[0].row, 3), '_blank');
}
});
My single row of data for debugging purposes was:
dataTable.addRows([
['My text here', 'bar label', '#676767', 'https://www.google.com', new Date(2019, 12, 22), new Date(2019, 12, 26)]]);
I had shuffled the columns around and was pointing to the wrong column. Just had to change to the right column above to get it to work (column 3, being zero-based).

How to use disabledDate in bootstrap datepicker

I wanto to disabled all the dates after a date that a person choose, so I call a function who is doing
$( "#final_date" ).datepicker({ datesDisabled: ['+m'] });
And my datepicker is like that
activeDate() {
$("#initial_date").datepicker({
changeMonth: true,
changeYear: true,
format: 'dd/mm/yyyy',
startView: "days",
minViewMode: "days",
language: 'pt-BR'
});
$("#final_date").datepicker({
changeMonth: true,
changeYear: true,
format: 'dd/mm/yyyy',
startView: "days",
minViewMode: "days",
language: 'pt-BR',
datesDisabled: this.disabledDates
});
}
But only one day after my date is being disabled, what am I doing wrong?????
Given that the goal is to
disable all dates after a date
The bootstrap datepicker documentation says you can do this with maxDate.
Takes a maxDate string, Date, moment, boolean:false parameter and disallows the user to select a moment that is after that moment. If a boolean:false value is passed options.maxDate is cleared and there is no restriction to the maximum moment the user can select. [emphasis mine]
Try this (while passing in your value for final_date):
final_date = '2019-11-11';
$( "#final_date" ).datepicker({ maxDate: final_date });

Calendar control for ionic?

I have managed to find several ionic calendar modules but cannot find any calendar control modules where a user can select from available dates. Is there anything out there?
http://www.clearlyinnovative.com/ionic-framework-custom-formly-template-using-datepicker-plugin
I have used the $cordovaDatePicker plugin successfully here and integrated it with formly in this blog post with a full working project.
here is the plugin - http://ngcordova.com/docs/plugins/datePicker/
module.controller('MyCtrl', function($scope, $cordovaDatePicker) {
var options = {
date: new Date(),
mode: 'date', // or 'time'
minDate: new Date() - 10000,
allowOldDates: true,
allowFutureDates: false,
doneButtonLabel: 'DONE',
doneButtonColor: '#F2F3F4',
cancelButtonLabel: 'CANCEL',
cancelButtonColor: '#000000'
};
document.addEventListener("deviceready", function () {
$cordovaDatePicker.show(options).then(function(date){
alert(date);
});
}, false);
});

Materialize datepicker SelectOnClose not working

I'm trying to create a datepicker with Materialize.
According to the documentation the datepicker should close when the user selects a date.
That's not working in my page. I'm using the latest Chrome browser on Windows. I've tried IE browser, but there's the whole datepicker not showing...
Click here for my page (input 3 and 4 are datepickers)
My javascript:
$('#due_date').pickadate({
monthsFull: [ 'januari', 'februari', 'maart', 'april', 'mei', 'juni', 'juli', 'augustus', 'september', 'oktober', 'november', 'december' ],
monthsShort: [ 'jan', 'feb', 'maa', 'apr', 'mei', 'jun', 'jul', 'aug', 'sep', 'okt', 'nov', 'dec' ],
weekdaysFull: [ 'zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag' ],
weekdaysShort: [ 'zo', 'ma', 'di', 'wo', 'do', 'vr', 'za' ],
today: 'vandaag',
clear: 'verwijderen',
close: 'sluiten',
firstDay: 1,
format: 'dd-mm-yyyy',
formatSubmit: 'yyyy/mm/dd',
closeOnSelect: true,
selectMonths: true, // Creates a dropdown to control month
selectYears: 3, // Creates a dropdown of 15 years to control year
min: new Date()
});
Can anyone help me to fix these datepickers?
Please add below few lines to your code..
onSet: function (ele) {
if(ele.select){
this.close();
}
}
var datePicker = $('.datepicker').pickadate({
onSet: function () {
this.close();
}
});
The developer of materialize thought that it would match Google's date picker if it doesn't close on select according to this issue:
https://github.com/Dogfalo/materialize/issues/870
However you can change the source code of materialize if you don't mind, like this:
https://github.com/Dogfalo/materialize/commit/db0629d30a9d3e5ac06a019955a8e10062f91833
Better Solution: Use if ( 'select' in arg ) condition so that the datepicker dialog wont hide when you select month or year.
$('.datepicker').pickadate({
onSet: function( arg ){
if ( 'select' in arg ){ //prevent closing on selecting month/year
this.close();
}
}
});
i had the same problem and i solved it this way:
$('.datepicker1').pickadate({
selectMonths: true, // Creates a dropdown to control month
selectYears: 15, // Creates a dropdown of 15 years to control year
min: true,
onOpen: function () {
this.clear();
},
onSet: function () {
var x,y,year,date,month;
x = $('.datepicker1').pickadate().val().toString();
y = x.split(/[ ,]+/);
date = y[0];
month = y[1];
year = y[2];
console.log(y[0]+" "+ y[1]+ " "+ y[2]);
if(date && month && year){
this.close();
}
}
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Materialize Datepicker</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.96.1/css/materialize.min.css">
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.96.1/js/materialize.min.js"></script>
</head>
<body>
<form class="col s6">
<label for="To" >To : </label>
<input type="date" id="To" class="datepicker1">
</form>
<script src="site.js"></script>
</body>
</html>
The onSet: function(called when a date is set) ensures the date,month and year are entered and closes only if the date is set.
The onOpen: function(called when the datepicker opens) clears the input when datepicker is opened again, useful in case when the user inputs the wrong date.. Without using this function , the datepicker cant navigate though different months,years without closing..
Hope this solves your problem.
If "closeOnSelect: true" is not working then you can call click event of the close button
HTML code for input element:
<input type='text' id='purchase_date'/>
Js code for the element:
jQuery(document).ready(function(){
$('#purchase_date').pickadate({format: 'yyyy-mm-dd'})
.on('change', function(){
$(this).next().find('.picker__close').click();
});
});
Hope this will solve your problem.
Tested on materializecss 1.0.0: use onSelect callback
$('.datepicker').datepicker({
autoClose: true,
today: 'Today',
clear: 'Clear',
close: 'Close',
format: 'dd/mm/yyyy',
//perform click event on done button
onSelect: function () {
$('.confirmation-btns .datepicker-done').click();
}
});