I am updating data and then I am adding them back to my list. However if I pres the update button few times on the row I will get the same line repeated few times. Can you please help how to add updated data without duplication?
First I remove
private void OnItemSelected(DocumentData selectedItem)
{
var index = Results.IndexOf(selectedItem);
Results.Remove(selectedItem);
Navigation.PushPopupAsync(new EditPopUp(selectedItem, this, index));
}
And then I update
public void UpdateValue(DocumentData selectedItem, int index)
{
var detail = new DocumentData()
{
FieldValue = selectedItem.FieldValue,
FieldDescriptor = selectedItem.FieldDescriptor,
Size = LoadSize(),
Padding = LoadPadding(),
};
Results.Insert(index, detail);
}
check for the existence of a matching item before you insert
var exists = Results.Any(r => r.FieldValue == selectedItem.FieldValue && r.FieldDescriptor == selectedItem.FieldDescriptor);
if (!exists) {
var detail = new DocumentData()
{
FieldValue = selectedItem.FieldValue,
FieldDescriptor = selectedItem.FieldDescriptor,
Size = LoadSize(),
Padding = LoadPadding(),
};
Results.Insert(index, detail);
}
Related
I'm working on a simple multi-staged registration page for a site I'm building, and I give the user the choice of choosing programs/programming languages he knows using checkboxes:
but when I hit the "next" button, in order to go to the next stage, the checkbox I checked isn't set to true, but checkbox no. 18 is set to true(although I didn't check it)
I'm certain it has something to do with the stage before this one, in which I'm building dynamically radio buttons in which the user is choosing his profession (such as Artist, singer and etc').
there are 17 radio buttons, and they are somehow interfering with the next stage, in which the checkbox's checked values are only starting from checkbox no. 18 as I mentioned earlier.
here is some of the code:
else if (int.Parse(ViewState["DivID"].ToString()) == 2)
{
// save the Birthday Date, Language and country of the user.
ViewState["year"] = int.Parse(DropDownYear.SelectedValue);
ViewState["month"] = int.Parse(DropDownMonth.SelectedValue);
ViewState["day"] = int.Parse(DropDownDay.SelectedValue);
ViewState["Language"] = int.Parse(langDropDown.SelectedValue);
ViewState["Country"] = int.Parse(CountryDropDown.SelectedValue);
// ---------------------------------------------
// change from part 2 of the registration to part 3
registrationP2.Visible = false;
BindProfessions(radios, Page);
registrationP3.Visible = true;
radios.Visible = true;
}
else if (int.Parse(ViewState["DivID"].ToString()) == 3)
{
// change from part 3 of the registration to part 4
ViewState["Profid"] = CheckRadio(radios);
registrationP3.Visible = false;
BindKnowledge(CheckboxCon, Page);
registrationP4.Visible = true;
CheckboxCon.Visible = true;
// ---------------------------------------------
//next.Visible = true;
}
else if(int.Parse(ViewState["DivID"].ToString()) == 4)
{
List<int> v = GetCheckBox(CheckboxCon);
ViewState["Knowids"] = GetCheckBox(CheckboxCon);
}
Binding methods:
public static void BindProfessions(HtmlControl ctrl, Page thispage)
{
List<Profession> Plist = Profession.GetProfessionList();
foreach (Profession p in Plist)
{
HtmlInputRadioButton rd_button = new HtmlInputRadioButton();
const string GROUP_NAME = "Professions";
rd_button.Name = GROUP_NAME;
string LinkID = "P" + p.ProfessionID.ToString();
rd_button.Attributes["id"] = LinkID;
RegisterUserControl userprofession = (RegisterUserControl)thispage.LoadControl("~/RegisterUserControl.ascx");
userprofession.imgP = p.ProfPath;
userprofession.fieldName = p.ProfName;
userprofession.IDnum = p.ProfessionID;
userprofession.RadioName = LinkID;
userprofession.EnableViewState = false;
rd_button.EnableViewState = false;
ctrl.Controls.Add(rd_button);
rd_button.Value = p.ProfessionID.ToString();
ctrl.Controls.Add(userprofession);
}
}
public static void BindKnowledge(HtmlControl ctrl, Page thispage)
{
List<Knowledge> Plist = Knowledge.RetKnowledgeList();
foreach (Knowledge p in Plist)
{
HtmlInputCheckBox rd_button = new HtmlInputCheckBox();
const string GROUP_NAME = "knowledge";
rd_button.Name = GROUP_NAME;
string LinkID = "Know" + p.ProgramID.ToString();
rd_button.Attributes["id"] = LinkID;
rd_button.Value = p.ProgramID.ToString();
RegisterUserControl userprofession = (RegisterUserControl)thispage.LoadControl("~/RegisterUserControl.ascx");
userprofession.imgP = p.ProgPath;
userprofession.fieldName = p.PName;
userprofession.IDnum = p.ProgramID;
userprofession.RadioName = LinkID;
userprofession.EnableViewState = false;
rd_button.EnableViewState = false;
ctrl.Controls.Add(rd_button);
ctrl.Controls.Add(userprofession);
}
}
checking methods for both radios and checkbox :
public static int CheckRadio(HtmlControl ctrl)
{
try
{
int counter = 0;
int id = -1;
foreach (Control rdButton in ctrl.Controls)
{
if (rdButton is HtmlInputRadioButton)
{
HtmlInputRadioButton bu = (HtmlInputRadioButton)rdButton;
if (bu.Checked)
{
counter++;
id = int.Parse(bu.Value);
}
}
}
if (counter > 1)
{
return -1;
}
return id;
}
catch (Exception e)
{
return -1;
}
}
public static List<int> GetCheckBox(HtmlControl ctrl)
{
List<int> id_list = new List<int>();
foreach (Control rdButton in ctrl.Controls)
{
if (rdButton is HtmlInputCheckBox)
{
HtmlInputCheckBox bu = (HtmlInputCheckBox)rdButton;
if (bu.Checked)
{
id_list.Add(int.Parse(bu.Value));
}
}
}
return id_list;
}
}
when debugging you can see, that if I choose the first 3 professions, the values returned to me in the List<int> v are 18, 19, and 20
photo: debugging photo
I should mention that after I create the dynamic usercontrols and checkbox/radion buttons, I'm creating them again at postback in protected void Page_Load.
I'm stuck on this for days, and I don't know from where the problem emanates, is it because of ViewState, or the way I'm creating the controls... I really don't know.
Thanks in advance, Idan.
edit:
I played with it a bit, and have found out that when I disable the Binding of the professions which I have initiated earlier in Page_load it does work correctly, page load code look at the second if statement :
protected void Page_Load(object sender, EventArgs e)
{
IsPageRefresh = false;
if (!IsPostBack)
{
ViewState["DivID"] = 1;
ViewState["postids"] = System.Guid.NewGuid().ToString();
Session["postid"] = ViewState["postids"].ToString();
}
else
{
if (ViewState["postids"].ToString() != Session["postid"].ToString())
{
IsPageRefresh = true;
}
Session["postid"] = System.Guid.NewGuid().ToString();
ViewState["postids"] = Session["postid"].ToString();
}
if (int.Parse(ViewState["DivID"].ToString()) == 3)
{
//BindProfessions(radios, Page);
}
else if(int.Parse(ViewState["DivID"].ToString()) == 4)
{
BindKnowledge(CheckboxCon, Page);
}
}
the problem is that I still need to initiate it again after hitting the button in order to get the checked value, how can I fix this thing, and why this is happening? your help would very much be appreciated.
The problem happens because the page recognize that I added 17 new checkbox's, and than when I go over them the first 17 are not checked until the 18'th(the first one of the ones that I checked) what ends up not checking the right checkbox....
And to make it clears I add the other radio buttons to a different div on the page, I don't know what is happening here
for anyone who has the same problem.
I ended up creating the object in Page_PreInit() and it solved the problem, it is recommended(by things I read) to create dynamic objects in Page_PreInit, before anything else is happening to the page.
protected void Page_PreInit(object sender, EventArgs e)
{
try
{
if (!IsPostBack && Session["DivID"] == null)
{
Session["DivID"] = 1;
}
if ((int)Session["DivID"] == 3)
{
InitBindProfessions(Page);
}
else if ((int)Session["DivID"] == 4)
{
InitBindKnowledge(Page);
}
}
catch
{
Response.Redirect("HomePage.aspx");
}
}
InitBindKnowledge and InitBindProfessions are just like BindKnowledge and BindProfession but without adding usercontrols to the control tree
This is my arraycollection
o = JSON.parse(event.result.toString());
jsonarray = new ArrayCollection(o as Array);
in this array i have a duplicate values of product name, so i wants to remove duplicacy.\
my code is here,its not working please let me know, i am a flex beginner. thanx in advance.
function removeDuplicates(item:Object):Boolean
{
var returnValue:Boolean = false;
if (!myObject.hasOwnProperty(item.ProductName))
{
myObject[item.ProductName] = item;
returnValue = true;
}
prodArray.push(myObject);
return returnValue;
}
Call the filterCollection method given below and in that use the filterfunction to remove duplicates
private var tempObj:Object = {};
private function filterCollection():void {
// assign the filter function
jsonarray.filterFunction = removeDuplicates;
//refresh the collection
jsonarray.refresh();
}
private function removeDuplicates(item:Object):Boolean {
return (tempObj.hasOwnProperty(item.ProductName) ? false : tempObj[item.ProductName] = item && true);
}
I using openxml to create a powerpoint from an web app.I created a ppt with charts and opened ppt in openxml sdk productivity tool and code which was generated with that i modified the chart data which is coming from database,Code for which i created to modify the chart data as
created a class for the code in the sdk,in that CreatePart() i added these links
ChartPart chartPart1 = slidePart1.AddNewPart<ChartPart>("rId3");
GenerateChartPart1Content(chartPart1);
// This is below code added
#if true // Injects the chart part modification process
var chartModifier1 = new ChartPartModifier();
chartModifier1.UpdateSecondChartPart(chartPart1);
#endif
EmbeddedPackagePart embeddedPackagePart1 = chartPart1.AddNewPart<EmbeddedPackagePart>("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "rId2");
GenerateEmbeddedPackagePart1Content(embeddedPackagePart1);
and created a class for ChartPartModifier()
public void UpdateSecondChartPart(ChartPart chartPart)
{
// Searchs SeriesText and its Values to replace them with your dynamic data
var seriesLabels = chartPart.ChartSpace.Descendants<SeriesText>().ToList();
var seriesValues = chartPart.ChartSpace.Descendants<Values>().ToList();
var categoryAxis = chartPart.ChartSpace.Descendants<CategoryAxisData>().ToList();
for (int i = 0; i < this._lineSecCharts.Count; ++i)
{
var yourLine = this._lineSecCharts[i];
var label = seriesLabels[i].Descendants<NumericValue>().FirstOrDefault();
var values = seriesValues[i].Descendants<NumericValue>().ToList();
var categories = categoryAxis[i].Descendants<NumericValue>().ToList();
// Replaces the label of the series
label.Text = yourLine.Label;
// Replaces the values of the series
for (int valIdx = 0; valIdx < values.Count(); ++valIdx)
{
values[valIdx].Text = yourLine.Plots[valIdx].Value.ToString();
categories[valIdx].Text = yourLine.Plots[valIdx].Category;
}
}
}
Like this is there any way to modify the data in the table,If so can any one provide me the solution is much appreciated.
I found answer after a research i'm able to update the table values from database using openxml
the below code which(if condition) added between table appending the rows and graphicdata appending
table1.Append(tableProperties1);
table1.Append(tableGrid1);
table1.Append(tableRow1);
table1.Append(tableRow2);
table1.Append(tableRow3);
table1.Append(tableRow4);
table1.Append(tableRow5);
table1.Append(tableRow6);
table1.Append(tableRow7);
#if true // Injects the table modification process
TableModifier tableModifier = new TableModifier();//Create a class
tableModifier.UpdateTable(table1);//Send the table object of which you wanted to update
#endif
graphicData1.Append(table1);
graphic1.Append(graphicData1);
In class of TableModifier
using DocumentFormat.OpenXml.Drawing;
using DocumentFormat.OpenXml.Packaging;
public class TableModifier
{
public TableModifier()
{
this.SetupDataSource();
}
public void UpdateTable(Table table)
{
var rows = table.Descendants<TableRow>().ToList();
for (int r = 0; r < rows.Count(); ++r)
{
var yourRow = this._rows[r];
var cells = rows[r].Descendants<TableCell>().ToList();
for (int c = 0; c < cells.Count(); ++c)
{
var yourCell = yourRow.Cells[c];
var text = cells[c].Descendants<Text>().FirstOrDefault();
if (text != null)
{
text.Text = yourCell.Value;
}
}
}
}
private void SetupDataSource()
{
this._rows.Add(new Row()
{
Cells = new List<Cell>()
{
new Cell(){ Value = "Products" },
new Cell(){ Value = "2010" },
new Cell(){ Value = "2011" },
new Cell(){ Value = "2012" },
}
});
for (int i = 0; i < 6; ++i)
{
var productName = string.Format("Product {0}", (char)(i + 'A'));
this._rows.Add(new Row()
{
Cells = new List<Cell>()
{
new Cell(){ Value = productName },
new Cell(){ Value = "10%" },
new Cell(){ Value = "20%" },
new Cell(){ Value = "30%" },
}
});
}
}
#region Private Data Structure
private class Row
{
public List<Cell> Cells { get; set; }
}
private class Cell
{
public string Value { get; set; }
}
#endregion
private List<Row> _rows = new List<Row>();
}
I have some data that gets pulled out of a database and mapped to an arraycollection. This data has a field called parentid, and I would like to map the data into a new arraycollection with hierarchical information to then feed to an advanced data grid.
I think I'm basically trying to take the parent object, add a new property/field/variable of type ArrayCollection called children and then remove the child object from the original list and clone it into the children array? Any help would be greatly appreciated, and I apologize ahead of time for this code:
private function PutChildrenWithParents(accountData : ArrayCollection) : ArrayCollection{
var pos_inner:int = 0;
var pos_outer:int = 0;
while(pos_outer < accountData.length){
if (accountData[pos_outer].ParentId != null){
pos_inner = 0;
while(pos_inner < accountData.length){
if (accountData[pos_inner].Id == accountData[pos_outer].ParentId){
accountData.addItemAt(
accountData[pos_inner] + {children:new ArrayCollection(accountData[pos_outer])},
pos_inner
);
accountData.removeItemAt(pos_outer);
accountData.removeItemAt(pos_inner+1);
}
pos_inner++;
}
}
pos_outer++;
}
return accountData;
}
I had a similar problem with a hierarchical task set which was slightly different as it has many root elements, this is what i did, seems good to me:
public static function convertFlatTasks(tasks:Array):Array
{
var rootItems:Array = [];
var task:TaskData;
// hashify tasks on id and clear all pre existing children
var taskIdHash:Array = [];
for each (task in tasks){
taskIdHash[task.id] = task;
task.children = [];
task.originalChildren = [];
}
// loop through all tasks and push items into their parent
for each (task in tasks){
var parent:TaskData = taskIdHash[task.parentId];
// if no parent then root element, i.e push into the return Array
if (parent == null){
rootItems.push(task);
}
// if has parent push into children and originalChildren
else {
parent.children.push(task);
parent.originalChildren.push(task);
}
}
return rootItems;
}
Try this:
AccountData:
public class AccountData
{
public var Id:int;
public var ParentId:int;
public var children:/*AccountData*/Array;
public function AccountData(id:int, parentId:int)
{
children = [];
this.Id = id;
this.ParentId = parentId;
}
}
Code:
private function PutChildrenWithParents(accountData:ArrayCollection):AccountData
{
// dummy data for testing
//var arr:/*AccountData*/Array = [new AccountData(2, 1),
// new AccountData(1, 0), // root
// new AccountData(4, 2),
// new AccountData(3, 1)
// ];
var arr:/*AccountData*/Array = accountData.source;
var dict:Object = { };
var i:int;
// generate a lookup dictionary
for (i = 0; i < arr.length; i++)
{
dict[arr[i].Id] = arr[i];
}
// root element
dict[0] = new AccountData(0, 0);
// generate the tree
for (i = 0; i < arr.length; i++)
{
dict[arr[i].ParentId].children.push(arr[i]);
}
return dict[0];
}
dict[0] holds now your root element.
Maybe it's doesn't have the best possible performance but it does what you want.
PS: This code supposes that there are no invalid ParentId's.
Here's what I ended up doing, apparently you can dynamically add new properties to an object with
object['new_prop'] = whatever
From there, I used a recursive function to iterate through any children so you could have n levels of the hierarchy and if it found anything it would pass up through the chain by reference until the original function found it and acted on it.
private function PutChildrenWithParents(accountData : ArrayCollection) : ArrayCollection{
var pos_inner:int = 0;
var pos_outer:int = 0;
var result:Object = new Object();
while(pos_outer < accountData.length){
if (accountData[pos_outer].ParentId != null){
pos_inner = 0;
while(pos_inner < accountData.length){
result = CheckForParent(accountData[pos_inner],
accountData[pos_outer].ParentId);
if ( result != null ){
if(result.hasOwnProperty('children') == false){
result['children'] = new ArrayCollection();
}
result.children.addItem(accountData[pos_outer]);
accountData.removeItemAt(pos_outer);
pos_inner--;
}
pos_inner++;
}
}
pos_outer++;
}
return accountData;
}
private function CheckForParent(suspectedParent:Object, parentId:String) : Object{
var parentObj:Object;
var counter:int = 0;
if ( suspectedParent.hasOwnProperty('children') == true ){
while (counter < suspectedParent.children.length){
parentObj = CheckForParent(suspectedParent.children[counter], parentId);
if (parentObj != null){
return parentObj;
}
counter++;
}
}
if ( suspectedParent.Id == parentId ){
return suspectedParent;
}
return null;
}
i created a form dynamically by adding each component in action script,
now i want to get back the text/data entered in to that each component dynamically?
private function loadAllComponents():void
{
var formItemArray:Array = new Array();
for(var i:int=0; i< Application.application.designList.length; i++)//which had the colonName, colComponet to be dispalyed,
{
var fm:FormItem = new FormItem();
fm.label = Application.application.designList.getItemAt(i).colName;
var comp:String = Application.application.designList.getItemAt(i).component;
switch(comp)
{
case "TextBox":
var ti:TextInput = new TextInput();
ti.id = Application.application.designList.getItemAt(i).component;
fm.addChild(ti);
break;
case "TextArea":
var ta:TextArea = new TextArea();
ta.id = Application.application.designList.getItemAt(i).colName;
fm.addChild(ta);
break;
case "ComboBox":
var mycb:myComboBox = new myComboBox();
mycb.getAllMasterCBData(Application.application.selectedgridItem, Application.application.designList.getItemAt(i).colName);
fm.addChild(mycb);
break;
case "DateField":
var df:DateField = new DateField();
df.id = Application.application.designList.getItemAt(i).component;
fm.addChild(df);
break;
}
myform.addChild(fm);
}
}
private function saveToDb():void // Here i wan to read all the formdata
{
var formItems:Array = myform.getChildren();
for each (var item:UIComponent in formItems)
{
if (item is TextInput)
{
var text:String = Object(item).text;
Alert.show("came here");
}
else if (item is DateField)
{
var date:Date = DateField(item).selectedDate;
}
}
}
]]>
</mx:Script>
<mx:Form id="myform" cornerRadius="5" borderColor="#B7BABC" borderStyle="solid" width="100%" height="100%" />
<mx:HBox width="100%" height="100%" >
<mx:Spacer width="120"/>
<mx:Button label=" Save " id="saveBtn" click="saveToDb()" />
</mx:HBox>
You're creating the input components in ActionScript, but based on this code you are not creating them dynamically; you're just hard coding them. With your given sample, you'll know the components you are creating at compile time.
You'll need to store a reference to the form items you create; make them public variables instead of 'var' local variables. Kind of like this:
protected var ti:TextInput ;
protected var ta:TextArea ;
protected var df:DateField;
Then in your creation method, do something like this:
ti = new TextInput();
ti.id = Application.application.designList.getItemAt(i).component;
fm.addChild(ti);
ta = new TextArea();
ta.id = Application.application.designList.getItemAt(i).colName;
fm.addChild(ta);
df = new DateField();
df.id = Application.application.designList.getItemAt(i).component;
fm.addChild(df);
myform.addChild(fm);
Then when you need to access them, just do something like this:
private function getMyformData()
{
ti.text;
ta.text;
}
If you're generating the form components at run time based on data, then store then form elements in an array of some sort.
You could also work something out by looping over all children of your container, although that wouldn't be my first approach.
Since poster posted more complete code; here are some additions. I added the protected array of all form items and in each 'switch' block; the new input element is pushed onto the array.
<mx:Script>
protected var itemsArray : Array = new Array();
private function loadAllComponents():void
{
var formItemArray:Array = new Array();
for(var i:int=0; i< Application.application.designList.length; i++)//which had the colonName, colComponet to be dispalyed,
{
var fm:FormItem = new FormItem();
fm.label = Application.application.designList.getItemAt(i).colName;
var comp:String = Application.application.designList.getItemAt(i).component;
switch(comp)
{
case "TextBox":
var ti:TextInput = new TextInput();
ti.id = Application.application.designList.getItemAt(i).component;
fm.addChild(ti);
itemsArray.push(ti)
break;
case "TextArea":
var ta:TextArea = new TextArea();
ta.id = Application.application.designList.getItemAt(i).colName;
fm.addChild(ta);
itemsArray.push(ta)
break;
case "ComboBox":
var mycb:myComboBox = new myComboBox();
mycb.getAllMasterCBData(Application.application.selectedgridItem, Application.application.designList.getItemAt(i).colName);
fm.addChild(mycb);
itemsArray.push(mycb)
break;
case "DateField":
var df:DateField = new DateField();
df.id = Application.application.designList.getItemAt(i).component;
fm.addChild(df);
itemsArray.push(df)
break;
}
myform.addChild(fm);
}
}
The sateToDb method will change to be something like this:
private function saveToDb():void // Here i wan to read all the formdata
{
var formItems:Array = myform.getChildren();
for each (var item:UIComponent in itemsArray )
{
if (item is TextInput)
{
var text:String = Object(item).text;
Alert.show("came here");
}
else if (item is DateField)
{
var date:Date = DateField(item).selectedDate;
}
}
}
]]>
</mx:Script>
Edited Response:
OK, I think I see the issue.
You're adding your data controls to FormItems and adding those to the Form. But then you're iterating over the Form's children and as if they were the data controls and not FormItems.
Without commenting on the rest of the code, have a look at what this updated function is doing to retrieve the data controls:
private function saveToDb():void
{
var formItems:Array = myform.getChildren();
for each (var item:FormItem in formItems)
{
var itemChildren:Array = item.getChildren();
for each (var control:UIComponent in itemChildren)
{
if (control is TextInput)
{
var text:String = Object(item).text;
Alert.show("TextInput");
}
else if (control is DateField)
{
var date:Date = DateField(item).selectedDate;
Alert.show("Date");
}
}
}
You can delete the formItemArray variable too, it's not needed since we're getting the list of children from the Form and FormItems.
Original response:
If you keep a reference to each of the dynamic form items in an Array you can iterate over each of them in your getMyFormData() function.
e.g.
protected var formItems:Array = new Array();
// Other class stuff here...
var ti:TextInput = new TextInput();
ti.id = Application.application.designList.getItemAt(i).component;
formItems.push(ti); // Add item to array.
fm.addChild(ti);
var ta:TextArea = new TextArea();
ta.id = Application.application.designList.getItemAt(i).colName;
formItems.push(ta); // Add item to array.
fm.addChild(ta);
var df:DateField = new DateField();
df.id = Application.application.designList.getItemAt(i).component;
formItems.push(df); // Add item to array.
fm.addChild(df);
myform.addChild(fm);
<mx:button click="getMyformData()"/>
private function getMyformData()
{
//How to get the myform Data dynamically here after validations... ? &
for each (var item:UIComponent in formItems)
{
if (item is TextInput || item is TextArea)
{
// Cast to Object to access the 'text' property without the compiler complaining.
var text:String = Object(item).text;
// Do something with the text...
}
else if (item is DateField)
{
var date:Date = DateField(item).selectedDate;
// Do something with the date...
}
// Insert additional type checks as needed.
}
}
You'll have to work out what to do with the data on your own though :)
If you are using a separate list make sure you clear out the formItems array when you're done with it so you don't have references to the items keeping them in memory unnecessarily.
Instead of keeping a separate array of form items you could also iterate over the children in the fm container. You might have to make some assumptions about the children you'd be accessing but it looks like you have control over all of the children being added so that's no problem.
I hope that helps...
:)