How to modify the Task Name Column using JSLink in Sharepoint 2013 - sharepoint-2013

I am trying to modify the color of SharePoint 2013's Task Name column in a list using JSLink. I can override every other column using this code:
var overrideCtx = {
Templates: {
Fields: {
‘Title': {‘View’ : taskSample.TitleRendering },
‘PercentComplete': {‘View’ : taskSample.PercentCompleteRendering}
}
}
};
For some reason when I debug the code in Google Chrome the TitleRendering function is always skipped, while the PercentCompleteRendering function is executed fine.
Does anyone have any insight into this issue?
Thanks
I have tried the suggestion of LinkTitle in the answers below; it did not resolve my issue. I am including all my code for review. Any other suggestions?
var taskSample = taskSample || {};
taskSample.CustomizeFieldRendering = function () {
RegisterSod('hierarchytaskslist.js', '/_layouts/15/hierarchytaskslist.js');
LoadSodByKey('hierarchytaskslist.js', null);
debugger;
// Intialize the variables for overrides objects
var overrideCtx = {
Templates: {
Fields: {
'Unit': {
'View' : taskSample.UnitRendering
},
'LinkTitle': {
'View' : taskSample.TitleRendering
},
'PercentComplete': {
'View' : taskSample.PercentCompleteRendering
}
}
}
};
// Register the override of the field
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);
}
taskSample.PercentCompleteRendering = function (ctx) {
debugger;
var output = [];
var _dueDate = new Date(ctx.CurrentItem.DueDate);
var _now = new Date();
var nowPlus = new Date();
nowPlus.setDate(_now.getDate()+7);
output.push('<div style="background: #dbdbdb; display:block; height: 20px; width: 150px;">');
if ((_dueDate >= _now && _dueDate <= nowPlus)&& (ctx.CurrentItem.PercentComplete.replace(" %", "") === "0") ) {
output.push('<span style="color: #dbc900; font-weight: bold; position:absolute; text-align: center; width: 150px;">');
}
else if ((_dueDate < _now)&& (ctx.CurrentItem.PercentComplete.replace(" %", "") === "0") ) {
output.push('<span style="color: #CC0000; font-weight: bold; position:absolute; text-align: center; width: 150px;">');
}
else{
output.push('<span style="color: #fff; font-weight: bold; position:absolute; text-align: center; width: 150px;">');
}
output.push(ctx.CurrentItem.PercentComplete);
output.push('</span>');
output.push('<div style="height: 100%; width: ');
if (_dueDate == 'Invalid Date') {
output.push(ctx.CurrentItem.PercentComplete.replace(" %", "") + '%; background: #757575;'); //grey
}
else if (ctx.CurrentItem.PercentComplete.replace(" %", "") === "100") {
output.push(ctx.CurrentItem.PercentComplete.replace(" %", "") + '%; background: #339900;'); //gree
}
else if (_dueDate < _now) {
output.push(ctx.CurrentItem.PercentComplete.replace(" %", "") + '%; background: #CC0000;'); //red
}
else if (_dueDate >= _now && _dueDate <= nowPlus) {
output.push(ctx.CurrentItem.PercentComplete.replace(" %", "") + '%; background: #dbc900;'); //yellow
}
else if (_dueDate > _now) {
output.push(ctx.CurrentItem.PercentComplete.replace(" %", "") + '%; background: #339900;'); //green
}
output.push('"></div></div>');
return output.join('');
}
taskSample.UnitRendering = function (ctx) {
debugger;
var output = [];
var _Unit = ctx.CurrentItem.Unit;
switch(_Unit) {
case "Unit 1":
output.push('<span style="color: DarkMagenta;">');
output.push(ctx.CurrentItem.Unit);
output.push('</span>');
break;
case "Unit 2":
output.push('<span style="color: DarkRed;">');
output.push(ctx.CurrentItem.Unit);
output.push('</span>');
break;
case "Unit 3":
output.push('<span style="color: MidnightBlue;">');
output.push(ctx.CurrentItem.Unit);
output.push('</span>');
break;
case "Unit 4":
output.push('<span style="color: DarkOliveGreen ;">');
output.push(ctx.CurrentItem.Unit);
output.push('</span>');
break;
case "Unit 5":
output.push('<span style="color: GoldenRod;">');
output.push(ctx.CurrentItem.Unit);
output.push('</span>');
break;
case "Unit 6":
output.push('<span style="color: Coral;">');
output.push(ctx.CurrentItem.Unit);
output.push('</span>');
break;
default:
output.push(ctx.CurrentItem.Unit);
break;
}
return output.join('');
}
taskSample.TitleRendering = function (ctx) {
debugger;
var output = [];
var _Unit = ctx.CurrentItem.Unit;
switch(_Unit) {
case "Unit 1":
output.push('<span style="color: DarkMagenta;">');
output.push(ctx.CurrentItem.Title);
output.push('</span>');
break;
case "Unit 2":
output.push('<span style="color: DarkRed;">');
output.push(ctx.CurrentItem.Title);
output.push('</span>');
break;
case "Unit 3":
output.push('<span style="color: MidnightBlue;">');
output.push(ctx.CurrentItem.Title);
output.push('</span>');
break;
case "Unit 4":
output.push('<span style="color: DarkOliveGreen ;">');
output.push(ctx.CurrentItem.Title);
output.push('</span>');
break;
case "Unit 5":
output.push('<span style="color: GoldenRod;">');
output.push(ctx.CurrentItem.Title);
output.push('</span>');
break;
case "Unit 6":
output.push('<span style="color: Coral;">');
output.push(ctx.CurrentItem.Title);
output.push('</span>');
break;
default:
output.push(ctx.CurrentItem.Title);
break;
}
return output.join('');
}
taskSample.CustomizeFieldRendering();

