How to Show 30 days in Day View with Horizontal Scrollbar in Dhtmlx Scheduler? - dhtmlx

I want to show 30 days in Day View Scheduler with Horizontal Scrollbar. Currently, Horizontal Scrollbar is available only for Timeline View but I want it for Day View as well as Month View.
For Timeline View with Horizontal Scrollbar code:
scheduler.createTimelineView({
name: "timeline",
x_unit: "minute",
x_date: "%H:%i",
x_step: 30,
x_size: 24*7,
x_start: 16,
x_length: 48,
y_unit: sections,
y_property: "section_id",
render: "bar",
scrollable: true,
column_width: 70,
scroll_position:new Date(2018, 0, 15) });
Please share your ideas and Sample links
Thanks in Advance

Try using Custom View. You can remove the default Day view and display your own instead, with the number of days you want to display. This can be done like this:
First in scheduler.config.header set tab "thirty_days" instead of "day":
scheduler.config.header = [
"thirty_days",
"week",
"month",
"date",
"prev",
"today",
"next"
];
The label for the view is set as in:
scheduler.locale.labels.thirty_days_tab = "Days";
Next, set the start date of the viewing interval, as well as viewing templates. It's better to create the custom view in the onTemplatesReady event handler function so that your custom view templates are ready before the scheduler is initialized:
scheduler.attachEvent("onTemplatesReady", () => {
scheduler.date.thirty_days_start = function(date) {
const ndate = new Date(date.valueOf());
ndate.setDate(Math.floor(date.getDate()/10)*10+1);
return this.date_part(ndate);
}
scheduler.date.add_thirty_days = function(date,inc) {
return scheduler.date.add(date,inc*30,"day");
}
const format = scheduler.date.date_to_str(scheduler.config.month_day);
scheduler.templates.thirty_days_date = scheduler.templates.week_date;
scheduler.templates.thirty_days_scale_date = function(date) {
return format(date);
};
});
To add horizontal scrolling to the view, you can place the scheduler inside the scrollable element and give the scheduler the width required to display all columns. You'll need to hide a default navigation panel of the scheduler and create a custom one with HTML, so it would have a correct width and won't be affected by scrolling:
scheduler.xy.nav_height = 0;
scheduler.attachEvent("onSchedulerReady", function () {
const navBar = scheduler.$container.querySelector(".dhx_cal_navline").cloneNode(true);
navBar.style.width = "100%";
document.querySelector(".custom-scheduler-header").appendChild(navBar);
document.querySelectorAll(".custom-scheduler-header .dhx_cal_tab").forEach(function (tab) {
tab.onclick = function () {
const name = tab.getAttribute("name");
const view = name.substr(0, name.length - 4);
scheduler.setCurrentView(null, view);
};
});
document.querySelector(".custom-scheduler-header .dhx_cal_prev_button").onclick = function () {
const state = scheduler.getState();
scheduler.setCurrentView(scheduler.date.add(state.date, -1, state.mode));
};
document.querySelector(".custom-scheduler-header .dhx_cal_next_button").onclick = function () {
const state = scheduler.getState();
scheduler.setCurrentView(scheduler.date.add(state.date, 1, state.mode));
};
document.querySelector(".custom-scheduler-header .dhx_cal_today_button").onclick = function () {
scheduler.setCurrentView(new Date());
};
scheduler.attachEvent("onBeforeViewChange", (oldView, oldDate, newView, newDate) => {
const innerContainer = document.getElementById("scheduler_here");
if (newView === "thirty_days") {
innerContainer.style.width = "3000px";
} else {
innerContainer.style.width = "100%";
}
return true;
});
scheduler.attachEvent("onViewChange", function (view, date) {
const dateLabel = document.querySelector(".custom-scheduler-header .dhx_cal_date");
const state = scheduler.getState();
dateLabel.innerHTML = scheduler.templates[view + "_date"](state.min_date, state.max_date);
document.querySelectorAll(".custom-scheduler-header .dhx_cal_tab").forEach(function(tab) {
tab.classList.remove("active");
});
const activeTab = document.querySelector(".custom-scheduler-header ." + view + "_tab");
if (activeTab) {
activeTab.classList.add("active");
}
});
});
Styles that you will need:
.custom-scheduler-header .dhx_cal_navline{
display: block !important;
height: 60px !important;
}
.custom-scheduler-header .dhx_cal_navline.dhx_cal_navline_flex{
display: flex !important;
}
.dhx-scheduler {
height: 100vh;
width: 100vw;
position: relative;
overflow: hidden;
background-color: #fff;
font-family: Roboto, Arial;
font-size: 14px;
}
.dhx_cal_container .dhx_cal_navline {
display: none;
}
Please see an example: https://snippet.dhtmlx.com/znd7ffiv
You may need to fix the hour scale so that it remains visible when scrolling horizontally on the calendar. I did not implement this in the example, I think that this can be done in the same way as for the navigation panel. If you need, write to me and I will send an update in a few working days.
As for the "Month" view, the approach is the same as for the "Day" view.

