Marionette Show new element after increment - marionette

I am attempting to have a view where after every fetch of 20 different products from my backend (.fetch()), the DOM will display a product ad. The problem I am running into is that every time the collection fires the add event, the CompositeView is re-rendered.
How can I add Children Views to a CompositeView without re-rendering the whole parent?
define(["marionette", "lodash", "text!fonts/products/template.html",
'fonts/products/item-view', 'fonts/products/model', 'eventer'],
function(Marionette, _, templateHTML, ProductItemView, ProductsModel, eventer) {
'use strict';
var ProductsView = Marionette.CompositeView.extend({
template: _.template(templateHTML),
childView: ProductItemView,
childViewContainer: '.items',
productsLimit: 150,
initialize: function() {
this.listenTo(eventer, 'sort:products', this.sortCollection, this);
this.listenTo(this.collection, 'reset sort add', this.render, this);
this.listenTo(this.collection, 'sync', this.setupSync, this);
},
sortCollection: function(field) {
this.collection.sortByKey(field);
},
setupSync: function() {
this.setupWindowScrollListener();
this.render();
},
productsEnd: function() {
eventer.trigger('products:end');
},
setupWindowScrollListener: function() {
var $window = $(window),
$document = $(document),
that = this,
collectionSize = that.collection.length;
if(collectionSize <= that.productsLimit) {
$window.on('scroll', _.throttle(function() {
var scrollTop = $window.scrollTop(),
wHeight = $window.height(),
dHeight = $document.height(),
margin = 200;
if(scrollTop + wHeight > dHeight - margin) {
eventer.trigger('fetch:more:products');
$window.off('scroll');
}
}, 500));
} else {
that.productsEnd();
}
},
});
return ProductsView;
});
Generate Ad Code
Here is the code I am using to try to generate ads
https://gist.github.com/dennismonsewicz/aecf9bd0befe63e96ee6

What's causing your parent view to re-render, is that you're calling a render on a collection add event :)
this.listenTo(this.collection, 'reset sort add', this.render, this);
Unless you really want to re-render that parent CompositeView you don't need this listener at all because Marionette handles:
collection#add: _onCollectionAdd will render and place new childviews in the default (based on a comparator, if none then id) sort order
collection#reset: Marionette already has a listener on your CompositeView that will call this.render for you if your collection is reset
collection#sort: If you provide your view { sort: true } as an option to your CompositeView, it will handle 'sort' events on your collection. The default is to sort the children views and then call render on the CompositeView. If you don't want your CompositeView to be re-rendered, pass { reorderOnSort: true } and the children view will be efficiently reordered without re-rendering anything (parent nor children), simply moving the children DOM elements in the sort order dictated by the collection.comparator.

Related

slick carousel adjust height manually

I have a slick-carousel that a have some accordion tabs inside.
I need to be able to react to the bootstrap accordion collapse/expansion and adjust the height of the carousel.
It adjusts with the adaptive height correctly but only once done a full rotation.
How would I go about this.
so have established this so far. I are actually using velocityjs for the accordion.
if ($(this).hasClass('active')) {
toggleActivePanel.find('.content-collapse').attr('aria-expanded', false).velocity('slideUp', {
easing: 'easeOutQuad'
}, { complete: resize_slider() });
$(this).attr('aria-expanded', false).removeClass('active');
} else {
toggleActivePanel.find('.content-collapse').attr('aria-expanded', true).velocity('slideDown', {
easing: 'easeOutQuad'
}, { complete: resize_slider() });
$(this).attr('aria-expanded', true).addClass('active');
}
function resize_slider() {
var sliderAdaptiveHeight = function () {
var heights = [];
let items = $('.slick-active')
items.each(function () {
heights.push($(this).height());
});
$('.slick-list').height(Math.max.apply(null, heights));
}
sliderAdaptiveHeight();
$('.slider').on('afterChange', function (event, slick, currentSlide, nextSlide) {
sliderAdaptiveHeight();
});
}
the resize_slider function is being triggered however the height adjustments are back to front.
ie when expanding the slick slider height retracts and when collapsing the slick slider expands.
any thoughts

How to make a context menu in a custom ckeditor5 widget?

I made a inline widget similar a placeholder (ckeditor4), but now I want to render a dropdown when the widget is selected to show options values to replace the placeholder. I trying use BalloonPanelView but no success until now, someone have a idea about how to make it?
this.editor.editing.view.document.on('click', (evt, data) => {
evt.stop();
const element = data.target;
if (element && element.hasClass('placeholder')) {
if (!element.getAttribute('data-is-fixed')) {
const balloonPanelView = new BalloonPanelView();
balloonPanelView.render();
['option1', 'option2', 'option3'].forEach((value) => {
const view = new View();
view.set({
label: value,
withText: true
});
balloonPanelView.content.add(view);
});
balloonPanelView.pin({
target: element
});
}
}
});
I found the solution using ContextualBalloon class:
import ContextualBalloon from "#ckeditor/ckeditor5-ui/src/panel/balloon/contextualballoon";
// Define ballon
const balloon = editor.plugins.get(ContextualBalloon);
const placeholderOptions = // Here I defined list with buttons '<li><button></li>'
// Finnaly render ballon
balloon.add({
view: placeholderOptions,
singleViewMode: true,
position: {
target: data.domTarget
}
});

