How to prevent tabulator input to close when clicking elsewhere - tabulator

I have a custom datepicker calendar I want to show for editing dates in tabulator. I have managed to open the calendar when the row cell is click by providing a custom editor.
The problem is that as soon as I click on my calendar, (what I think happens) is that Tabulator´s "As a fallback Tabulator will cancel the edit if an editor is blured and the event has not been correctly handled." behavior triggers before I can process the click on my calendar and update the cell value.
Is there a way to allow the user to click on the calendar without making tabulator cancel the edit?

Don't know which custom date picker you are using but here is a working example using flatpickr:
let initialTableData = [{
eventName: "Christmas party",
eventDate: "12-25-2021"
},
{
eventName: "New Years party",
eventDate: "12-31-2021"
}
]
function dateEditor(cell, onRendered, success, cancel, editorParams) {
let editor = document.createElement("input")
editor.value = cell.getValue()
let datepicker = flatpickr(editor, {
dateFormat: "m-d-Y",
onChange: setDate,
onClose: setDate
})
function setDate(selectedDates, dateStr, instance) {
success(dateStr)
instance.destroy()
}
onRendered(() => {
editor.focus()
})
return editor
}
let eventTable = new Tabulator("#eventTable", {
data: initialTableData,
columns: [{
title: "Event",
field: "eventName",
width: 200
},
{
title: "Event Date",
field: "eventDate",
editor: dateEditor
}
]
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/tabulator/5.0.7/js/tabulator.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/flatpickr/4.6.9/flatpickr.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/tabulator/5.0.7/css/tabulator.min.css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css" rel="stylesheet" />
<div id="eventTable"></div>
Here is the CodePen

Related

v-data-table button loading per row

Using vue v2.5 with vueCLI 3 trying to have a v-data-table that on each row have a button, when this button clicked should make it appear as loading.
v-btn has loading property by default, really I don't know why is not working...
<v-data-table
:headers="headers"
:items="records"
#dblclick:row="editRowCron_jobs">
<template v-slot:[`item.actions`]="props">
<v-btn color="blue-grey" :loading="props.item.createloading" fab dark small #click="ManuralRun(props.item)">
<v-icon dark>mdi-google-play</v-icon>
</v-btn>
</template>
</v-data-table>
On the click method, I can read but not set the item
export default {
data() {
return {
headers: [
{ text: "id", value: "id", align: " d-none" },
{ text: "actions", value: "actions" }
],
records: [] //grid rows filled by API
}
},
methods: {
ManuralRun(item){
this.records[2].createloading=true; //even I set it like that, nothing happens
item.createloading = true; //property changed here - ok
console.log(item); //here outputs the clicked item - ok
},
so, according to this
the property MUST pre-exist in the array, that means, when we get the result from the API, we have to add the property as:
this.records = data.data.map(record => {
return {
createloading: false,
...record
}
})

Sharepoint survey: Dynamically update lookup

I currently am working on designing a Sharepoint survey.
The first question is a lookup from a list, which looks like this:
Course1
Course2
Course3
Course4
Now, the user has to select one of these answers. While I got the lookup working, I have problem in updating the list.
the idea is, that the user can add his own courses to complement the list.
So for example, he can select OTHER and type in Course5 into a textbox, which should then be added to the list. The next user should then be able to select Course5 from the drop down list.¨
I have problems writing the result of a survey into the list - is this even possible?
Kind regards.
In choice field, it provide the 'fill-in' feature, unfortunately, the lookup column can't provide this feature.
As a workaround, we can using jQuery append a textbox and a button in the lookup column below in the newform.aspx page. Add some text in the textbox and click the "Add" button, then add data to the lookup list. The following example for your reference:
<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script type="text/javascript">
var questionTitle="question1";
var lookupListName="CL30";
$(function(){
$("select[title='"+questionTitle+"']").closest("td").append("<input id='lookupitemTitle' type='text'/> <input id='addlookupitembtn' type='button' value='Add'>");
$("#addlookupitembtn").click(function(){
if($("#lookupitemTitle").val().trim()!=""){
AddListItem(lookupListName);
}
});
});
function AddListItem(listName){
var itemType = GetItemTypeForListName(listName);
var item = {
"__metadata": { "type": itemType },
"Title": $("#lookupitemTitle").val()
};
$.ajax({
url: _spPageContextInfo.siteAbsoluteUrl + "/_api/web/lists/getbytitle('" + listName + "')/items",
type: "POST",
contentType: "application/json;odata=verbose",
data: JSON.stringify(item),
headers: {
"Accept": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val()
},
success: function (data) {
var item=data.d;
$("select[title='"+questionTitle+"']").append("<option selected='selected' value='"+item.ID+"'>"+item.Title+"</option>");
},
error: function (data) {
alert("Error");
}
});
}
function GetItemTypeForListName(name) {
return "SP.Data." + name.charAt(0).toUpperCase() + name.split(" ").join("").slice(1) + "ListItem";
}
</script>

Liferay 7 date picker does not trigger onChange

I added this AUI date picker to my JSP:
<aui:input
type="text"
id="myDate"
name="my-date"
value="2017-12-14"
placeholder="yyyy-mm-dd"
onChange="javascript:alert('date changed');"/>
<aui:script>
AUI().use(
'aui-datepicker',
function(A) {
new A.DatePicker(
{
trigger: '#<portlet:namespace/>myDate',
mask: '%Y-%m-%d',
popover: {
zIndex: 1000
}
}
);
}
);
</aui:script>
Problem: Changing the date using the calendar widget that pops up does not display the alert.
If I ignore the widget and change the date manually (using the keyboard), the alert correctly shows up as soon as the input loses focus.
What am I doing wrong?
How to have onChange be called whenever the date is changed, be via mouse or keyboard?
As the guys in the comments mentioned use the js callback definitions. There are a couple of examples in the documentation.
https://alloyui.com/examples/datepicker
If you really want to have the onChange also there, you can trigger the change event from the js callback code.
<button class="btn btn-primary"><i class="icon-calendar icon-white"></i> Select the date</button>
<script>
YUI().use(
'aui-datepicker',
function(Y) {
new Y.DatePicker(
{
trigger: 'button',
popover: {
zIndex: 1
},
on: {
selectionChange: function(event) {
console.log(event.newSelection)
}
}
}
);
}
);
</script>

Single calendar Date Range Picker

I am looking to build a date range picker that's values only consist of January-December of a single year at a time.It will look something like this:
(This is taken from my existing kendo date range picker and poorly photoshopped)
I have built one using the kendo date picker but it seems to require two calendars, one for start date and the other for end date. Being that my range can only span months in a single year, I just need one calendar like below where the user can either click and drag for the desired range, or they can just click two dates. Does anyone know of a date range picker that already functions this way? Or if there is a way to alter the kendo one to do the same?
Thanks.
Edit: Here is my code for my existing date range picker:
var start = $("#StartDate").kendoDatePicker({
value: LastMonthString,
format: "MM/yyyy",
start: 'year',
depth: 'year',
change: startChange,
open: function() {
$('#StartCalendar').append($('#StartDate_dateview'));
},
close: function(e) {
e.preventDefault();
}
}).data("kendoDatePicker");
var end = $("#EndDate").kendoDatePicker({
value: TodaysDateString,
format: "MM/yyyy",
start: 'year',
depth: 'year',
change: endChange,
open: function() {
$('#EndCalendar').append($('#EndDate_dateview'));
},
close: function(e) {
e.preventDefault();
}
}).data("kendoDatePicker");
start.max(end.value());
end.min(start.value());
$("#StartDate").attr("readonly", true);
$("#EndDate").attr("readonly", true);
start.open();
end.open();
This is how I've made it to show years only but you can change the format obviously
$('#sandbox-container').datepicker({
format: "yyyy",
startView: 1,
viewMode: "years",
minViewMode: "years",
minViewMode: "years",
multidate: true,
multidateSeparator: ", ",
autoClose: true,
}).on("changeDate",function(event){
var dates = event.dates, elem = $('#sandbox-container');
if(elem.data("selecteddates") == dates.join(",")) return; //To prevernt recursive call, that lead to lead the maximum stack in the browser.
if(dates.length>2) dates=dates.splice(dates.length-1);
dates.sort(function(a,b){return new Date(a).getTime() - new Date(b).getTime()});
elem.data("selecteddates",dates.join(",")).datepicker('setDates', dates);
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.7.1/css/bootstrap-datepicker.min.css" rel="stylesheet" type="text/css" media="screen">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.7.1/js/bootstrap-datepicker.min.js"></script>
<div id="sandbox-container">
<input type="text" id="date" value="">
</div>

Dgrid + Selection Issue

Still trying to work with Dgrid (0.4) and dojo (1.10), I have now another issue with the selection.
My web page contain a Dialog opened when you click on a button.
Inside this dialog, we have the following code which display a grid with data coming from a database through a Json HTTP page. This is working fine, even sorting and query filtering.
What I want to do know is to allow the user to double click on a row, get the selected row Id contains in the first column to update the form in the main page. I use the dgrid/selection for this. However, it always return the last row of the grid instead of the one the user selected.
The selection code is based on this :
http://dgrid.io/tutorials/0.4/hello_dgrid/
Any idea?
Thanks
<script language="javascript">
require
(
[
"dojo/_base/declare",
"dojo/_base/array",
"dgrid/OnDemandList",
"dgrid/OnDemandGrid",
"dgrid/Keyboard",
"dgrid/Selection",
"dgrid/Editor",
"dgrid/extensions/ColumnHider",
"dstore/Memory",
"dstore/RequestMemory",
"dojo/_base/lang",
"dojo/dom-construct",
"dojo/dom",
"dojo/on",
"dojo/when",
"dojo/query",
"dojo/store/Observable",
"dstore/Rest",
"dojo/_base/Deferred",
"dojo/store/Cache",
"dojo/domReady!",
],
function(
declare, arrayUtil, OnDemandList, OnDemandGrid, Keyboard, Selection, Editor, ColumnHider, Memory, RequestMemory, lang, ObjectStore, dom, on, when, query, Observable, Rest, Deferred
){
var fform = dom.byId("filterForm");
var ContactColumns = [
{ label: "", field: "contact_id", hidden: true, unhidable: true},
{ label: "Company Name", field: "company_name", unhidable: true },
{ label: "Contact Name", field: "contact_name", unhidable: true },
{ label: "Email", field: "contact_email", unhidable: true }
];
var ContactGrid=declare([OnDemandGrid, Keyboard, Selection,ColumnHider]);
var contactlist = new Observable(new Rest({ target: './ajax.contactsLoader.php' }));
var selection = [];
window.contactgrid = new ContactGrid(
{
className: "dgrid-selectors",
collection: contactlist,
maxRowsPerPage:10,
selectionMode: 'single',
cellNavigation: false,
columns: ContactColumns
}, "contacttable"
);
on(fform, "submit", function (event) {
var cpy_filter = fform.elements.fcompany_name.value;
var ct_filter = fform.elements.fcontact_name.value;
var email_filter = fform.elements.fcontact_email.value;
contactgrid.set('collection',contactlist.filter({contact_name: ct_filter, company_name: cpy_filter, contact_email: email_filter }));
contactgrid.refresh();
event.preventDefault();
});
contactgrid.on('dgrid-select', function (event) {
// Report the item from the selected row to the console.
console.log('Row selected: ', event.rows[0].data);
});
contactgrid.on('dgrid-deselect', function (event) {
console.log('Row de-selected: ', event.rows[0].data);
});
contactgrid.on('.dgrid-row:click', function (event) {
var row = contactgrid.row(event);
console.log('Row clicked:', row.data);
});
}
);
</script>
<div class="dijitDialogPaneContentArea" style="width:96%;margin-left:5px">
<form id="filterForm">
<div class="dijitDialogPaneActionBar" >
<button data-dojo-type="dijit.form.Button" type="submit">Filter</button>
<button
data-dojo-type="dijit.form.Button"
data-dojo-attach-point="submitButton"
type="submit"
>
Select
</button>
<button
data-dojo-type="dijit.form.Button"
data-dojo-attach-point="cancelButton"
>
Close
</button>
</div>
<div data-dojo-attach-point="contentNode" >
<input type="text" data-dojo-type="dijit.form.TextBox" name="fcompany_name" id="fcompany_name" style="width:33%">
<input type="text" data-dojo-type="dijit.form.TextBox" name="fcontact_name" id="fcontact_name" style="width:32%">
<input type="text" data-dojo-type="dijit.form.TextBox" name="fcontact_email" id="fcontact_email" style="width:33%">
<div id="contacttable">
</div>
</div>
</form>
</div>
Just found the reason.
the columns need to have a 'id' column called ID. I just change the 'contact_id' column to 'id' and it works fine.
thanks

Resources