SharePoint List CSR handler are not fired - SharePoint online - sharepoint-2013

I am trying to change style of sharepoint list using CSR. I want to apply bold to title column. I have added these code in JS file and reffered as JSLink(JavaScriptDisplayTemplate) to webpart. On document ready both renderTitleHandler & preRenderHandler are registered and also preRenderHandler are called successfully. But renderTitleHandler are not fired.
Please find my code snippet,
function renderTitleHandler(ctx) {
var fieldVal = ctx.CurrentItem[ctx.CurrentFieldSchema.Name];
var title = fieldVal.toString();
var html = '';
html += '<b>' + title + '</b>';
return html;
}
function preRenderHandler(ctx) {
ctx.ListTitle = '<b>' + ctx.ListTitle + '</b>';
}
(function() {
var overrideCtx = {};
overrideCtx.Templates = {};
overrideCtx.Templates.OnPreRender = preRenderHandler;
overrideCtx.Templates.Fields = {
"Title" : {"View" : renderTitleHandler}
};
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);
})();
Thanks in advance.
Kannan.

Possibilities:
disable Minimal Download Strategy (mds). Sometimes this blocks your
javascripts caused by the async loading in the back of certain OOTB
scripts
remove the debugger;-line (is it possible that your code works when developer tools in your browser are open?)
Edit:
Found an example on my dev environment and i have the word View between quotes:
linkFilenameFiledContext.Templates.Fields = {
"Title": { "View": renderTitleHandler}
};
Hope it helps

Related

Color Status indicator in O365 SharePoint Online

I am working with O365 SharePoint Online platform with SharePoint lists around 300 items in All Items View. For the first 30 items Text to Html Javascript function successfully converts text code to Html and displays status in HTML color format, but when I am trying to select next 31 items and go ahead using the pagination the function does not able to convert Html and display only text codes. I also changed the calculated column value type to "Number" to get the HTML to render in the list view. But not being changed yet. Does anyone please who have the code handy to make this work easy? Below is the Text to HTML code used in O365 platform.
<script type="text/javascript">
function TextToHTML(NodeSet, HTMLregexp) {
var CellContent = "";
var i=0;
while (i < NodeSet.length){
try {
CellContent = NodeSet[i].innerText || NodeSet[i].textContent;
if (HTMLregexp.test(CellContent)) {NodeSet[i].innerHTML = CellContent;}
}
catch(err){}
i=i+1;
}
}
// Calendar views
var regexpA = new RegExp("\\s*<([a-zA-Z]*)(.|\\s)*/\\1?>\\s*");
TextToHTML(document.getElementsByTagName("a"),regexpA);
// List views
var regexpTD = new RegExp("^\\s*<([a-zA-Z]*)(.|\\s)*/\\1?>\\s*$");
TextToHTML(document.getElementsByTagName("TD"),regexpTD);
// This function is call continuesly every 100ms until the length of the main field changes
// after which the convert text to HTML is executed.
//
var postElemLength = 0;
function PostConvertToHtml()
{
if (postElemLength == document.getElementsByTagName("TD").length)
{
setTimeout(PostConvertToHtml,100);
}
else
{
var regexpTD = new RegExp("^\\s*<([a-zA-Z]*)(.|\\s)*/\\1?>\\s*$");
TextToHTML(document.getElementsByTagName("TD"),regexpTD);
}
}
// Grouped list views
ExpGroupRenderData = (function (old) {
return function (htmlToRender, groupName, isLoaded) {
var result = old(htmlToRender, groupName, isLoaded);
var regexpTD = new RegExp("^\\s*<([a-zA-Z]*)(.|\\s)*/\\1?>\\s*$");
TextToHTML(document.getElementsByTagName("TD"),regexpTD);
// start the periodic callback to check when the element has been changed
if(isLoaded == 'false')
{
postElemLength = document.getElementsByTagName("TD").length;
setTimeout(PostConvertToHtml,100);
}
};
})(ExpGroupRenderData);
// Preview pane views
if (typeof(showpreview1)=="function") {
showpreview1 = (function (old) {
return function (o) {
var result = old(o);
var regexpTD = new RegExp("^\\s*<([a-zA-Z]*)(.|\\s)*/\\1?>\\s*$");
TextToHTML(document.getElementsByTagName("TD"),regexpTD);
};
})(showpreview1);
}</script>
Below is the generated text code which needs to be converted to Html used in calculated columns. Thanks.
=IF([Trend]="Cancelled","DarkGray",IF([Trend]="Completed","DodgerBlue",IF([Trend]="Declining","DarkOrange",IF([Trend]="Improving","ForestGreen",IF([Trend]="No Change","ForestGreen",IF([Trend]="Not Started","White",IF([Trend]="On Hold","DarkGray","")))))))
And..
="<div style='position:relative;display:inline-block;width:100%;'>
<div style='width:100%;display:inline-block;text-align:center;border:1px solid "&[VPN provisioning_Clr]&";position:absolute;color:"&[VPN provisioning_Clr]&";'> "&[VPN provisioning]&"
</div>
<div style='display:inline-block;width: 100%;background-color:"&[VPN provisioning_Clr]&";text-align:center;border:1px solid;z-index:-1;filter:alpha(opacity=20);opacity:0.2;'>"&[VPN provisioning]&"
</div>
</div>"
Assuming you are using the Classic UI in SharePoint Online...
Two possible issues:
Check to see if the site has the Minimal Download Strategy enabled.
If so disable it and test your code. MDS often is the cause for JavaScript running only once. (The page is not reloaded, only the data area.)
The loading of the next page of the list is via a Web Service call and that may not be triggering your JavaScript. (Again, the page is not reloaded, only the data area.) You may need to intercept the paging link to insure your code is run. (Also check to see if the "Asynchronous Load" option has been enabled. Edit the page, edit the web part, and expand the "AJAX Options" section.)
You may want to take a look at a workflow plus a Calculated column solution to add the color coding. See: http://techtrainingnotes.blogspot.com/2018/01/adding-html-to-sharepoint-columns-color.html

