I am creating column model at code behind, but I am stack at creating editoption for numeric values which is a function checks the value if its numeric otherwhise alert a message but I couldn't fit javascript function at code behind.
after I model at code behind I convert to json to use at in aspx page.
c# code behind
else if (prop.PropertyType == typeof(decimal))
{
pr.name = prop.Name;
pr.index = prop.Name;
pr.sorttype = "number";
pr.editoptions = new { dataInit = numericonly };
}
aspx
function numericonly(elem) {
$(elem).numeric(false, function() { alert("Integers only"); this.value = ""; this.focus(); });
}
The problem is clear. JSON don't support functions as a type. What you easy can do is the following: 1) you fill strings as the value of dataInit on the server side. 2) you "pre-process" the column model and change illegal string values of dataInit to the reference to the corresponding function. You can "pre-process" the column model before creating of the grid or after creating inside of beforeProcessing callback or even later somewhere before starting of editing. Because dataInit will be used only during editing you have to fix dataInit at any time before the editing will be started.
To change colModel you can either use setColProp method or you can get the reference of internal colModel array by var colModel = $("#gridid").jqGrid("getGridParam", "colModel"); and then do any required modification of some columns. The code will look about as below:
function numericonly(elem) {
...
}
...
var colModel = $("#gridid").jqGrid("getGridParam", "colModel"), i, cm;
for (i = 0; i < colModel.length; i++) {
cm = colModel[i];
if (cm.editoptions != null && typeof cm.editoptions.dataInit === "string") {
switch (cm.editoptions.dataInit) {
case "numericonly":
// function numericonly is visible here and can be used
cm.editoptions.dataInit = numericonly;
break;
....
default:
delete cm.editoptions.dataInit; // delete wrong value
break;
}
}
}
The old answer contains description of the same idea for the case of custom formatters.
Related
I want to update data in a database using values from datagridview but I have not succeeded. My aim is to search through my datagrid view and if my product name exist in gridview, then I update the quantity.
if (bunifuDataGridView1.Rows.Count > 0)
{
foreach (DataGridViewRow row in bunifuDataGridView1.Rows)
{
if (Convert.ToString(row.Cells[2].Value) == bunifuTextBox11.Text)
{
row.Cells[5].Value = Convert.ToString(Convert.ToInt32(bunifuTextBox10.Text) + Convert.ToInt32(row.Cells[5].Value));
found = true;
obj5.ProductName = Convert.ToString(row.Cells[2].Value);
obj5.CostPricePerProduct = Convert.ToInt32(row.Cells[3].Value);
obj5.SellingPricePerProduct = Convert.ToInt32(row.Cells[4].Value);
obj5.Quantity = Convert.ToInt32(row.Cells[5].Value);
obj5.ExpiryDate = Convert.ToString(row.Cells[6].Value);
obj5.ProductNumber = Convert.ToInt32(obj2.ProductNumber);
obj5.Quantity = Convert.ToInt32(row.Cells[5].Value);
context.Entry.state = Entrystate.modified;
context.SaveChanges();
inboundgoods();
refreshcustomergrid();
}
}
if (!found)
{
inboundgoods();
}
}
else
{
inboundgoods();
}
I wish for my code to be able to search through datagridview for product name, and if there is a match, it should update that record by incrementing the stock quantity and save in stock database.
This is hard to debug without having the full app in front of us, but we can recommend some code changes that will assist with debugging:
if (bunifuDataGridView1.Rows.Count > 0)
{
foreach (DataGridViewRow row in bunifuDataGridView1.Rows)
{
// Compare the Product on each row, add a watch to this value to assist debugging
var product = Convert.ToString(row.Cells[2].Value);
if (product == bunifuTextBox11.Text) // consider rename bunfuTextBox11 to something meaningful, like 'ProductNameTextBox'
{
row.Cells[5].Value = Convert.ToString(Convert.ToInt32(bunifuTextBox10.Text) + Convert.ToInt32(row.Cells[5].Value)); // consider rename bunifuTextBox10 to something more meaningful like 'ProductQuantityTextBox'
found = true;
obj5.ProductName = Convert.ToString(row.Cells[2].Value);
obj5.CostPricePerProduct = Convert.ToInt32(row.Cells[3].Value);
obj5.SellingPricePerProduct = Convert.ToInt32(row.Cells[4].Value);
obj5.Quantity= Convert.ToInt32(row.Cells[5].Value);
obj5.ExpiraryDate = Convert.ToString(row.Cells[6].Value);
obj5.ProductNumber = Convert.ToInt32(obj2.ProductNumber);
obj5.Quantity = Convert.ToInt32(row.Cells[5].Value);
//context.Entry.state=Entrystate.modified;
// If your context has automatic change tracking enabled, this following line is not necessary
// But you need to make sure you are setting the State on the correct object tracker instance by passing it in to the Entry method.
var dbEntry = g.Entry(obj5);
if (dbEntry.State == EntryState.Detached)
dbEntry.State = EntryState.Added;
else
dbEntry.State = EntryState.Modified;
context.SaveChanges();
inboundgoods();
refreshcustomergrid();
}
}
if (!found)
{
inboundgoods();
}
}
else
{
inboundgoods();
}
If you are not getting to the found = true; line of code during debugging then review your comparison logic, look for spelling and whitespace issues, you may want to change the comparison to something like this if your inputs or stored data might have blank spaces or inconsistent letter casing.
if (product.Trim().Equals(bunifuTextBox11.Text.Trim(), StringComparison.OrdinalIgnoreCase))
Take the time to use meaningful names for your data entry field controls, it will make you code easier to read and understand, especially when you post code examples to forums like SO!
I have a datagridview with a combobox column that is bound to an enum as follows:
var D = (DataGridViewComboBoxColumn)dgvInputs.Columns[2];
D.ValueType = typeof(MyType);
D.ValueMember = "Value";
D.DisplayMember = "Display";
D.DataSource = new MyType[] {
MyType.Rev,
MyType.Model,
MyType.User,
MyType.Status
}.Select(x => new { Display = x.ToString(), Value = (int)x }).ToList();
The datagridview is then bound to a DataTable named ParameterTable:
BindingSource ParamSource = new BindingSource();
ParamSource.DataSource = DataEntry.ParameterTable;
dgvInputs.AutoGenerateColumns = false;
dgvInputs.DataSource = ParamSource;
dgvInputs.Columns[0].DataPropertyName = "Name";
dgvInputs.Columns[1].DataPropertyName = "Prompt";
dgvInputs.Columns[2].DataPropertyName = "Type";
dgvInputs.Columns[3].DataPropertyName = "Width";
dgvInputs.Columns[4].DataPropertyName = "Default Value";
When the user finishes editing the table, I need to validate it. In particular, I need to test that the Type has been defined in each row, and that the Default Value is compatible with the Type.
The problem is, every test I've found for checking if the Type has been set has failed. When I later try to cast the value as MyType as part of testing the default value, I get an error. When I check the .Value property on the empty Type cell in the debugger, it shows a value of "{}".
Currently, I have this code for the test, in the Validating event for the datagridview itself. I have tried various other versions and they have also failed:
foreach (DataGridViewRow Row in dgvInputs.Rows) {
if (!Row.IsNewRow) {
// test other columns ...
DataGridViewComboBoxCell Cell = (DataGridViewComboBoxCell)(Row.Cells[2]);
if (Cell == null || Cell.Value as string == string.Empty) {
// Error ...
}
MyType PType = (MyType)(Cell.Value);
How can I test if a DataGridViewComboBox cell has not been set, and what is this value "{}"?
FYI - I am using VS 2008, and .Net 3.5 SP1. Not my choice. Just what is available to me.
There are a couple problems with this code.
First, D.ValueType = typeof(MyType); is incorrect because from what I see, you are binding to int field. Just remove that line, ValueType will be inferred from the data source.
Now, the main issue. When binding to a data table, the non entered value is represented by DBNull.Value. I would suggest you checking for both null and DBNull.Value. When entered, the value type in your case will be int, but you can safely unbox it to MyType.
The code should be something like this
//...
var value = Row.Cells[2].Value;
if (value == null || value == DBNull.Value)
{
// Error ...
}
else
{
var type = (MyType)value;
// Check if type contains a valid value ...
}
I'm trying to import a ForeignKey values using ComboBox, but the ComboBox loads string values and the ForeignKey type is int,I tried to convert ToString(),then I got error:
"The left hand side of an assignment must be a variable property or indexer"
ShippingDocumentDataClassesDataContext dc = new ShippingDocumentDataClassesDataContext();
t_tracking newInvoice = new t_tracking();
newInvoice.SupplierId.ToString() = comboBox1.Text;
dc.t_trackings.InsertOnSubmit(newInvoice);
dc.SubmitChanges();
Any help would be appreciated.
This line is wrong:
newInvoice.SupplierId.ToString() = comboBox1.Text;
you are trying to assign value to method call.
Instead this line should be:
newInvoice.SupplierId = Int32.Parse(comboBox1.Text);
or safer way:
int id = 0;
if (Int32.TryParse(comboBox1.Text, out id))
{
//we get valid integer from combobox
newInvoice.SupplierId = id;
dc.t_trackings.InsertOnSubmit(newInvoice);
dc.SubmitChanges();
}
else
{
//wrong value handling code goes here
}
If I try to change a value in a ComboBox's Items, it will only actually update if the new value is different from the current value after a case-insensitive compare.
Let's make a ComboBox with one item:
ComboBox cboBox = new ComboBox();
cboBox.Items.Add("Apple");
The following code will make the ComboBox still show "Apple", even though the string should look different:
cboBox.Items[0] = "APPLE";
And the naive workaround that I've been using, which will make it display correctly:
cboBox.Items[0] = "";
cboBox.Items[0] = "APPLE";
I wanted to figure out how this was happening, so I dug around with a reflector and found this. This is the ComboBox.ObjectCollection.SetItemInternal method that gets called when you try to modify a value:
internal void SetItemInternal(int index, object value)
{
...
this.InnerList[index] = value;
if (this.owner.IsHandleCreated)
{
bool flag = index == this.owner.SelectedIndex;
if (string.Compare(this.owner.GetItemText(value), this.owner.NativeGetItemText(index), true, CultureInfo.CurrentCulture) != 0)
{
this.owner.NativeRemoveAt(index);
this.owner.NativeInsert(index, value);
if (flag)
{
this.owner.SelectedIndex = index;
this.owner.UpdateText();
}
if (this.owner.AutoCompleteSource == AutoCompleteSource.ListItems)
{
this.owner.SetAutoComplete(false, false);
return;
}
}
else
{
if (flag)
{
this.owner.OnSelectedItemChanged(EventArgs.Empty);
this.owner.OnSelectedIndexChanged(EventArgs.Empty);
}
}
}
}
That true in string.Compare is telling it to ignore the case of the string. Why was this method chosen for deciding whether or not to update the value? And why didn't they expose the case sensitivity?
Is there an alternative way to update an item in an ObjectCollection so that I don't have to guess whether or not it actually gets updated?
EDIT: I should note that the DropDownStyle is set to DropDownList: this is a read-only ComboBox that occasionally needs to be updated due to actions elsewhere in the program.
Try this, add a SelectedIndexChanged event, and inside it put:
int index = cboBox.SelectedIndex;
if (index - 1 >= 0) {
cboBox.SelectedIndex = index - 1;
cboBox.SelectedIndex = index;
}
else if (index + 1 < cboBox.InnerList.Count) {
cboBox.SelectedIndex = index + 1;
cboBox.SelectedIndex = index;
}
This is probably as "naive" as your work around, but maybe worth a try?
After submitting a report to the MSDN, it was marked as "by-design" and nothing more, so that's that.
I am trying to create a dynamic table that is being built based on the value of a search text box. The Table will have probably 6 columns of 20(max) rows.
My problem is I can't figure out how to return the data from the web-service to the JS function in a way that will allow me to extract the data that I need.
Here is the web-service method I have currently:
[WebMethod]
public v_EMU_AIR_AIR[] GetCompletionList(string prefixText)
{
NeoDataContext dataContext = new NeoDataContext();
var results = from a in dataContext.GetTable<v_EMU_AIR_AIR>()
where a.Report_Date_ID.StartsWith(prefixText) ||
a.Item_Description.Contains(prefixText) ||
a.Drw_Nbr.StartsWith(prefixText)
select a;
return results.ToArray<v_EMU_AIR_AIR>();
}
This will return an Array my objects, but in my javascript:
populateTable:function(returnList) {
var length = returnList.childNodes[0].childNodes.length
for(var i=0; i<length; i++) {
var textValue = returnList.childNodes[0].childNodes[i].textContent
$("<tr><td>" + textValue + "</td></tr>").insertAfter(this.tblResults[0].childNodes[1]);
}
}
All I can produce is a dump of the entire Object and can't pull out the specific fields that I need.
I would serialize your object using Javascript Object Notation (JSON).
Unfortunately, this feature isn't built in to the .NET framework, so you'll need to write the code yourself.
Fortunately, most of it is already done for you. Check out this link or this link for more information.
In your javascript, you can retreive the JSON object with jquery (documentation) and access the values of your properties like you would in C#
$(document).ready(function() {
$.getJSON("http://url.to.webservice.com/", function(jsonObj) {
alert(jsonObj.property);
});
});