Set cursor style doesn't work well - fullcalendar

I'm trying to set the cursor to "no-drop" for days before the current day and to "pointer" for days after current day.
I tried using css: fc-past, fc-today,fc-future and works well, also I tried from jquery plugin configuration and as well works fine.
dayRender: function( date, cell ) {
var yesterday = moment();
if (date <= yesterday) {
cell.css('background', '#F1F1F1');
cell.css('cursor', 'no-drop');
}else{
cell.css('cursor', 'pointer');
}
}
This works fine when there're no events, the problem appear when I have an event in the calendar.
Fullcalendar creates a set of empty for days without events, that are on cells and the cursor style is lost.
Into fc-content-skeleton there's a table with z-index 4,this div is over fc-bg which have the cursor css.
This fc-content-skeleton has fc-event-container for each event (I can set the css) but in days that doesn't have events, create an empty that I can't set style.
This causes that de cursor of the mouse can't be set into this . The result is that in the same day (without events) if you move the cursor, it changes from my style (setted in fc-bg) to default when the cursor if over an empty .
You can see this in the showcase on http://fullcalendar.io/ home.
<div class="fc-content-skeleton">
<table>
<thead>
<tr>
<td class="fc-day-number fc-sun fc-past" data-date="2016-05-08">8</td>
<td class="fc-day-number fc-mon fc-past" data-date="2016-05-09">9</td>
<td class="fc-day-number fc-tue fc-past" data-date="2016-05-10">10</td>
<td class="fc-day-number fc-wed fc-past" data-date="2016-05-11">11</td>
<td class="fc-day-number fc-thu fc-past" data-date="2016-05-12">12</td>
<td class="fc-day-number fc-fri fc-past" data-date="2016-05-13">13</td>
<td class="fc-day-number fc-sat fc-past" data-date="2016-05-14">14</td>
</tr>
</thead>
<tbody>
<tr>
<td class="fc-event-container" colspan="2">
<a class="fc-day-grid-event fc-h-event fc-event fc-not-start fc-end fc-draggable fc-resizable">
<div class="fc-content">
<span class="fc-title">Long Event</span>
</div>
<div class="fc-resizer fc-end-resizer"/>
</a>
</td>
<!-- here comes the empty td for days that haven't have events -->
<td rowspan="6"/>
<td rowspan="6"/>
</tr>
...
...
</tbody>
</table>
</div>
I spent a lot of time trying to set the cursor to this td but without results. This behavior is making me crazy.
Thanks for the help.
Add a examble from JS Bin:http://jsbin.com/qekajezepu/1/edit?js,output

This is a tricky one. The problem is that the fullcalendar UI is built in such a way that the day cell is not one unit, but sibling DIVs that contains overlaying tables.
The cell object that you set the cursor no-drop is setting it only to one of the tables. So you can't even trick it with setting a class and apply it to all children because they are not children, they are nested siblings.
So you can trick it by set a class on the cell when it renders and after the whole calendar rendered you can search all the overlapping elements (TDs in your case) and set them to be cursor: 'no-drop' as well.
Add this class to your css:
.cell-no-drop {
cursor: 'no-drop'
}
And set dayRender and eventAfterAllRender in full calendar to be:
dayRender: function( date, cell ) {
var yesterday = moment();
if (date <= yesterday) {
$(cell).css('background', '#F1F1FF');
$(cell).addClass('cell-no-drop');
}else{
cell.css('cursor', 'pointer');
}
},
eventAfterAllRender: function(view, element){
var dts = $("#calendar").find('td');
$($(".cell-no-drop")).each(function(){
var self = this;
$(dts).each(function(){
var pos = $(self).offset();
var w = pos.left + $(self).width();
var h = pos.top + $(self).height();
if (pos.top <= $(this).offset().top && $(this).offset().top <= h && pos.left <= $(this).offset().left && $(this).offset().left <= w){
$(this).css('cursor', 'no-drop');
}
});
});
},

