Fill dropdown list from xml with linq - asp.net

i have the following xml doc:
<?xml version="1.0" encoding="utf-8" ?>
<dropdowns>
<dropdown name="DropDownLoc">
<menu text="Select" value="-1" />
<menu text="North" value="1200" />
<menu text="South" value="1400" />
</dropdown>
<dropdown nome="DropDownEsp">
<menu text="Select" value="-1" />
<menu text="Est" value="7" />
<menu text="Ovest" value="9" />
</dropdown>
</dropdowns>
I want to read this xml and fill two dropdowns with a method given the dropdownlist name (like "DropDownEsp")
I want to accomplish this with linq, who can help me please ?

Below is code which would help you read XML and create a list of items (ListItem):
// or use XDocument.Parse("xml string") to parse string
XDocument xdoc = XDocument.Load(#"c:\testxml.xml");
var dropLists = xdoc.Descendants("dropdown")
.Select(d => d.Descendants("menu").Select(m =>
new /* new ListItem(text, value) */
{
Text = m.Attribute("text"),
Value = m.Attribute("value")
}))
.ToList();
Try adding items into controls yourself.

If you have an empty <asp:DropDownList ID="DynamicDropDown" runat="server" /> control on your .aspx page, you can data bind it a the results of a LINQ query like this:
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
// Assuming your XML file is in the App_Data folder in the root of your website
string path = Server.MapPath("~/App_Data/DropDowns.xml");
// Let's say we want to use the options from the second <dropdown>-tag in your XML
string whichDropDown = "DropDownEsp";
// This is the LINQ query to find those options from the XML
// and turn them into ListItem objects
var query =
from dropDown in XDocument.Load(path).Descendants("dropdown")
where dropDown.Attribute("name").Value == whichDropDown
from name in dropDown.Descendants("name")
let text = name.Attribute("text").value
let value = name.Attribute("value").value
select new ListItem(text, value);
// Now we data bind the query result to the control
DynamicDropDown.DataSource = query;
DynamicDropDown.DataBind();
}
}
In the LINQ query we first select only the <dropdown> element with the right name (based on the whichDropDown variable). Then we select all the <name> elements, and from each one we put the attributes in the text and value values. Then we use these values to create a new ListItem (one is created for each <name> element).
This result can then be used to data bind the <asp:DropDownList> control.

Related

SAPUI5 How to display only the first value of an entitySet