In Tasks default view Task Name (linked to item with edit menu) column is used by default for rendering task name. If so, then you should use LinkTitle internal name instead of Title.
Example
SP.SOD.executeFunc("clienttemplates.js", "SPClientTemplates", function() {
SPClientTemplates.TemplateManager.RegisterTemplateOverrides({
Templates: {
Fields: {
'LinkTitle' : {
'View' : function(ctx){
var percentValue = ctx.CurrentItem.PercentComplete;
if(percentValue == "100 %"){
return String.format('<span style="background-color:#00ff00">{0}</span>',ctx.CurrentItem.Title);
}
else {
return String.format('<span>{0}</span>',percentValue = ctx.CurrentItem.Title);
}
}
}
}
}
});
});
Result

Related

JS switch onlick between two colors w/ if else

I'm working on my portfolio and need to switch between to stylings states of an element. Currently, I'm trying to make it work on the following example. In this particular case, my goal is to click the button and switch between green and red background with every click. But something won't work. I can switch from green to red, but not from red to green. What am I missing?
<button id="button">Toggle</button>
<div class="test" id="test"></div>
.test {
width: 100px;
height: 100px;
background: green;
margin-top: 20px;
}
var btn = document.getElementById("button");
var test = document.getElementById("test");
btn.onclick = function() {
if (test.style.background = "green") {test.style.background = "red";} else {test.style.background = "green";}};
Codepen Demo https://codepen.io/yanniksturm/pen/rNVmqJe
Thanks a lot!
In if condition there should be double (==) equal sign and also check by backgroundColor instead of background because of some browsers has more properties with background like background: green none repeat scroll 0% 0%; so condition will not execute.
I recommend use backgroundColor instead of background.
var btn = document.getElementById("button");
var test = document.getElementById("test");
btn.onclick = function() {
if (test.style.backgroundColor == "red") {
test.style.backgroundColor = "green";}
else {
test.style.backgroundColor = "red";
}
}
.test {
width: 100px;
height: 100px;
background: green;
margin-top: 20px;
}
<button id="button">Toggle</button>
<div class="test" id="test"></div>

