I'm using event sources with FullCalendar 5. I need the cells containing events from one of the event sources to not be clickable.
I realize I can use eventClassNames or className to add a class for a given event source, but that class is added to the event text, not the cell, and nothing about the event source seems to be present as a selector at the cell level, either.
To summarize, the calendar is being used for reservations. If the date is present in a given event source, it is not available, so the cell should not be clickable. How do I accomplish that?
You could perform a check against existing events in the select callback - https://fullcalendar.io/docs/select-callback
so check that there is event(s) within the date range, and some custom property that identifies the source you wish to check for.
So when you import your events, have something like.
sourceType: "a" / sourceType: "b"
Then in the select, do a check, here blocking selection if an event of sourceType "b" is found within the cell.
select: function( selectionInfo ) {
if(calendar.getEvents().filter(x => (x.start >= selectionInfo.start && x.end <= selectionInfo.end && x.extendedProps.sourceType == "b").length > 0) ) {
calendar.unselect();
selectionInfo.jsEvent.stopPropagation();
return false;
}
// your handler if selection is allowed goes here
}
Related
The is pretty straightforward. I'm trying to find a way to get the active section Index number. I want the number to change when you scroll to a different section.
What I want to achieve:
Demo
Make use of fullPage.js callbacks or state classes.
Notice you have the slideIndex on the callbacks:
afterSlideLoad: function(anchorLink, index, slideAnchor, slideIndex){
//do whatever here
$(body).append(slideIndex);
},
Because the afterSlideLoad callback won't get fired on section change, you'll need to also make use of the afterLoad callback and get the slide number by using the state classes added by fullPage.js:
afterLoad: function(anchorLink, index){
var slideNumber = $('.fp-section.active').find('.fp-slide.active').index() + 1
//do whatever here
$(body).append(slideNumber);
}
I have a grouped Kendo Grid and need to trap collapse and expand events. For grids with detail there is detailExpand event . Is there something equivalent for group expand/collapse?
After poking around in the kendo source code, there is no directly provided event but you can just attach your own handler to the same event that kendo attaches to internally to handle the expand/collapse.
Internally, kendo attached a handler to expand/collapse icons like so:
if (that._isLocked()) {
that.lockedTable.on(CLICK + NS, '.k-grouping-row .k-i-collapse, .k-grouping-row .k-i-expand', that._groupableClickHandler);
} else {
that.table.on(CLICK + NS, '.k-grouping-row .k-i-collapse, .k-grouping-row .k-i-expand', that._groupableClickHandler);
}
where CLICK = "click" and NS = ".kendoGrid".
So, you can just add your own handler to the exact same element, i.e.:
var grid = $("#grid").getKendoGrid();
var table = grid._isLocked() ? grid.lockedTable : grid.table;
table.on('click.kendoGrid', '.k-grouping-row .k-i-collapse, .k-grouping-row .k-i-expand', myGroupableClickHandler);
and then do whatever you need to do in myGroupableClickHandler().
Example: http://dojo.telerik.com/#Stephen/udUga
Is there any way i can hide HOT columns from javascript?
The requirement is such that the column to hide will come as a parameter in javascript and based on that the respective column will show hide accordingly.
The HOT has rowHeaders and colHeaders and the data with 20 columns.
Please advise.
OUTDATED SOLUTION
Ok I founnd a possible solution. I tested it out on my own system but it's actually quite simple.
You should be using a customRenderer in your columns option. Read up about this if you aren't already. The idea is that you're giving each cell its own renderer. In this custom function, you can do something like this:
var colsToHide = [3,4,6]; // hide the fourth, fifth, and seventh columns
function getCustomRenderer() {
return function(instance, td, row, col, prop, value, cellProperties) {
if (colsToHide.indexOf(col) > -1) {
td.hidden = true;
} else {
td.hidden = false;
}
}
}
What this renderer does is hide the cells that the var colsToHide specify. All you do now is add a DOM element that lets the user pick which and so every time the table gets rendered (which happens basically after any change, or manually triggered need be), the cells in the columns specified will be hidden, keeping the data array intact like you described. And when not in colsToHide they are re-rendered so make sure you get that working as well.
Here I implemented it with very basic functionality. Just enter the index of a column into the input fields and watch the magic happen.
http://jsfiddle.net/zekedroid/LkLkd405/2/
Better Solution: handsontable: hide some columns without changing data array/object
I have a slickgrid that, in the 'onMouseEnter' event, I do the following:
change the underlying css for the row in question
call grid.invalidateRow()
call grid.render()
These latter two calls are necessary for the new css classes to be reflected. However, I then need to capture the onMouseLeave event, and it is not fired when I move my mouse away from the cell (or row), presumably because the call to invalidate/render has placed a new DOM element under my mouse, and it's no longer the one I initially "entered."
So I have two questions:
Is there another way to have the new css classes for a given cell be rendered without calling invalidateRow/render?
If not, is there another way to do this and still have the onMouseLeave event fired?
One option is to use the setCellCssStyles function.
grid.onMouseEnter.subscribe(function(e, args){
var cell = grid.getCellFromEvent(e),
param = {},
columnCss = {};
for(index in columns){
var id = columns[index].id;
columnCss[id] = 'my_highlighter_style'
}
param[cell.row] = columnCss
args.grid.setCellCssStyles("row_highlighter", param);
})
So the above changes the background-color of every cell of the row that has been moused into. In my fiddle, the mouseLeave subscription performs a simple console.log to ensure it is still firing.
Edit: fixed the external resource usages in the fiddle for cross-browser support
I have a form with 2 text inputs and 2 span controls. Normally, when textbox A is changed an event is fired to change span A, and when textbox B is changed, an event is fired to change span B.
However, in one particualar case I would like a change either textbox A or textbox B to update both span A and B. I tried wiring the events up to the corresponding controls in this case, but it didn't work because there is much state that is set up in the event building code (not to mention each event calls 'this', which would make the logic use the wrong control if it were fired from a different one than it was intended).
To make things easy, it would be best to pass a string (representing the other text input id) to the event handler at the time it is created, and then calling the change() event manually on the second control. However, this puts things in an infinite loop of recursion. I thought of a way to get around the recursion, but it reqires a global variable.
Is there a better way than this, preferably one that doesn't require a global variable?
ml_inEvent = false;
$ctlToVal.bind('keyup change', {feedbackCtl: ml_feedback, controlsToMonitor: ary, validationGroup: this.validationGroup, controlToFire: ctlToFire}, function(event) {
// Other processing happens here...
if (event.data.controlToFire != '') {
var $controlToFire = $('#' + event.data.controlToFire);
if ($controlToFire.length) {
// Use a global variable to ensure this event is not fired again
// as a result of calling the other one
if (!ml_inEvent) {
ml_inEvent = true;
$controlToFire.change();
ml_inEvent = false;
}
}
}
});
You can use the extraParameters argument on .trigger() to break out, for example:
$ctlToVal.bind('keyup change', {feedbackCtl: ml_feedback, controlsToMonitor: ary, validationGroup: this.validationGroup, controlToFire: ctlToFire}, function(event, fire) {
// Other processing happens here...
if(fire !== false) $('#' + event.data.controlToFire).trigger('change', false);
});
You can give it a try here. What this does is the event handler callback not only receives the event object but also any other arguments you pass in, in this case we're just using a simple false and a !=== check this in important so undefined (the parameter not passed at all) still changes both controls. So for instance $("#control").change() would change both controls, but still not loop...you can test that here.