Constant values in DataGridVIew - visual-studio-2010

I have a DataGridView with 3 columns.
I need the first two columns remain constant, These columns always have to be the same and the user will not be able to enter a different value to these.
The values for the two first columns of the DGV are in textBox1 and textBox2.
I need that when the user is going to add a new row in the DGV the first two columns automatically fill with these constant values and set the focus to the third column.
Thanks in advance

If you don't want the user to edit the first two columns, just set their ReadOnly property to true:
this.dataGridView1.Columns[0].ReadOnly = true;
As for your other criteria, first set the following property to limit control of when a new row is added (ex. click of a button):
this.dataGridView1.AllowUserToAddRows = false;
Then create your own method to add new rows when needed:
private void AddNewRow()
{
DataGridViewRow row = new DataGridViewRow();
row.CreateCells(this.dataGridView1);
row.Cells[0].Value = this.textBox1.Text;
row.Cells[1].Value = this.textBox2.Text;
this.dataGridView1.CurrentCell = row.Cells[2];
this.dataGridView1.BeginEdit(true);
}
Technically, you could do this when AllowUserToAddRows == true by handling the DataGridView.RowsAdded event and the above code slightly modified, but you'll get an annoying behavior where as soon as you enter one character into the new row, 3rd column, another new row is added and the editing cell loses focus (probably before you actually entered anything useful).

Related

Validation in a Datagridview

I have an application with a datagrid view
This datagrid is filled by code, not binded to a datasource.
All cells are editable
when a user edits a value in a cell, then i need to perform an action
Private Sub dgView_CellValidated(sender As Object, e As DataGridViewCellEventArgs)
Handles dgView.CellValidated
Dim nColumnIndex As Integer
DIm nRowIndex as Integer
If sender.iscurrentRowDirty Then
nRowIndex = e.RowIndex
nColumnIndex = e.ColumnIndex
Call UpdateRowData(nRowIndex, nColumnIndex)
End If
End Sub
The Function UpdateRowData is called when user edits en then leave the cell, but if he goes to a cell in the same row. Then this routine will be called again when the user again goes to another cell without any editing
I want this function only called once
How are you going to know if the cell’s value had “actually” changed from its original value? And what is this “action” that is taken if the cell “was” changed? Is what I am getting at… is that it is unclear “what” this “action” is doing? If it is an extensive process that may take some time and you want to avoid this “action” if the cells value doesn’t “actually” change. Then you will need to know if a cells value actually DID change. And this will require a different event and some additional code implementation on your part.
On the other hand, if the “action” is simply to update something with the new value, then it may take MORE execution steps to actually “check” if the value has changed as opposed to simply overwriting the same values. So, if the “action” is trivial, I wouldn’t bother “checking” if the values have changed.
However, if you DID need to make sure that the user “actually” did change the cells value… Then below is a crude, yet simple, solution for this.
One possible issue is if the user clicked into a cell and edited it by “actually” typing some characters, but, after the user finishes typing characters they had ended up simply re-typing what the original value was… then “technically” from the grids perspective… THAT cells value DID change. In other words, We will need to somehow get the original value of the cell “BEFORE” the user starts to edit the cell. Then we could “compare” the new value with the original value when the user tries to leave the cell.
Fortunately, there is a grid event that should make this fairly trivial to implement. The event I suggest using is the grids CurrentCellDirtyStateChanged event. This event will actually fire TWICE. The event will fire once when the cell goes into “edit” mode. And it will fire again when the user ends the same cells edit mode.
Therefore, we can take advantage of this, however, we will need to know that WHEN the event fires… is it fired when the user “enters” the cells edit mode… OR … is the event fired because the user is “ending” the cells edit mode. I do not think the event keeps track of this internally so we need to create our own “mechanism” to be able to distinguish when the event is fired on the “begin” edit and the “end” edit.
One possible solution to make this work is to create two global variables… one a bool variable called FirstIn and a string variable called OriginalValue… When the event fires the first time to “begin” the cells edit mode, we can check the FirstIn variable. If it is true then we know the cell is “beginning” the edit of the cell… this is where we would capture the cells current value and set the OrignalValue string variable so we can “check” it against the final cells value when the user ends the cells edit mode.
Capturing the current cells value and setting FirstIn to false is all we need to do. We now wait until the user ends the cells edit mode and the event fires for the second time. When it fires the second time… again we check the FirstIn variable and in this case it is false which means the cells is ending its edit mode. Here we could check the OriginalValue with the cells current value and do your “action” if they are different. And finally setting FirstIn to true to start the whole process over.
Below is an example of what is described above.
bool FirstIn = true;
string OriginalValue;
private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e) {
if (FirstIn) {
FirstIn = false;
OriginalValue = dataGridView1.CurrentCell.Value.ToString();
}
else {
string NewValue = dataGridView1.CurrentCell.Value.ToString();
FirstIn = true;
if (OriginalValue.Equals(NewValue)) {
MessageBox.Show("NO changes were made in the cell edit");
}
else {
MessageBox.Show("YES changes were made in the cell edit");
}
}
}
Sorry but I wrote this in C#, below is a VB version.
Dim FirstIn As Boolean = True
Dim OriginalValue As String
Private Sub DataGridView1_CurrentCellDirtyStateChanged(sender As Object, e As EventArgs) Handles DataGridView1.CurrentCellDirtyStateChanged
If (FirstIn) Then
FirstIn = False
OriginalValue = DataGridView1.CurrentCell.Value.ToString()
Else
Dim NewValue As String = DataGridView1.CurrentCell.Value.ToString()
FirstIn = True
If (OriginalValue.Equals(NewValue)) Then
MessageBox.Show("NO changes were made in the cell edit")
Else
MessageBox.Show("YES changes were made in the cell edit")
End If
End If
End Sub

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);
}
}
}

