jQuery UI datepicker onSelectAfter - jquery-ui-datepicker

how can i execute a function after a date was selected? onSelect seems to fire before. i want to check if the selected date has a particular class.
onSelect: function (dateText, inst) {
if($('.ui-state-active').parent().hasClass('express')){
console.log('express click');
}else{
console.log('no express click');
}
}
this doesn't work. Thanks for any hint.

Try this please:
onSelect: function (dateText, inst) {
var day = inst.selectedDay,
mon = inst.selectedMonth,
year = inst.selectedYear;
var el = $(inst.dpDiv).find('[data-year="'+year+'"][data-month="'+mon+'"]').filter(function() {
return $(this).find('a').text().trim() == day;
});
if ( el.parent().hasClass('express')){
console.log('express click');
}else{
console.log('no express click');
}
}

Related

Don't Display Entry Date if Same as previous Entry Date in List

I have a list of entries containing dates. I would like to only display the date if it is different from the previous entry date.
I am reading in the entries from core data and passing them to the method ckEntryDate for determination of whether to display the date. The method is called from inside a list. If the string returned by ckEntryDate is blank (string.isEmpty) I know that the current entry date is the same as the previous date and I don't need to display the date.
There are no errors occurring, but the current entry date is not being saved via userDefaults. I would appreciate any ideas on how to save the current date or how to check for identical dates.
Thanks
struct HistoryView: View {
#EnvironmentObject var userData: UserData
#Environment(\.managedObjectContext) var viewContext
// fetch core data
#FetchRequest(
entity: CurrTrans.entity(),
sortDescriptors: [NSSortDescriptor(keyPath: \CurrTrans.entryDT, ascending: true)]
) var currTrans: FetchedResults<CurrTrans>
var body: some View {
GeometryReader { g in
VStack (alignment: .leading) {
ShowTitle(g:g, title: "History")
ShowHistoryHeader(g: g)
ScrollView (.vertical) {
List {
ForEach(currTrans, id: \.id) { item in
let entryDate = userData.ckEntryDate( item: item)
showRow(g:g, item: item, entryDate: entryDate)
}
.onDelete(perform: deleteItem)
}
}.font(.body)
}
}
}
This method is part of the class UserData: ObservableObject {
// check if history entry date is same as previous date or the first entry
func ckEntryDate( item: CurrTrans) -> (String) {
var outDate: String = ""
var savedDate: String = ""
//read in savedDate
if UserDefaults.standard.string(forKey: "storeDate") != "" {
savedDate = UserDefaults.standard.string(forKey: "storeDate") ?? ""
}else {
savedDate = ""
}
// convert Date? to String
let cdate = item.entryDT ?? Date()
let currDate = cdate.getFormattedDate()
// check if no previous entries
if savedDate.isEmpty {
outDate = currDate
}
else { // savedDate is not blank
if savedDate == currDate {
outDate = ""
}
else { // date entries different
outDate = currDate
}
savedDate = currDate
}
// save savedDate
UserDefaults.standard.set(savedDate, forKey: "saveDate")
return outDate
}
}
extension Date {
func getFormattedDate() -> String {
// localized date & time formatting
let dateformat = DateFormatter()
dateformat.dateStyle = .medium
dateformat.timeStyle = .none
return dateformat.string(from: self)
}
}
Assuming your function ckEntryDate works correctly, you could try this approach of filtering the data at the ForEach:
ForEach(currTrans.filter { "" != userData.ckEntryDate(item: $0) }, id: \.id) { item in
showRow(g:g, item: item, entryDate: userData.ckEntryDate(item: item))
}
You can also try this:
ForEach(currTrans, id: \.id) { item in
let entryDate = userData.ckEntryDate(item: item)
if !entryDate.isEmpty {
showRow(g:g, item: item, entryDate: entryDate)
}
}
I have been looking for a way to persist the current entry date for comparison to the next entry date for checking if the dates are the same.
I discovered that I could do this by simply placing a variable at the top of the class that contains the method ckEntryDate.
class UserData: ObservableObject {
var storedDate: String = ""
So thanks to all who took the time to consider a possible answers.
// check if history entry date is the 1st entry or the same as previous date
func ckEntryDate( item: CurrTrans) -> (String) {
var outDate: String = ""
// initialzie the entry date
let cdate = item.entryDT ?? Date()
let entryDate = cdate.getFormattedDate()
// if savedDate is blank -> no previous entries
if storedDate.isEmpty {
outDate = entryDate
}
else { // savedDate is not blank
if storedDate == entryDate {
outDate = ""
}
else { // date entries different
outDate = entryDate
}
}
storedDate = entryDate
// outDate returns blank or the current date
return (outDate)
}
}