Related

How to highlight a selected row in *ngFor?

I couldn't find something that will help me to solve this issue in Angular2. I'd like to set a css class when I select a row. (without using jQuery)
<table class="table table-bordered table-condensed table-hover">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Website</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of companies" (click)="selectedCompany(item, $event)">
<td>{{item.name}}</td>
<td>{{item.email}}</td>
<td>{{item.website}}</td>
</tr>
</tbody>
</table>
I'm using Angular2 final release
There are plenty of solutions to do this, one of them is you can store the current company when clicked.
In the *ngFor you check if the current item is the currentCompany and you add the class highlighted or whatever class you wish if its the same company.
export class TableComponent {
public currentCompany;
public selectCompany(event: any, item: any) {
this.currentCompany = item.name;
}
}
And then on your template:
<tr *ngFor="let item of companies" (click)="selectCompany($event, item)"
[class.highlighted]="item.name === currentCompany">
--
Another solution if you wish to have multiple highlighted companies you can add a property highlighted to your item. Then on selectCompany() you just set the property to true. On your check you do [class.highlighted]="item.highlighted".
I know this was answered a while ago, but to expand on the accepted answer, you could also use [ngClass]="{'class_name': item.id === currentCompany }". The table hover may need to be removed as it may hide the background color change
<tr *ngFor="let item of companies" (click)="selectCompany($event, item)" [ngClass]="{'class_name': item.id === currentCompany }" >
Then css
.class_name{ background-color: yellow; }

How do I change ng-class on window resize?

I have functionality where when I shrink the screen below a certain size and click on a table row it reveals other items in that table row. (white screen on left).
Then when I expand the window I want all table rows to return to normal, but I have a bug where if it's open already it won't close.
I tried setting the $scope.showIt variable to true/false, but it only seems to have an effect if it's the opposite of the initial $scope.showIt value. How do I change all the ng-classes in every td when the screen is a certain size?
This is my html:
<tr class="table-body "ng-repeat="service in services | orderBy:myOrderBy | filter:search">
<td align="center" valign="middle" ng-click="showIt = dropDetails(showIt)" ng-class="{'name-show':showIt, 'name-show-disabled':!showIt}">{{ service.name }}</td>
<td ng-class="{'show':showIt, 'show-disabled':!showIt}">{{ service.description }}</td>
<td ng-class="{'show':showIt, 'show-disabled':!showIt}">{{ service.prices }}</td>
</tr>
And in my controller:
$scope.dropDetails = function(showIt){ //This function works well.
console.log(window)
console.log(window.innerWidth)
if(window.innerWidth < 760){
return !showIt;
}else{
return showIt;
}
}
var w = angular.element($window);
var resizeId=0;
$scope.showIt = true;
w.bind('resize ', function (a) {
clearTimeout(resizeId);
resizeId = setTimeout(function(){
if(w[0].innerWidth < 760){
}else{
$scope.showIt = true; //Does nothing.
$scope.$apply();
}
}, 500);
})
Do use Dot Rule while defining ng-model in Angular view. So that will help you to follow prototypal inheritance while refering to there property.
The reason here is, you have used ng-repeat(which does create prototypically inherited child scope while rendering template each time on view). Here the same thing you need to do. Define model like $scope.model and inside that define showIt property. Rather you should put that showIt on each of you element of services, by which you handle each event individually.
Markup
<tr class="table-body" ng-repeat="service in services | orderBy:myOrderBy | filter:search">
<td align="center" valign="middle"
ng-click="service.showIt= dropDetails(service.showIt)"
ng-class="{'name-show':service.showIt, 'name-show-disabled':!service.showIt}">
{{ service.name }}
</td>
<td ng-class="{'show':service.showIt, 'show-disabled':!service.showIt}">
{{ service.description }}
</td>
<td ng-class="{'show':service.showIt, 'show-disabled':!service.showIt}">
{{ service.prices }}
</td>
</tr>
Now question remains how to hide all the services, so that would be very easy. Loop through each services collection element & make showIt variable as false.
angular.forEach($scope.services, function(service){
service.showIt = false;
})
Also you are using custom event on DOM, I'd suggest you to put this code in directive. So that can get reusable too.

