Cluetip doesn't work after changing uidatepicker month - javascript

Picked ui datepicker as calendar and used cluetip to show events. Script is working until I change the month (push button <- or ->).
Main idea was to set title to the element that holds date and on hover show & split text in lines using cluetip.
EDIT: Here is example - hope it will help to understand my problem.
Here is the javascript code:
$(document).ready(function() {
var dates =[ // adding events
[new Date(2010,8,01),new Date(2010,8,03),"Event1 | text | next line"]
];
$('#calendar').datepicker({
beforeShowDay: highlightEvents,
});
function highlightEvents(date) {
for (var i = 0; i < dates.length; i++) {
if (dates[i][0] <= date && dates[i][2] >= date) {
return [true, 'odd', dates[i][2]]; } // odd == style
}
$('td.odd').cluetip({ // cluetip main function
splitTitle: '|',
cluetipClass: 'jtip',
arrows: true,
dropShadow: true,
});
});
Html code:
<div id="calendar"></div>
Thanks in advance!

Thanks to UberNeet post:
jQuery UI Datepicker with jQuery tipsy
Found the answer.
// Because the the event `onChangeMonthYear` get's called before updating
// the items, we'll add our code after the elements get rebuilt. We will hook
// to the `_updateDatepicker` method in the `Datepicker`.
// Saves the original function.
var _updateDatepicker_o = $.datepicker._updateDatepicker;
// Replaces the function.
$.datepicker._updateDatepicker = function(inst){
// First we call the original function from the appropiate context.
_updateDatepicker_o.apply(this, [inst]);
// No we can update the Tipsys.
addTipsys(inst.drawYear, inst.drawMonth+1, inst.id);
};
Hope this will help someone.

Related

How to execute dc.js renderlet or pretransition functions in dc-tableview.js without rerendering whole table?

I am trying to conditionally format a dc-tableview.js table.
This works for the first page with following code:
tableView1.on('pretransition', function (tableView1) {
// tableView1.on('renderlet', function(tableView1){
var SecretKPIs = tableView1.selectAll('td.SecretKPI');
console.log('renderlet function 2');
SecretKPIs.each(function (d, i){
if (this.innerText >= MediumValueThreshhold && this.innerText < BadValueThreshhold){
this.classList.add('MediumValueFont');
} else if (this.innerText >= BadValueThreshhold){
this.classList.add('BadValueFont');
};
})
})
When I change to the next page or change the sorting of a column - the values change but the conditional formating does not apply anymore.
Any idea how I could apply the conditional formating again?
If I use the render function tableView1.render() - the table does not apply the filter of the page or the sorting.
Any help is highly appreciated.

Set value to a datepicker without clicking 'Done' button

I'm using the Webix time picker and have no idea how to force it to set the value without clicking the "Done" button (I don't want to display it at all). Is there a way to do this through the DOM or through the plain JS?
For example, a time picker (a datepicker with type:"time")
var time = webix.ui({
view:"datepicker",
align: "right",
label: 'Select Date',
labelWidth:100, width:350,
type:"time", stringResult:true
});
http://webix.com/snippet/232a2e2c
I modified your code a little. Now you can select a date hitting the Enter key:
var time = webix.ui({
view:"datepicker",
align: "right",
label: 'Select Date',
labelWidth:100, width:350,
type:"time", stringResult:true
});
document.addEventListener("keydown", keyDownTextField, false);
function keyDownTextField(e) {
var keyCode = e.keyCode;
if(keyCode==13) {
var done = document.getElementsByClassName('webix_cal_done');
if(done.length > 0){
done[0].click();
}
}
}
Working fiddle: http://webix.com/snippet/91f4cecc
I've created a similar solution for my project using DOM. Works good enough for me, but actually, it's a temporary hack (unless I can find something better). Check it out:
time.getPopup().attachEvent("onhide", function(){
var timeArr = document.getElementsByClassName("webix_cal_block webix_selected");
if (timeArr.length == 2){
var hour = timeArr[0].getAttribute("data-value");
var min = timeArr[1].getAttribute("data-value");
time.setValue(hour+" "+min);
}
});
http://webix.com/snippet/ff554921
Based on your code, I would look at using datepicker() directly instead of using ui. its part of the jquery UI set. I have linked directly to the datepicker site.
var time = webix.datepicker();
And on the jquery page there is a list of time picker plugins that may also help fill the void
Timepicker plugins
all done in one script:
var time = webix.ui({
view:"datepicker",
align: "right",
label: 'Select Date',
labelWidth:100, width:350,
type:"time", stringResult:true
}).attachEvent("onBlur", function(){
document.getElementsByClassName('webix_cal_done')[0].click();
});
thanks #Hackerman http://webix.com/snippet/1613c3d2