How to apply a common dropdown value on multiple selected rows in a Webix datatable

I need a help on applying common drop down values to multiple selected rows in a Webix datatable. Let's say I want to select all the rows of my datatable (by Ctrl+click) for which the 'Name' column has value as 'Mark' and then want to apply a common color for them (for example : green) by clicking so that it gets applied on all the rows at one go.
The snippet is here : https://webix.com/snippet/1162ccd1
Any help on how can this be achieved would be appreciated.
Thanks in advance.
Further to this post, I am including a re-phrased and a half-way solution below for the experts to dispel any confusion about the requirement :
It does not necessarily have to be those rows which have 'Name' as 'Mark'. I put it that way to give an example. Basically, it could be any randomly selected row either consecutive or haphazard and selecting a common value for them from the drop down of the 'color' column (it could be any color in that drop down ) so that its value gets assigned to those cells of those selected rows. Note, selecting a color should not change the color of the row, so there is no css effect I want here.
I have so far written the code like below, which is able to fetch the selected rows.
rows = $$("mytable").getSelectedId(true);
for (i in rows) {
id = rows[i];
item = $$("mytable").getItem(id);
/* below effect has to happen from the drop down of data table gui */
item.id2 = "green"; //for example, it could be any value
}
Can anybody please help me in:
i) how can I apply the value selected from the drop down of data table to all the selected rows ?
ii) Secondly, how can I trigger this code ( through which event ?) once they are selected in the data table and the value is chosen from the drop down ?
Thanks.
You can do something like this by adding the onBeforeFilter event, and track only color filter ("id2" in your snippet):
onBeforeFilter: function(id, value, config) {
if (id === "id2") {
const selected = this.getSelectedId(true);
const color = this.getFilter("id2").value;
for (let row in selected) {
const item = this.getItem(selected[row]);
item["id2"] = color;
this.updateItem(item.id, item);
}
}
}
Sample is here https://webix.com/snippet/538e1ca0
But I think this is not the best way.
You can also create a context menu that is displayed by right-clicking on the table and making a choice of values in it.

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

Change value of drop down of specific row in jqGrid

I have created at a table using jqGrid. In that I have a comboBox. I want the values of the combobox such that It is not used in the previous row.
But, once my first row displayed, then I am unable to change the values of comboBoc in the second row.
Ex: In my combobox, there are three values .. one, two, three. I have selected value "two" in the first row. Then the combo box of the second must have two values: one and three.
I have tried the following code:
$("#listData").setColProp('denomination',
{editoptions:{value:getDenominationList('addOperation').toString()}});
Here:
getDenominationList('addOperation') will return a String "1:one;3:three"
But this is not working.
I hope I understand correct your question and you want to change the value parameter of editoptions every time depend on the current row id or other grid contain. You can do this inside your custom dataInit event handler (see editoptions):
dataInit: function (elem) {
var v = $(elem).val();
var rowId = $(e.target).closest('tr.jqgrow').attr('id');
var newValue = getDenominationList('addOperation').toString();
$("#listData").setColProp('denomination', { editoptions: { value:newValue} });
}
The function getDenominationList used in your question don't has the rowid parameter which you probably will need. To simplified it I included in the code above the line which show how the id of the row can be got.
I recommend you to look inside the another answer which I recently answered. It showed how the initial values of value property can be reseted in case of inline editing. It you use form editing you should do this inside of onClose event handler. Moreover in case of form editing you must use recreateForm:true which will force that dataInit event handler will be called not once, but on every row editing.

Resources