Prevent Handsontable cells from being selected on column header click

In a Handsontable, when a column header is clicked, all cells of that column are selected. Is the a way to prevent this from happening ?
I don't think there's such an option in the documentation. I didn't find where the events are registered on the DOM within the source code of the Handsontable library itself either.
Any hint would be appreciated. Thanks.
It is possible to stop the event from propagating using the beforeOnCellMouseDown hook, which prevents the cells of the header column that was clicked to be selected:
/**
* #param {MouseEvent} event
* #param {WalkontableCellCoords} coords
* #param {Element} element
*/
var handleHotBeforeOnCellMouseDown = function(event, coords, element) {
if (coords.row < 0) {
event.stopImmediatePropagation();
}
};
Handsontable.hooks.add('beforeOnCellMouseDown',
handleHotBeforeOnCellMouseDown, handsontable);
A very special thanks to Gustavo for his help!
I don't think it's possible to prevent that behavior. I haven't found any clue neither in the documentation nor quickly inspecting the source code.
However, you could deselect the selected cells right after they have been selected. Binding a function to handle the cell click event would do the trick. You could do that either by registering the callback when instantiating your handsontable:
$('#my_handsontable').handsontable({
...
afterOnCellMouseDown: function(event, coords){
// 'coords.row < 0' because we only want to handle clicks on the header row
if (coords.row < 0){
$('#my_handsontable').handsontable('deselectCell');
}
},
...
});
Or by means of a hook:
Handsontable.hooks.add('afterOnCellMouseDown', function(event, coords){
if (coords.row < 0){
$('#my_handsontable').handsontable('deselectCell');
}
});
Alternatively, you could edit handsontable source code and comment the piece of code in walkontableConfig that does select the whole column when a header cell is clicked:
var walkontableConfig = {
...
onCellMouseDown: function (event, coords, TD, wt) {
...
// if (coords.row < 0) {
// instance.selectCell(0, coords.col, instance.countRows() - 1, coords.col);
// instance.selection.setSelectedHeaders(false, true);
// }
...
},
...
};
Yes, There is an trick or we can say option to prevent selecting cell on header click. "Just set selectionMode to single single."
Try below code:
document.addEventListener("DOMContentLoaded", function() {
var example1 = document.getElementById('example1');
var selectOption = document.getElementById('selectOption');
var settings1 = {
data: Handsontable.helper.createSpreadsheetData(10, 10),
width: 700,
height: 272,
colWidths: 75,
rowHeights: 20,
rowHeaders: true,
colHeaders: true,
selectionMode: 'single', // 'single', 'range' or 'multiple',
};
var hot1 = new Handsontable(example1, settings1);
});

Change switch position with draggable/droppable and save the new position in db

Got a nice solution for my project on stack but I test now some days for a solution to save data after switch in db.
The original post: change switch position behavior
$(function()
{
$(".swapable").
draggable({ revert: true }).
droppable(
{
drop:function(event,ui)
{
swapNodes($(this).get(0),$(ui.draggable).get(0));
}
});
});
function swapNodes(a, b)
{
var aparent= a.parentNode;
var asibling= a.nextSibling===b? a : a.nextSibling;
b.parentNode.insertBefore(a, b);
aparent.insertBefore(b, asibling);
}
http://jsfiddle.net/keGuN/1/
Now I want use the stop to save something after drop.
$(function() {
$(".swapable").
draggable(
{
revert: true,
stop:function()
{
// put new div combination in db
}
}).
droppable(
{
drop:function(event,ui)
{
swapNodes($(this).get(0),$(ui.draggable).get(0));
}
});
});
function swapNodes(a, b)
{
var aparent= a.parentNode;
var asibling= a.nextSibling===b? a : a.nextSibling;
b.parentNode.insertBefore(a, b);
aparent.insertBefore(b, asibling);
}
How to find a way to put new div combination put in database?
My problem is how to get the right way to show new div combination.

In kendo ui How to Collapsing Graph could expand table but expanding graph then bring both the graph and table to be visible too

collapsing Graph could expand table but expanding graph immediately shall bring both the graph and table to be visible too,Vice versa.
You need to implement a collapse and expand function handlers.
$("#panelbar").kendoPanelBar({
expandMode: "single",
expand: function (e) {
...
},
collapse: function (e) {
...
}
});
On these handlers you check which item is being collapsed (or expanded) and decide which ones to expand and collapse according to your algorithm.
For knowing which item is being collapse / expanded you should use inside the handler:
var itemId = $("span", e.item).attr("id");
The very last thing is remember that if you want more than one bars opened you should switch you expandMode to multiple.
EDIT: As first approach to what you need:
$("#panelbar").kendoPanelBar({
expandMode: "multiple",
expand : function (e) {
var itemId = $("span", e.item).attr("id");
if (itemId === "Span1") {
this.expand($("#Span2").closest("li"));
} else {
this.collapse($("Span1").closest("li"));
}
},
collapse : function (e) {
var itemId = $("span", e.item).attr("id");
if (itemId === "Span1") {
this.expand($("#Span2").closest("li"));
} else {
this.collapse($("Span1").closest("li"));
}
}
});

Resources