Sharepoint 2013 - Open search result in new window/tab

Ok, so I've been struggling with this problem for a few hours now...
I need to modify the links in the search results, so that they open in a new window/tab.
Specifically it's the search results that links to a "off-site"-hit.
I've created a copy of Item_WebPage.html, but I just can't get it to work.
I guess that there are some kind of async loads that screws it all up.
My js-code is as follows:
var anchors = document.getElementsByClassName('ms-srch-item-link');
for (var i = 0; i < anchors.length; i++) {
anchors[i].setAttribute("target", "_blank");
}
}
However, "anchors" always is "0".
Is there a "sharepoint-document-ready-as-h*ll"-function I can use?
My guess is that my problem is that not all content is loaded into the DOM before I run my code...
A custom display template is a good way of changing the behavior of the search results. I've used JQuery code to make sure that external links always load in a new window :
<script type="text/javascript">
if (window.jQuery) {
$(window).load(function () {
// Open external links in a new tab
var url = '://' + window.location.hostname;
// get the current website name, and i add :// to make sure we're looking at the right name //
url = url.toLowerCase(); // lowercase everything to compare apples to apples
$("a").each(function () {
var link = this; // assign the link object to another variable for easier managability
var linkHref = link.href.toLowerCase(); // lower case it
if (linkHref.indexOf(url) < 0 && linkHref.indexOf('javascript:') < 0) { // check to see if this A object has this domain in it and make sure it's not a javascript call
link.target = '_blank'; // change the target to be in the new window
} if (linkHref.indexOf('.pdf') > 0) { // check to see if this is a PDF
link.target = '_blank'; // change the target to be in the new window
$(link).removeAttr("onclick"); //remove the SP click event
} if (linkHref.indexOf('/forms/') > 0 && linkHref.indexOf(').aspx') > 0) { //check for links in the forms library
link.target = '_blank'; // change the target to be in the new window
$(link).removeAttr("onclick"); //remove the SP click event
}
});
});
}
</script>
It's way too long and you may have resolved it.
I was looking for the same and added - target="_blank" to the anchor tag in a custom display template
In SharePoint online, this worked perfectly for me, applies to all results though.
Using SharePoint Designer, update the Item_CommonItem_Body.html Display Template from within _catalogs/masterpage/display templates/search.
Search for below line :
var titleHtml = String.format('<a clicktype="{0}" id="{1}" href="{2}" class="ms-srch-item-link" title="{3}" onfocus="{4}" {5} >{6}</a>',
and replace it with :
var titleHtml = String.format('<a clicktype="{0}" id="{1}" href="{2}" class="ms-srch-item-link" title="{3}" onfocus="{4}" {5} target="_blank">{6}</a>',
Save the change and, from the browser master page library, publish a major version. When you search now the results should open in new tabs although you may need to load the page cache again (CTRL+F5).
From https://social.technet.microsoft.com/Forums/ie/en-US/a7db8389-3740-4ff6-ac52-645776b29a56/search-results-in-new-tabwindow-in-sharepoint-2013

Meteor subscriptions using deps

I'm trying to implement a searching feature in a Meteor application that re-subscribes/publishes a collection on every search, so there is only the exact Collection necessary in the client. I'm creating a reactive variable searchString, then changing it to the text in the search box on every search, then splitting the string into tags:
// Client
var searchString = "";
var searchStringDep = new Deps.Dependency;
var getSearchString = function(){
searchStringDep.depend();
return searchString;
}
var handle = Deps.autorun(function(){
var tags = getSearchString().split(" ");
tags = _.map(tags, function(tag){
return tag.replace(/[^\w]/g, "");
}).filter(function(t){
return t.toLowerCase();
});
Meteor.subscribe('results', tags);
});
Template.library.events({
'submit form': function(ev){
ev.preventDefault();
searchString = ev.target.search.value;
searchStringDep.changed();
}
})
Then, publishing a new Collection on the server, based on the tags:
// Server
Meteor.publish('results', function(tags){
regTags = _.map(tags, function(tag) { return new RegExp(tag)});
return Samples.find({tags: {$in: regTags}})
});
So I'm trying to match on regexes, but am having a weird issue where the subscription only changes when I add another tag, but changing existing tags fails.
So if the first searchString was tag1 and the second tag1 tag2, it works fine.
But if the first is tag1 and the second is tag2, the Collection doesn't update.
Any help is appreciated...I'm a beginner to Meteor, so if there is a better way to do what I'm trying to do, all suggestions are welcome. Thanks so much
'change #search': function(){
Meteor.subscribe('sampleResults', $('#search').val()); // or if you want on submit it's the same idea
}
and publish like
Meteor.publish('sampleResults, function(text){
return Samples.find({tags: {$regex: text}});
}
A few things:
1) Meteor has a very nice way of setting up reactive variables with the ReactiveVar component. I would suggest using that rather than creating another dependency for a variable.
2) The name that you are subscribing to: results is different than what is published on the server sampleResults and that can cause issues.
3) If you are on Meteor >= 0.9.1 you should be using Tracker and not Deps. You can use Deps if you want, but the new updated API is Tracker and is probably more stable. See the changelog for more details on that.
4) You don't have to set your Deps.autorun function equal to a variable. So you can have it as:
Tracker.autorun(function() {
// Code here
});

