Context menu to add column not working when defining columns property to hide some columns - handsontable

I needed a way to create a spreadsheet where user can potentially paste in any no of columns. Currently pasting things in the spreadsheet does not work as mentioned here https://github.com/warpech/jquery-handsontable/issues/553, so I wanted to enable the context menu to add column. This works fine when you have plain array as data source and you are not setting the columns property, but if you do need to define the columns attribute then things dont work when setting the
contextMenu: ['col_right']
. I needed to define the columns property because I need to hide certain columns (as mentioned here https://github.com/warpech/jquery-handsontable/issues/120).
The only way to make things work would be to define custom action for context menu, but I am not sure how to go about it.
Here is a jsbin : http://jsfiddle.net/8V4Z5/1/
Thanks

Ok one work around that worked for me requires playing bit with the data structure. Seeing that I could only make context menu work when data source is plain array and "columns" property should not be defined , I had to provide plain array as data source. Example like:
var actualData = [
{"spreadSheetData":[ "Kia", "Nissan", "Toyota", "Honda"]},
{"year":"2008", "spreadSheetData":[10, 11, 12, 13]},
{"year":"2009", "spreadSheetData":[ 20, 11, 14, 13]},
{"year":"2010", "spreadSheetData":[30, 15, 12, 13]}
];
var data = [];
actualData.forEach(function(d){
data.push(d.spreadSheetData);
});
example: http://jsfiddle.net/Yw3WE/

As soon as you initialize a Handsontable with the columns option, you can no longer use the context menu to add a column.
A solution is to use the cell option instead.
To solve your issue, I replaced...
columns: [{
data: 1
}, {
data: 2
}, {
data: 3
}],
...with...
cells: function (row, col, prop) {
var cellProperties = {};
cellProperties.data = col;
return cellProperties;
},
Here's the working fiddle:
http://jsfiddle.net/oyxv3g9w/
Note that I also commented out a callback in the fiddle because the way it was implemented, it prevented the new column from being created despite the context menu item wasn't greyed out anymore.

Related

Display a dropdown menu only when a different cell contains a certain value

I'm very new to writing script for Google Sheets, and I'm attempting to create a spreadsheet that will only display a dropdown in a column ("Provisional Notes") if the value in a column ("Certified or Provisional" is "Provisional." If it is "Certified," the user is be able to enter data freely. I'm also wanting to remove the validation if the value changes from "Provisional". I also need the solution to run on the Google Sheets App, as this spreadsheet will be run on an iPad and/or a smartphone.
I've done quite a bit of searching, and only seem to find dropdowns that depend on other dropdowns, rather than leaving a cell blank if the initial dropdown is a certain value.
What I have come up with so far only runs once (even though I've attempted to have it occur on every edit?) Also, if the value changes from Provisional to Certified, the validation does not get removed.
For my practice, I've applied it to only 2 specific cells, rather than the entire 2 columns.
function onEdit2(e){
var dropdownCell = SpreadsheetApp.getActive().getRange('P2');
var certCell = SpreadsheetApp.getActive().getRange('J2');
var rule = SpreadsheetApp.newDataValidation().requireValueInList(['Test 1', 'Test 2'], true).build();
function insertDropdown(){
if(e.certCell.getValue() === "P"){
dropdownCell.setDataValidation(rule);
}
}
}
I greatly appreciate all suggestions!
To delete a data validation you just need to use the method setDataValidation() and set its value to null to delete the data validation present on that cell.
In the following code example, depending on the value inserted I am adding or deleting the data validation. This code example has self explanatory comments:
function onEdit(e) {
// get sheet
var sheet = SpreadsheetApp.getActive().getSheetByName('Sheet1');
// if modifications happen in A
if(e.range.getColumn()==1){
// check inserted value
if(e.range.getValue()=='Provisional'){
// create rule from a list range and set it to the same row in column B
var rule = SpreadsheetApp.newDataValidation().requireValueInList(['A','B']).setAllowInvalid(false).build();
sheet.getRange(e.range.getRow(),2).setDataValidation(rule);
}
// if it is set to certified
if(e.range.getValue()=='Certified'){
// delete any data validation that may have been in its adjacent cell
sheet.getRange(e.range.getRow(),2).setDataValidation(null);
}
}
}

Adding multiple selected values from an array to a Kendo Multi Select

Background:
I getting values from a db that will be needed to be pre-selected in a kendo multi select. I am able to do this with one word, however when the return value from the DB is multiple words I run into problems.
Problem:
I am not able to populate pre-selected values in my kendo multi select. In the best cases when I only get one returned word I am able to run these two lines var value = multiSelect.value(); multiSelect.value(["test"]); and the multi select would be populated with the test selection. However when I do multiple values from an array, it does not work the same way.
Code:
var keyWordPool = [{Words: "Test"},{Words: "Test2"}, {Words: "Test3"},
{Words: "Test4"},{Words: "Test5"}];
var returnedWords = ["Test","Test4", "Test5"]; **<< This does not work**
var returnedWords = ["Test"]; **<< This does work**
CreateandPopulateMultiSelect(keyWordPool, returnedWords)
function CreateandPopulateMultiSelect(dataSource, wordsToPopulate)
{
var multiSelect = $(".PanelMultiSelect").kendoMultiSelect({
dataSource: dataSource,
filter: "contains",
dataTextField: "Words",
dataValueField: "Words",
select: function (e) {
var item = e.item;
var text = item.text();
var stop = 0;
}
}).data("kendoMultiSelect");
var value = multiSelect.value();
multiSelect.value([wordsToPopulate]);
}
Objective:
I am not able to control the amount of words that come back from the DB, so I will need to be able to add multiple words at any given time, as well as one word. I will need to have wordsToPopulate to already be selected when a person opens a panel bar.
Well, I can't tell you exactly what is happening internally in kendo, but your wordsToPopulate variable is already an array when you pass it in to CreateandPopulateMultiSelect(). If you change
multiSelect.value([wordsToPopulate]);
to
multiSelect.value(wordsToPopulate);
it should work.
http://dojo.telerik.com/#Stephen/aMEma

Hiding columns of handsontable from javascript

Is there any way i can hide HOT columns from javascript?
The requirement is such that the column to hide will come as a parameter in javascript and based on that the respective column will show hide accordingly.
The HOT has rowHeaders and colHeaders and the data with 20 columns.
Please advise.
OUTDATED SOLUTION
Ok I founnd a possible solution. I tested it out on my own system but it's actually quite simple.
You should be using a customRenderer in your columns option. Read up about this if you aren't already. The idea is that you're giving each cell its own renderer. In this custom function, you can do something like this:
var colsToHide = [3,4,6]; // hide the fourth, fifth, and seventh columns
function getCustomRenderer() {
return function(instance, td, row, col, prop, value, cellProperties) {
if (colsToHide.indexOf(col) > -1) {
td.hidden = true;
} else {
td.hidden = false;
}
}
}
What this renderer does is hide the cells that the var colsToHide specify. All you do now is add a DOM element that lets the user pick which and so every time the table gets rendered (which happens basically after any change, or manually triggered need be), the cells in the columns specified will be hidden, keeping the data array intact like you described. And when not in colsToHide they are re-rendered so make sure you get that working as well.
Here I implemented it with very basic functionality. Just enter the index of a column into the input fields and watch the magic happen.
http://jsfiddle.net/zekedroid/LkLkd405/2/
Better Solution: handsontable: hide some columns without changing data array/object

Webgrid MVC 3 conditional row style

I am using a WebGrid to display a list of items,
I like to set the background color of the rows based on a condition. I want to set the background color of the entire row, not just one cell.
Any example?
thank you
This is an old question, but I just stumbled upon it and have an answer that I don't think is too hacky. The previous answer supplied only works if the value you're using to conditionally change the background color is the value of a table cell.
If that's not the case, you can set a data- attribute for the first cell in your table rows using the Format property of a WebGridColumn. Here, the first column of my table contains hyperlinked IDs. I'm defining it in my code-behind (controller action in MVC) and I've added a data-in-error attribute from the IsInError property of my object. You can set the value of this attribute in whatever way makes sense for your application.
new WebGridColumn
{
ColumnName = "Id",
Header = "ID",
Format = (x) => new HtmlString(String.Format("{1}", x.Value.IsInError, x.Value.Id))
});
Then, using jQuery, I find all of the rows in my table that have an anchor in the first cell of the row, and set the class of that row to 'error'.
$(document).ready(function () {
$('table tbody tr td:first-child a[data-in-error="True"]').each(function () {
$(this).parent().parent().addClass('error');
});
});
Hope this helps.
Is jQuery an option? If so, check out: http://devpinoy.org/blogs/keithrull/archive/2010/06/09/how-to-change-table-cell-color-depending-on-its-value-using-jquery.aspx

slickgrid select rows while filter is on forgets previous selections

I have a large list where I've implemented filtering. I'd like to user to be able to select some rows, filter the list, select a few more, change the filter, select more, and have all of the selections remain.
I am following this example:
http://mleibman.github.com/SlickGrid/examples/example4-model.html
Follow these steps to see my problem:
Click on the 0 row
Shift-click on the 10 row. Rows 0 through 10 are selected now.
Move the slider up to about 90%, so only a few of the rows 0 - 10 show. (For me, 2, 6, and 8 still show and are still selected.)
Ctrl-click on an un-selected row (for me, row 29)
Slide the filter back down to zero.
Now this issue is seen. For me, only rows 2, 6, 8, and 29 are selected. I would prefer that 0 through 10 and 29 remain selected. Is there an option to get this behavior? If not, can someone recommend an approach that might work?
This problem has been solved on Github.
First, add a variable to store id.
var selectedIds=[];
Second, modifiy syncGridSelection
DataView.syncGridSelection(grid, true, true, function(syncIds) { selectedIds = syncIds;});
The trick is to:
Save some indication for every selected row
As you build the filtered data, note which lines are selected in an array
Call "setSelectedRows" after "setGridData"
Here is code that does it.
// filter grid without harming selection
// grid: a SlickGrid Object
// filter: a function that receieves a "data row" and returns true if it meets the filter
function filterGrid(grid,filter) {
var oldline;
var olddata=grid.getData();
var oldselection=grid.getSelectedRows()
var newline=0;
var newdata=[];
var newselection=[];
for (oldline=0; oldline<olddata.length ; oldline++ ) {
if (filter(olddata[oldline]) {
newdata.push(olddata[oldline]);
if (oldselection.indexOf(oldline)>-1) { // note on condition: ECMA5 - in IE8 you will need to loop
newselection.push(newline);
newline++;
}
}
}
grid.setData(newdata);
grid.setSelectedRows(newselection);
grid.updateRowCount();
grid.render();
}
Note that this code DOES NOT preserve selected rows which do not pass the filter.

Resources