Locking columns in CFGRID using extjs javascript - javascript

I am trying to create a cfgrid (Coldfusion 9) with locked columns.
I looked at the code at http://dev.sencha.com/deploy/ext-4.0.0/examples/grid/locking-grid.html and can see that the property I need to set is 'locked' = true...
here is the javascript code:
<cfsavecontent variable="headContent">
<script type="text/javascript">
function init()
{
var myGrid = ColdFusion.Grid.getGridObject('gridData');
//turn on the grid panel's lockable option - not sure if this is needed or not
myGrid.lockable = true;
//get the column model
cm = myGrid.getColumnModel();
//lock the first two columns in the grid
for(var i=0; i < 2; i++) {
var thisid = cm.getColumnId(i);
var thiscol = cm.getColumnById(thisid);
thiscol.locked = true;
//for (prop in thiscol){ document.write("object." + prop + " = " + thiscol[prop] + "<br>");}
}
//refresh the grid
ColdFusion.Grid.refresh('gridData',false);
}
</script>
</cfsavecontent>
I don't get any errors..but don't get my locked columns either.
I know I can affect the properties of the grid using this particular javascript code - I tried setting thiscol.sortable = false and that did indeed grey out the ability to sort the column.
any ideas??

I solved my problem by downloading extjs 4 and creating the js code needed..

Related

Multiple JSON parses + parsing top 10 games from Twitch API