Related

OpenLayers 6 DragZoom Control - how to change condition

in OL 6 I would like to use a button, so a user can click to activate a change for the drag zoom control
so it will be available without holding down shift.
In https://openlayers.org/en/latest/apidoc/module-ol_interaction_DragZoom-DragZoom.html it lists the option 'condition' to handles this.
I could not figure out how to change and set that condition. Any examples how to do this?
Here my example, hope be usefull.
You can change the style with CSS or in your JS.
HTML code:
<style>
.ol-dragzoom {
border-color: red !important;
}
</style>
<div id="map"></div>
<div id="tool-zoom" class="shadow-sm">
<a id="tool-lupa" class="text-secondary">
<i class="icono-arg-lupa"></i>
</a>
</div>
And the JS code:
var aplica_lupa = function(e) {
const dragZoom = new ol.interaction.DragZoom({
condition : ol.events.condition.always,
})
map.addInteraction(dragZoom);
};
$("#tool-lupa").on("click",function() {
aplica_lupa();
})
If you are importing OL methods, avoid the "ol.interaction...".
And if you want to change the DragZoom style in your JS, try something like this:
const dragZoom = new ol.interaction.DragZoom({
condition : ol.events.condition.always,
style : new ol.style.Style({
fill : new ol.style.Fill({
color : 'rgba(255, 255, 255, 0.6)'
}),
stroke : new ol.style.Stroke({
color : '#CD4D64',
width : 3
})
})
});
And other option, with onclick remove interaction:
const dragZoom = new ol.interaction.DragZoom({
condition : ol.events.condition.always,
})
var aplica_lupa = function(e) {
map.addInteraction(dragZoom);
};
var remueve_lupa = function(e) {
map.removeInteraction(dragZoom);
};
$('#tool-lupa').bind('click', myHandlerFunction);
var first = true;
function myHandlerFunction(e) {
if(first){
document.body.style.cursor="all-scroll";
aplica_lupa();
}else{
document.body.style.cursor="default";
remueve_lupa();
}
first = !first;
}

UIKit 3 accordion external button

How to close\ open accorion on click to .shewron element?
Example: https://codepen.io/npofopr/pen/vYKKXbJ?editors=1010
let util = UIkit.util;
let lkOrderIconExpand = document.querySelectorAll(".shewron");
util.on(lkOrderIconExpand, "click", function () {
let accordionEl = util.$("[uk-accordion]");
// find closed li array
let allItems = util.$$("[uk-accordion] > li");
// for each element
util.each(allItems, function (el) {
// get index
let openIndex = util.index(el);
// Check if some element has some class
if (util.hasClass(allItems, "uk-open")) {
console.log("Class was found!");
// toggle it
UIkit.accordion(accordionEl).toggle(openIndex);
} else {
console.log("Class was NOT found!");
// toggle it
UIkit.accordion(accordionEl).toggle(openIndex);
}
});
});
You can easily do it with CSS:
.uk-accordion-title::before{
background-image: url(**icon-url-here);
}
.uk-open > .uk-accordion-title::before{
background-image: url(**icon-url-here);
}
So that your chevron icons will show instead of default accordion icons.

drag and drop with auto scrolling (dom-autoscrolling)

I have a list of text elements and want to automatically scroll my list to the bottom when I'm dragging my new element.
This example below works properly once I drag-and-dropped one time an element in a list.
I believe I need to call once an observable before the drag.
I'm using dragula and dom-autoscrolling.
import {takeUntil} from "rxjs/internal/operators/takeUntil";
import * as autoScroll from 'dom-autoscroller';
const drake = this.dragulaService.find(this.dragulaBagName);
this.dragulaService.drag.pipe(
takeUntil(this.destroyed$),
).subscribe(([bag, movingEl, containerEl]) => {
autoScroll(containerEl.parentNode, {
margin: 20,
pixels: 10,
scrollWhenOutside: true,
autoScroll: function () {
return this.down && drake && drake.drake && drake.drake.dragging;
}
});
});
Apparently, this.down in callback autoScroll is set to false at the beginning... once drag-and-dropped one time, it works correctly.
Any ideas?
try use (mousedown)="initAutoScroll()"
initAutoScroll(){
const drake = this.dragulaService.find(this.dragulaBagName);
this.scroll = autoScroll(
containerEl.parentNode,
{
margin: 30,
maxSpeed: 25,
scrollWhenOutside: true,
autoScroll: function () {
return this.down && drake.drake.dragging;
}
});
}
this.dragulaService.dragend.asObservable().subscribe(value => {
if (this.scroll) {
this.scroll.destroy(); // destroy when don't use auto-scroll
}
});

Highslide, Auto follow scroll

