Code not saving when trying to wrap promoted tiles in SharePoint Online - sharepoint

Apologies for another question re this, but I've tried so hard to get this working (I'm fairly new to SharePoint, don't have extensive coding knowledge, but know HTML and generally alright at trouble shooting).
We are using SharePoint online and we have SharePoint Tiles. We have recently added a few more tiles and it's obviously not wrapping these tiles, thus having to scroll right to access some.
I have found the code for wrapping the tiles here and when editing the page source, it appears to be working... until I save it. The code I put in is stripped out when I next go to the content editor.
I've read a few pages on it and have tried things such as the content editor web part, but for the life of me cannot get it to work.
If anyone would know if there's a step to step guide to ensure wrapped tiles are saved, I may be able to get it to work.
Any help is greatly appreciated.
If it changes anything, we use SharePoint online that is part of our Office 365 account.

Add the following code into script editor web part in the page.
<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
// Update this value to the number of links you want to show per row
var numberOfLinksPerRow = 6;
// local variables
var pre = "<tr><td><div class='ms-promlink-body' id='promlink_row_";
var post = "'></div></td></tr>";
var numberOfLinksInCurrentRow = numberOfLinksPerRow;
var currentRow = 1
// find the number of promoted links we're displaying
var numberOfPromotedLinks = $('.ms-promlink-body > .ms-tileview-tile-root').length;
// if we have more links then we want in a row, let's continue
if (numberOfPromotedLinks > numberOfLinksPerRow) {
// we don't need the header anymore, no cycling through links
$('.ms-promlink-root > .ms-promlink-header').empty();
// let's iterate through all the links after the maximum displayed link
for (i = numberOfLinksPerRow + 1; i <= numberOfPromotedLinks; i++) {
// if we're reached the maximum number of links to show per row, add a new row
// this happens the first time, with the values set initially
if (numberOfLinksInCurrentRow == numberOfLinksPerRow) {
// i just want the 2nd row to
currentRow++;
// create a new row of links
$('.ms-promlink-root > table > tbody:last').append(pre + currentRow + post);
// reset the number of links for the current row
numberOfLinksInCurrentRow = 0;
}
// move the Nth (numberOfLinksPerRow + 1) div to the current table row
$('#promlink_row_' + currentRow).append($('.ms-promlink-body > .ms-tileview-tile-root:eq(' + (numberOfLinksPerRow) + ')'));
// increment the number of links in the current row
numberOfLinksInCurrentRow++;
}
}
});
</script>
We can also use CSS style below in script editor web part in the page to achieve it.
<style>
.ms-promlink-body {
width: 960px;
}
</style>

Related

dynamically adding PXTabItem from codebehind

Trying to add a new tab items from the page cs file in the Page_Init method which contains a PXSmartPanel in Iframe mode.
Initially I just created the blank tab
for (int i=0;i<3;i++)
{
PXTabItem tabItem = new PXTabItem();
tabItem.Key = "myKey"
tabItem.Text = "myTab" + i;
tabItem.Visible = true;
this.tab.Items.Add(tabItem);
PXSmartPanel smartPanel = new PXSmartPanel();
smartPanel.RenderIFrame = true;
smartPanel.InnerPageUrl = "thispage" + i;
..... {other smartpanel properties}
tabitem.TemplateContainer.Controls.Add(smartPanel);
}
This does create the tabs on my page and works/looks correctly in Chrome however in Firefox, the style of the iframe rendered is always 150px regardless of the style set in the smartPanel above.
Tried adding the following
smartPanel.height = new Unit(100, UnitType.Percentage);
smartPanel.Style["height"] = "100%";
Tried even forcing a specific size of say 600px.
As a secondary test, I added directly to my page the tab items, smart panels and those render correctly in both Chrome and Firefox.
I also attempted to create a "dummy" / "template" and use the tabitem.CopyFrom() method to set it up. This also renders correctly in chrome but not firefox.
Has anyone added tab items directly from the code behind file and have any hints on what property I am missing here?

Getting and setting of a text selection in a textarea

