Tablesorter Set output widget options on the fly - javascript

I'm using the tablesorter fork from Mottie. I am not very experienced with javascript, but so far I got everything to work. Here is the problem:
NOW I want to have two buttons above my table to allow the download of either all rows or download just the selected rows.
For this I have the following javascript code which works partly. I just need to get it to work to download all(!) rows.
What I am doing wrong ?
Here is the portion which outputs all:
$('.downloadall').click(function(){
var $table = $('.tablesorter');
wo = $table[0].config.widgetOptions,
saved = $table.find('.output-filter-all :checked').attr('class');
wo.output_includeHTML = false;
wo.output_delivery = 'p';
// d = download p = page
wo.output_saveRows ='a';
// a = all f=filtered
$table.trigger('outputTable');
return false;
});
This works very well including the setting of all the other output options.
The following code does exactly the same thing, but I want, of course, just the selected rows.
$('.downloadselected').click(function(){
var $table = $('.tablesorter');
wo = $table[0].config.widgetOptions,
saved = $table.find('.output-filter-all :checked').attr('class');
wo.output_includeHTML = false;
wo.output_delivery = 'p';
// d = download p = page
wo.output_saveRows = saved;
// a = all f=filtered
$table.trigger('outputTable');
return false;
});
I've tried various things but with no luck.

Since I can't tell what to expect from the table HTML. I don't know what the saved variable ends up as, but it appears to be missing the leading period to make a jQuery selector for a class name.
wo.output_saveRows = '.' + saved;
Anyway, it got me thinking that currently you can't select a row based on its content, so I updated the saveRows option to now accept a filter callback function which as of this writing is currently only available in the master branch, and can be used as follows:
$('.downloadselected').click(function(){
var $table = $('.tablesorter'),
wo = $table[0].config.widgetOptions
wo.output_includeHTML = false;
wo.output_delivery = 'p';
wo.output_saveRows = function(){
// include row only if it has a checked checkbox
return $(this).find('input[type="checkbox"]:checked').length > 0;
};
$table.trigger('outputTable');
return false;
});

Well I just overlooked that the class name '.saved' is of course not correct. At the end Mottie pointed me to the right direction. Here is the solution to my original question just use the correct class name .checked and everthing works as expected.:
$('.downloadselected').click(function(){
var $this =$('#table');
var $table = $('.tablesorter');
wo = $table[0].config.widgetOptions,
wo.output_includeHTML = false;
wo.output_delivery = 'p';
// d = download p = page
//saved = '.checked';
// a = all f=filtered
wo.output_saveRows = '.checked';
$table.trigger('outputTable');
return false;
});
It

Related

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)

CKEditor get table dialog class init Value in Set Up function of another element added on dialogDefinition

