Currently, I'm populating a drop down list when a file is created in a configurable folder.
if (!downloadRspDropDown.Items.Contains(new ListItem(txt, fileData.FullName))
Then, I add the file and remove "No Responses Available".
However, if the same file is resubmitted (i.e., the file name is the same but the timestamp is different), then I want to remove the older entry and replace it with a new entry in the drop down list.
I have the filename, so I go into the "else" block from the line of code above. From there, I'm checking to see if I have the same filename and a different creation time.
if (downloadRspDropDown.Items.Contains(new ListItem(txt, fileData.FullName) &&
downloadRspDropDown.Items.Contains(new ListItem(txt, fileData.CreationTime)
From here, I want to find the position, remove it, and add the new text. This approach isn't working. Can anyone offer an alternate approach?
I dont know if that is your current problem, but this line is definitly causing trouble:
if (!downloadRspDropDown.Items.Contains(new ListItem(txt, fileData.FullName))
What you probably want to achieve is a check for equality based on a value. But this line of code performs an equality check based on a reference and can't be true, because you create a new ListItem that definitly has another reference than the item already added to the Dropdownlist.
Try to use the .FindByValue method instead.
Edit based on comment:
Try something like this:
ListItem _li = downloadRspDropDown.Items.FindByValue(fileData.FullName);
if(_li != null)
{
downloadRspDropDown.Items.Remove(_li);
}
Related
I have a situation wherein a List object is built off of values pulled from a MSSQL database. However, this particular table is mysteriously getting an errant record or two tossed in. Removing the records cause trouble even though they have no referential links to any other tables, and will still get recreated without any known user actions taken. This causes some trouble as it puts unwanted values on display that add a little bit of confusion. The specific issue is that this is a platform that allows users to run a search for quotes, and the filtering allows for sales rep selection. The select/dropdown field is showing these errant values, and they need to be removed.
Given that deleting the offending table rows does not provide a desirable result, I was thinking that maybe the best course of action was to modify the code where the List object is created and either filter the values out or remove them after the object is populated. I'd like to do this in a clean, scalible fashion by providing some kind of appendable data object where I could just add in a new string value if something else cropped up as opposed to doing something clunky that adds new code to find the value and remove it each time.
My thought was to create a string array, and somehow loop through that to remove bad List values, but I wasn't entirely certain that was the best way to approach this, and I could not for the life of me think of a clean approach for this. I would think that the best way would be to add a filter within the Find arguments, but I don't know how to add in an array or list that way. Otherwise I figured to loop through the values either before or after the sorting of the List and remove any matches that way, but I wasn't sure that was the best choice of actions.
I have attached the current code, and would appreciate any suggestions.
int licenseeID = Helper.GetLicenseeIdByLicenseeShortName(Membership.ApplicationName);
List<User> listUsers;
if (Roles.IsUserInRole("Admin"))
{
//get all users
listUsers = User.Find(x => x.LicenseeID == licenseeID).ToList();
}
else
{
//get only the current user
listUsers = User.Find(x => (x.LicenseeID == licenseeID && x.EmailAddress == Membership.GetUser().Email)).ToList();
}
listUsers.Sort((x, y) => string.Compare(x.FirstName, y.FirstName));
-- EDIT --
I neglected to mention that I did not develop this, I merely inherited its maintenance after the original developer(s) disappeared, and my coworker who was assigned to it left the company. I'm not really really skilled at handling ASP.NET sites. Many object sources are hidden and unavailable for edit, I assume due to them being defined in a DLL somewhere. So, for any of these objects that are sourced from database tables, altering the tables will not help, since I would not be able to get the new data anyway.
However, I did try to do the following to filter out the undersirable data:
List<String> exclude = new List<String>(new String[] { "value1" , "value2" });
listUsers = User.Find(x => x.LicenseeID == licenseeID && !exclude.Contains(x.FirstName)).ToList();
Unfortunately it only resulted in an error being displayed to the page.
-- EDIT #2 --
I got the server setup to accept a new event viewer source so I could write info to the Application log to see what was happening. Looks like this installation of ASP.NET does not accept "Contains" as an action on a List object. An error gets kicked out stating that the method is not available.
I will probably add a bit to the table and flag Errant rows and then skip them when I query the table, something like
&& !ErrantData
Other way, that requires a bit more upkeep but doesn't require db change, would be to keep a text file that gets periodically updated and you read it and remove users from list based on it.
The bigger issue is unknown rows creeping in your database. Changing user credentials and adding creation timestamps may help you narrow down the search scope.
In a dropdown I've got a list of country of this type:
Text: "Italy" Value :"IT"
I need a copy of one of the country in the top of the list referred to the current language of the portal I'm working in, so the user can both select the first or the one into the list. Is just a hint we can say.
So I've just added a copy in this way:
cmbNazione.Items.Insert(0, cmbNazione.Items.FindByText(valori.Rows[0]["M_SOAAuthorityCountry"].ToString().ToUpper()));}
This code works fine. I got my duplicate value and I can select it without problem.
I am stuck when I already have a country that I have to set into the dropDown.
I just wrote that:
cmbNazione.Items.Insert(0, cmbNazione.Items.FindByText(valori.Rows[0]["M_SOAAuthorityCountry"].ToString().ToUpper()));
cmbNazione.ClearSelection();
cmbNazione.Items.FindByText(valori.Rows[0]["M_SOAAuthorityCountry"].ToString().ToUpper()).Selected = true;
The problem is that I receive the error: Cannot have multiple items selected in a DropDownList.
In fact if I check I got both the list Items (first, and the identical in the list) with the prop : selected = true. If I try to make one false both change to false. I cannot use them separately.
I can't understand why I can use them correctly when I select manually, as a user, but not when I try to select them through code.
I also tried something like :
cmbNazione.SelectedIndex = cmbNazione.Items.IndexOf(cmbNazione.Items.FindByText(valori.Rows[0]["M_SOAAuthorityCountry"].ToString().ToUpper()));
But nothing. I'll every time have multiple items in the list of the selected
You should not have a duplicate value as it will confuse the user (if the value is on 2-3 position already) and architecture as retrieval may lead to 2 values being selected.
Your use case seem like you are offering the most commonly used value as the first one and then the remaining. If this is the case, follow the approach outlined below.
Find the ListItem required, then remove it from the list and add on the 1st position. Then mark it as selected.
var preferredItem = cmbNazione.Items.FindByText(...);
if (preferredItem != null) {
cmbNazione.Items.Remove(preferredItem);
cmbNazione.Items.Insert(0, preferredItem);
cmbNazione.SelectedItemIndex = 0;
}
This way, there will be single item being selected and preserve the sanctity of the item (underlying value etc) while still allowing user to have the preferred one on top of list. You can chose to have this as 'pre-selected' or let user select it explictly.
using Salesforce's enterprise wsdl I am trying to save opportunity line items along with opportunity. But I am getting following error:
INVALID_FIELD: No such column 'OpportunityLineItems' on entity 'Opportunity' If you are attempting to use a custom field, be sure to append the '__c' after the custom field name. Please reference your WSDL or the describe call for the appropriate names.
Here is my code to create line items:
if (oppLineItems.Count > 0)
{
sfOpportunity.OpportunityLineItems = new QueryResult();
sfOpportunity.HasOpportunityLineItem = true;
sfOpportunity.OpportunityLineItems.records = oppLineItems.Values.ToArray();
Pricebook2 priceBook = new Pricebook2();
priceBook.PricebookEntries = new QueryResult();
priceBook.PricebookEntries.records = new List<PricebookEntry>() { priceBookEntry }.ToArray();
sfOpportunity.Pricebook2 = priceBook;
}
oppLineItems is a dictionary whole values have proxy objects of opportunity line items.
sfOpportunity is proxy object of Opportunity which is then sent to Salesforce.
There's a very similar question here, not sure if we should mark it as duplicate though: Salesforce: Creating OpportunityLineItems as part of the Opportunity in PHP
OpportunityLineItems on Opportunity isn't a real field. Its something called "relationship name"... Similar to table alias in normal databases, useful especially when you're making joins. And HasOpportunityLineItem is a readonly field :) And I don't think these should be QueryResult, check http://www.salesforce.com/us/developer/docs/api/Content/sample_create_call.htm for some hints?
You will need to insert the Opportunity first, the operation result will give you the record's Id. Then you should insert a list (array) of the line items.
This means 2 API calls and extra considerations what to do when the Opp header saves OK but one or more lines fails... So maybe it's good idea to write an Apex webservice like I suggested in that other question.
I have an ASP.Net form and I want to send an email when the user changes their data. The email should only include data that has changed, and there are about 15 data fields total.
I don't want to use an ORM since I am updating a website that a 3rd party built for us, and all their data access calls go through a custom library of theirs.
The only ways to do this I can think of is
Make another database call to get old values and compare the form values one-by-one. If they're different, append to the email.
Store original data somewhere when it's first loaded (hidden field, session, etc), and once again compare the data one field at a time and append the differences to an email
Have someone on SO tell me there's an easier and/or simpler way that I haven't thought of
All the text boxes will have a TextChanged event, you can have them mark themselves as modified. ComboBox's will have a SelectedIndexChanged event, and so on.
Edit: All changed events can check their initial values (even on reverted changes) and either mark themselves as still modified or on a revert, as un-modified.
Here are some suggestions that may / may not be useful:
Trigger on the database table and the trigger compares the old (using the DELETED table) and updated (using the INSERTED table) and then sends an email. This may or may not be viable and I am not a big advocate of triggers.
Like you have already said you could make another database call, which would be my reccommended approach.
From what you've said I think that the only way forward is to create a duplicate dataset on the form to store the old data and run a comparison at the point where you want to produce the email.
You can use Dataset.Copy to copy structure and data.
However, now that I think about it there's always the Datset.GetChanges() method and the Dataset.AcceptChanges() along with DataSet.HasChanges()
Example code from this link:
if(dataSet.HasChanges(DataRowState.Modified |
DataRowState.Added)&& dataSet.HasErrors)
{
// Use GetChanges to extract subset.
changesDataSet = dataSet.GetChanges(
DataRowState.Modified|DataRowState.Added);
PrintValues(changesDataSet, "Subset values");
// Insert code to reconcile errors. In this case, reject changes.
foreach(DataTable changesTable in changesDataSet.Tables)
{
if (changesTable.HasErrors)
{
foreach(DataRow changesRow in changesTable.Rows)
{
//Console.WriteLine(changesRow["Item"]);
if((int)changesRow["Item",DataRowVersion.Current ]> 100)
{
changesRow.RejectChanges();
changesRow.ClearErrors();
}
}
}
}
// Add a column to the changesDataSet.
changesDataSet.Tables["Items"].Columns.Add(
new DataColumn("newColumn"));
PrintValues(changesDataSet, "Reconciled subset values");
// Merge changes back to first DataSet.
dataSet.Merge(changesDataSet, false,
System.Data.MissingSchemaAction.Add);
}
PrintValues(dataSet, "Merged Values");
I have a Windows.Forms.ListView where the user shall be able to add and remove entries. Particularly, those are files (with attributes) the user can pick through a dialog. Now, I want to check whether the file names / entries I get from the file picker are already in the list; in other words, there shall only be unique items in the ListView.
I could not find any way to compare ListViewItems to check whether the exact same entry and information is already present in my ListView. The only way I see now is to:
> Loop through the files I get from the picker (multiselect is true)
> Loop through ListView.Items
compare ListViewItem.Text
> Loop through ListViewItem.SubItems
compare .Text
If during the comparisons a complete match was found, the new entry is a duplicate and thus is not added afterwards.
This seems like an awful lot of effort to do something that I would find to be a function that is not so uncommon. Is there any other way to achieve this?
The file system itself uses only the filename to test for uniqueness, so you should do the same, no need to compare sub-items too.
Items in a ListView typically represent some object. What I usually do is to assign that object (or at least some value identifying the object) to the Tag property of the corresponding ListViewItem when they are added to the list. That way you get a quite simple setup where you can compare items by getting the values from the Tag property and perform the comparison on those objects instead of the list view representation of them.