I was looking for a fix/solution for that and found this topic:
http://highslide.com/forum/viewtopic.php?t=3030
function fixElement(el) {
var stl = el.style;
stl.position = 'fixed';
stl.top = (parseInt(stl.top) - hs.page.scrollTop) +'px';
stl.left = (parseInt(stl.left) - hs.page.scrollLeft) +'px';
}
function unfixElement(el) {
var stl = el.style;
stl.position = 'absolute';
stl.top = (parseInt(stl.top) + hs.page.scrollTop) +'px';
stl.left = (parseInt(stl.left) + hs.page.scrollLeft) +'px';
}
if (!hs.ie || hs.ieVersion() > 6) {
hs.Expander.prototype.onAfterExpand = function() {
fixElement (this.wrapper);
if (this.outline) fixElement(this.outline.table);
};
hs.Expander.prototype.onBeforeClose = function() {
unfixElement (this.wrapper);
if (this.outline) unfixElement(this.outline.table);
};
}
Got a small hack on the forum topic, but the hack does not work on any Internet Explorer that I tried (IE7, IE8 and IE9).
Does anyone has a "fix" on the hack to make it work on IE?
I think it's something related on this part of the code, this condition:
if (!hs.ie || hs.ieVersion() > 6)
I removed and it worked, but maybe this code could be changed.
Thank you.
The below code is what you need. Live demo: http://www.highslide.com/studies/position-fixed.html
Note: requires highslide-full.js
// Highslide fixed popup mod. Requires the "Events" component.
if (!hs.ie || hs.uaVersion > 6) hs.extend ( hs.Expander.prototype, {
fix: function(on) {
var sign = on ? -1 : 1,
stl = this.wrapper.style;
if (!on) hs.getPageSize(); // recalculate scroll positions
hs.setStyles (this.wrapper, {
position: on ? 'fixed' : 'absolute',
zoom: 1, // IE7 hasLayout bug,
left: (parseInt(stl.left) + sign * hs.page.scrollLeft) +'px',
top: (parseInt(stl.top) + sign * hs.page.scrollTop) +'px'
});
if (this.outline) {
stl = this.outline.table.style;
hs.setStyles (this.outline.table, {
position: on ? 'fixed' : 'absolute',
zoom: 1, // IE7 hasLayout bug,
left: (parseInt(stl.left) + sign * hs.page.scrollLeft) +'px',
top: (parseInt(stl.top) + sign * hs.page.scrollTop) +'px'
});
}
this.fixed = on; // flag for use on dragging
},
onAfterExpand: function() {
this.fix(true); // fix the popup to viewport coordinates
},
onBeforeClose: function() {
this.fix(false); // unfix to get the animation right
},
onDrop: function() {
this.fix(true); // fix it again after dragging
},
onDrag: function(sender, args) {
//if (this.fixed) { // only unfix it on the first drag event
this.fix(true);
//}
}
});

How to create a group in fabric.js

I want to create a group that will contain a combination of Image and Text and will behave as one, however when I do that:
https://gist.github.com/1682293
I can't move that group. To make it work I need to first add image and text to canvas, then create a group with these image and text, and then delete the image and text added separately.
What am I doing wrong there?
This seems to have been fixed in the latest version of fabric.js. I was able to get it to work with version 0.9.15:
function drawImage(name, left, top) {
fabric.Image.fromURL('../nav-host.png', function (img) {
var oImg = img.scale(4);
var caption = new fabric.Text(name, {
fontFamily: 'Arial'
});
var group = new fabric.Group([oImg, caption], { left: left, top: top });
canvas.add(group);
});
}
I came up this to add part of the text being generated dynamically from a counter script.
This code will add a group made from an image and text. The text is set to be above the image and it updates itself with every click of the button as it adds them to your canvas. So when you click the button the first time the text will say Sticky Card #1. The next click will give you your second group with the text saying Sticky card #2. The image was only 30px X 30px.
This is the counter script in the head of my page.
$(window).load(function(){
$('.stickycard').click(function() {
$('#cardcount').html(function(i, val) { return val*1+1; });
});
});
This is my fabric.js code that I used inside the kitchensink.js.
if ($(element).hasClass('image1')) {
fabric.Image.fromURL('toolimg/yellow-stickycard.png', function(img) {
var yellcard = img.scale(1.0).set({ left: 22, top: 15 });
var cardcount = $('#cardcount').text();
var sticky = new fabric.Text('Sticky Card #'+ (cardcount), {
fontSize: 12,
cornerSize: 6
});
var group = new fabric.Group([ sticky, yellcard ], {
left: 150,
top: 100,
cornerSize: 6
});
group.set({
left: left,
top: top,
});
canvas.add(group);
});
}
This is my HTML for the button and the div that shows the count.
<button type="button" class="btn image1 stickycard" id="yellstickycard"><img src="toolimg/yellow-stickycard.png" /></button>
<div id="cardcount">0</div>

Resources