adding custom content to header in fullcalendar timeline view - fullcalendar

I am trying to add additional content to the header for each day in timeline view
According to this link:
https://github.com/fullcalendar/fullcalendar-scheduler/issues/311
it should be doable by hooking into resourceRender.
But as far as I can tell, and what I have tried so far, I can only get hold of the resource it self and not the header per day.
I have created a codepen and hooked into resourceRender to play around with: https://codepen.io/thomasabcd/pen/YzzezoO
resourceRender: function(renderInfo){
console.log(renderInfo.el);
},
Any ideas?

If anybody else faces the same issue, I found a solution by hooking into the datesRender-callback. The code below makes a check and only adds the additional HTML to resourceTimelineWeek. Just remove the check if you don't need it.
See Codepen here: https://codepen.io/thomasabcd/pen/jOOZYRm
datesRender: function(renderInfo) {
let viewType = renderInfo.view.viewSpec.type;
if (viewType == "resourceTimelineWeek") {
let dateHeaders = renderInfo.el.querySelectorAll("th[data-date]");
dateHeaders.forEach(element => {
let headerDate = element.dataset.date;
let headerText = element.querySelector(".fc-cell-text");
let extraHTML = "<p>some text</p>";
headerText.innerHTML = headerText.innerHTML + extraHTML;
})
}
}

Related

Angular SlickGrid is it possible to use pagination AND set row color based on value?

Is it possible to set the background color for a row in slickgrid (based on data values) AND use pagination? For angular-slickgrid package.
I used getItemMetadata as suggested multiple other (old) posts - example SlickGrid: How to loop through each row and set color based on the condition?.
This code:
metadata(old_metadata_provider) {
return function(row) {
var item = this.getItem(row);
var ret = (old_metadata_provider(row) || {});
if (item) {
ret.cssClasses = (ret.cssClasses || '');
if ("attribute" in item) {
return { cssClasses: 'redRow' }; //redRow is in styles.css
}
}
return ret;
}
}
and the call is:
this.dataViewObj.getItemMetadata = this.metadata(this.dataViewObj.getItemMetadata);
It works correctly. However, when I turn pagination on, the color does not work as expected. I read that SlickGrid re-uses the same row elements when scrolling or paginating and will overwrite the styles associated with them. Is there another way to do it? Thanks for any help on this.
I tried adding the following code, after reading suggestion from ghiscoding, but the colors are still not working when pagination is enabled.
angularGridReady(angularGrid: AngularGridInstance) {
this.angularGrid = angularGrid;
this.dataViewObj = angularGrid.dataView;
this.gridObj = angularGrid.slickGrid;
this.checkRowBackgroundColor(); //where I call the metadata function from my previous post, if the dataView object is defined.
//I added this code:
var self = this;
this.dataViewObj.onPagingInfoChanged.subscribe(function (e, dataView, grid) {
self.gridObj.invalidate();
self.gridObj.render();
});
}
Try this approach:
angularGridReady(angularGrid: AngularGridInstance) {
this.angularGrid = angularGrid;
this.dataViewObj = angularGrid.dataView;
this.gridObj = angularGrid.slickGrid;
// check color change logic for the first time page load
this.checkRowBackgroundColor();
// use arrow function so that 'this' works properly
this.dataViewObj.onPagingInfoChanged.subscribe((e, dataView, grid) => {
// check your color change logic every time Paging Info Changed
this.checkRowBackgroundColor();
});
}
Inside your checkRowBackgroundColor:
checkRowBackgroundColor() {
// ... any of your logic
// get metadata
this.dataViewObj.getItemMetadata = this.metadata(this.dataViewObj.getItemMetadata);
// rerender the grid after getting new metadata
this.gridObj.invalidate();
this.gridObj.render();
}
Your problem should be solved now. As I have not tested on my local machine, I can not give guarantee. You can checkout original documentation of angular-slickgrid about this specific topic here: Dynamically Add CSS Classes to Item Rows

How do I create a paragraph break in Google Form help text?

