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>
Related
I'm making changes to website front and I need to change the "sidebar(vertical_categories)" so that it doesn't open to side, but that it always open under the chosen category(category_list_large).
I've tried to change the CSS stylesheet, so that it could be done with as few changes as possible to the Click -function. I tried that classes .category_expanded_container and .category_list_large were in the same grid_area, but I didn't get it to work. I add some pictures from the old and new layout, so it's easier to understand. Any help is welcome, thanks for advance.
Old layout
New layout, how it should appear after changes
Here is the Class for Category
class CategoryListViewer {
private $categoryTree = [];
private $prevItemDepth = NULL;
public function __construct($categoryTree) {
$this->categoryTree = $categoryTree;
}
public function show() {
echo '<div class="category_list">';
foreach ($this->categoryTree as $item) {
$this->showCategoryItem($item);
}
echo '</div>';
}
private function showCategoryItem($item) {
if ($item->isImage()) {
$body = '<img src="'.$item->getImage().'" border="0" alt="'.$item->getName().'">';
} else {
$body = $item->getName();
}
if ($item->getDepth() == 1) {
$is_category_header = count($item->getSubcategories()) > 0 ? true : false;
$cat_head_class = $is_category_header ? 'category_list_header' : '';
$cat_head_text_class = $is_category_header ? 'category_list_header_text' : '';
if ($item->isLink()) {
echo '<div class="category_list_large '.$cat_head_class.'"><a class="category_list_color" href="'.$item->getLink().'"><div class="category_link '.$cat_head_text_class.'">'.$body.'</div></a>';
} else {
echo '<div class="category_list_large category_list_color '.$cat_head_class.'"><div class="category_nonlink category_list_color '.$cat_head_text_class.'">'.$body.'</div>';
}
if ($is_category_header) {
echo '<div class="category_side_box category_expand" data-category-expanded="false">';
echo '<i class="icon-chevron-right icon-1x category_list_color"></i>';
echo '</div>';
}
echo '</div>';
if (count($item->getSubcategories()) > 0) {
echo '<div class="category_list_sub_container" data-template="true">';
foreach ($item->getSubcategories() as $i) {
$this->showCategoryItem($i);
}
echo '</div>';
}
} elseif ($item->getDepth() == 2) {
echo '<div class="category_list_sub category_link">'.$body.'</div></div>';
}
}
}
Here is click -function
$('.category_expand').live('click', function(){
let expanded = $(this).attr('data-category-expanded') === 'true' ? true : false;
let content = $(this).parent('.category_list_header').next('.category_list_sub_container');
let header_text = $(this).parent('.category_list_header').find('.category_list_header_text').text();
let container = $('.vertical_categories')[0];
let offset = $(this).position().top;
let offset_div = $('<div class="subcategory_offset"></div>');
$(offset_div).css('width','100%').css('height','calc('+offset+'px - 5.1em)');
$('.category_expand.active').toggleClass('active', false);
if ($('.category_expanded_header').length > 0){
let old_header = $('.expanded_header_text').text();
$('.category_expanded_container').remove();
toggleCategoryShroud(false);
if (old_header === header_text){
return false;
}
}
let expanded_container = $('<div class="category_expanded_container"></div>');
let expanded_header = $('<div class="category_expanded_header"><span class="expanded_header_text">'+header_text+'</span></div>');
$(expanded_header).appendTo(expanded_container);
$(content).clone().attr('data-template','false').prepend(offset_div).appendTo(expanded_container);
$(expanded_container).appendTo(container);
toggleCategoryShroud(true);
$(this).toggleClass('active', true);
});
And here is CSS stylesheet
.vertical_categories{
position:fixed;
top: 0;
left: 0;
padding-left: 10%;
margin-left: -10%;
overflow-y: auto;
box-shadow: 0 0 0.75em rgba(0,0,0,0.2);
z-index: 320;
transition: all 0.3s cubic-bezier(0.18, 0.89, 0.32, 1.28);
display: grid;
grid-template-rows: 5em auto;
grid-auto-flow: column;
grid-template-areas: "toggle subcategory_container" "category_list subcategory_container";
height: 100%;
}
.category_expanded_container{
grid-area: subcategory_container;
display: grid;
grid-template-areas:
"header"
"list";
grid-template-columns: auto;
grid-template-rows: min-content auto;
overflow-y: auto;
}
.category_list_large{
display: grid;
grid-template-columns: auto min-content;
}
I'm generating a pie chart with legend that looks like so:
As you can perceive, the pie is pitifully puny. I prefer it to be twice as tall and twice as wide.
Here is the code I am using:
var formatter = new Intl.NumberFormat("en-US");
Chart.pluginService.register({
afterDatasetsDraw: function (chartInstance) {
var ctx = chartInstance.chart.ctx;
ctx.font = Chart.helpers.fontString(14, 'bold', Chart.defaults.global.defaultFontFamily);
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
ctx.fillStyle = '#666';
chartInstance.config.data.datasets.forEach(function (dataset) {
for (var i = 0; i < dataset.data.length; i++) {
var model = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._model,
total = dataset._meta[Object.keys(dataset._meta)[0]].total,
mid_radius = model.innerRadius + (model.outerRadius - model.innerRadius) / 2,
start_angle = model.startAngle,
end_angle = model.endAngle,
mid_angle = start_angle + (end_angle - start_angle) / 2;
var x = mid_radius * 1.5 * Math.cos(mid_angle);
var y = mid_radius * 1.5 * Math.sin(mid_angle);
ctx.fillStyle = '#fff';
if (i === 0 || i === 3 || i === 7) { // Darker text color for lighter background
ctx.fillStyle = '#666';
}
var percent = String(Math.round(dataset.data[i] / total * 100)) + "%";
// this prints the data number
// this prints the percentage
ctx.fillText(percent, model.x + x, model.y + y);
}
});
}
});
var data = {
labels: [
"Bananas (18%)",
"Lettuce, Romaine (14%)",
"Melons, Watermelon (10%)",
"Pineapple (10%)",
"Berries (10%)",
"Lettuce, Spring Mix (9%)",
"Broccoli (8%)",
"Melons, Honeydew (7%)",
"Grapes (7%)",
"Melons, Cantaloupe (7%)"
],
datasets: [
{
data: [2755, 2256, 1637, 1608, 1603, 1433, 1207, 1076, 1056, 1048],
backgroundColor: [
"#FFE135",
"#3B5323",
"#fc6c85",
"#ffec89",
"#021c3d",
"#3B5323",
"#046b00",
"#cef45a",
"#421C52",
"#FEA620"
]
}]
};
var optionsPie = {
responsive: true,
scaleBeginAtZero: true,
legend: {
display: false
},
tooltips: {
callbacks: {
label: function (tooltipItem, data) {
return data.labels[tooltipItem.index] + ": " +
formatter.format(data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index]);
}
}
}
};
var ctx = $("#top10ItemsChart").get(0).getContext("2d");
var top10PieChart = new Chart(ctx,
{
type: 'pie',
data: data,
options: optionsPie,
animation: {
duration: 0,
easing: "easeOutQuart",
onComplete: function () {
var ctx = this.chart.ctx;
ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontFamily, 'normal', Chart.defaults.global.defaultFontFamily);
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
this.data.datasets.forEach(function (dataset) {
for (var i = 0; i < dataset.data.length; i++) {
var model = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._model,
total = dataset._meta[Object.keys(dataset._meta)[0]].total,
mid_radius = model.innerRadius + (model.outerRadius - model.innerRadius) / 2,
start_angle = model.startAngle,
end_angle = model.endAngle,
mid_angle = start_angle + (end_angle - start_angle) / 2;
var x = mid_radius * Math.cos(mid_angle);
var y = mid_radius * Math.sin(mid_angle);
ctx.fillStyle = '#fff';
if (i === 3) { // Darker text color for lighter background
ctx.fillStyle = '#444';
}
var percent = String(Math.round(dataset.data[i] / total * 100)) + "%";
// this prints the data number
ctx.fillText(dataset.data[i], model.x + x, model.y + y);
// this prints the percentage
ctx.fillText(percent, model.x + x, model.y + y + 15);
}
});
}
}
});
$("#top10Legend").html(top10PieChart.generateLegend());
How can I increase the size of the pie?
UPDATE
The "View" as requested by Nkosi is:
<div class="row" id="top10Items">
<div class="col-md-6">
<div class="topleft">
<h2 class="sectiontext">Top 10 Items</h2>
<br />
<div id="piechartlegendleft">
<div id="container">
<canvas id="top10ItemsChart"></canvas>
</div>
<div id="top10Legend" class="pieLegend"></div>
</div>
</div>
</div>
. . .
The classes "row" and "col-md-6" are Bootstrap classes.
The custom classes are "topleft":
.topleft {
margin-top: -4px;
margin-left: 16px;
margin-bottom: 16px;
padding: 16px;
border: 1px solid black;
}
...sectionText:
.sectiontext {
font-size: 1.5em;
font-weight: bold;
font-family: Candara, Calibri, Cambria, serif;
color: green;
margin-top: -4px;
}
...and "pieLegend":
.pieLegend li span {
display: inline-block;
width: 12px;
height: 12px;
margin-right: 5px;
}
You just need to change the canvas size.
When you are creating the chart you can specify it right in the element:
<canvas id="top10ItemsChart" width="1000" height="1000"></canvas>
Or if you prefer to do it in javascript
var ctx = $("#top10ItemsChart").get(0).getContext("2d");
ctx.width = 1000;
ctx.height = 1000;
If the resizing doesn't work as you wish, you can also try setting the maintainAspectRatio option to false:
var optionsPie = {
/** ... */
responsive: true,
maintainAspectRatio: false,
/** ... */
};
Hope it helps.
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
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?
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.