I have an issue with a listbox and the combobox behaviour. I have a listbox with a group of rows and I try to edit inline and change the value of a field based on the values of a combobox. But when I select one value in the combo of one row then all the values of the comboboxes of the other rows change to the same value. Please, let me know what I am doing wrong. Thanks for your help!
Here is my code:
<template name="model" var="item">
<listitem >
<listcell label="#load(item.id)"/>
<listcell label="#load(item.descCodigoTrafico)"/>
<listcell label="#load(item.descAmbitoDeTrafico)"/>
<listcell>
<combobox
model="#load(vm.listaPrecioEspecial)"
onChange="#command('addToUpdate', entry=item)"
selectedItem="#load(item.precioEspecial) #save(item.precioEspecial, before='updateItems')">
<template name="model" var="el">
<comboitem label="#load(el)"/>
</template>
</combobox>
</listcell>
<listcell label="#load(item.tipoDescuento)" />
<listcell>
<decimalbox inplace="true"
value="#load(item.ppm) #save(item.ppm, before='updateItems')"
onChange="#command('addToUpdate', entry=item)"
format="#.0000"/>
</listcell>
</listitem>
</template>
And the code of the two methods in de VM:
#Command
public void addToUpdate(#BindingParam("entry") TblEscenarioCondTrafico item){
itemsToUpdate.add(item);
LOGGER.info(item.toString());
for(TblEscenarioCondTrafico i : itemsToUpdate){
LOGGER.info("Item a guardar " + i.toString());
//LOGGER.info("Elemento...");
}
}
#NotifyChange("listaTraficos")
#Command
public void updateItems() throws Exception{
EscenarioCondTraficoService ects = new EscenarioCondTraficoService(em);
for (TblEscenarioCondTrafico i : itemsToUpdate){
LOGGER.info("Guardando " + i.toString());
ects.save(i);
}
itemsToUpdate.clear();
listaTraficos = getListaTraficos();
}
The problem should be that
model="#load(vm.listaPrecioEspecial)"
sets the same Collection to every Combobox as its model and so it is bound to all Combobox instances.
I had the same problem, like Nabil A. said the problem was the model, the same for all the items. I solved creating a new model for every item.
Instead of:
model="#load(vm.listaPrecioEspecial)"
I put something like:
model="#load(vm.getNewListaPrecioEspecial())
And in the VM class you have to create a method named getNewListaPrecioEspecial that returns a new list. (In my case a new SortingPagingListModel)
Related
I have 2 combo boxes and 1 input text field. On change of the 1st combo I set some value in the input field and partial refresh the panel where the input field is.
OnComplete of this refresh, i partial refresh (using XSP partialRefreshPost) the panel of the 2nd combo box. This combo box value as you can see is just the 1st combo's value.
The problem is:
The combo value is set but the input value is not! Although input's panel refresh comes first and on complete comes the combo's panel refresh. If i remove the code from inside the 2nd combo's value tab then the input field works. (or if i just remove the reference of the 1st combobox from the 2nd combobox then it works again).
The weird thing is:
if i use a listbox instead of the second combo box then it works!!
The xpage design is:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:table>
<xp:tr>
<xp:td>
<xp:comboBox id="comboBox1">
<xp:selectItem itemLabel="a" itemValue="a"></xp:selectItem>
<xp:selectItem itemLabel="b" itemValue="b"></xp:selectItem>
<xp:selectItem itemLabel="c" itemValue="c"></xp:selectItem>
<xp:eventHandler event="onchange" submit="true"
refreshMode="partial" refreshId="panel1">
<xp:this.action><![CDATA[#{javascript:var inputText1:com.ibm.xsp.component.xp.XspInputText = getComponent("inputText1");
inputText1.setValue("aaaaaa");}]]></xp:this.action>
<xp:this.onComplete><![CDATA[alert("refreshed panel1");
XSP.partialRefreshPost("#{id:panel0}",{onComplete: function(){alert("refreshed panel0");}});]]></xp:this.onComplete>
</xp:eventHandler></xp:comboBox></xp:td>
<xp:td></xp:td>
</xp:tr>
<xp:tr>
<xp:td></xp:td>
<xp:td></xp:td>
</xp:tr>
</xp:table>
<xp:br></xp:br>
<xp:br></xp:br>
<xp:panel id="panel0">
<xp:comboBox id="comboBox2">
<xp:selectItems>
<xp:this.value><![CDATA[#{javascript:var comboBox1:com.ibm.xsp.component.xp.XspSelectOneMenu = getComponent("comboBox1");
if(comboBox1.getValue()!=null){
return comboBox1.getValue().toString();
}else{
return "its empty";
}}]]></xp:this.value>
</xp:selectItems>
</xp:comboBox></xp:panel>
<xp:br></xp:br>
<xp:panel id="panel1">
<xp:inputText id="inputText1"></xp:inputText>
</xp:panel>
<xp:br></xp:br>
<xp:br></xp:br></xp:view>
Just replace 2nd combo with this and see....
<xp:listBox id="listBox1">
<xp:selectItems>
<xp:this.value><![CDATA[#{javascript:var comboBox1:com.ibm.xsp.component.xp.XspSelectOneMenu = getComponent("comboBox1");
if(comboBox1.getValue()!=null){
return comboBox1.getValue().toString();
}else{
return "its empty";
}}]]></xp:this.value>
</xp:selectItems>
</xp:listBox>
Any ideas?
When using a combobox, the first value in the list is the selected value. When you are using a list box, you have to choose a value from the list first. If you select a value, your example will fail too.
Because you are changing the allowed values of the combobox/listbox programmatically, and then try to set a value which is not longer in the list (the value is posted back to the server when doing a partial refresh), a validation error occurs, and the value of the inputText ('aaaaa') is not set in the backend.
You can add a xp:messages component inside of the panels, then you can see the error message.
Try doing this bind the controls to a viewScope then it should work.
I always bind my components to something scope variable, field or bean because if you don't you can get lot's of strange value problems. That's my experience.
I've tested you code and my suggestion works as far as I can see.
I am using Telerik's dropdownlist in my MVC application View. I am facing two problems:
1) When I run my application, I find every value of kendo dropdownlist is "Undefined".
This is the code for my View:
#model IEnumerable<EulenMgrKendoUIMvcApplication.Dominio.Tablas.DelegacionProductoUsuario>
#(Html.Kendo().DropDownListFor(d=>d)
.Name("IdDelegacionProductoDrpDwn").HtmlAttributes(new { #style = "font-size:12px" })
.DataTextField("IdDelegacionProducto")
.DataValueField("IdDelegacionProducto")
**.BindTo((System.Collections.IEnumerable)ViewData["IdDelegacionProducto"]))**
This is my controller, where I populate the dropdownlist:
public class DelegacionProductoUsuarioController : Controller
public ViewResult List()
{
IEnumerable<DelegacionProductoUsuario> delegaciones = DelegacionProductoUsuario.GetAll();
**PopulateDelegacionProducto();**
return View(delegaciones);
}
private void PopulateDelegacionProducto()
{
List<Int64> IdDelegacionProductoList = new List<Int64>();
foreach( DelegacionProductoUsuario d in DelegacionProductoUsuario.GetAll()){
IdDelegacionProductoList.Add(d.IdDelegacionProducto);
}
ViewData["IdDelegacionProducto"] =IdDelegacionProductoList ;
}
}
>I am debugging the application and the controller is passing to the view the proper values,so I don't understand why it doesn't show them.
2) Second problem: I insert this Dropdownlist in one of the columns of a kendo grid with no success.
In it's place it appears a common label. Here is the code for my Grid, I mark in Bold the column where I try to show my dropdownList:
#(Html.Kendo().Grid(Model)
.Name("Grid")
.Columns(columns=>
{
columns.Bound(d => d.BorradoLogico).Title("Borrado logico");
columns.Bound(d => d.FTick).Title("Ftick");
**columns.Bound(d => d.IdDelegacionProducto).Title("IdDelegacionProducto").EditorTemplateName("IdDelegacionProductoDrpDwn");**
columns.Bound(d => d.IdUsuario).Title("IdUsuario");
})
How does that 'DelegacionProductoUsuario' class look like? Does it have property named 'IdDelegacionProducto' ? It looks like you have not set the dataValueField correctly.
As for the second question, where did you put that EditorTemplate (is it in the Shared/EditorTemplate or in a EditorTemplates folder? More info about editor template can be found here.
Dear Petur: thanks a lot for answering. On regard to your answer:
My class DelegacionProductoUsuario does have a property called IdDelegacionProducto. On regard to your question "where I place the EditorTemplate" , I don't understand what you mean, I place it in the view that Lists all of my DelegacionProductoUsuario . Please keep on helping me. Thanks a lot Petur.
I have a problem with the binding of a datagrid control in net 4 wpf c# project
Sorry if I have posted too much info or not enough I never guess the correct amount
This is what I have.
1.A datagrid control called dgCSVData, which has autogenerate columns ticked
my xaml is
<DataGrid ItemsSource="{Binding dgCSVData}" Name="dgCSVData" Height="283" Width="1033" IsEnabled="True" ContextMenuService.ShowOnDisabled="True" IsReadOnly="True" SelectionChanged="dgCSVData_SelectionChanged" >
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Command="Copy">
<!--<MenuItem.Icon>
<Image Source="Images/copy.png" />
</MenuItem.Icon>-->
</MenuItem>
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>
I'm reading a csv into a list and using the list to create a datatable which has been cloned from my sql db. The datatable is created in a background reader and handed back to the main thread. I have cycled through the items in the tables data row and confirmed the datatable gets back with correct information: here is one row from the table outputed from debug
Year Item: 2013/14,From Item: 12/10/2013 00:00:00,To Item: 18/10/2013 00:00:00,Week No Item: 27,Clock No Item: 1139,Name Item: SINGH,Initial Item: R,Dept Item: 1,Own Hours Item: 55.50,Other Hours Item: 0.00,Total Hours Item: 55.50,O/T Premium Item: 7.92
I set (or rather try to) set the content of the datagrid with this code
void objProgress_ValueChanged(DataTable Result,string msg)
{
//Handle the event of csv datatable ready to return
oTable = Result;
//this is just for debug
DataRow Dr = oTable.Rows[0];
foreach (var item in Dr.ItemArray)
{
System.Windows.Forms.MessageBox.Show(item.ToString());
}
//this meant to set the binding BUT DOES NOT WORK TOTALLY LAST COLUMN MISSING
this.dgCSVData.DataContext = oTable.DefaultView;
this.dgCSVData.ItemsSource = oTable.DefaultView;
tbLoadDgStat.Visibility = Visibility.Visible;
//This does some error checking
if (oTable.Rows.Count > 1)
{
if (msg.Trim().StartsWith("Warning"))
{
System.Windows.Media.Color c = Colors.Red;
this.tbLoadDgStat.Background = new SolidColorBrush(c);
System.Windows.Forms.MessageBox.Show(oTable.Rows.Count.ToString());
}
this.tbLoadDgStat.Text = msg;
progressBar1.Value = 100;
btUpload.IsEnabled = true;
}
else
{
this.tbdgImport.Text = "Error no data returned";
progressBar1.Value = 50;
}
System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default;
progressBar1.Visibility = Visibility.Hidden;
this.Show();
}
The error I receive is
System.Windows.Data Error: 40 :
BindingExpression path error: 'O' property not found on 'object' ''DataRowView' (HashCode=30297615)'. BindingExpression
:Path=O/T Premium; DataItem='DataRowView' (HashCode=30297615)
; target element is 'TextBlock' (Name='')
; target property is 'Text' (type 'String')
The path O/T Premium is the last column of both the datatable and the datagrid.
it should be from the row above a value of O/T Premium Item: 7.92 from the data table this is a decimal, but so are the four previous items that bind correctly
I'm trying to make the binding as generic as possible as I am expecting to read different csv file into the datagrid in the next stage of the development
I do not understand the binding issue as all the other items from the data table are displayed correctly and done by the two lines of code
this.dgCSVData.DataContext = oTable.DefaultView;
this.dgCSVData.ItemsSource = oTable.DefaultView;
You can't use a '/' character in your Binding.Path... you can see that the error says that it can't find the O property because '/' means something in Binding path syntax. Removing the the '/' charcter from the column will fix your problem.
You can find out more about the Binding.Path syntax from the Binding.Path Property page on MSDN. From the linked page:
When the source is a collection view, the current item can be specified with a slash (/). For example, the clause Path=/ sets the binding to the current item in the view. When the source is a collection, this syntax specifies the current item of the default collection view.
Please see the comment above from #Sheridan
My problem was that / is the escape character in wpf binding see the microsoft docs here
so my data column which in sql was [O/T Premium] for my data table column when autogenerating the binding path ended up at O and hence not mapped.
After changing my sql data column in my table there was no problem.
(I guess if you can not change the data table you could rename the problem column in your sql command such as Select [O/T Premium] as [OT Premium]
I have not been able to find any documentation and searches return useless docs not involving what I want to do.
I want to take the text entered by the user, and when they click Add Record it adds the text to the array. The list box at the bottom displays each item in the array in the order it was entered.
I am just a beginner with a basic understanding of how the code is written, but I have no idea which things to use in order to take the text, make it into a string, add it to the array, and display the array in the list.
The trick here is to just use the buttons click event to add an item to the ArrayCollection you use to provide the data to your list. Here's the sample I just came up with which does what I think you are asking:
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
title="HomeView">
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
private var _records:ArrayCollection = new ArrayCollection();
protected function addRecord(event:MouseEvent):void
{
if(textInput.text != "") {
_records.addItem(textInput.text);
}
}
]]>
</fx:Script>
<s:TextInput id="textInput" left="10" right="10" top="5" prompt="Enter Text" />
<s:Button top="64" label="Add Record" horizontalCenter="0" click="addRecord(event)" />
<s:List left="10" right="10" top="132" bottom="5" dataProvider="{_records}" />
</s:View>
In the AspxGridView there are two comboboxes in DataItemTemplate, manually loaded. So when user selects one field of the first combo second will be disabled, i wrote this:
<dxe:ASPxComboBox ID="cmbEqualNotEqual" runat="server"
ClientInstanceName="cmbCEqualNotEqual" EnableClientSideAPI="true">
<Items>
<dxe:ListEditItem Text=" " Value="0" />
<dxe:ListEditItem Text="Eşittir" Value="1" />
<dxe:ListEditItem Text="Eşit Değildir" Value="0" />
</Items>
<ClientSideEvents SelectedIndexChanged="function(s,e){
alert(s.GetEnabled());
var selectedIndex = s.GetSelectedIndex();
if(selectedIndex == 2)
{
cmbCBiggerSmaller.SetEnabled(false);
}
}" />
</dxe:ASPxComboBox>
But this code disables the combo at the last row, not the row user works on. How can i disable the row user works on?
Thanks
I answer it for myself:
for (int i = 0; i < grid.VisibleRowCount; i++)
{
ASPxComboBox combito = grid.FindRowCellTemplateControl(i, grid.Columns[2] as GridViewDataColumn, "combito") as ASPxComboBox;
//combito.Value
}
The problem appears because the ClientInstanceName property is set for all editors in the same column to the same value. A possible solution is to handle the HtmlRowCreated event of the ASPxGridView and set the ClientInstanceName for both editors to a unique value. Also, in this event handler you should write the client side SelectedIndexChanged event handler. Finally, to obtain an editor instance, use the ASPxGridView's FindRowCellTemplateControl method.
Also, the following article can be helpful to you:
http://www.devexpress.com/Support/Center/ViewKBIssue.aspx?kbid=K18282