Changing CSS classes within Ember and SortMixin

I have a table which I have applied sorting to but to complete this task I would like the classes to change to show carets going up or down based on the sorting.
As you can see I have used the standard SortableMixin within Ember to get the sorting functionality but I'm having trouble changing the class of the individual element which has been clicked.
App.CampaignsController = Ember.ArrayController.extend({
sortProperties: ["id"],
sortAscending: true,
actions: {
sortBy: function(property){
if (this.get("sortProperties")[0] === property){
this.toggleProperty("sortAscending");
} else {
this.set("sortProperties", [property]);
this.set("sortAscending", true)
}
}
}
});
The table I'm I've applied the actions to is below:
<table class="table table-striped table-hover">
<thead>
<tr>
<th {{action "sortBy" "name"}}><i {{bind-attr class=":fa sortAscending:fa-caret-up:fa-caret-down"}}></i>Campaign Name</th>
<th {{action "sortBy" "campaign_code"}}><i {{bind-attr class=":fa sortAscending:fa-caret-up:fa-caret-down"}}></i>Campaign Code</th>
</tr>
</thead>
<tbody>
<td>{{name}}</td>
<td>{{campaign_code}}</td>
</tbody>
</table>
I'm using the sortAscending boolean to dictate what CSS class will appear. My problem is if I click the first heading, the classes on the second heading also change.
How do I get the CSS to change only on the heading that I have clicked?
Your <th> now has state (whether it's sorted, and whether it's ascending or descending), so you should wrap it up in a component. Something like this
<table>
<thead>
<tr>
{{#sortable-th property='name' action='sortBy'}}
Campaign Name
{{/#sortable-th}}
</tr>
</thead>
</table>
The component's template
// templates/components/sortable-th.js
<th>
<i {{bind-attr class=":fa sortAscending:fa-caret-up:fa-caret-down"}}></i>
{{yield}}
</th>
and code
// components/sortable-th.js
export default Ember.Component.extend({
sortAscending: true,
click: function() {
this.toggleProperty('sortAscending');
this.sendAction('action', this.get('property'), this.get('sortAscending'));
}
}
That's just a rough outline, try the implementation yourself. But that's how I would start thinking about it.

Get column index in onresizecolumn of declarative dojox.grid.datagrid

In a declarative dojox.grid.datagrid, am using onresizecolumn in table tag.
onresizecolumn="columnResize(this.id,this.cellIdx)"
onresizecolumn calls a function. on resizing particular column i want to get the cellIdx.
<div class="claro" id="eterte" name="dataGrid" onclick="getConnect('inner__eterte');setWidgetproperty(this.id,'xy','inner__eterte');" ondblclick="editCustomGrid(this.id)" onmouseup="setDocStyle(this.id)" style="height:200px; left:39px; position:absolute; top:251px; width:950px;">
<table class="claro" dojotype="dojox.grid.DataGrid" id="inner__eterte" onresizecolumn="columnResize(this.id,this.cellIdx)" rowselector="10px" style="height: 180px; width: 400px;">
<thead>
<tr>
<th field="Column1" id="Column1_6" width="159px">
Column1
</th>
</tr>
</thead>
</table>
<input id="hidden__eterte" name="dataGrid" style="display:none;" type="hidden">
</div>
function columnResize(id,index){
alert();
alert(id);
alert(index);
}
By reading the API documentation I come to the conclusion that Dojo automatically sends the Cell index to the event handler. So the solution is by simply providing the following attribute onResizeColumn="myFunction" and then you define a function like this:
function myFunction(cellDx) {
alert(cellDx);
}
This should work, I even made a JSFiddle to test it. By the way, is there any reason why you would like to do all of it in a declarative way? As far as my experience goes, it's a lot easier to write most of this in JavaScript.
I can get it working this way, not sure if it's a best practice.
http://jsfiddle.net/gE8rH/6/
HTML (removed onresizecolumn attribute):
<div class="claro" id="eterte" name="dataGrid" onclick="getConnect('inner__eterte');setWidgetproperty(this.id,'xy','inner__eterte');" ondblclick="editCustomGrid(this.id)" onmouseup="setDocStyle(this.id)" style="height:200px; width:950px;">
<table dojotype="dojox.grid.DataGrid" id="inner__eterte" rowselector="10px" style="height: 180px; width: 400px;">
<thead>
<tr>
<th field="Column1" id="Column1_6" width="109px">Column1</th>
<th field="Column2" id="Column1_7" width="109px">Column2</th>
<th field="Column2" id="Column1_8" width="109px">Column3</th>
</tr>
</thead>
</table>
</div>
JS (using Dojo 1.7+ module names), assign to the widget's onResizeColumn property:
require(["dojo/parser", "dijit/registry", "dojox/grid/DataGrid"], function (parser, registry) {
parser.parse().then(afterParse);
function afterParse() {
var d = registry.byId("inner__eterte");
console.log(d);
d.onResizeColumn = function (colIdx) {
console.log("columnResize");
console.log("args", arguments);
console.log("this", this);
console.log("colIdx", colIdx);
};
}
});
Outputs this when resizing the first column:
columnResize
args [0]
this [Widget dojox.grid.DataGrid, inner__eterte] { _attachPoints=[4], _attachEvents=[1], _connects=[0], more...}
colIdx 0

How to Get / Set Div and Table Width / Height

I have a Table (or a region) and want to set it's Width and Height value to another Div (or region).
The second one is actually a Ajax Indicator modal which display a loading text when the page is asynchronously post back. here is the example
<table id="MainTable">
<tr>
<td>
Content ....
</td>
</tr>
</table>
<div id="Progress">
Ajax Indocator
</div>
the following javascript didn't work
document.getElementById("Progress").style.width = document.getElementById("MainTable").style.width;
document.getElementById("Progress").style.height = document.getElementById("MainTable").style.height;
It should work both on IE and FireFox. how to correct it.
I checked some other solution in StackOverFlow but I couldn't fix it.
I'm waiting to hear from you.
Update : I use this
<script>
function SetSize(regionToChange, mainRegion) {
$(document).ready(function() {
$('#regionToChange)
.width($('#mainRegion).outerWidth())
.height($('#mainRegion).outerHeight());
});
}
</script>
and I call it like
<asp:Button ID="btnReset" runat="server" SkinID="Button" Text="Reset" OnClick="btnReset_OnClick" OnClientClick="SetSize('Progress', 'MainTable');" />
But it shows me an error which can not find the object
Update 2 I see this error
and in debugger I face with this
spoken in jQuery:
$(document).ready(function(){
$('#Progress')
.width($('#MainTable').outerWidth())
.height($('#MainTable').outerHeight());
});
in jQuery you can do
$("#Progress").css('width', function(){
return $("#MainTable").width()+'px';
});
and so with the height...
edit
on javascript,
this
document.getElementById("Progress").style.width = document.getElementById("MainTable").style.width;
document.getElementById("Progress").style.height = document.getElementById("MainTable").style.height;
will work if your html is something like this for id="MainTable"
<table id="MainTable" style="width: 500px; height: 300px;">
<tr>
<td>
Content ....
</td>
</tr>
</table>
because you are accessing style attribute...
edit2
function SetSize(regionToChange, mainRegion) {
$(regionToChange)
.width($(mainRegion).outerWidth())
.height($(mainRegion).outerHeight());
}
//you can use it as
SetSize('#Progress','#MainTable'); // prefix '#'if it's an ID

Resources