PLEASE READ QUESTION BEFORE READING CODE!!!
I've added a checkbox element on Dialog definition of the table dialog (it works). Now I want the checkbox to be checked by default when the table being edited has a certain class (which is usually visible on the advanced tab). According to the documentation, I should be able to do something like this in my setup function. I've tried many things and you could hopefully help me. This is my code.
CKEDITOR.on( 'dialogDefinition', function( evt )
{
var dialog = evt.data;
if(dialog.name == 'table' || dialog.name=='tableProperties')
{
// Get dialog definition.
var def = evt.data.definition;
var infoTab = def.getContents( 'info' );
infoTab.add(
{
type: 'checkbox',
id: 'myCheckBox',
label: 'Table Has Property',
setup: function()
{
//Class to look for if I successfully get the input's value
var classValueToLookFor = 'has-property';
// The current CKEditor Dialog Instance
var thisDialog = CKEDITOR.dialog.getCurrent();
// The Element whose value I want to get
var classElement = theDialog.getContentElement('advanced','advCSSClasses');
// Trying to Get Value of this class Element According to documentation
var containedClasses = theDialog.getValueOf('advanced','advCSSClasses');
// Trying to debug the value above
console.log(containedClasses); // This shows nothing
// Trying to debug InitValue which shows something according to prototype
console.log(classElement.getInitValue()); //This also shows nothing
//Checking if Element has the class I'm looking for to mark the checkbox
if(containedClasses.indexOf(classValueToLookFor) != -1)
{
//Check current checkbox since value has been found
this.setValue('checked');
}
}
onClick: function() // You can ignore this function, just put it in case you were wondering how I'm putting the has-property, might help someone else (works well) ;)
{
var checked = this.getValue();
var classValueToSet = 'has-property';
var thisDialog = CKEDITOR.dialog.getCurrent();
var containedClasses = theDialog.getValueOf('advanced','advCSSClasses');
if(checked)
{
if(containedClasses.indexOf(classValueToSet) != -1)
{
//console.log('already contains class: '+classValueToSet);
}
else
{
containedClasses += containedClasses+" "+classValueToSet;
}
}
else
{
if(containedClasses.indexOf(classValueToSet) != -1)
{
containedClasses = containedClasses.replace(classValueToSet,'');
}
else
{
//console.log('already removed class: '+classValueToSet);
}
}
thisDialog.setValueOf('advanced','advCSSClasses',containedClasses);
}
}
}
Here are some debug statements that can be helpful to add into the setup function and understand what is going on, you shouldn't need to go through all I've went through ;)
console.log('in setup function');
console.log(classElement);
console.log(classElement._);
console.log(classElement.getInitValue());
console.log(classElement.getInputElement());
var inputElement = classElement.getInputElement();
var inputElementId = inputElement.getId();
console.log($('#'+inputElementId+'.cke_dialog_ui_input_text'));
console.log(classElement.getInputElement().value);
It would be nice to test your answer before suggesting. Many of the things I've tried should work in theory, but are practically not working.
Alright, so finally after a few days of trial and error, this is what finally worked for me. Maybe it could be helpful to someone. I'm sure there should be a much cleaner way to do this. All the best to everyone.
setup: function()
{
//This current checkbox
var checkbox = this;
//the class I want to find on my table
var var classValueToLookFor = 'has-property';
//Current Dialog instance
var thisDialog = CKEDITOR.dialog.getCurrent();
//This code below gets a <td> element in the table
var startElement = thisDialog.getParentEditor().getSelection().getStartElement();
// This gets me the parent of the <td> element which is my current table instance
var parentTable = $(startElement.$.offsetParent);
//Finally check if the table has the property I'm looking for.
if(parentTable.hasClass(classValueToLookFor))
{
//Mark the checkbox
checkbox.setValue('checked');
}
}

jQuery multiple language script

Found this script on JSFiddle that would switch between languages. The problem is. When I type in the text with <br> it displays the breaks.
How can I get it to actually break the text?
Also, how can I get it to choose a default language? So every time you reload the page it will be that language that is selected. Otherwise, nothing is displayed until you select the language manually.
Also, I would highly appreciate it, if you can recommend other such scripts that are better then this one.
function getLanguageResources(){
var fr = new Array(); var en = new Array();
fr['settings'] = "paramètres"; en['settings'] = "settings";
fr['default_feed'] = "Flux par défaut"; en['default_feed'] = "Default feed";
fr['hidden'] = "Masquer"; en['hidden'] = " Hidden";
fr['save_settings'] = "Enregistrer les paramètres"; en['save_settings'] = "Save settings";
var resources = new Array();
resources['fr'] = fr;
resources['en'] = en;
return resources;
}
function changeLanguage(lang){
var langResources = getLanguageResources()[lang];
$("span[name='lbl']").each(function(i, elt){
$(elt).text(langResources[$(elt).attr("caption")]);
});
}
$(document).ready(function() {
$("input[name='radio-language']").click(function(){
changeLanguage($(this).val());
});
});
Thanks.
To break the text, apply your string as HTML instead of text:
$(elt).html(langResources[$(elt).attr("caption")]);
To set a default language, set the checked attribute on the appropriate radio button and simulate a click event in your $(document).ready callback:
$("#radioEnglish").attr("checked", true).trigger("click");

Update div with jQuery upon entry of data

I have a form with four text input elements. Every time one of them is updated, I want the sum of the four text input boxes to be displayed in a div below without the user pushing a button. Here's what I have so far (I got the idea from here [does this only work with select?]):
var getSum = function() {
var email = $('#emailDown').val();
var internet = $('#internetDown').val();
var server = $('#serverDown').val();
var desktop = $('#pcDown').val();
//TODO:Check for integers (not needed with sliders)
var sum = email + internet + server + desktop;
$('totalHoursDown').html(sum);
}
$('#emailDown').change(getSum(event));
$('#internetDown').change(getSum(event));
$('#serverDown').change(getSum(event));
$('#pcDown').change(getSum(event));
Currently, it's not updating. (Don't worry about validating). I'm new to PHP, so I'm not sure if I should be using it in this instance.
You are missing a # or . in your selector, depending on if totalHoursDown is a class or an ID:
$('totalHoursDown').html(sum);
// Should be this if ID
$('#totalHoursDown').html(sum);
// or this if class
$('.totalHoursDown').html(sum);
Update:
I modified the code by jmar777 a bit to make it work. Try this instead:
$(function(){
var $fields = $('#emailDown, #internetDown, #serverDown, #pcDown'),
$totalHoursDown = $('#totalHoursDown');
$fields.change(function() {
var sum = 0;
$fields.each(function()
{
var val = parseInt($(this).val(), 10);
sum += (isNaN(val)) ? 0 : val;
});
$totalHoursDown.html(sum);
});
});
​Here is a working fiddle as well: http://jsfiddle.net/mSqtD/
Try this:
var $fields = $('#emailDown, #internetDown, #serverDown, #pcDown'),
$totalHoursDown = $('#totalHoursDown');
$fields.change(function() {
var sum = 0;
$fields.each(function() { sum += $(this).val(); });
$totalHoursDown.html(sum);
});
Also, in your example, you had $('totalHoursDown').html(sum);, which I'm assuming was intended to be an ID selector (i.e., $('#totalHoursDown').html(sum);.

Jquery script freezing browser but working

i'm trying to make a live search for my mobile website, I don't want to query the database every time a user type a letter so I created a ordered list with all the names that can be searched for and i'm looping through it with jquery, problem is that I have 3300 names and it's freezing the browser when it searches through them, can anyone give me a tip about better ways to do it? here is my code:
$(document).ready(function(){
$("input#search").keyup(function(){
var filter = $(this).val(), count = 0;
var html = "";
$("ol.pacientes li").each(function(){
var nome_paciente = $(this).text();
if(nome_paciente.indexOf(filter.toUpperCase()) != -1){
html = html + " " + nome_paciente;
}
$('#pacientes_hint').html(html);
});
Use the jQuery autocomplete version. You can load an array with all your names and pass it in to autocomplete, which will work on the fly.
http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/
You could change your each to:
var text = $("ol.pacientes li:contains(\""+filter.toUpperCase()+"\")").map(function() {
return $(this).text();
}).join(' ');
$('#pacientes_hint').text(text);
Besides being shorter, the only improvement will be setting the contents of $('#pacientes_hint') only at the end, which could help.
Let me know if you need a more creative solution.
First of all, you could move #pacientes_hint outside the each function.
$(document).ready(function(){
$("input#search").keyup(function(){
var filter = $(this).val(), count = 0;
var html = "";
$("ol.pacientes li").each(function(){
var nome_paciente = $(this).text();
if(nome_paciente.indexOf(filter.toUpperCase()) != -1){
html = html + " " + nome_paciente;
} // end if
}); // end each
$('#pacientes_hint').html(html);
Then, you can define ol.pacientes as a variable before the keyup handler, so it doesn't look for it everytime and in the each function, search inside the variable:
$(document).ready(function(){
var pacientes_list = $("ol.pacientes");
var pacientes_hint = $("#pacientes_hint");
$("input#search").keyup(function(){
...
$("li", $(pacientes_list)).each(function(){ // search in the container
...
}); // end each
$(pacientes_hint).html(html);

Categories