Rendering data on specific calendar dates - antd

Goal: display data in calendar on days specified by a datepicker.
Problem: I am unable to assign data to specific dates- all calendar dates display the same data.
The calendar component is rendered by passing a function to its dateCellRender prop which generates the content to be displayed in the cell. The function passed to dateCellRender accepts a moment object as its sole argument, which is generated by the datepicker form. I inspected the Moment object and everything looks good there, i.e. calling moment.date() returns a number.
I tried to mimic the pattern in the documentation, but I keep running into the same issue.
What I'm really confused about is where the filtering is supposed to happen and what's going on behind the scenes. Is dateCellRender being called for every single cell in the calendar and displaying content only when a conditional is met?
Thanks.
The documentation example Calendar displays the list data on 8th, 10th, and 15th of every month. I'm putting it here for convenience. My code is below.
function getListData(value) {
let listData;
switch (value.date()) {
case 8:
listData = [
{ type: 'warning', content: 'This is warning event.' },
{ type: 'normal', content: 'This is usual event.' },
]; break;
case 10:
listData = [
{ type: 'warning', content: 'This is warning event.' },
{ type: 'normal', content: 'This is usual event.' },
{ type: 'error', content: 'This is error event.' },
]; break;
case 15:
listData = [
{ type: 'warning', content: 'This is warning event' },
{ type: 'normal', content: 'This is very long usual event。。....' },
{ type: 'error', content: 'This is error event 1.' },
{ type: 'error', content: 'This is error event 2.' },
{ type: 'error', content: 'This is error event 3.' },
{ type: 'error', content: 'This is error event 4.' },
]; break;
default:
}
return listData || [];
}
function dateCellRender(value) {
const listData = getListData(value);
return (
<ul className="events">
{
listData.map(item => (
<li key={item.content}>
<span className={`event-${item.type}`}>●</span>
{item.content}
</li>
))
}
</ul>
);
}
ReactDOM.render(
<Calendar dateCellRender={dateCellRender} />
, mountNode);
My exploratory code. "test" is displayed on every day of every month when the 3rd is chosen from datepicker.
testDate = () => {
console.log("in testDate", moment.date());
if (moment.date() === 3) {
return "foo";
};
render() {
return <Calendar dateCellRender={this.testDate} />
}
I expect 'foo' to be displayed on the third of every month when moment.date() === 3, but it's displayed instead on every date.
There are no error messages.

Related

How to prevent select2 to call select2:close the second time when selectOnClose is set to true?

I am using Select2 V. 4.0.10
I want to have a select2 that behaves the same way when you select using the Enter key and the Tab key.
What happens is that when selecting using the Tab key, the close event is called twice, which is not what was intended to do.
var data = [
{ id: 0, text: 'New' },
{ id: 1, text: 'In Process' },
{ id: 2, text: 'Draft' },
{ id: 3, text: 'Submitted' },
{ id: 4, text: 'Deleted' }
];
$(".test").select2({
allowClear: true,
selectOnClose: true,
data: data,
placeholder: "Select a status"
});
$("select.test", "body").off("select2:close").on("select2:close", function (e){
// This is called twice
console.log("select2:close");
});
select.test {
width: 200px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.10/css/select2.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.10/js/select2.min.js"></script>
<select class="test"></select>
Here are the sequences of the select2 events that are triggered when selecting with the Tab/Enter key.
TAB
select2:opening
select2:open
select2:closing
select2:selecting
change
change.select
select2:closing
select2:close
select2:select
select2:close
ENTER
select2:opening
select2:open
select2:selecting
change
change.select
select2:closing
select2:close
select2:select
As the pattern in always the same, the solution was to create a variable that would be toggled on when select2:select was triggered, and use that to see if it was be used before.
Notice, instead of using the global window object you should rather use a class variable or a prototype property to store this boolean.
var data = [
{ id: 0, text: 'enhancement' },
{ id: 1, text: 'bug' },
{ id: 2, text: 'duplicate' },
{ id: 3, text: 'invalid' },
{ id: 4, text: 'wontfix' }
];
window._select2Select = false;
$(document).on('select2:select', "select", function (e) {
window._select2Select = true;
});
$(".test").select2({
allowClear: true,
selectOnClose: true,
data: data,
placeholder: "Select a status"
});
$("select.test", "body")
.off("select2:close")
.on("select2:close", function(e) {
if(window._select2Select){
window._select2Select = false;
return;
}
console.log("select2:close");
window._select2Select = false;
});

Adding a media field when creating a new entry

I've searched around and looked at all the SDK docs and on Contentful's API docs I am having difficulty understanding how to add a media field with a link to an asset when creating a new entry. I can successfully create the other fields, but a media field should be an object but I am not sure exactly how to format that so Contentful will accept it.
const videoAsset = yield client.getAsset(assetID)
fields = {
title: {
"en-US": 'Title' //works
},
description: {
"en-US": 'Description' //works
},
video: {
"en-US": //contenful api wants an object, what does this object look like?
//i have a published asset in videoAsset returned by client.getAsset()
},
team: {
"en-US": 'Community' //works
},
}
const entryCreated = yield space.createEntry(action.payload.contentType, {
fields: fields
})
When I I say "works" I mean that I can successfully create an entry that appears in Contentful space.
I got it!
This person wasn't doing exactly the same thing but the answer in terms of formatting was here:
https://github.com/contentful/contentful-management.js/issues/57
Basically the field should look like this:
const videoAsset = yield client.getAsset(assetID)
fields = {
title: {
"en-US": 'Title' //works
},
description: {
"en-US": 'Description' //works
},
video: {
"en-US": {
sys: {
type: "Link", linkType: "Asset", id: assetID
}
}
}, //this formatting works!
team: {
"en-US": 'Community' //works
},
}
const entryCreated = yield space.createEntry(action.payload.contentType, {
fields: fields
})

Fullcalendar timezone option is ignored

I am fighting with the timezone option of fullCalendar plugin. It doesn't matter what I set: none, UTC or a specific location, everything is ignored by the plugin. All given times are shown as UTC+2 (Thats my location). What i do:
First creating some events according following code:
if(!newsCalendarEvent){
var newsCalendarEvent = [];
}
newsCalendarEvent["Event_1"] = {
events: [
{
title: 'my first news',
start: '2015-08-02T17:46:00Z',
end: '2015-08-10T17:46:00Z',
className: 'Event_1'
}
],
color: '',
textColor: ''
}
Then creating the calendar and looping through these events:
newsCalendar = $('#calendar').fullCalendar({
lang: 'de',
buttonIcons: false, // show the prev/next text
weekNumbers: true,
timezone : 'none',
timeFormat: 'H(:mm)'
})
for (var key in newsCalendarEvent) {
if (newsCalendarEvent.hasOwnProperty(key)) {
newsCalendar.fullCalendar( 'addEventSource', newsCalendarEvent[key] )
}
}
Solved. The problem had nothing to do with this plugin. It has been a qustion of timesetting in my php code.

kendo ui Combobox binded to a Grid losts it's value and text after Grid's Cancel button pressed

I have two views in database. Bonuses and employees. One(employee)-to-many(bonuses).
I have kendo ui grid (kendo web), which displays ajax results from controller called Bonuses
And an autocompliting element - Employee Combobox binded with Employee filed of a grid.
Grid's datasource:
// bind json result from /Bonuses/GetPagedJsonBonuses
var bonusesDataSource = new kendo.data.DataSource({
transport: {
read: "#Url.Action("GetPagedJsonBonuses", "Bonuses")",
update: {
url: "#Url.Action("Edit", "Bonuses")",
type: "PUT"
},
create: {
url: "#Url.Action("Create", "Bonuses")",
type: "POST"
},
parameterMap: function(options, operation) {
if (operation === "update" || operation === "create") {
// updates the BonusDTO.EmployeeId with selected value
if (newValueEmployeeId !== undefined)
options.EmployeeId = newValueEmployeeId;
}
return options;
}
},
schema: {
data: "Data", // PagedResponse.Data
total: "TotalCount", // PagedResponse.TotalCount
model: {
id: "BonusId", // Data
fields: {
EmployeeId: { type: "number" },
EmployeeLastName: {
type: "string",
editable: true,
//validation: { required: {message: "Employee's last name is required"}}
},
Amount: {
type: "number",
editable: true,
nullable: false,
validation: {
required: { message: "Amount is required to be set" }
}
}
} // fields
} // model
}// schema
});
Grid element looks like this:
// creates bonuses grid control
$("#bonusesGrid").kendoGrid({
dataSource: bonusesDataSource,
toolbar: ["create"],
editable: "inline",
columns: [
"BonusId",
"EmployeeId",
{
field: "EmployeeLastName",
editor: employeeAutocompletingEditor,
template: "#=EmployeeLastName#"
},
"Amount",
{
command: ["edit"],
title: " "
}
],
save: function(e) {
if (newValueEmployeeId !== undefined && newValueEmployeeLastName !== undefined) {
e.model.EmployeeId = newValueEmployeeId; // it's a hack to bind model and autocomplete control
e.model.EmployeeLastName = newValueEmployeeLastName;
}
},
edit: function(e) {
setCurrentValueEmployeeIdAndLastName(e.model.EmployeeId, e.model.EmployeeLastName);
},
cancel: function(e) {
setCurrentValueEmployeeIdAndLastName(e.model.EmployeeId, e.model.EmployeeLastName);
}
});
Autocompleting combobox has it's own datasource using ajax:
// datasource for autocomlete combobox to lookup employees names from
var employeesDataSource = new kendo.data.DataSource({
transport: {
read: "#Url.Action("GetJsonEmployeesByLastName", "Bonuses")",
},
parameterMap: function(options, operation) {
if (operation === "update" || operation === "create") {
setNewValueEmployeeIdAndLastName(options.Id, options.LastName);
}
return options;
},
});
Autocompliting combobox look's like this:
function employeeAutocompletingEditor(container, options) {
$('<input required data-text-field="LastName" data-value-field="EmployeeId" data-bind="value:' + options.field + '"/>')
.appendTo(container)
.kendoComboBox({
// sets the local variables to update values of current row.
change: function() {
setNewValueEmployeeIdAndLastName(this.value(), this.text());
},
dataBinding: function (e) {
console.log("dataBinding: ", e, this.dataItem());
},
dataBound: function (e) {
console.log("dataBound: ", e, this.dataItem());
},
dataSource: employeesDataSource
});
}
I use Editor binding to pass values(EmployeeId) and Text (EmployeeLastName) from grid to combobox.
I also use a hack like temporal variables (newValueEmployeeId, currentValueEmployeeId) to
send selected Employee in combobox and pass it to grid for correct save. A found it's a most common practice to pass a value back to grid.
My problems is:
If I press Edit button on my grid first time The combobox displays current employee's name from grid row:
If I press Cancel button and again press Edit button, combobox doesn't display current value of grid (employee's name)
IF I type some name, change some other values, and Udate(save) value, next time combobox again displays employees name, but only once before Cancel was pressed.
I'm very new in Kendo UI and this problem drives me crazy...
I think that combobox losts it's binding or doesn't update smth. I tried to set values while onBound and onBinding events, but this doesn't help. Please help me with an advice and example.
PS all evenets and functions is my try to debug and find solution.
only one fix helped me:
var employeeList = new List<Employee>()
employeeList.add(new Emplpyee()) // add fake employee record.
return Json(employeeList)
I don't know why, but grid control start make cyclying empty ajax requests if I return empty list of employees or null. This doesn't work:
return Json(new List<Employee>());
return Json(null);
I think it's a problem in kendo combobox itself ,because it's not ready to receive and handle empty list or null as json result.
Also I heared something, that JQuery doesn't support empty or null results anymore...maybe that's the reason

MVC ASP.NET - Getting jtable to call httpPost method?

I'm trying my hand at jTables with MVC 3, but have run into an issue. When my page loads, I'm not getting any calls to my [HttpPost] method. I think because of this, I keep getting the 'error connecting to database' message.
Can someone explain why my [HttpPost] method isn't getting called? Here's the relevant code:
<div id="CompetitionTable""></div>
<script type="text/javascript">
$(document).ready(function () {
//Prepare jtable plugin
$('#CompetitionTable').jtable({
title: 'The Events List',
paging: true, //Enable paging
pageSize: 10, //Set page size (default: 10)
sorting: true, //Enable sorting
defaultSorting: 'Name ASC', //Set default sorting
actions: {
listAction: '#Url.Action("EventList", "CompetitionController")'
},
fields: {
EventID: {
key: true,
create: false,
edit: false,
list: false
},
EventName: {
title: 'Name',
width: '15%'
},
CompetitorEmail: {
title: 'Email address',
list: false
},
CompetitorName: {
title: 'Competitor',
width: '15%',
},
Score: {
title: 'Score',
width: '10%',
}
}
});
//Load list from server
$('#CompetitionTable').jtable('load');
});
</script>
[HttpPost]
public JsonResult EventList(int compId)
{
try
{
//Get data from database
List<Event> events = Event.getEventsByCompetitionId(compId);
//Return result to jTable
return Json(new { Result = "OK", Records = events});
}
catch (Exception ex)
{
return Json(new { Result = "ERROR", Message = ex.Message });
}
}
The way you call listAction is wrong. you should call it like this '/CompetitionController/EventList'
Your MVC action waits for a parameter (compId). But your lisAction does not provide that:
listAction: '#Url.Action("EventList", "CompetitionController")'
It must be something like that:
listAction: '#Url.Action("EventList", "CompetitionController")compId=5'
Probably, this table is populated dynamically for every competition and it's known on the server side. So, it must be something like:
listAction: '#Url.Action("EventList", "CompetitionController")compId=#ViewBag.compId'
Surely, you must set compId in the action of this view.

Resources