passing HTML to template in Meteor

I'm making my first Meteor app - a regular expression matcher is the first component that I'm making. It will highlight matching items in an editable string by surrounding the matches with a span tag.
I figured out how to create the tags around matches in vanilla JavaScript:
http://jsbin.com/iXUVUJA/1/
But the way I added it into a Meteor template, the tags are being shown in the browser. Is there a way to have the tags read as html in the browser?
Here is the relevant code from my .js file:
var str = "There are thousands and thousands of uses for corn... All of which I will tell you about right now.";
var regEx = /[A-Z]/g;
if (Meteor.isClient) {
Template.sampleText.someText = function() {
return str.replace(regEx, ("span class='highlighted'>" + "$&" + "</span>") );
};
}
And here is the relevant code from my .html file:
<template name="sampleText">
{{someText}}
</template>
This is the output on the page from the server:
span class='highlighted'>There are thousands and thousands of uses for corn... span class='highlighted'>All of which span class='highlighted'>I will tell you about right now.
You can use Handlebars.SafeString, as seen in the Handlebars documentation. In your case you can do:
if (Meteor.isClient) {
Template.sampleText.someText = function() {
var element = str.replace(regEx, ("span class='highlighted'>" + "$&" + "</span>") );
return new Handlebars.SafeString(element);
};
}

Django - jquery : populate combobox based on selection of another combobox

I am quite new to Django and jquery stuff. I am trying to populate a comboBox (ChoiceField in Django) based ont the choice selected in another comboBox (without reloading the page).
I can't find any simple example of such a basic application of ajax.
For now I'm call the following ajax function when I select an item from the first dropdown list.
function get_asset_from_type(){
var type_asset = $("#id_type").val();
var data = {type_asset:type_asset};
var args = {type:"POST", url:"/asset/etatType/", data:data};
$.ajax(args);
alert(type_asset);
return false;
};
It alerts the right type but gives a 403 error on the given url. Weird thing is this url works the first time I load the page. I don't understand what's going on..
EDIT:
403 error seems to be gone, remains the initial question :)
I think you're running up against a CSRF problem. As Django by default blocks POST requests that do not have a CSRF Token with a 403. There are a couple ways to deal with this in JS. One is to pull the value out of the cookie, the code to do that can be found here: https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax
or you can do it by passing the CSRF_TOKEN in with the javascript script tag:
<script src='myjavascript.js?CSRF_TOKEN={{ csrf_token }}'></script>
Note that it's using a double braket, instead of {%%}. This gets the value of the token, instead of the form input.
function getOptionsFromScriptSrc() {
// Get last script tag in parsed DOM.
// Due to the way html pages are parsed,
// the last one is always the one being loaded.
var options = {}
var js_src = $('script').last().attr('src');
if(js_src.match(/\?/)) {
var options_list = js_src.split('?')[1].split('&');
for(var i = 0; i < options_list.length; i++) {
var tmp = options_list[i].split('=');
options[$.trim(tmp[0])] = $.trim(tmp[1]);
}
}
return options;
}
function get_asset_from_type(){
var options = getOptionsFromScriptSrc();
var type_asset = $("#id_type").val();
var data = {type_asset: type_asset, csrfmiddlewaretoken: options['CSRF_TOKEN']};
var args = {type:"POST", url:"/asset/etatType/", data:data};
$.ajax(args);
alert(type_asset);
return false;
};
I haven't, of course, tested this code, but I have used this method before and it works pretty well.
To the main problem of populating a select box, you need to specify a callback for your ajax post, and then deal with the data returned from your server:
function get_asset_from_type(){
var options = getOptionsFromScriptSrc();
var type_asset = $("#id_type").val();
var post_data = {type_asset: type_asset, csrfmiddlewaretoken: options['CSRF_TOKEN']};
$.post('/asset/etatType/', post_data, function(data){
// Assuming server is going to respond with the html of the options, eg: <option value="1">One</option><option value="2">Two</option>...
$('#id_ofmyselectbox').append(data);
});
};