I'm currently working on an app for displaying some data, which I get from an EntitySet.
The mockup for my application looks like this:
On the top, I have an input Field with a button to apply the filter with the value of the input.
After that, there are 5 ObjectListItems at the moment. I don't know if its the right thing to use.
Under these boxes, there is a table to display further information about the chosen entry. The table works as intended and looks good.
My Problem now lies within these 5 Boxes.
{Binding1} to {Binding5} contains always the same Value for one giving "Input Value". Which means, {Binding1} for example would be 7 times Value1 and {Binding2} 7 times Value2. Now i want these to be shown only one time in there own Box.
Values, which are differ per row, are shown in the table below.
I don't know how I could make this work...
View:
<l:VerticalLayout width="100%">
<l:BlockLayout background="Dashboard">
<l:BlockLayoutRow>
<l:BlockLayoutCell width="100%">
<Title text="Test {Binding1} - {Binding2}"/>
</l:BlockLayoutCell>
</l:BlockLayoutRow>
<l:BlockLayoutRow>
<l:BlockLayoutCell width="50%">
<ObjectListItem
intro="Site"
icon="sap-icon://building"
title="{Binding3}"
/>
</l:BlockLayoutCell>
<l:BlockLayoutCell width="50%">
<ObjectListItem
intro="Adress"
icon="sap-icon://addresses"
title="{Binding4}"
/>
</l:BlockLayoutCell>
</l:BlockLayoutRow>
<l:BlockLayoutRow>
<l:BlockLayoutCell width="50%">
<ObjectListItem
intro="Supplier"
icon="sap-icon://supplier"
title="{Binding5}"
/>
</l:BlockLayoutCell>
<l:BlockLayoutCell width="50%">
<ObjectListItem
intro="Currency"
icon="sap-icon://lead"
title="{Binding6}"
/>
</l:BlockLayoutCell>
</l:BlockLayoutRow>
</l:BlockLayout>
</l:VerticalLayout>
<Table
id="table1"
items="{path: '/EntitySet'}">
<columns>
<Column>
<Text text="Category"/>
</Column>
...
</columns>
<items>
<ColumnListItem>
<cells>
<Text text="{Category}"/>
...
</cells>
</ColumnListItem>
</items>
</Table>
Controller:
return Controller.extend("com.zf.cmi.zz1ui5_ivdp.controller.View", {
onInit: function() {
},
onPress: function() {
var oTable = this.getView().byId("table1");
var oTableBinding = oTable.getBinding("items");
var filter = new sap.ui.model.Filter("InvoiceNo", sap.ui.model.FilterOperator.EQ, this.byId("search").getValue());
oTableBinding.filter(filter);
}
});
Is there a way to show the value of {Binding1} - {Binding5} only one time at their given Box?
*edit
As an addition, the result of my XML model would look like this:
Entry1: Entry2: Entry3:
Binding1 = a Binding1 = a Binding1 = a
Binding2 = b Binding2 = b Binding2 = b
Binding3 = ... Binding3 = ... Binding3 = ...
Binding10 = 1 (Table) Binding10 = 2 Binding10 = 3
If It's a JSON Model you can use binding path like this {/Binding1/0}.
If It's a XML Model you need to know the KEY to set the binding path like this {/Binding1('Key')}. If you don't know the key, you have to use JS in controller to get it or change/create your service to return the data in an away better to you UI5 show it.
Using JS Controller
onInit: function () {
this.getView().bindElement({
path: "/BINDING_PATH",
events: {
dataReceived: function (oEvent) {
var data = oEvent.getParameter('data');
var array_paths = oEvent.getSource().getModel();
}.bind(this),
}
});
}
Now on data you have all data returned by service, and on array_path you have an array with path and data, you can get the array KEY (that's the service path) to binding to your controls.
<ObjectListItem
intro="Site"
icon="sap-icon://building"
title="{/EntrySet('1')/Binding3}" />
is the same as
<ObjectListItem
binding="{/EntrySet('1')}"
intro="Site"
icon="sap-icon://building"
title="{Binding3}" />
is the same as
<ObjectListItem
id="Item3"
intro="Site"
icon="sap-icon://building"
title="{Binding3}" />
const iID = 1;
const sKey = "/EntrySet('" + iID + "')";
this.byId("Item3").bindElement(sKey);
You can then replace iID with something meaningful depending on the input.

Sorting XML data in gridview

I am trying to display sorting data in gridview from XML.
Operation of sorting is successful, but now how can I display all sorted data in gridview.
XML File:
<?xml version="1.0" encoding="utf-8"?>
<ProjectList>
<Business>
<ID>1</ID>
<Name>Rajan</Name>
<Mobile>123456</Mobile>
<Emailaddress>rajan#yahoo.co.in</Emailaddress>
<Date>24/01/2014</Date>
<Project>ttpl</Project>
</Business>
<Business>
<ID>12</ID>
<Name>nitant patel</Name>
<Mobile>123456</Mobile>
<Emailaddress>nitant#yahoo.co.in</Emailaddress>
<Date>27/01/2014</Date>
<Project>ttpl</Project>
</Business>
<Business>
<ID>10</ID>
<Name>Rajan10</Name>
<Mobile>123456</Mobile>
<Emailaddress>rajan#yahoo.co.in</Emailaddress>
<Date>24/01/2014</Date>
<Project>ttpl</Project>
</Business>
</ProjectList>
C# code:
XElement ProjectList = XElement.Load("Project.xml");
IEnumerable<XElement> ordered =
ProjectList.Elements().OrderBy(Business => int.Parse(Business.Element("ID").Value));
foreach (XElement element in ordered)
{
Console.Out.WriteLine(element.ToString());
}
gvdata.DataSource = ordered.ToList();
gvdata.DataBind(); //GIVE ME ERROR
ERROR is : The data source does not support server-side data paging.
I believe the issue is that the default Gridview may be trying to page the data...or at least, set it up for paging.
Try adding the 'AllowPaging="false"' attribute to your GridView tag, like so:
<asp:GridView ID="cantankerousgv" runat="server" AllowPaging="false">
//other GV stuff...
</asp:GridView>
Default behavior is often at the root of these kinds of issues.

variable in iframe with zk

i have a for each in my zk page, and in the each i am creating a column, and in my column i need add a iframe, and to each frame i need pass as variable the label of the column.
I have something like:
<zk>
<window title="Dynamic Columns" border="normal" width="1824px" apply="org.zkoss.bind.BindComposer" viewModel="#id('vm') #init('pkg$.DynamicColumnModel')">
<grid >
<columns>
<column forEach="${vm.columnList}" label="${each}">
<iframe
src="test.zul" />
</column>
</columns>
</grid>
</window>
</zk>
But i have an error when i include the page, and my first problem is that i do not know how can i pass a variable to each iframe.
And my java is something like:
public class DynamicColumnModel {
private List<String> columnList = new ArrayList<String>();
private String texto="123";
#Init
public void init(){
columnList.add("Dynamic Col A");
columnList.add("Dynamic Col B");
columnList.add("Dynamic Col C");
columnList.add("Dynamic Col D");
}
public List<String> getColumnList() {
return columnList;
}
public void setColumnList(List<String> columnList) {
this.columnList = columnList;
}
public String getTexto() {
return texto;
}
public void setTexto(String texto) {
this.texto = texto;
}
#Command
public void mensaje(){
}
}
Thanks
If your each is a String, which it appears to be as you set it as the column label, just go ahead and pass it as a URL parameter to the iframe.
<window apply="org.zkoss.bind.BindComposer"
viewModel="#id('vm') #init('pkg$.DynamicColumnModel')">
<grid >
<columns>
<column forEach="${vm.columnList}" label="${each}">
<iframe src="test.zul?myValue=${each}" />
</column>
</columns>
</grid>
</window>
Note that when you are using an iframe component, you are stepping outside ZK. True, the iframe itself points to a ZK page, but it's a not within the same ZK environment. The iframe could just as easily include www.google.com and so there is no specific ZK support for passing values to ZK pages included in this manner.
If you're only including ZK pages and want to pass information to these pages more fluidly, you'll want to use ZK's include tag. Have a look at the documentation on how to pass values to included ZK pages.
Edit
If going the iframe route, you can access URL parameter values from test.zul using ZK's Execution class:
Execution execution = Executions.getCurrent();
execution.getParameter("myValue");

Updating external Flex components from an action

I'm new to Flex and am having trouble understanding Events. I think Events are what I want to use for my situation. I have 2 components, addUser.mxml and listUsers.mxml. I access these from a ViewStack in my main application. When I load listUsers.mxml it shows a list of current users in a datagrid via a HTTPService call. When I add a user using the form on addUser.mxml I would like the datagrid in listUsers.mxml to refresh when I return to that view to show the new user. I've tried several different things with addEventListener and dispatchEvent but can't seem to get it working. Can someone help me with this logic?
--
Sample code for comment, I've parsed out the non-relative stuff.
adduser look like this:
<mx:HTTPService id="httpService"
url="{'http://someurl.com'}"
useProxy="false"
method="POST"
fault="faultHandler()"
result="resultHandler(event)"
/>
public function addUser():void{
if(validateForm()){
params = {};
params['action'] = 'adduser';
params['firstName'] = firstName.text;
params['lastName'] = lastName.text;
params['email'] = email.text;
params['isActive'] = isActive.selected;
httpService.cancel();
httpService.addEventListener("result", addUserResult);
httpService.send(params);
}
}
public function addUserResult(event:ResultEvent):void{
var result:Object = event.result;
//reset fields if add user was successful
if(result.returnXML.action=='adduser'){
var m:String = result.returnXML.message.toString();
if(result.returnXML.status=='fail'){
Alert.show(m, null, Alert.OK, null, null, Application.application.IconError);
}
if(result.returnXML.status=='success'){
firstName.text = "";
lastName.text = "";
email.text = "";
isActive.selected = true;
Alert.show(m, null, Alert.OK, null, null, Application.application.IconSuccess);
}
}
}
<mx:Button id="addButton" label="Add" click="addUser();" />
listUsers looks like this:
<mx:HTTPService id="httpListService"
url="{'http://someurl.com'}"
useProxy="false"
method="POST"
fault="faultHandler()"
result="resultHandler(event)"
/>
<mx:DataGrid id="dgUsers"
itemClick="dgClickEvent(event);"
width="85%"
maxHeight="500"
>
<mx:columns>
<mx:DataGridColumn headerText="First Name" dataField="fn" />
<mx:DataGridColumn headerText="Last Name" dataField="ln" />
<mx:DataGridColumn headerText="Email" dataField="email" />
<mx:DataGridColumn headerText="Active" dataField="active" />
</mx:columns>
</mx:DataGrid>
I don't think event listeners are necessarily the way to go. You use an event listener to do something upon detection of something else. ie) listening for a mouse down on a ui component = detect mouse down, do drag operation.
Given your example I think you just need to chain your functions together. It looks like your addUser function saves the user to the same source as your list users gets data from, so in your position I would call the listUsers httpService at the end of the add user result to refresh your data populating the datagrid.
httpListService.send()
I don't see your result handler for httpListService but that's where you update the data in your dataGrid.
good luck, and please post back with any complications.
Got it working. Here's what i did - basically everytime the parent viewstack brings the listUsers view into focus, it sends the httpListService and refreshes the datagrid regardless of any events (or non events) in the addUser component or any other component. it adds to the network traffic but, for the scope of my project, that is acceptable.
in listUsers.mxml:
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()">
...
public function init():void{
//vsUsers is my view stack on the main application component
Application.application.vsUsers.addEventListener(IndexChangedEvent.CHANGE, refreshUsersGrid);
}
...
public function refreshUsersGrid(e:IndexChangedEvent):void{
//if the new viewable child is the list users view, then refresh the datagrid
if(Application.application.vsUsers.getChildAt(e.newIndex).name=='viewListUsers'){
//the sendListUsersRequest method fires the HTTPService send method and binds the results to the datagrid
sendListUsersRequest();
}
}

Flex 3 StringValidator Highlight Field

I want to perform simple validation against multiple fields. Please note these fields are not within a mx:Form since the way they are displayed isn't the norm. The validation works properly, however, it does not highlight the textInput with the error message.
myValidator.source = empName1;
myValidator.property = "text";
if(myValidator.validate().type == ValidationResultEvent.VALID)
{
Alert.show("good");
}
...
<mx:StringValidator id="myValidator" required="true" minLength="1" requiredFieldError="This field is required" />
<mx:TextInput x="152" y="32" width="207" id="empName1"/>
Please note I want to use the same validator "myValidator" against multiple fields which is why the source and property are set in the actionscript 3 code.
Thanks
Update:
heres a similar function I created that works:
private function validateField(fields:Array):Boolean
{
var rtnResult:Boolean = true;
for each(var i:Object in fields)
{
myValidator.source = i;
myValidator.property = "text";
i.validateNow();
if(myValidator.validate().type == ValidationResultEvent.INVALID)
rtnResult = false;
}
return rtnResult;
}
which is called like so:
if(!validateField([TicketTitle,TicketDesc]))
{
Alert.show("Required fields were left blank!", "Warning");
return;
}
and the mxml validator
<mx:StringValidator id="myValidator" required="true" minLength="1" requiredFieldError="This field is required" />
Solved it... I needed this:
empName1.validateNow();

Resources