I'm trying to create a select option bar that when onChange event is triggered, it returns the index of the selected file. For the first few selections, I get the correct number for the location of its index. However, after the third selection, the index being returned becomes 1 everytime I make a selection on the selection bar. Is there a way to fix this?
function handleUtilities(selection){
var index = selection.selectedIndex;
var selected = selection.options[index].value;
accountIndex = getOneUtility(data, selected);
}
function getOneUtility(array, utility){
var start = [];
var end = [];
var cost = [];
var usage = [];
var row = 0;
utility = utility.substring(0, utility.indexOf(")")+1);
for(row = 0; row < array.length; row++){
data = array[row][0];
if(data.indexOf(utility) != -1){
row += 3;
break;
}
}
return row;
}
I believe you are overwriting data in your for loop and the update to data doesn't impact functionality until the third run.
I suggest changing data = array[row][0]; to var data = array[row][0]; based on the supplied information.
Related
I have a script that creates a table with specifications given by the user.
The issue is that when the table is printed more than once, it prints below the other table. Turning a 10x10 table into a 10x20 table. (if that makes sense)
In previous assignments I used:
//Clean grid
while(grid.firstChild)
grid.removeChild(grid.firstChild);
to clear the grid, but this assignment is using jQuery and I am not sure how to do it. I've tried:
var divBlock = document.getElementById('my_table');
while (divBlock.firstChild) {
divBlock.removeChild(divBlock.firstChild);
and
$("#my_table").empty();
and
$("#my_table").remove();
and
$('#my_table').remove('table');
but neither seem to work, here is the full code:
// TODO: clear table
var $rows = $("#rows");
var $cols = $("#cols");
var $print_button = $("#print");
var $my_table = $("#my_table");
var $stats = $("#stats");
var arr = [];
var $table_obj = $('<table>'); //Create an element
var $row_obj;
var $col_obj;
var counter = 0;
$print_button.on('click', function() {print_pattern();});
function print_pattern()
{
// Clear table
// var divBlock = document.getElementById('my_table');
// while (divBlock.firstChild) {
// divBlock.removeChild(divBlock.firstChild);
// }
// $("#my_table").empty();
$('#my_table').remove('table');
// Get row and column values
var r = $rows.val(); //Get value of rows
element
var c = $cols.val(); //Get value of cols element
// Create 2-D Array
for (var i = 0; i < r; i++) {
arr[i] = [];
}
// Double for-loop to create table
for (var i = 0; i < r; i++) {
$row_obj = $('<tr>'); // Create row
for (var j = 0; j < c; j++) {
$col_obj = $('<td>'); // Create table cell
var n = Math.floor(Math.random()*10000)%100; //Math methods:
floor and random
$($col_obj).append(n); // Append random number to table cell
$($row_obj).append($col_obj); // Append column to row
$($table_obj).append($row_obj); // Append row to table object
// if random number > 90 -> make background color yellow
if (n > 90) {
$col_obj.css('background-color', 'yellow'); //Change css
counter++; // counter for stats
}
}
$($table_obj).append($row_obj); // Append row to table object
}
$($my_table).append($table_obj); // Append table to div container
// Stats calculation
$stats.html("<b>" + (counter/(r*c)*100).toFixed(2) + "%<b>");
//Change html content
counter = 0; // reset counter
// event function for removing a row when its clicked on
$('tr').on('click', function(){ $(this).fadeOut(500); });
}
So I've tried a number of things, I am not sure if I am just getting the syntax wrong or if I am using the wrong function to clear the div tag.
If anyone can point me in the right direction that would help a lot!
Thank you.
EDIT: I figured out the issue. My original while() block worked fine when I put all the variables inside the function.
First of all, you have to distinguish variables.
A. There is a variable that has to define 1 time, and any changes will
be stored on that.
B. And there is a variable that needs to be reset every function
called.
variable on condition b you need put inside your function so it won't keep last value and make it has double value (last value + new value)
in this case i could say this variable is on condition b:
$table_obj, $row_obj, $col_obj, arr, ...
I'm trying to write a simple script for google spreadsheet.
The code should work as follows: it should be a priority list, which can be simply edited. For example I have a list of 7 tasks and want to change the priority of one task. My code simply looks for values greater or eqauls then the value I put in a cell and increments them by 1. So at the end the last task has priority 8 and I have only 7 tasks, so there is one gap somewhere.
Here is what I've already done:
function onEdit(e) {
var range = e.range;
var numRowsWithData = SpreadsheetApp.getActiveSheet().getDataRange().getNumRows();
var columnOfCellEdited = range.getColumn();
var cellEdited = range.getA1Notation();
if (columnOfCellEdited === 2) {
var valueOfEditedCell = range.getValue();
for (var i = 2; i <=numRowsWithData; i++) {
var rangeSheet = SpreadsheetApp.getActiveSheet().getDataRange();
var currentCell = rangeSheet.getCell(i, 2);
var currentValue = currentCell.getValue();
if(currentValue >= valueOfEditedCell) {
if(cellEdited == currentCell.getA1Notation()){
continue;
}
currentCell.setValue(currentValue+1);
};
}
};
};
This script works, but I've got some missing numbers, because every time I add 1 to the current value.
How to edit it to have all the numbers in proper order, without any missing ones?
I know it's not very complicated, but I don't have any idea for now:/
Thanks in advance!
Completely rewritten answer, following clarification of the question.
This function reads all of the existing priorities, including the new entry. Any existing value greater than the new one is incremented by 1. An array is used to store the row on which each value occurs. The array is then looped over, skipping any undefined entries (missing numbers), and renumbering those that do exist starting from 1.
This doesn't change the order of the rows. It simply renumbers the second column.
Where possible I've left your original code intact, and re-used your approach in the new bit.
function onEdit(e) {
var range = e.range;
var numRowsWithData = SpreadsheetApp.getActiveSheet().getDataRange().getNumRows();
var columnOfCellEdited = range.getColumn();
var cellEdited = range.getA1Notation();
if (columnOfCellEdited === 2) {
var valueOfEditedCell = range.getValue();
// get snapshot of current priorities
var priorityRows = [];
for (var row = 2; row <=numRowsWithData; row++) {
var rangeSheet = SpreadsheetApp.getActiveSheet().getDataRange();
var currentCell = rangeSheet.getCell(row, 2);
var currentValue = currentCell.getValue();
if(currentValue >= valueOfEditedCell && cellEdited !== currentCell.getA1Notation()) {
currentValue++;
};
priorityRows[currentValue] = row;
}
// renumber priorities
var newPriority = 1;
for (var i = 0; i < priorityRows.length; i++) {
var row = priorityRows[i];
if (row) {
var rangeSheet = SpreadsheetApp.getActiveSheet().getDataRange();
var currentCell = rangeSheet.getCell(row, 2);
currentCell.setValue(newPriority++);
}
}
}
}
I have written that has a for loop that will run additional code if (sheetData[i] !== "").
Ideally, I would like to run the following code after the condition, but then loop back around and run it again for the next item that matches the condition. Any ideas on how I can achieve this?
function getSheetSectionDataTest(){
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Params"); // get sheet
var sheetData = sheet.getDataRange().getValues(); //get all sheet data
var sectionNames = normalizeHeaders(normalizeHeaders(sheet.getRange('A1:A').getValues()));
var sectionData = []; // main array to contain all section data
// create an array for each section
for(h = 0; h < sectionNames.length; h++) {
sectionData[sectionNames[h]] /*property name or key of choice*/
= [];
}
for (var i = 0; i < sheetData.length; i++){ //loop through each row in the spreadsheet
var sectionName = normalizeHeaders(sheetData[i]); //return normalized camelCase section name found in column A.
if (sheetData[i] !== ""){ // Test - stop at a cell that matches the criteria and return the data table.
var headerRow = normalizeHeaders(sheetData[i+1]); //define and normalize the table headers
for (var j = i+2; j < sheetData.length; j++) { //loop through each row in the data table.
if (sheetData[j][1] !== ""){ //if there are contents in the table keep looping.
var obj = {};
sectionData[sectionName[0]].push(obj); // Need to replace ranges with a dynamic variable that gives us the current sectionName value as an object?
for (var rowColumn = 0; rowColumn < headerRow.length; rowColumn++) { //loop through each column in the current row of the table.
obj[headerRow[rowColumn]]=sheetData[j][rowColumn+1];
}
}
else { //stop when an empty cell is reached
return sectionData; //when the data table loop runs into an empty cell stop loop and return the data
}
}
}
}
};
I have an JS Array that is supposed to show only one element. It does, however its index is 1 rather than 0 and the count is 2. Also the array does not show a 0 index.
My code:
var _UnitOfMeasureRelatedUnitData = [];
var rows = $('#jqxUOMRelatedUnitsDropdownGrid').jqxGrid('getrows');
var RecordCount = 0;
if (rows.length !== 1 && rows[0]["UOMRelatedUnit_Name"] !== ""){
for(var i = 0; i < rows.length; i++){
var row = rows[i];
var _row = {};
if(row.UOMRelatedUnit_AddItem !== F) {
RecordCount += 1;
_row["Name"] = $("#txtUnitOfMeasureSetName").val();
_row["Active"] = T;
_row["UnitOfMeasureTypeID"] = $("input[type='radio'][id='rblUnitOfMeasureType']:checked").val();
_row["BaseUnitID"] = $("input[type='radio'][id='rblUnitOfMeasureBaseUnit']:checked").val();
_row["RelatedUnitDisplayOrder"] = RecordCount;
_row["RelatedUnitName"] = row.UOMRelatedUnit_Name;
_row["RelatedUnitAbbreviation"] = row.UOMRelatedUnit_Abbreviation;
_row["RelatedUnitConversionRatio"] = row.UOMRelatedUnit_ConversionOfBaseUnits;
_row["UnitOfMeasureSetID"] = UnitOfMeasureSetID;
_UnitOfMeasureRelatedUnitData[i] = _row;
}
}
....
}
In my JQx Grid, I have at least four choices. For this issue, Ive only selected the 2 choice in the Grid and its AddItem value is True, everything else is False.
What do I need to change in my logic as I can not see it at this point?
EDIT 1
I overlooked the placement of RecordCount += 1;, I will try moving it to the end of the assignments and see what happens.
EDIT 2
The placement made no difference.
Maintain another variable for indexing your data like this
var index=0; // place this outside of for loop
_UnitOfMeasureRelatedUnitData[index++] = _row;
you don't need RecordCount += 1; .
you can get the rowscount by using _UnitOfMeasureRelatedUnitData.length
I have been working on a scheduling website for the past few weeks. I am showing the schedules as PHP generated html-tables. I use merged cells for showing events. I have come to a problem when trying to delete events using JS. Since those are merged cells, using rowspan, I have to go through the table and re-adding empty cells whenever there is a need when I delete one. My solution is working fine for when my table contains one merged cell among nothing but empty cells, but with a more complex table, it fails. I can't really grasp what's wrong with it, except that it doesn't correctly find the cellIndex anymore. Does anyone have a clue? Here is what I'm talking about:
http://aturpin.mangerinc.com/table.html
(Click on an event to remove it, or attempt to anyhow)
This sample may help you find your solution. It seems to demonstrate your problem as well as have some sample code to generate a matrix to help you solve it.
EDIT: I liked the puzzle and decided to play with it for a bit, here is a "functioning" example of implementing that sample (although sometimes the table doesn't seem to redraw correctly. This should probably help you get further along the way.
function getTableState(t) {
var matrix = [];
var lookup = {};
var trs = t.getElementsByTagName('TR');
var c;
for (var i=0; trs[i]; i++) {
lookup[i] = [];
for (var j=0; c = trs[i].cells[j]; j++) {
var rowIndex = c.parentNode.rowIndex;
var rowSpan = c.rowSpan || 1;
var colSpan = c.colSpan || 1;
var firstAvailCol;
// initalized the matrix in this row if needed.
if(typeof(matrix[rowIndex])=="undefined") { matrix[rowIndex] = []; }
// Find first available column in the first row
for (var k=0; k<matrix[rowIndex].length+1; k++) {
if (typeof(matrix[rowIndex][k])=="undefined") {
firstAvailCol = k;
break;
}
}
lookup[rowIndex][c.cellIndex] = firstAvailCol;
for (var k=rowIndex; k<rowIndex+rowSpan; k++) {
if(typeof(matrix[k])=="undefined") { matrix[k] = []; }
var matrixrow = matrix[k];
for (var l=firstAvailCol; l<firstAvailCol+colSpan; l++) {
matrixrow[l] = {cell: c, rowIndex: rowIndex};
}
}
}
}
// lets build a little object that has some useful funcitons for this table state.
return {
cellMatrix: matrix,
lookupTable: lookup,
// returns the "Real" column number from a passed in cell
getRealColFromElement: function (cell)
{
var row = cell.parentNode.rowIndex;
var col = cell.cellIndex;
return this.lookupTable[row][col];
},
// returns the "point" to insert at for a square in the perceived row/column
getPointForRowAndColumn: function (row,col)
{
var matrixRow = this.cellMatrix[row];
var ret = 0;
// lets look at the matrix again - this time any row that shouldn't be in this row doesn't count.
for (var i=0; i<col; i++)
{
if (matrixRow[i].rowIndex == row) ret++;
}
return ret;
}
};
}
function scheduleClick(e)
{
if (e.target.className != 'event')
return;
//Get useful info before deletion
var numRows = e.target.rowSpan;
var cellIndex = e.target.cellIndex;
var rowIndex = e.target.parentNode.rowIndex;
var table = e.target.parentNode.parentNode;
var tableState = getTableState(table);
var colIndex = tableState.getRealColFromElement(e.target);
//Deletion
e.target.parentNode.deleteCell(cellIndex);
//Insert empty cells in each row
for(var i = 0; i < numRows; i++)
{
var row = table.rows[rowIndex + i];
row.insertCell(tableState.getPointForRowAndColumn(rowIndex+i, colIndex));
}
}