Weird discrepancy between preview and HIT page on MTurk

I am trying to create an MTurk task with a basic multi-page navigator
written in Javascript. I have tested it offline and everything work just
fine. I got the code onto MTurk, and in the preview page, everything still
work. However, when I tried to create a batch of jobs, the worker's view
does not show the navigator bar, even with exactly the same code (see
attached screenshots).
I also attached my code for reference.
<!-- You must include this JavaScript file -->
<!--<script src="https://assets.crowd.aws/crowd-html-elements.js"></script>-->
<style>
.pagination {
margin-top: 18px;
font-size: 0;
text-align: center;
}
.pagination .page-li {
display: inline-block;
font-size: 15px;
line-height: 1;
-ms-user-select: none;
-moz-user-select: none;
-webkit-user-select: none;
user-select: none;
}
.pagination .page-li:hover {
cursor: pointer;
background-color: #EAEAEA; }
.pagination .page-li.page-active {
cursor: default;
color: #fff;
border-color: #555555;
background-color: #555555;
}
.pagination .page-li.number-ellipsis {
border: none;
cursor: default;
}
.pagination .page-li.number-ellipsis:hover {
background-color: #fff; }
.pagination .page-number {
width: 38px;
padding-top: 8px;
padding-bottom: 8px;
border: 1px solid #EAEAEA;
text-align: center;
}
.pagination .page-prev {
padding: 8px 14px;
margin-right: 8px;
border: 1px solid #EAEAEA;
}
.pagination .page-prev.no-prev {
color: #c6c6c6;
}
.pagination .page-prev.no-prev:hover {
cursor: default;
background-color: #fff;
}
.pagination .page-next {
padding: 8px 14px;
margin-left: 8px;
border: 1px solid #EAEAEA;
}
.pagination .page-next.no-next {
color: #c6c6c6;
}
.pagination .page-next.no-next:hover {
cursor: default;
background-color: #fff;
}
.pagination .number-ellipsis {
display: inline-block;
font-size: 15px;
padding: 8px 14px;
}
.pagination .number-ellipsis.page-hidden {
display: none;
}
</style>
<!--<crowd-form answer-format="flatten-objects" >-->
<div>
<p><b>Question: </b> </p>
<input type="radio" name='choice-x' value="y"> <label> Yes </label>
<br>
<input type="radio" name='choice-x' value="n"> <label> No </label>
</div>
<div class="box"> random </div>
<!--</crowd-form>-->
<script type="text/javascript">
class SimplePagination {
constructor (totalPageCount) {
if (!totalPageCount) return
this.state = {
pageNumber: 1,
totalPageCount
}
}
init (paramsObj) {
let state = this.state
state.container = paramsObj.container || 'body'
state.maxShowBtnCount = paramsObj.maxShowBtnCount || 5
state.pCName = paramsObj.pCName || 'page-li',
state.activeCName = paramsObj.activeCName || 'page-active',
state.dataNumberAttr = paramsObj.dataNumberAttr || 'data-number',
state.prevCName = paramsObj.prevCName || 'page-prev',
state.nextCName = paramsObj.nextCName || 'page-next',
state.disbalePrevCName = paramsObj.disbalePrevCName || 'no-prev',
state.disbaleNextCName = paramsObj.disbaleNextCName || 'no-next',
state.pageNumberCName = paramsObj.pageNumberCName || 'page-number'
state.swEvent = paramsObj.swEvent || 'click'
state.onPageChange = paramsObj.onPageChange
state.totalPageCount > state.maxShowBtnCount + 2 && (state.activePosition = Math.ceil(state.maxShowBtnCount / 2))
this.renderPageDOM()
}
switchPage () {
let state = this.state
let pCNameList = this.selectorEle('.' + state.pCName, true)
let pageNumber
pCNameList.forEach(item => {
item.addEventListener(state.swEvent, e => {
const currentPageEle = e.target
if (this.hasClass(currentPageEle, state.activeCName)) return
let dataNumberAttr = currentPageEle.getAttribute(state.dataNumberAttr)
if (dataNumberAttr) {
pageNumber = +dataNumberAttr
} else if (this.hasClass(currentPageEle, state.prevCName)) {
state.pageNumber > 1 && (pageNumber = state.pageNumber - 1)
} else if (this.hasClass(currentPageEle, state.nextCName)) {
state.pageNumber < state.totalPageCount && (pageNumber = state.pageNumber + 1)
}
pageNumber && this.gotoPage(pageNumber)
})
})
}
gotoPage (pageNumber) {
let state = this.state
let evaNumberLi = this.selectorEle('.' + state.pageNumberCName, true)
let len = evaNumberLi.length
if (!len || this.isIllegal(pageNumber)) return
this.removeClass(this.selectorEle(`.${state.pCName}.${state.activeCName}`), state.activeCName)
if (state.activePosition) {
let rEllipseSign = state.totalPageCount - (state.maxShowBtnCount - state.activePosition) - 1
if (pageNumber <= state.maxShowBtnCount && (pageNumber < rEllipseSign)) {
if (+evaNumberLi[1].getAttribute(state.dataNumberAttr) > 2) {
for (let i = 1; i < state.maxShowBtnCount + 1; i++) {
evaNumberLi[i].innerText = i + 1
evaNumberLi[i].setAttribute(state.dataNumberAttr, i + 1)
}
}
this.hiddenEllipse('.ellipsis-head')
this.hiddenEllipse('.ellipsis-tail', false)
this.addClass(evaNumberLi[pageNumber - 1], state.activeCName)
}
if (pageNumber > state.maxShowBtnCount && pageNumber < rEllipseSign) {
this.hiddenEllipse('.ellipsis-head', pageNumber === 2 && state.maxShowBtnCount === 1)
this.hiddenEllipse('.ellipsis-tail', false)
for (let i = 1; i < state.maxShowBtnCount + 1; i++) {
evaNumberLi[i].innerText = pageNumber + (i - state.activePosition)
evaNumberLi[i].setAttribute(state.dataNumberAttr, pageNumber + (i - state.activePosition))
}
this.addClass(evaNumberLi[state.activePosition], state.activeCName)
}
if (pageNumber >= rEllipseSign) {
this.hiddenEllipse('.ellipsis-tail')
this.hiddenEllipse('.ellipsis-head', false)
if (+evaNumberLi[len - 2].getAttribute(state.dataNumberAttr) < state.totalPageCount - 1) {
for (let i = 1; i < state.maxShowBtnCount + 1; i++) {
evaNumberLi[i].innerText = state.totalPageCount - (state.maxShowBtnCount - i) - 1
evaNumberLi[i].setAttribute(state.dataNumberAttr, state.totalPageCount - (state.maxShowBtnCount - i) - 1)
}
}
this.addClass(evaNumberLi[(state.maxShowBtnCount + 1) - (state.totalPageCount - pageNumber)], state.activeCName)
}
} else {
this.addClass(evaNumberLi[pageNumber - 1], state.activeCName)
}
state.pageNumber = pageNumber
state.onPageChange && state.onPageChange(state)
this.switchPrevNextAble()
var inputElems = document.getElementsByTagName("input");
for (var i=inputElems.length-1; i>=0; --i) {
var elem = inputElems[i];
if ((elem.type || "").toLowerCase() == "radio" && elem.name.startsWith("choice")) {
elem.name = "choice-" + pageNumber.toString();
}
}
}
switchPrevNextAble () {
let state = this.state
let prevBtn = this.selectorEle('.' + state.prevCName)
let nextBtn = this.selectorEle('.' + state.nextCName)
state.pageNumber > 1
? (this.hasClass(prevBtn, state.disbalePrevCName) && this.removeClass(prevBtn, state.disbalePrevCName))
: (!this.hasClass(prevBtn, state.disbalePrevCName) && this.addClass(prevBtn, state.disbalePrevCName))
state.pageNumber >= state.totalPageCount
? (!this.hasClass(nextBtn, state.disbaleNextCName) && this.addClass(nextBtn, state.disbaleNextCName))
: (this.hasClass(nextBtn, state.disbaleNextCName) && this.removeClass(nextBtn, state.disbaleNextCName))
}
renderPageDOM () {
let state = this.state
let pageContainer = this.selectorEle(state.container)
if (!pageContainer) return
let { totalPageCount, pCName, prevCName, disbalePrevCName, pageNumberCName,
activeCName, dataNumberAttr, maxShowBtnCount,nextCName, disbaleNextCName } = state
let paginationStr = `
<ul id="pagination" class="pagination">
<br>
<li class="${pCName} ${prevCName} ${disbalePrevCName}">prev</li>
<li class="${pCName} ${pageNumberCName} ${activeCName}" ${dataNumberAttr}='1'>1</li>
`
if (totalPageCount - 2 > maxShowBtnCount) {
paginationStr += `
<li class="${pCName} number-ellipsis ellipsis-head" style="display: none;">...</li>`
for (let i = 2; i < maxShowBtnCount + 2; i++) {
paginationStr += `<li class="${pCName} ${pageNumberCName} ${i === 1 ? activeCName : ''}" ${dataNumberAttr}='${i}'>${i}</li>`
}
paginationStr += `
<li class="${pCName} number-ellipsis ellipsis-tail">...</li>
<li class="${pCName} ${pageNumberCName}" ${dataNumberAttr}='${totalPageCount}'>${totalPageCount}</li>
`
} else {
for (let i = 2; i <= totalPageCount; i++) {
paginationStr += `<li class="${pCName} ${pageNumberCName}" ${dataNumberAttr}='${i}'>${i}</li>`
}
}
paginationStr += `<li class="${pCName} ${nextCName}${totalPageCount === 1 ? ' ' + disbaleNextCName : ''}">next</li></ul>`
pageContainer.innerHTML = paginationStr
this.switchPage()
}
isIllegal (pageNumber) {
let state = this.state
return (
state.pageNumber === pageNumber || Math.ceil(pageNumber) !== pageNumber ||
pageNumber > state.totalPageCount || pageNumber < 1 ||
typeof pageNumber !== 'number' || pageNumber !== pageNumber
)
}
hiddenEllipse (selector, shouldHidden = true) {
this.selectorEle(selector).style.display = shouldHidden ? 'none' : ''
}
selectorEle (selector, all = false) {
return all ? document.querySelectorAll(selector) : document.querySelector(selector)
}
hasClass (eleObj, className) {
return eleObj.classList.contains(className);
}
addClass (eleObj, className) {
eleObj.classList.add(className);
}
removeClass (eleObj, className) {
if (this.hasClass(eleObj, className)) {
eleObj.classList.remove(className);
}
}
}
console.log('running slp')
const slp = new SimplePagination(12)
console.log(slp)
slp.init({
container: '.box',
maxShowBtnCount: 3,
onPageChange: state => {console.log('pagination change:', state.pageNumber)}
})
</script>

Extjs Custom Combobox

how to create a custom combo like above?
here i just did a small hack to the component.by this way you can add any html element to the selection item in combo.
Ext.define('AMShiva.ux.custom.Combo', {
extend: 'Ext.form.field.ComboBox',
alias: 'widget.ux_combo',
colorField: 'color',//to get color value
displayField: 'text',
valueField:'value',
initComponent: function () {
var me = this;
// dropdown item template
me.tpl = Ext.create('Ext.XTemplate',
'<tpl for=".">',
'<div class="x-boundlist-item">',
'<span style="background-color: {' + me.colorField + '};" class="color-box-icon"></span>{' + me.displayField + '}',
'</div>',
'</tpl>'
);
me.callParent(arguments);
// here change the selection item html
me.on('change',
function(element, newValue) {
var inputEl = element.inputCell.child('input');
var data = element.getStore().findRecord(element.valueField, newValue);
if (data) {
inputEl.applyStyles('padding-left:26px');
var parent = inputEl.parent(),
spanDomEle = parent.child('span');
if (!spanDomEle) {
Ext.DomHelper.insertFirst(parent, { tag: 'span', cls: 'color-box-icon' });
var newSpanDomEle = parent.child('span');
newSpanDomEle.applyStyles('background-color: ' + data.get(element.colorField) + ';float: left;position: absolute;margin: 3px 2px 2px 4px;');
} else {
spanDomEle.applyStyles('background-color:' + data.get(element.colorField));
}
}
});
}
});
sample store:
var store = Ext.create('Ext.data.Store', {
fields: ['value', 'text', 'color']
});
css:
.color-box-icon {
width: 16px;
height: 16px;
margin: 0px 4px 0px -3px;
padding: 0px 8px;
}
Is there another way to do this kind of thing?

Scrollable Foundation Section headers

Looking through http://foundation.zurb.com/docs/components/section.html, is there anyway I can add horizontal scroll for Section headers ( Tabs) . I am looking something like http://www.seyfertdesign.com/jquery/ui.tabs.paging.html in foundation sections with horizontal scroll and continue to use accordion in small screen
I found a solution for those interested : https://codepen.io/gdyrrahitis/pen/BKyKGe
.tabs {
overflow-x: auto;
white-space: nowrap;
-webkit-overflow-scrolling: touch;
.tabs-title {
float: none;
display: inline-block;
}
}
if someone needs an angularjs with jquery implementation, below code can help you, for pure jquery replace angularjs directive method with a native js method with respective attributes.
I tried to search for similar implementation but found nothing, so I have written a simple angular directive which can transform a foundation CSS tabs to scrollable tabs
angular.module("app.directives.scrollingTabs", [])
.directive("scrollingTabs", ScrollingTabsDirective);
//#ngInject
function ScrollingTabsDirective($timeout, $window) {
return {
restrict: 'A',
link: function (scope, element, attr) {
if(attr.scrollingTabs == "true"){
element.addClass('scrolling-tabs-container');
element.find('.nav-buttons').remove();
element.append('<div class="scrolling-tabs nav-buttons nav-buttons-left"></div>');
element.append('<div class="scrolling-tabs nav-buttons nav-buttons-right"></div>');
let scrolledDiv = $(element).find('.tabs');
let scrolled;
let scrolling;
let scrollFn = (step, animationTime, cb) => {
scrolled = Math.max(scrolled + step, 0);
scrolledDiv.animate({
scrollLeft: scrolled
}, animationTime, ()=>{
if (scrolling) {
scrollFn(step, animationTime, cb)
}else{
if(cb){cb()}
}
});
};
let checkActiveNavButtonsClasses = () => {
scrolled = scrolledDiv.scrollLeft();
let scrollWidth = scrolledDiv.get(0).scrollWidth;
let scrolledDivWidth = scrolledDiv.get(0).clientWidth;
if(scrollWidth > scrolledDivWidth){
element.addClass('nav-active');
scrollWidth = scrolledDiv.get(0).scrollWidth;
if(scrolled == 0){
element.removeClass('nav-active-left').addClass('nav-active-right')
}else if(scrolled > 0 && scrolled + scrollWidth < scrolledDivWidth){
element.addClass('nav-active-left').addClass('nav-active-right');
}else if(scrolled > 0 && scrolled + scrollWidth >= scrolledDivWidth){
element.addClass('nav-active-left').removeClass('nav-active-right');
}else{
element.removeClass('nav-active-left').removeClass('nav-active-right')
}
}else{
element.removeClass('nav-active-left').removeClass('nav-active-right').removeClass('nav-active');
}
};
let scrollToActiveTab = () => {
let activeDD = scrolledDiv.find('dd.active');
let tabsOffset = scrolledDiv.offset();
let activeTaboffset = activeDD.offset();
let activeTabwidth = activeDD.width();
let scrolledStep = activeTaboffset.left - tabsOffset.left - scrolledDiv.width() + activeTabwidth;
scrollFn(scrolledStep, 100, checkActiveNavButtonsClasses);
};
element.find(".nav-buttons.nav-buttons-left")
.off("click.scrolling")
.on("click.scrolling", (event)=>{
event.preventDefault();
scrolling = false;
scrollFn(-100, 100, checkActiveNavButtonsClasses);
})
.off("mouseover.scrolling")
.on("mouseover.scrolling", function (event) {
scrolling = true;
scrollFn(-2, 1, checkActiveNavButtonsClasses);
})
.off("mouseout.scrolling")
.on("mouseout.scrolling", function (event) {
scrolling = false;
});
element.find(".nav-buttons.nav-buttons-right")
.off("click.scrolling")
.on("click.scrolling", (event)=>{
event.preventDefault();
scrolling = false;
scrollFn(100, 100, checkActiveNavButtonsClasses);
})
.off("mouseover.scrolling")
.on("mouseover.scrolling", function (event) {
scrolling = true;
scrollFn(2, 1, checkActiveNavButtonsClasses);
})
.off("mouseout.scrolling")
.on("mouseout.scrolling", function (event) {
scrolling = false;
});
$timeout(()=>{
checkActiveNavButtonsClasses();
scrollToActiveTab()
},1000);
$($window).off('resize.scrolling').on('resize.scrolling', _.debounce(()=> {
checkActiveNavButtonsClasses();
}, 500));
scope.$on('$destroy', function() {
$($window).off('resize.scrolling');
});
}
}
}}
css:
.scrolling-tabs-container {
position: relative;
.tabs {
overflow-x: hidden;
white-space: nowrap;
-webkit-overflow-scrolling: touch;
display: block;
margin-right: 18px;
dd {
display: inline-block;
float: none;
margin: 0px -3px 0px 0px;
}
.tabs-title {
float: none;
display: inline-block;
}
}
.scrolling-tabs {
&.nav-buttons {
display: none;
position: absolute;
width: 19px;
height: 38px;
border: 1px solid #c1c1c1;
top: 1px;
background-color: rgba(255, 255, 255, 0.5);
opacity: 0.4;
cursor: pointer;
&:hover {
opacity: 1;
&:before {
color: #444;
}
}
&:before {
position: absolute;
left: 7px;
top: 8px;
color: #777;
}
&.nav-buttons-left {
left: 0;
&:before {
content: '<';
}
}
&.nav-buttons-right {
right: 18px;
&:before {
content: '>';
}
}
}
}
&.nav-active{
.tabs{
margin-right: 36px;
margin-left: 18px;
}
.scrolling-tabs {
&.nav-buttons {
display: inline-block !important;
}
}
}
&.nav-active-left{
.scrolling-tabs{
&.nav-buttons-left{
opacity: 0.8;
}
}
}
&.nav-active-right{
.scrolling-tabs{
&.nav-buttons-right{
opacity: 0.8;
}
}}}
HTML: Foundation Tabs template.
<tabset class="list-tabs" scrolling-tabs="true">
<tab heading="tab1"></tab>
<tab heading="tab2"></tab>
<tab heading="tab2"></tab>
</tabset>
Before you start you'll want to verify that both jQuery (or Zepto) and foundation.js are available on your page. These come with foundation package so just uncomment them in your footer or include them accordingly.
<div class="section-container auto" data-section>
<section class="active">
<p class="title" data-section-title>Section 1</p>
<div class="content" data-section-content>
<p>Content of section 1.</p>
</div>
</section>
<section>
<p class="title" data-section-title>Section 2</p>
<div class="content" data-section-content>
<p>Content of section 2.</p>
</div>
</section>
</div>
The foundation documentation has all of the information for this :
http://foundation.zurb.com/docs/components/section.html#panel2
This will get you your section tabular headers. You then want to manage the content to be scrollable.
<div class="content" data-section-content>
<p>Content of section 1.</p>
</div>
This content here will be the area to work on, try adding a new class called .scrollable
Within this class use something like:
.scrollable{
overflow:scroll;
}
You may want to add some more to this however this will get you started. Your HTML should now look like this :
<div class="content scrollable" data-section-content>
<p>Content of section 1. This content will be scrollable when the content has exceeded that of the div size. </p>
</div>
This this is what you are looking for.

Group nodes together in Cytoscape.js

I am using Cytoscape for network visualization.
I have found this example of grouped nodes that you can expand and contract.
My question is, is it possible to highlight nodes and then dynamically add/remove them to a group on an ad-hoc basis?
I am yet to find an examples online of someone actually trying this and all the examples I have found like the aforementioned already have the groups predefined in the initial data load.
You can use the drag and drop extension of cytoscape.
Also, there is the clipboard extension, where you can select multiple elements via ctrl + mousedrag.
var cy = window.cy = cytoscape({
container: document.getElementById('cy'),
style: [{
selector: 'node',
style: {
'label': 'data(id)'
}
},
{
selector: 'node:parent',
style: {
'label': ''
}
},
{
selector: 'edge',
style: {
'curve-style': 'bezier',
'target-arrow-shape': 'triangle'
}
},
{
selector: '.cdnd-grabbed-node',
style: {
'background-color': 'red'
}
},
{
selector: '.cdnd-drop-sibling',
style: {
'background-color': 'red'
}
},
{
selector: '.cdnd-drop-target',
style: {
'border-color': 'red',
'border-style': 'dashed'
}
}
],
elements: {
nodes: [{
data: {
id: 'a'
}
},
{
data: {
id: 'b'
}
},
{
data: {
id: 'c'
}
},
{
data: {
id: 'd',
parent: 'p'
}
},
{
data: {
id: 'p'
}
}
],
edges: [
]
}
});
var cdnd = cy.compoundDragAndDrop();
var removeEmptyParents = false;
var isParentOfOneChild = function(node) {
return node.isParent() && node.children().length === 1;
};
var removeParent = function(parent) {
parent.children().move({
parent: null
});
parent.remove();
};
var removeParentsOfOneChild = function() {
cy.nodes().filter(isParentOfOneChild).forEach(removeParent);
};
// custom handler to remove parents with only 1 child on drop
cy.on('cdndout', function(event, dropTarget) {
if (removeEmptyParents && isParentOfOneChild(dropTarget)) {
removeParent(dropTarget);
}
});
// custom handler to remove parents with only 1 child (on remove of drop target or drop sibling)
cy.on('remove', function(event) {
if (removeEmptyParents) {
removeParentsOfOneChild();
}
});
// toggle check handler
document.getElementById('remove-1ch-parents').addEventListener('click', function() {
removeEmptyParents = !removeEmptyParents;
if (removeEmptyParents) {
removeParentsOfOneChild();
}
});
body {
font-family: helvetica neue, helvetica, liberation sans, arial, sans-serif;
font-size: 14px;
}
#cy {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: 1;
}
h1 {
opacity: 0.5;
font-size: 1em;
font-weight: bold;
}
#options {
z-index: 2;
position: absolute;
right: 0;
top: 0;
margin: 0.5em;
}
<head>
<title>cytoscape-compound-drag-and-drop demo</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
<script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/cytoscape-compound-drag-and-drop#1.0.0/cytoscape-compound-drag-and-drop.min.js"></script>
</head>
<body>
<h1>cytoscape-compound-drag-and-drop</h1>
<div id="cy"></div>
<div id="options">
<input id="remove-1ch-parents" type="checkbox" value="false" />
<label for="remove-1ch-parents">Remove parents with only one child</label>
</div>
</body>
The question itself is not that clear requirenment-wise, so if there is still something unclear, please edit it to be more precise (and maybe your code so that we can use that as a base. THX