How do I disable future dates when using jQuery datepicker inside Tabulator?

I am attempting to disable future dates on a jQuery datepicker being utilized with Tabulator but to no avail.
var table = new Tabulator("#MyDiv", {
height: "100%",
layout: "fitDataFill",
columns: [
{ title: "Date Worked", field: "DateComp", hozAlign: "center", sorter: "date", editor: dateEditor },
{ title: "Memo", field: "Memo", width: 144, hozAlign: "left", editor: "input" },
]
});
var dateEditor = function (cell, onRendered, success, cancel) {
var cellValue = moment(cell.getValue(), "MM/DD/YYYY").format("YYYY-MM-DD");
input = document.createElement("input");
input.setAttribute("type", "date");
input.style.padding = "4px";
input.style.width = "100%";
input.style.boxSizing = "border-box";
input.value = cellValue;
onRendered(function () {
input.style.height = "100%";
//$(input).datepicker({ endDate: new Date() });
$(input).datepicker({ maxDate: 0 });
input.focus();
});
function onChange() {
if (input.value != cellValue) {
success(moment(input.value, "YYYY-MM-DD").format("MM/DD/YYYY"));
} else {
cancel();
}
};
//submit new value on blur or change
input.addEventListener("blur", onChange);
//submit new value on enter
input.addEventListener("keydown", function (e) {
if (e.keyCode == 13) {
onChange();
}
if (e.keyCode == 27) {
cancel();
}
});
return input;
};
I have attempted a couple of fixes by tweaking the datepicker options list (e.g. maxDate and endDate) but nothing seems to work. The future dates on the datepicker are selectable regardless. Is this a Tabulator issue? Or, a jQuery issue?
I have found similar questions regarding use of the jQuery datepicker on other forums and the recommended solutions always seem to revolve around use of the maxDate and endDate options.
Any assistance is greatly appreciated.
It looks like there is an issue using the datepicker inside of the cell, that I couldn't figure out. An error is thrown about the instance data missing.
Here is an example using flatpickr instead of the jQuery datepicker.
https://jsfiddle.net/nrayburn/65t1dp23/49/
The two most important parts are including a validator, so that users cannot type in a date. (I don't think they ever could, but if somehow they do it will prevent invalid dates.). The other is using the maxDate or equivalent parameter from the date picking library when you create the date picker instance.
Here is a custom validator to prevent any dates in the future. (It may not handle time differences properly in this setup.)
function noFutureDate(cell, value){
const cellValue = moment(new Date(value));
const today = moment();
if (cellValue.diff(today) > 0){
return false;
}
return true;
}
You also have to create a custom editor. Here is what you specifically need for the date picker instance. You can get the rest from the fiddle, but the other parts aren't really related to a date picker specifically.
const input = document.createElement("input");
input.value = cell.getValue();
onRendered(function(){
flatpickr(input, {
maxDate: moment().format('MM/DD/YYYY')
})
input.focus();
});

Passing Multiple Values

I have a visualization table that has an event listener on select.
The need: I want the user to be able to delete documents on the google drive without having to leave the webpage
The set up: I added a button so that when clicked, I get a confirm alert box that includes the value. Once I click OK, it runs the scripts from the client-side with an event handler. This works perfectly!
The problem: I can move one document at a time but if I need to move 20+ documents it gets really tedious to click rows one after the other. Is it possible to pass multiple values to the successhandler?
google.visualization.events.addListener(archiveChart.getChart(), 'select', function () {
$("#docArchive").on("click", function() {
var selection = archiveChart.getChart().getSelection();
var dt = archiveChart.getDataTable();
if (selection.length > 0) {
var item = selection[0];
var docurl = dt.getValue(item.row, 2);
var docname = dt.getValue(item.row, 1);
var folder = dt.getValue(item.row, 4);
if(confirm("Are you sure you want to archive " + docname + "?") == true) {
archiveChart.getChart().setSelection([]);
return google.script.run.withSuccessHandler(onSuccessArchive).withFailureHandler(function(err) {
alert(err);
}).archiveDoc(docurl,folder);
} else {
archiveChart.getChart().setSelection([]);
}
}});
})
I feel like I might need to add this:
for (var i = 0; i < selection.length; i++) {
var item = selection[i];
I'm struggling a little with understanding what I might need to change (still learning). Any help or guidance is appreciated!
recommend confirming once, for all documents
then loop the selection to archive each document
google.visualization.events.addListener(archiveChart.getChart(), 'select', function () {
$("#docArchive").on("click", function() {
var selection = archiveChart.getChart().getSelection();
var dt = archiveChart.getDataTable();
var docNames = selection.map(function (item) {
return dt.getValue(item.row, 1);
}).join('\n');
if (selection.length > 0) {
if(confirm("Are you sure you want to archive the following document(s)?\n" + docNames) == true) {
for (var i = 0; i < selection.length; i++) {
var item = selection[i];
var docurl = dt.getValue(item.row, 2);
var docname = dt.getValue(item.row, 1);
var folder = dt.getValue(item.row, 4);
return google.script.run.withSuccessHandler(onSuccessArchive).withFailureHandler(function(err) {
alert(err);
}).archiveDoc(docurl, folder);
}
}
archiveChart.getChart().setSelection([]);
}
});
});

UISearchbar Search in all fields in swift 3

I've got a tableview showing some data and I filter the shown data uisng UISearchbar. Each data struct consists of different values and
struct Cake {
var name = String()
var size = String()
var filling = String()
}
When a user starts typing I don't know whether he is filtering for name, size or filling. I don't want to use a scopebar. Is there a way to filter for various fields at the same time in swift 3?
This is the code I use to filter:
func updateSearchResults(for searchController: UISearchController) {
if searchController.searchBar.text! == "" {
filteredCakes = cakes
} else {
// Filter the results
filteredCakes = cakes.filter { $0.name.lowercased().contains(searchController.searchBar.text!.lowercased()) }
}
self.tableView.reloadData()
}
thanks for your help!
func updateSearchResults(for searchController: UISearchController)
{
guard let searchedText = searchController.searchBar.text?.lowercased() else {return}
filteredCakes = cakes.filter
{
$0.name.lowercased().contains(searchedText) ||
$0.size.lowercased().contains(searchedText) ||
$0.filling.lowercased().contains(searchedText)
}
self.tableView.reloadData()
}

Applying color to rows in Sharepoint based on if an item is overdue

I'm using Sharepoint to develop an open issues list for my company that will automatically track if an issue is about to be due or overdue based on the color of the row. I have a way to override the default Sharepoint list features and edit the rows, but I think my date comparisons aren't functioning correctly. Here is my code so far:
SP.SOD.executeFunc("clienttemplates.js", "SPClientTemplates", function() {
SPClientTemplates.TemplateManager.RegisterTemplateOverrides({
OnPostRender: function(ctx) {
var statusColors = {
'Almost Due' : '#FFFF00',
'Overdue' : '#FF0000',
};
var rows = ctx.ListData.Row;
for (var i=0;i<rows.length;i++)
{
var due = rows[i]["Due Date"];
var duedate = new Date(due);
var rowId = GenerateIIDForListItem(ctx, rows[i]);
var row = document.getElementById(rowId);
var today = new Date();
if(duedate <= today) {
var status = 'Overdue';
}
Else if (due.toDateString - today.toDateString <= 7 && due.toDateString - today.toDateString >= 0){
var status = 'Almost Due';
}
row.style.backgroundColor = statusColors[status];
}
}
});
});
I need the row to change red if the issue is past due and the issue to change yellow if the issue is due within one week.
Modified example:
SP.SOD.executeFunc("clienttemplates.js", "SPClientTemplates", function() {
SPClientTemplates.TemplateManager.RegisterTemplateOverrides({
OnPostRender: function(ctx) {
var statusColors = {
'Almost Due' : '#FFFF00',
'Overdue' : '#FF0000',
};
var rows = ctx.ListData.Row;
for (var i=0;i<rows.length;i++)
{
var dueDate = new Date(rows[i]["DueDate"]);
var today = new Date();
var status = null;
if(dueDate <= today) {
status = 'Overdue';
}
else if (daysBetween(today,dueDate) <= 7 && daysBetween(today,dueDate) >= 0){
status = 'Almost Due';
}
if (status != null){
var rowId = GenerateIIDForListItem(ctx, rows[i]);
var row = document.getElementById(rowId);
row.style.backgroundColor = statusColors[status];
}
}
}
});
});
function daysBetween(startDate, endDate) {
var timeDiff = Math.abs(endDate.getTime() - startDate.getTime());
var diffDays = Math.ceil(timeDiff / (1000 * 3600 * 24));
return diffDays;
}
The list of changes:
Fixed some typos like Else keyword
Introduced daysBetween function for getting dates difference in
days
due.toDateString - today.toDateString ...
I suspect that due.toDateString is returning a function definition. If you want your code to actually run that function, you'd want due.toDateString().
That said, since you're trying to do math with these dates, it's best to keep them as datetime objects or numbers rather than convert them to strings. Otherwise your subtraction is going to surprise you with NaN and your comparisons are going to be perpetually false.
If you subtract a date object from another date object in JavaScript, you'll get the difference between the dates in milliseconds. Convert that to days and you'll be good to go!