I want to create a textarea where users can select a part of a text, and I will react according to their selection. So I need to
1) get the start and end positions of the selection text
2) get the position of the focus, if it is in the textarea and there is no selection
It seems that the functions to do so are different from an explorer to another. So could anyone tell me what is the approach to do that in Office Add-in?
I have tried the following 2 ways (ie, select a part of the text in myTextarea, click on button, and then debug the code), they don't seem to be the right functions.
(function() {
"use strict";
Office.initialize = function(reason) {
$(document).ready(function() {
app.initialize();
$('#button').click(showSelection);
});
};
function showSelection() {
// way 1
console.log(document.selection); // undefined
document.getElementById("myTextarea").focus();
var sel = document.selection.createRange(); // Uncaught TypeError: Cannot read property 'createRange' of undefined
selectedText = sel.text;
// way 2
console.log(document.getElementById("myTextarea").selectionstart); // undefined
console.log(document.getElementById("myTextarea").selectionend); // undefined
}
})();
Additionally, it would be great if one could also tell me how to realise the follows by code:
1) select a part of a text, from a start and end positions
2) set the focus at a certain position of the textarea
Edit 1:
I just tried window.getSelection() within my Excel add-in:
function showselection() {
var a = window.getSelection();
var b = window.getSelection().toString();
var c = window.getSelection().getRangeAt(0);
}
After selecting a text in the textarea, and clicking on button, I debugged step by step: the first line made a a = Selection {anchorNode: null, anchorOffset: 0, focusNode: null, focusOffset: 0, is ...; the second line returned "", the third line got an error Home.js:19 Uncaught IndexSizeError: Failed to execute 'getRangeAt' on 'Selection': 0 is not a valid index. It looks like the selection has not been successfully caught...
Here is JSBin without Excel add-in frame, which returns almost same results as above.
Use JQuery.
For instance, the following two lines get the caret position:
function showselection() {
console.log($('#myTextarea')[0].selectionStart);
console.log($('#myTextarea')[0].selectionEnd);
}
There are some plug-ins:
https://github.com/localhost/jquery-fieldselection
http://madapaja.github.io/jquery.selection/
The second one has several short samples with buttons (where we may lose selection). You could either use their API, or look into their code to see which JQuery functions they call.
If the desired selection is just the selected text in the HTML page (and not the user's selection in Excel/Word), then there are some good stackoverflow answers about accessing that selection.
One of the key features of the JavaScript APIs for Office is that they follow an asynchronous model (the code you've written above for showSelection() appears to be synchronous). I'd recommend reading the Excel and Word JS API overview pages to get a feel for how they work. As an example, here's how you'd get the text from a selection:
Word.run(function (context) {
var myRange = context.document.getSelection();
context.load(myRange, 'text');
return context.sync().then(function () {
log("Selection contents: " + myRange.text);
});
})
Then for the other specifics of your question please clarify as requested in my comment. Thanks!
-Michael (PM for Office add-ins)

Interval Selection Event in Primefaces Chart

I have a dynamic LineChart. I am setting the zoom to false but I want to be able to trigger an Ajax Event when selecting an area in the Chart (like the zoom functionnality when selecting the area you want to zoom), I want to call a server method and getting the max and min x axis values of the selected area.
Can anyone help with this?
Else if I set the zoom to true, is there any way to get the values from the zoomed area ?
PrimeFaces and JSF is in this context nothing more than an html/javascript/css generator. If you look at the source of the generated page in your browser developer tool, you'll see a lot of javascript, including all datapoints.
<script id="j_idt87_s" type="text/javascript">
$(function(){PrimeFaces.cw('Chart','chart'{
id:'j_idt87',
type:'line',
data:[[[1,2],[2,1],[3,3],[4,6],[5,8]],[[1,6],[2,3],[3,2],[4,7],[5,9]]],
title:"Zoom",
legendPosition:"e",
axes:{
xaxis:{
label:"",
renderer:$.jqplot.LinearAxisRenderer,
tickOptions:{angle:0}},
yaxis: {
label:"",
min:0,
max:10,
renderer:$.jqplot.LinearAxisRenderer,
tickOptions:{angle:0}}
},
series:[{label:'Series 1',renderer: $.jqplot.LineRenderer,showLine:true,markerOptions:{show:true, style:'filledCircle'}},{label:'Series 2',renderer: $.jqplot.LineRenderer,showLine:true,markerOptions:{show:true, style:'filledCircle'}}],zoom:true,datatip:true},'charts');});
</script>
So the answer to this question is valid for the PrimeFaces charts as well.
Running the following code (from the link above) in your browser developer tool on the zoom examples will show you the data points that fall in your zoom region
chart = PF('chart').plot;
PF('chart').plot.target.bind('jqplotZoom', function(ev, gridpos, datapos, plot, cursor){
var plotData = plot.series[0].data;
for (var i=0; i< plotData.length; i++) {
if(plotData[i][0] >= chart.axes.xaxis.min && plotData[i][0] <= chart.axes.xaxis.max ) {
//this dataset from the original is within the zoomed region
//You can save these datapoints in a new array
//This new array will contain your zoom dataset
//for ex: zoomDataset.push(plotData[i]);
console.log(plotData[i]);
}
}
});
Replacing PF(çhart') with PF('myLineChartWV') will make it work for your example to
Once you have gathered the data, you can use this in e.g. a PrimeFaces remoteCommand to pass it to the server.
Notice that this only takes the x-axis value of the zoom into account. If you want the y-axis taken into account to (so the real zoom area), add
plotData[i][1] >= chart.axes.yaxis.min && plotData[i][1] <= chart.axes.yaxis.max
to the if-statement in the loop.
Also notice it just takes the first series. If you have multiple, you have some simple homework to do.

SVG - raphael: storing last path selected so element data can be changed

The current state
As from my link you can pick different regions on the map and everything seems to be working until you re-select a county you have selected before. Data values stored with each path decide if it isSelected or notSelected. I have no problem in changing the element data just clicked with this but I can't find a way of storing the last element selected in a way that I can change it's element data. Which means I first have to click on the previous county to set it's element data to notSelected
First I define var currentcountyselected = "";. This allows me to store the paths[arr[this.id]].name;. When I click on a new path I can make the last path fill change with $('#'+currentcountyselected).attr({fill: attributes.fill});
In Raphael's for loop I set obj.data('selected', 'notSelected'); so all path elements are set to notSeelected.
So what I need is some way to store the last path so I can change it's element data
This is the click function cleaned up from live example.
obj.click(function(){
if(this.data('selected') == 'notSelected')
{this.animate({fill: '#698B22' }, 300);
this.data('selected', 'isSelected');
$('#'+currentcountyselected).attr({fill: attributes.fill});
paths[arr[this.id]].value = "isSelected";
currentcountyselected = paths[arr[this.id]].name;
}
else
{this.animate({fill: '#32CD32'}, 300);
paths[arr[this.id]].value = "notSelected"; /* set path value*/
this.data('selected', 'notSelected');
}
});/* end mark selections */
I've been working on this project for a while and the client now wants the interface to work differently. This has really ate up my hourse.
EDIT:Although I have found a solution by simply taking out the if/else I would still like to know how to get at element data in a previous path (or any path for that matter).
Here is my solution, posted as it might help someone. The link in my question has problems with click happy users.
Globals
var previouscountyselected = "Mayo"; /* default start, can be any county(path) */
var start = true;
var past = null;
Changed code
obj.click(function(){
if(paths[arr[this.id]].value == 'notSelected')
{
this.animate({fill: '#698B22'}, 200);
paths[previouscountyselected].value = "notSelected";
paths[arr[this.id]].value = "isSelected";
previouscountyselected = paths[arr[this.id]].name;
if (!start && past != this)
{
past.animate({ fill: '#fff' }, 200);
}
past = this;
start = false;
}
else if(paths[arr[this.id]].value == 'isSelected')
{
this.animate({fill: '#32CD32'}, 200);
paths[arr[this.id]].value = "notSelected"; /* set path value */
}
});
Overview
if (!start && past != this) is a little unusual and is required or animated fades get messed up and choppy. The fade is not triggered if it is the first time a path is clicked and if you just hammer clicks on one path it doesn't fade to white. The main if/else handles the actual control value.
Until I get a jsfiddle up this link will demonstrate the desired behaviour.
Note! the drop menu in this link does not work.
Click happy friendly

Slide content with page up and down

A few small questions on this web page I am putting together.
http://dansiop.com/guyc/our-team/
I am looking to get the content that appears when you click on an image to slide with the mouse as you scroll down. Not sure if this is possible, if so can anyone help.
I have tried looking but as I am such a n00b to jquery I'm not sure what I am looking for. I found some code that used the tag slide and it was not what i wanted at all so not sure what the command would be.
You need to wrap your prof_1, prof_2, etc, in a wrapper I'm going to call this wrapper prof_wrapper
<div id="prof_wrapper"></div>
jQuery(document).ready( function(){
var orig_t = jQuery("#prof_wrapper").offset().top;
var mt = jQuery("#main").offset().top;
var mh = jQuery("#main").outerHeight();
jQuery(document).bind("scroll", function(event){
var ph = jQuery("#prof_wrapper").outerHeight();
var mo = (mt+mh) - jQuery(document).scrollTop();
var t = jQuery(document).scrollTop();
if(mo <= ph){ //Find out if the #main element's offset top plus it's height minus the scroll position is less than the prof_wrapper's height; if it is, leave the prof_wrapper at the bottom of the #main element
jQuery("#prof_wrapper").css({'position':'absolute', 'bottom':'0px', 'top':'auto'});
}else if(t >= orig_t){ //Otherwise, if we have scrolled past the prof_wrapper, make the prof_wrapper follow us down
jQuery("#prof_wrapper").css({'position':'fixed', 'top':'0px', 'bottom':'auto'});
}else{ //We are probably at the top of the page, so reset the original positioning
jQuery("#prof_wrapper").css({'position':'relative', 'top':'0px', 'bottom':'auto'});
}
});
});
You need to add - position:relative to your #main element, then I think this should be pretty close. Take a look at my comment about the padding and margin on the prof_wrapper.
The positioning of absolute, assumes that #main is the first parent element to have a position assigned to it; if so, then it will use this as the positioning for the bottom.
Something like that?

Resources