FullCalendar plugin - display hour in all of cells?

I am using FullCalendar jQuery plugin and I need to modify it. My goal is to automatically display hour in every single cell, in every single day as event. I am creating an online registration system for my application and I need this functionality. After user clicks any hour and confirms it, I want to disable clicks for that chosen hour.
You can see on the picture on Monday example what I want to achive(but for all days):
No need to alter the plugin itself. Just make good use of all of the options available.
If you are just trying to change the content of any event that is displayed on the calendar, pass a function to the eventRender callback that returns a new DOM element. Use the momentjs library to display a formatted string for the start property of the event. For example:
var calendarOptions = {
// ...other options
eventRender: function(event, element) {
$(element).html(moment(event.start).format('h:mm'));
return element;
}
}
When you are done with calendarOptions, you'll obviously need to pass it to fullCalendar:
$(calElement).fullCalendar(calendarOptions);
If you want to display an event in every single cell, then first make an array of events for every cell increment... something like this:
var myEvents = [];
var timeCursor = moment(startTime);
while (+timeCursor < +moment(endTime)) {
var start = +timeCursor;
timeCursor = timeCursor.add(timeIncrement,'minutes');
var end = +timeCursor;
myEvents.push({
start: start,
end: end
});
}
(where you've previously set startTime, endTime, and timeIncrement!)
Then the events property of the calendar options to this array before passing to fullCalendar:
calendarOptions.events = myEvents;
Finally, to handle clicks on an event, pass a function to the eventClick callback option that does whatever you want. For example, if you are keeping track of which events have been clicked, you might want to push their start times to an array:
var clickedEvents = [];
calendarOptions.eventClick: function(calEvent, jsEvent) {
if (clickedEvents.indexOf(calEvent.start) < 0) {
clickedEvents.push(calEvent.start);
} else {
return false;
}
}
Then of course you might want to modify your eventRender callback again to have your event display reflect this status by changing the style of the element, adding a line like this before returning the altered element:
if (clickedEvents.indexOf(calEvent.start) < 0) {
$(element).addClass('already-clicked');
}
(Be sure to set the style for .already-clicked in your CSS with something like cursor: not-allowed and opacity: 0.5.)
fullCalendar rocks!
I am trying to use #georgedyer code, but I have some issues :/
Firstly i will show You how it looks like in my MVC 4 application:
Here is my View(html) for display fullCallendar. The point of this is only to display events for every single cell:
//path to installed moment.js
<script src="~/Scripts/moment.js"></script>
<script>
$(document).ready(function () {
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
defaultView: 'agendaWeek',
editable: true,
allDaySlot: false,
selectable: true,
slotMinutes: 15,
events: myEvents,
eventRender: function(event, element) {
$(element).html(moment(event.start).format('h:mm'));
return element;
},
eventClick: function (calEvent, jsEvent, view) {
alert('You clicked on event id: ' + calEvent.start
+ "\nSpecial ID: " + calEvent.someKey
+ "\nAnd the title is: " + calEvent.title);
},
(...)
});
//HERE IS YOUR CODE ABOUT CREATING ARRAY
var myEvents = [];
var timeCursor = moment('2015-09-08');
while (+timeCursor < +moment('2015-10-01'))
{
myEvents.push { start: timeCursor }
timeCursor = timeCursor.add('15', 'minutes');
}
</script>
<div class="container">
<div id='calendar' style="width:65%"></div>
</div>
I have question about one line of code because VisualStudio display warning here about semicolon: myEvents.push { start: timeCursor }.
I tried to change it to this: myEvents.push ({ start: timeCursor }), error disappear, but still doesn't work :/
I don't know what is wrong in this. After run this code It just display empty FullCalendar. I know this code is a little different than your but I think this should work the same way. Please for some help here.
Edit: I think that eventRender: function works just fine because if I creating an event by myself,It displays hour like it should. So problem is only in creating events. I think in my code my myEvents array is in wrong place and when I invoke it in events: myEvents array has zero items.

Extjs 4.1.1a Check symbol of Checkbox on grid panel doesn't work

on a tab panel I create a tab for each year I have in a database (in this case the database contains at the moment only 3 years: 2012, 2013 ans 2014) and finally I set as active tab the current year (2013). In the controller I do the following:
var tp= this.getTpOverview();
this.getPlannedYearsStore().load({
callback: function(records) {
for (i=0; i< records.length; i++){
var year = records[i].data.year;
var tab = tp.add({
title: year,
year: year,
layout:'fit',
listeners: {
activate: function() {
var tbOverview = Ext.getCmp('tabOverview-'+ this.year);
if (!tbOverview) {
var gridOverview = Ext.create('WLPT.view.CPAssMonthActHours', {
id: 'tabOverview-' + this.year,
year: this.year,
xtype: 'cpassmonthacthoursview',
autoScroll: true
});
this.add(gridOverview);
} else {
selectedYear = this.year;
tbOverview.getStore().load({
params : {
wrk_year: selectedYear
}
});
}
}
}
});
if (currentYear == parseInt(records[i].data.year)) {
tab2Activate = tab;
}
}
tp.setActiveTab(tab2Activate);
}
});
When I run the application this seams to work fine.
I forgot to say that each tab contains a grid panel with a check column (Checkbox model) and for each item (row) a cell editor is setted on selected cells.
The active tab (2013) works fine. I can check the checkboxes to perfom a sum of the selected items. Indeed, the cell editor works fine.
The problem appears when I change the tab. The corresponding grid comes with the checkbox column. But on the javascript console appears the following error message:
Uncaught TypeError: Cannot call method 'setWidth' of undefined ext-all-debug.js:95689
Ext.define.onColumnResize ext-all-debug.js:95689
Ext.define.onColumnResize ext-all-debug.js:101362
Ext.util.Event.Ext.extend.fire ext-all-debug.js:8896
Ext.define.continueFireEvent ext-all-debug.js:9102
Ext.define.fireEvent ext-all-debug.js:9080
Ext.override.fireEvent ext-all-debug.js:51104
Ext.define.onHeaderResize ext-all-debug.js:97344
Ext.define.afterComponentLayout ext-all-debug.js:98063
Ext.define.notifyOwner ext-all-debug.js:28381
Ext.define.callLayout ext-all-debug.js:103511
Ext.define.flushLayouts ext-all-debug.js:103680
Ext.define.runComplete ext-all-debug.js:104194
callOverrideParent ext-all-debug.js:54
Base.implement.callParent ext-all-debug.js:3813
Ext.override.runComplete ext-all-debug.js:21234
Ext.define.run ext-all-debug.js:104175
Ext.define.statics.flushLayouts ext-all-debug.js:21238
Ext.define.statics.resumeLayouts ext-all-debug.js:21246
Ext.resumeLayouts ext-all-debug.js:23343
Ext.define.setActiveTab ext-all-debug.js:111589
Ext.define.onClick ext-all-debug.js:111357
(anonymous function)
Ext.apply.createListenerWrap.wrap
Despite that, the grid is shown correctly. But, when I select a item the javascript console shows the following error message:
Uncaught TypeError: Cannot call method 'up' of null ext-all-debug.js:99591
Ext.define.onRowFocus ext-all-debug.js:99591
Ext.util.Event.Ext.extend.fire ext-all-debug.js:8896
Ext.define.continueFireEvent ext-all-debug.js:9102
Ext.define.fireEvent ext-all-debug.js:9080
Ext.override.fireEvent ext-all-debug.js:51104
Ext.define.focusRow ext-all-debug.js:92462
Ext.define.onRowFocus ext-all-debug.js:92423
Ext.define.onLastFocusChanged ext-all-debug.js:109495
Ext.define.setLastFocused ext-all-debug.js:83855
Ext.define.doMultiSelect ext-all-debug.js:83761
Ext.define.doSelect ext-all-debug.js:83721
Ext.define.selectWithEvent ext-all-debug.js:83623
Ext.define.onRowMouseDown ext-all-debug.js:109750
Ext.util.Event.Ext.extend.fire ext-all-debug.js:8896
Ext.define.continueFireEvent ext-all-debug.js:9102
Ext.define.fireEvent ext-all-debug.js:9080
Ext.override.fireEvent ext-all-debug.js:51104
Ext.define.processUIEvent ext-all-debug.js:85315
Ext.define.handleEvent ext-all-debug.js:85227
(anonymous function)
Ext.apply.createListenerWrap.wrap
The selection on the item fires the event 'select' and 'deselect' when I click a second time. But the check symbol on the checkbox doesn't work any time.
I have thougth to put this symbol manually on the events 'select' and 'deselect' as a workaround, but I don't know how to put this style and which one is.
Do you have any ideas? Look forward for your suggestions. Thank you in advance.
Manuel
I think, the errors are not related to the code you posted. In fact, your code does not set the width, nor does it call up.
I find your code convoluted: a callback with a listener inside, that creates a view inside. And I don't understand if your code is inside a controller or another class.
Here is a problem:
var tab = tp.add({
//xtype is missing
title: year,
For debugging, I can giv you the following recommendation:
Use ext-dev.js instead of ext-all-debug.js. This will load all required classes one after the other, and the errors in the backtrace are not all inside ext-all-debug.js, but each line shows the line in the source class with all comments in it.
To get a cleaner programming style, try to follow the MVC pattern strictly:
Folder structure as recommended
Define events in the controller, like
init: function(){
this.listen({
store: {
'#plannedYearsStore': {load: this.onPlannedYearsStoreLoad}
}
})
this.control({
'tab': {activate: this.onTabActivate}
})
},
onPlannedYearsStoreLoad: function (store, records){
for (i=0; i< records.length; i++){
var year = records[i].data.year;
var tab = tp.add({
...
},
onTabActivate: function (){
var tbOverview = Ext.getCmp('tabOverview-'+ this.year);
...
},
If possible, define your tab in a view class in a separate file.
When you adhere striclty to this MVC structure, you will get a much easier maintainable code.

Data object in jquery is undefined after replaceWith

I'm coding a jquery plugin and I need some buttons to have a double state (like edit/save)
I get this info via JSON and insert it in the button as:
node
- current //['primary'/'secondary']
- primary // some info
- secondary // some info
Once I click the button I get here to change the action. So I want to replace the whole link through a template and the info I get from button.data.
As I want to replace not only the innerHtml but the outer, I have to use 'replaceWith'. Then I copy the 'data' to the new button and (ideally) delete the older one.
changeButtonAction : function(button, selector){
var node = button.data('node'),
info;
if(node.current == 'primary'){
info = node.secondary;
node.current = 'secondary';
}else{
info = node.primary;
node.current = 'primary';
}
button.replaceWith(multiReplace(OPERATION_ITEM, info, true));
button.data('node', $.extend( true, {}, node));
... //bit of interaction
}
The thing is: Once out the function I loose the new data as it says it's undefined.
Could somebody help? Using 'replaceWith' it's not a must, so if you come up with another solution it will be ok.
Ok, I solved it.
Thanks to Diode I tried reproducing it in jsfiddle. The click function did not work neither so I changes my code a bit. Instead of replacing with text:
button.replaceWith(multiReplace(OPERATION_ITEM, info, true));
button.data('node', $.extend( true, {}, node));
Do it with an object:
var button2 = $(multiReplace(OPERATION_ITEM, info, true))
.data('node', $.extend( true, {}, node));
button.replaceWith(button2);
You can see it in action:
http://jsfiddle.net/p8vMR/9/

Categories