I've looked on Google's product forums, and I can't find anything. The help text field is designed for brief text, but I want to insert a mulit-paragraph article. Without paragraph breaks, I wind up with a bunch of text that's difficult to read.
This has been bugging me for a long time and I've came up with a not so elegant but efficient solution based on Apps Script. Pavel Agarkov had the same idea! My version also works with multiple occurences and can be re-run if Google Forms removes the line breaks when you edit the text.
When editing a form, open the Script Editor from the main menu.
Create a new script, replace the content with the code below. Save it and return to your form.
Reload the page. You will notice a new option in the main menu, looking like this
That "Scripts" menu was added by our script. Don't use it for now, it won't do much.
When editing content, use fours spaces as a placeholder for line breaks.
Run the script from the Scripts menu. Now celebrate 👯‍♀️
Some things worth noting:
You will get a permission request the first time you run the script. It's ok, read the message and do what you have to do.
Once the line breaks are there, Google Forms, god bless its heart, will remove them every time you edit the field. Mildly infuriating. Just run the script again.
The script you need to use is:
// From https://stackoverflow.com/questions/22207368/
function onOpen() {
var ui = FormApp.getUi();
ui.createMenu('Scripts')
.addItem('Replace 4+ spaces with line breaks in Title and Description', 'addLineBreaks')
.addToUi();
}
function addLineBreaks() {
var theForm = FormApp.getActiveForm();
var theQuestions = theForm.getItems();
var thePlaceholder = new RegExp(/\s{4,99}|\n/, 'gi');
for (i = 0; i < theQuestions.length; i++) {
var theText = theQuestions[i].getHelpText();
if (theText.search(thePlaceholder) > 0 ) {
theQuestions[i].setHelpText(theText.replace(thePlaceholder,' \n'));
}
theText = theQuestions[i].getTitle();
if (theText.search(thePlaceholder) > 0 ) {
theQuestions[i].setTitle(theText.replace(thePlaceholder,' \n'));
}
}
}
I found that you can't do it through the editor but it is possible via the script.
Go to main menu -> script editor;
past the following code to the editor;
function addLineBreaks()
{
var form = FormApp.getActiveForm();
// find form items you need
var questions = form.getItems(FormApp.ItemType.MULTIPLE_CHOICE);
for(i = 0; i < questions.length; i++)
{
var title = questions[i].getTitle();
// if no replacement has been done yet
if(title.indexOf("\n") < 0)
{
// this will add line break after <double space> like in markdown
questions[i].setTitle(title.replace(" ", " \n"));
}
}
}
then set up trigger to start this method on form open.
I struggled with this question myself for too long!
However, when you know how its simple:
Go to "Add Item"
Choose "Section Header"
This option allows you to put paragraphed text into your Form.
As of June, 2018, the following work (but only the second option is documented):
Just put new lines in the description and it will be shown in the form - try using two for a paragraph.
If you want a bit more style - add a 'Title and Description' - see the second option in the tool bar showing 'Tᴛ'. The Title will always add extra space (even if it's empty) and will show any title as inverted, larger, text. You can disable the description if you just want a 'heading' followed by questions.
None of the above solutions worked for me, SO I added a unicode character https://www.compart.com/en/unicode/U+2002 pasted 4 to 5 times and this is how it looks
Sorry for the bad news, but this seems impossible to me.
I found the answer! While in the box into which you are entering text, go to Properties in the Developer tab. You will get a drop-down menu. At the bottom of the menu is "Plain Test Properties" with a check box for "Allow carriage returns (multiple paragraphs).
This is a better solution but based on the above. It allows you to edit the form which amazingly the above solutions don't:
// Version 2020-10-07a: by Dennis Bareis
// Handles "{nl}" in form & question descriptions
// Forms API: https://developers.google.com/apps-script/reference/forms
// Based on https://stackoverflow.com/questions/22207368/
// This code #: https://stackoverflow.com/a/64216993/3972414
// [0] ... -> Script Editor -> Create New Script
// [1] Paste into script editor
// [2] Run onOpen()
// [3] On first run authorise script
// [4] This adds 2 scripts under a new button in the edit form UI
// (to the left of the "Send" button)
// [5] Use "START" before re-editing form
// [6] Use "END" to publish the changes
// 5&6 required as otherwise you end up with "line1Line2Line3" etc
String.prototype.replaceAll = function(search, replacement)
{
var target = this;
return target.replace(new RegExp(search, 'g'), replacement);
};
//This doesn't perform the function on open, just adds it to the UI, you run when finished.
function onOpen()
{
var ui = FormApp.getUi();
ui.createMenu('Scripts')
.addItem('[1] Prepare for RE-EDITING this form (restore {nl})', 'editFormStart')
.addItem('[2] Publish the form (finished editing, remove {nl})', 'editFormEnd')
.addToUi();
}
function editFormStart()
{
swapLineBreaks("\n", "{nl}")
}
function editFormEnd()
{
swapLineBreaks("{nl}", "\n")
}
function swapLineBreaks(FromText, ToText)
{
var form = FormApp.getActiveForm();
// find form items you need
var oForm = FormApp.getActiveForm();
var questions = oForm.getItems();
// Fix the form's description
var formDesc = oForm.getDescription()
oForm.setDescription(formDesc.replaceAll(FromText, ToText))
// Work through each question
for(i = 0; i < questions.length; i++)
{
//var QTitle = questions[i].getTitle();
//questions[i].setTitle( QTitle.replaceAll(FromText, ToText));
var QText = questions[i].getHelpText();
questions[i].setHelpText(QText.replaceAll(FromText, ToText));
}
}

Make Event Background Color Unique on a Per-event Basis

I am sure there is a simple solution, but after reading existing posts and the documentation, I haven't been able to locate it just yet. This is my first post here, so any help is much appreciated.
I am integrating the FullCalendar with ExpressionEngine and the Calendar module for EE, and I have events rendering in FancyBox.
My only remaining issue is that the background of each event is the same color. What I am wanting to accomplish is on any given day, make multiple events have a different background color to identify the event as unique. In the documentation, it explains how to change the background color, but it's an "all-or-nothing" solution.
I also attempted to tweak the styles, but this made every day cell have the background color, rather than the actual individual events.
The code that builds the calendar and populates events from EE is listed as follows:
$(document).ready(function() {
$('#calendar').fullCalendar({
header: {
left: 'prev,next',
center: 'title',
right: ''
},
editable: false,
events: [ {}
{exp:calendar:events event_id="{segment_3}" sort="asc" dynamic="off"}
{occurrences}
,{title: '{event_title}',
url: '{url_title_path="path_to/event/"}',
start: new Date({occurrence_start_date format="%Y,%n-1,%j"}),
end: new Date({occurrence_end_date format="%Y,%n-1,%j"}),
allDay: true,}
{/occurrences}
{/exp:calendar:events}
],
eventClick: function(event) {
if (event.url) {
$("a").fancybox(event.url);
return false;
}
}
}); });
This would be simple to do if the events were manually being populated, but the data is coming from ExpressionEngine, rather than being hard-coded.
Any thoughts on how to make each event on a per-day basis render with a different background color than any of the other events listed for that same day?
Thanks for reading!!!
The current version of fullCalendar has a property on an event object '.backgroundColor' which can be set to change the background colour of that event. Of course you'd have to write some code to set up the background colours to all be unique within a day.
You may consider using the css3 nth child selectors here. This will allow CSS to automagically change the colors for you. See: http://css-tricks.com/how-nth-child-works/
You would of course need to target the appropriate elements, but without seeing the full DOM it will be very difficult for us to help with that here.
You can use eventAfterAllRenderwhich is triggered after all events have finished rendering in the fullCalendar from both source.
eventAfterAllRender: function( view ) {
var allevents = $('#calendar').fullCalendar('clientEvents');
}
Now, with the allevents object, you can do whatever toy wish.
Here is the one I took for me:
eventAfterAllRender: function(view) {
var allevents = $('#calendar').fullCalendar('clientEvents');
var countevents = 0;
if( allevents.length ) {
countevents = countevents + allevents.length;
}
if(!countevents) {
// alert('event count is'+countevents);
console.log('event count is',countevents);
}
}
One of my friend was able to get the id of duplicate events and now I can delete the duplicate event within a loop as:
$('#calendar').fullCalendar('removeEvents', allevents[i].id);
Now it is up to you. Very sorry because I am running a busy schedule nowadays. I'm glad if someone would generate a proper solution for Mr. Lane from this(even by editing this answer).
Thank you.

Error with jquery hover and ajax pagination when they're together

Thanks for reading. I have some codes on my wordpress site, the first one adds an overlay over an image with a color, the article title and a link to go to the project. The second code adds an ajax pagination using jQuery.
The thing is that i have my projects with images and the jquery overlay owrking perfect, but when they click on the previous projects link that calls the ajax pagination, the jquery overlay stops working.
I have been trying different options, but maybe i'm not on the correct way to solve it. Does anyone has a clue?
Thanks in advance.
The codes:
// PORTFOLIO HOVER EFFECT
jQuery('ul.portfolio-thumbs li').hover(function(){
jQuery(".overlay", this).stop().animate({top:'0px'},{queue:false,duration:300});
}, function() {
jQuery(".overlay", this).stop().animate({top:'190px'},{queue:false,duration:300});
});
// POSTS NAVIGATION
jQuery('#posts-navigation a').live('click', function(e){
e.preventDefault();
var link = jQuery(this).attr('href');
jQuery('#ajax-container').fadeOut(500).load(link + ' #ajax-inner', function(){ jQuery('#ajax-container').fadeIn(500); });
});
I've found the solution in the same day and #BrockAdams helped me with the doubts. I'm putting here the code because it can be helpful for someone.
jQuery('ul.portfolio-thumbs li').live('hover', function(event){
if (event.type == 'mouseenter') {
jQuery(".overlay", this).stop().animate({top:'0px'},{queue:false,duration:300});
} else {
jQuery(".overlay", this).stop().animate({top:'190px'},{queue:false,duration:300});
}
});
jQuery('#posts-navigation a').live('click', function(e){
e.preventDefault();
var link = jQuery(this).attr('href');
jQuery('#ajax-container').fadeOut(500).load(link + ' #ajax-inner', function(){ jQuery('#ajax-container').fadeIn(500); });
});
You can post answers to your own question.
And, you needed to use live()Doc on the hover, because the pagination presumably loads in new portfolio-thumbs lis.
Without the live(), these new lis would have no events attached to them (unless you re-called jQuery('ul.portfolio-thumbs li').hover after every pagination event).
Live is easier, and avoids the pitfall of having multiple copies of the same event-listener attached to an element.
And, yes, you can use both live() calls (or more) on the same page without problems.

Collapsible comments in Drupal 7

I'm using the latest Drupal 7.2 core and I have no idea how to solve my problem. I'd like to collapse all nodes comments (there's lots of them) and expose them for the user when he presses 'show comments'. I know it has something to do with the fieldsets (or maybe I'm wrong), but where, what and how ?
Every helpful answer will be appreciated.
Thanks in advance.
I wrote a begging private message to one of the contributors and he posted a working solution for collapsible comments in D7 - http://drupal.org/node/94035#comment-4674734
So i tried a bunch of ways as suggested here.
The thing I ended up doing since I was trying to basically just put all the comments stuff into a collapsible fieldset is outlined here:
Go into the Content Type -> Manage Display.
Create an empty fieldset called something like Comments (You'll need fieldset/fieldcollection modules)
Once you have the group, grab the field_groupname for later use in code.
In your theme's template.php, or whereever you have the render arrays you'll have something like this to basically add the "comments" object into the group fieldset you just created.
function mytheme_preprocess_node(&$vars, $hook){
$tempField = null;
// Copy the comments / comment form into a variable.
$tempField = $vars['content']['comments'];
// Rename some of the labels, use the markup
$tempField['#title'] = "DMS URL";
$tempField['#field_name'] = "field_comments";
$tempField[0]['#markup'] = $vars['content']['comments'];
// Add it into the group (fieldset/group name you copied)
$vars['content']['group_commentsgroup']['field_comments'] = $tempField;
}
This will basically add your comments markup into an empty fieldset/group you created using node's manage display using fieldset/fieldcollection. Also, I was using ajax_comments for this.
This is more of a tip than an answer to your problem, but our website stopped using Drupal comments since they were too basic and moved to use the free service called Disqus
After a looong time of searching For Individual Collapsible comments I found a solution, where you can put your comment replies in an individual collapsible fieldset. :)
Below code in script.js
Include the js in .info file as scripts[] = js/script.js
(function($) {$(function() {
// Hurry up and hide the comments and its replies, if present. In most browsers, this
$('.indented').hide();
// The Comment section will be turned into a toggle to
// open/close the comments
$('.comment').addClass('closed').bind('click', function() {
var $self = $(this),
$form = $self.siblings('.indented'),
speed = 250; // speed of animation, change to suit, larger = slower
if ($self.hasClass('open')) {
$self.addClass('transition').removeClass('open');
$form.hide(speed, function() {
$self.addClass('closed').removeClass('transition');
});
}
else {
$self.addClass('transition').removeClass('closed');
$form.show(speed, function() {
$self.addClass('open').removeClass('transition');
});
}
});
}); })(jQuery);

Resources