Alright. So the following code fetches only the first channel from the list, I want it to be fetching all the streams from the JSON. ( Bonus question: How can I format all the fetched streams into a nice row-per-row grid which features three streams in each row )
<script>
var twitchApi = "https://api.twitch.tv/kraken/streams";
$.getJSON(twitchApi, function (json) {
var streamGame = json.streams[0].game;
var streamThumb = json.streams[0].preview;
var streamVideo = json.streams[0].name;
$('#twitch').append('<li><iframe src="http://player.twitch.tv/?channel=' + streamVideo + '"></iframe></li>');
}
);
</script>
And the second thing I need help with is how to create a script which fetches the top 10 games from this JSON : https://api.twitch.tv/kraken/games/top .. Should be quite similar to the one above but my brain is frozen and I need to finish this.
You can get what you need to get done with a combination of loops and inline-block elements. Here, I used jQuery to create rows of three cells each.
var twitchApi = "https://api.twitch.tv/kraken/streams";
$.getJSON(twitchApi, function (json) {
var streamRow = $("<div class='stream-row'></div>").appendTo("#twitch"); // Create first row.
var streamCell;
var streamVideo;
for (var i = 0; i < json.streams.length; i++)
{
if (i % 3 == 0 && i > 0)
{
// Create a new row every multiple of 3.
streamRow = $("<div class='stream-row'></div>");
$("#twitch").append(streamRow);
}
// Create a cell with a video and add it to the row.
streamVideo = json.streams[i].channel.name;
streamCell = $("<div>", {
css: {
"class": "stream-cell",
"display": "inline-block"
}
});
streamCell.append('<iframe src="http://player.twitch.tv/?channel=' + streamVideo + '"></iframe>');
streamRow.append(streamCell);
}
});
You use another loop for the top ten thing. The API already returns 10 games, so I used the length instead of hard-coding 10.
var twitchApi = "https://api.twitch.tv/kraken/games/top";
$.getJSON(twitchApi, function (json) {
for (var i = 0; i < json.top.length; i++)
{
// Do whatever you need here with the info from the JSON.
console.log(json.top[i].game.name)
}
});
For fetching more than one stream at same time with the same data you can use a for loop.
Fixed your streamVideo variable, ".channel" was missing before ".name"(I recommed using a JSON viewer to get a clear vision of the structure, like Online JSON Viewer
And made the script so 10 iframes are displayed(also grabbed the embed code from twitch, your embed was so small).
The styling I let it to your own, I know nothing about styling iframes, you can try setting 30% width for each, so there are 3 per row, and the others go in the bottom row.
var twitchApi = "https://api.twitch.tv/kraken/streams";
$.getJSON(twitchApi, function(json) {
for (i = 0; i < 10; i++) {
var streamGame = json.streams[i].game;
var streamThumb = json.streams[i].preview;
var streamVideo = json.streams[i].channel.name;
$('#twitch').append('<li><iframe src="https://player.twitch.tv/?channel=' + streamVideo + '" frameborder="0" scrolling="no" height="378" width="620"></iframe><li>');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Null Reference Type Error using Javascript in Sharepoint 2013

Having an issue with javascript in sharepoint 2013. We have set up javascript and it is working by changing the colours of the rows in a task list. The issue is when the user goes into quick edit, and then stops that edit, the script stops running and the colours are removed. This is the script.
<script type = "text/javascript">
SPClientTemplates.TemplateManager.RegisterTemplateOverrides({
OnPostRender: function(ctx) {
var rows = ctx.ListData.Row;
for (var i=0;i<rows.length;i++)
{
var high = rows[i]["Priority"] == "High";
if (high)
{
var rowElementId = GenerateIIDForListItem(ctx, rows[i]);
var tr = document.getElementById(rowElementId);
tr.style.backgroundColor = "#F78181";
}
}
for (var i=0;i<rows.length;i++)
{
var normal = rows[i]["Priority"] == "Normal";
if (normal)
{
var rowElementId = GenerateIIDForListItem(ctx, rows[i]);
var tr = document.getElementById(rowElementId);
tr.style.backgroundColor = "#BCF5A9";
}
}
for (var i=0;i<rows.length;i++)
{
var milestone = rows[i]["Priority"] == "Milestone";
if (milestone)
{
var rowElementId = GenerateIIDForListItem(ctx, rows[i]);
var tr = document.getElementById(rowElementId);
tr.style.backgroundColor = "#F3F781";
}
}
for (var i=0;i<rows.length;i++)
{
var goLive = rows[i]["Priority"] == "Go Live";
if (goLive)
{
var rowElementId = GenerateIIDForListItem(ctx, rows[i]);
var tr = document.getElementById(rowElementId);
tr.style.backgroundColor = "#81B1F8";
}
}
}
});
</script>
This is an image of what it looks like on page load.
(NOTE: Priority is in the table but have removed it from the screenshot as it had a users name on there)
This is when we are in quick edit mode...
and this is what happens when we stop editing.
I am trying to help someone who is working with sharepoint. This not a language I have ever used so don't really know how to solve the problem. What I have done is create some JS code that does a simple alert on post render. This did not cause any issues. However, the minute we try to deal with the table content the problem arises. At a guess I think that SharePoint is changing the ID and so the JS script is no longer pointing at the right object? Having said that I tried to write some javascript that didn't use an ID and just changed the colour of a cell if a particular value was found but that resulted in nothing happening when stop editing. Here is the code.
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$Text = $("td.ms-cellstyle.ms-vb2:contains('High')");
$Text.css("background-color", "green");
$Text.css("font-weight", "bold");
$Text = $("td.ms-cellstyle.ms-vb2:contains('Normal')");
$Text.css("background-color", "red");
$Text.css("font-weight", "bold");
});
</script>
I'm not sure of this either, but looking under what is happening I can see that the program is waiting on a GIF file and it never receives it, would this mean the post render is never called?
However, why would the alert function then run?
But I could also be way off, so was hoping someone with far more knowledge in web processes, and javascript, could help me resolve this?
The specified error occurs since in Quick Edit mode list view is rendered differently then in default mode, that causes the following selector to return null:
var rowElementId = GenerateIIDForListItem(ctx, rows[i]);
var tr = document.getElementById(rowElementId); //returns null in Quick Edit mode since tr element does not contain id attribute
since tr element does not contain id attribute when list view is rendered in Quick Edit mode.
Below is shown function for retrieving row element for default & Quick Edit modes:
function getTableRow(ctx,row)
{
var rowElementId = GenerateIIDForListItem(ctx, row);
if(!ctx.inGridMode)
return document.getElementById(rowElementId);
return document.querySelectorAll('[iid="' + rowElementId + '"]')[0];
}
Final example
Below is provided the example that demonstrates how to highlight row in List View both in default and Quick Edit modes
SP.SOD.executeFunc("clienttemplates.js", "SPClientTemplates", function() {
SPClientTemplates.TemplateManager.RegisterTemplateOverrides({
OnPostRender: function(ctx) {
var colorMapping = {"High": "#F78181","Normal": "#81B1F8","Milestone": "#F3F781","Go Live": "#81B1F8"};
var rows = ctx.ListData.Row;
for (var i=0;i<rows.length;i++)
{
var key = rows[i]["Priority"];
var color = colorMapping[key];
highlightRow(ctx, rows[i],color);
}
}
});
});
function highlightRow(ctx,row,color){
var tr = getTableRow(ctx,row);
if(tr != null)
tr.style.backgroundColor = color;
}
function getTableRow(ctx,row)
{
var rowElementId = GenerateIIDForListItem(ctx, row);
if(!ctx.inGridMode)
return document.getElementById(rowElementId);
return document.querySelectorAll('[iid="' + rowElementId + '"]')[0];
}
Gist: ListView_HighlightRows.js
Results
Pic 1. List View in Quick Edit mode
Pic 2. List View (default mode)

JS function to hide or show elements

I have to JSON files, I load them both into two tables like this:
$(window).load(function(){
$.getJSON('http://1xxxxxx/xxxxx_1_18.json', function(data) {
var output="<div class='outer'>";
for (var i in data.lbclassic118) {
output+="<div style='visibility:hidden;' class='lbclassic118'id="+"age" + data.lbclassic118[i].ageinweeks+">"+ '<table class="table table-responsive"><tr class="cabecera"><th colspan="3"><center><strong>Age (weeks)'+ data.lbclassic118[i].ageinweeks+'</strong></center></th></tr><tr><td rowspan="3">Body Weight (g)</td><td>average</td><td><strong>'+ data.lbclassic118[i].average+'</strong></td></tr><tr><td>range min</td><td><strong>'+ data.lbclassic118[i].rangemin+'</strong></td></tr><tr><td>range mmax</td><td><strong>'+ data.lbclassic118[i].rangemmax+'</strong></td></tr><tr><td rowspan="3">feed sonsumption</td><td>kj bird day</td><td><strong>'+ data.lbclassic118[i].kjbirdday+'</strong></td></tr><tr><td>g bird day</td><td><strong>'+ data.lbclassic118[i].gbirdday+'</strong></td></tr><tr><td>cumulative</td><td><strong>'+ data.lbclassic118[i].cumulative+'</strong></td></tr></table>' +"</div>";
}
output+="</div>";
document.getElementById("placeholder1").innerHTML=output;
});
});
$(window).load(function(){
$.getJSON('http://xxxxxx/xxxxxx.json', function(data) {
var output="<div class='outer'>";
for (var i in data.lbclassic1990) {
output+="<div style='visibility:hidden;' class='lbclassic1990'id="+"age" + data.lbclassic1990[i].ageinweeks+">"+ '<table class="table table-responsive"><tr class="cabecera"><th colspan="3"><center><strong>Age (weeks) '+ data.lbclassic1990[i].ageinweeks+'</strong></center></th></tr><tr><td>Egg No. per H.H.</td><td>cumul.</td><td><strong>'+data.lbclassic1990[i].cumul+'</strong></td></tr><tr><td rowspan="2">Rate of Lay %</td><td>per H.H.</td><td><strong>'+data.lbclassic1990[i].perhh+'</strong></td></tr><tr><td>per H.D.</td><td><strong>'+data.lbclassic1990[i].perhd+'</strong></td></tr><tr><td rowspan="2"> Egg Weight (g)</td><td>egg weight in week</td><td><strong>'+data.lbclassic1990[i].eggweightinweek+'</strong></td></tr><tr><td>egg mass cumul.</td><td><strong>'+data.lbclassic1990[i].eggmasscumul+'</strong></td></tr><tr><td rowspan="2">Egg Mass -- g/H.D. -- kg/H.H.</td><td>egg mass in week</td><td><strong>'+data.lbclassic1990[i].eggmassinweek+'</strong></td></tr><tr><td>egg mass cumul.</td><td><strong>'+data.lbclassic1990[i].eggmasscumul2+'</strong></td></tr></table>' +"</div>";
}
output+="</div>";
document.getElementById("placeholder2").innerHTML=output;
});
});
The information comes up as it should, I have no problems with that.
However, what I'm trying to do is just show ONE table at a time, not all the tables at the same time (don't want a table for each element in the JSONs) to be seen, but only one a time.
For that I'm implemeting a function that with a slider control will show or hide the tables.
Here's an images of the HTML output data structure:
Now, what I want to to is hide or show different DIVs (tables) with this script:
<script>
function leslider(valor) {
var elementos_lbclassic118 = document.getElementsByClassName("lbclassic118");
var elementos_lbclassic1990 = document.getElementsByClassName("lbclassic1990");
var total_elementos = elementos_lbclassic118.length + elementos_lbclassic1990.length;
var i;
for (i = 1; i < total_elementos.length+1; i++) {
document.getElementById("age"+i).style.visibility = "hidden";
}
document.getElementById("age"+valor).style.visibility = "visible";
}
However it won't work, the 1st JSON will show all the elements but never hide it, and the second one will place them all on top of each other, not sure where I'm failing.
I guess you are wrong "leslider" function.
How to use this "leslider" function, let's me see this code.
I found the culprit, I was getting length from a numeric, value. Here's the updated function.
<script>
function leslider(valor) {
var elementos_lbclassic118 = document.getElementsByClassName("lbclassic118");
var elementos_lbclassic1990 = document.getElementsByClassName("lbclassic1990");
var total_elementos = elementos_lbclassic118.length + elementos_lbclassic1990.length;
var i;
for (i = 1; i < total_elementos+1; i++) {
document.getElementById("age"+i).style.display = "none";
}
document.getElementById("age"+valor).style.display = "block";
}

Trying to call Javascript Function when SharePoint List View Web Part is filtered

I have some JavaScript that will colour row in a SharePoint list View web part depending on values in certain column.
This part works fine and the rows are coloured correctly upon page load.
The issue I have is that when the List is filtered (if you click on any of the column headers and arrange by Ascending or Descending order) the formatting is lost and the colours disappear.
I'm looking for a way for the formatting to stay or be reapplied after the filter action has completed.
If the page is refreshed, the Filter that was selected will remain in place and the colours will return.
I need a way for the colours to be reapplied once a filter has been applied instead of just on Page Load.
Thanks in advance.
Here is my current JS:
SPClientTemplates.TemplateManager.RegisterTemplateOverrides({
OnPostRender: function(ctx) {
var rows = ctx.ListData.Row;
for (var i=0;i<rows.length;i++)
{
var trimmed = rows[i]["Age"]
var final = trimmed.replace(",", "");
var oneWeek = final < 7;
var oneToTwo = final >= 7 && final <= 14;
var twoOrMore = final > 14;
if (oneWeek)
{
var rowElementId = GenerateIIDForListItem(ctx, rows[i]);
var tr = document.getElementById(rowElementId);
tr.style.backgroundColor = "#CCFFCC";
}
else if (oneToTwo)
{
var rowElementId = GenerateIIDForListItem(ctx, rows[i]);
var tr = document.getElementById(rowElementId);
tr.style.backgroundColor = "#FFEECC";
}
else if (twoOrMore)
{
var rowElementId = GenerateIIDForListItem(ctx, rows[i]);
var tr = document.getElementById(rowElementId);
tr.style.backgroundColor = "#FFCCCC";
}
}
}
}
);
So after a ton of investigation, it turns out my formatting was being overwritten at the last second after a sort or filter had taken place.
The solution was to add this to the end of the code:
ctx.skipNextAnimation = true;
This skipped the animation that shows all of the rows falling into place and allows my formatting to take effect as it should.
I would recommend to check the jquery.tablesorter.js out, this will hold your styles.
The ordering is on client side in your case, so you have to solve it there.
You can apply it for simple tables, and add a short js:
$(document).ready(function()
{
$("#myTable").tablesorter();
}
);

Knockout JS with Kendo UI Grid forgets user's selection

I have a Kendo UI Grid and I am populating and maintaining the data it displays using Knockout JS (with knockout-kendo.min.js and knockout.mapping-latest.js). When the underlying data updates, the grid also updates to reflect this change. It's working well apart from the problem outlined below.
Code presented in the following Fiddle: http://jsfiddle.net/rTtS9/
The problem is that when the grid updates, it 'forgets' the selected cell that the user has chosen, such that if they are trying to keep an eye on a certain cell value, they can't. If this data is updating sub second (which it could), this gets very silly. The are many other use-case problems too (this is a contrived one).
Is there a way to have the Kendo UI Grid avoid a complete redraw when new data arrives such that the user's selection does not get forgotten?
I thought that this issue might be because KO thought that the whole object had changed, so rather than updating an existing object, it removed and added new ones. To make sure that this isn't the case, I uniquely identify objects using “keys” via the Mapping plugin. In addition, the array remain the same length.
I think that the mapping plugin is working OK as I seem to get desired behavior with the foreach binding, whereby you can select and highlight the ID part of the list item and it won't drop your selection when the data updates. See the Fiddle to see what I mean.
In case this is helpful for anyone else, I have included my solution below which remembers which grid cells were selected before the grid is re-drawn/bound.
I have attached the following code to the Kendo Grid change and dataBound events, respectively. Note, naming conversions for my grid variables always lead with "grid" followed by "name", such as "gridName".
So for the change event:
function saveGridSelection (gridID) {
try {
var shortName = gridID.substring(4,gridID.length)
var idxGrid = ns.grids.map(function(e) {return e.name}).indexOf(shortName);
var gridID = "#grid" + shortName;
var pair=[];
var columnHeader=[];
ns.grids[idxGrid].selectedCells = [];
// Loop over selected realized volsz
$(gridID + " > .k-grid-content .k-state-selected").each(function (index, elem) {
var grid = $(gridID).data("kendoGrid");
var row = $(this).closest("tr");
var colIdx = $("td", row).index(this);
pair[index] = $('td:first', row).text();
columnHeader[index] = $(gridID).find('th').eq(colIdx).text();
if (colIdx != 0 && ns.grids[idxGrid].dataGrid.length > 0 ) { // Check if cell is permitted and has data
pairID = ns.grids[idxGrid].dataGrid.map(function(e) { return e.pair; }).indexOf(pair[index]); // Get the index for the appropriate Pair
ns.grids[idxGrid].selectedCells.push({pair: pairID, container: (colIdx - 1), pairTitle: pair[index], columnHeader: columnHeader[index] });
}
});
} catch (err) {
console.log(err);
}
}
And for the dataBound event:
function loadGridSelection (gridID) {
try {
var shortName = gridID.substring(4,gridID.length)
var idxGrid = ns.grids.map(function(e) {return e.name}).indexOf(shortName);
var gridID = "#grid" + shortName;
var grid = ns.grids[idxGrid];
var gridSelectedCells = grid.selectedCells;
var tempSelectedCells = gridSelectedCells.slice(0); // Create a temp. array to work with
$(gridID + " > div.k-grid-content > table > tbody > tr").each(function (i,e) {
var pair = $("td:nth-child(1)", this).text();
if (tempSelectedCells && typeof tempSelectedCells !== "undefined") {
var ii = tempSelectedCells.length;
while(ii--) { // Loop backwards through teh array so we can slice out the bits we're finished with.
if (pair == tempSelectedCells[ii].pairTitle) {
var row = i;
var column = tempSelectedCells[ii].container;
var noColumns = $(gridID + " > div.k-grid-content > table").find("tr:first td").length;
var cell = (row * noColumns) + 1 + column;
$(gridID).data("kendoGrid").select(gridID + " td:eq("+cell+")");
tempSelectedCells.splice(ii, 1)
}
}
}
});
} catch (err) {
console.log(err);
}
}
Improvements to code always welcome.

Categories