I have unbound field and assigning file id to it, I even tried assign URL also but that is not working, please have a look at below design and code, please let me know where am doing a mistake.
<px:PXFormView runat="server" ID="frmImage2" DataSourceID="ds" DataMember="IconImage" SkinID="Preview">
<Template>
<px:PXLayoutRule ID="PXLayoutRule18" runat="server" StartColumn="true" />
<px:PXImageUploader runat="server" DataField="UsrKWJMThumbnailURL" AllowUpload="false" DataMember="IconImage" SuppressLabel="True" ID="imgViewImage12" Height="150px" Width="150px" />
</Template>
</px:PXFormView>
public PXSelect<AMProdItem> IconImage;
public virtual void iconImage()
{
foreach (AMProdItem item in Base.ProdItemRecords.Select())
{
AMProdItemExt extItems = item.GetExtension<AMProdItemExt>();
if (extItems != null)
{
if (extItems.UsrKWJMSerialNbr != null)
{
InfoSmartSearch.InfoINItemLotSerialImage infoItemLotSerialImg = PXSelectReadonly<InfoSmartSearch.InfoINItemLotSerialImage, Where<InfoSmartSearch.InfoINItemLotSerialImage.lotSerialNbr, Equal<Required<InfoSmartSearch.InfoINItemLotSerialImage.lotSerialNbr>>>>.Select(Base, extItems.UsrKWJMSerialNbr);
if (infoItemLotSerialImg != null)
{
if (!string.IsNullOrEmpty(infoItemLotSerialImg.UsrIconImageUrl))
{
NoteDoc noteDoc = PXSelectReadonly<NoteDoc, Where<NoteDoc.noteID, Equal<Required<NoteDoc.noteID>>>>.Select(Base, infoItemLotSerialImg.NoteID);
if (noteDoc != null)
{
UploadFile uploadFile = PXSelectReadonly<UploadFile, Where<UploadFile.fileID, Equal<Required<UploadFile.fileID>>>>.Select(Base, noteDoc.FileID);
if (uploadFile != null)
{
extItems.UsrKWJMThumbnailURL =
ControlHelper.GetAttachedFileUrl(null, uploadFile.FileID.ToString());
}
}
}
}
}
else
{
InventoryItem invItems = PXSelectReadonly<InventoryItem, Where<InventoryItem.inventoryID, Equal<Required<InventoryItem.inventoryID>>>>.Select(Base, item.InventoryID);
if (invItems != null)
{
if (!string.IsNullOrEmpty(invItems.ImageUrl))
{
NoteDoc noteDoc = PXSelectReadonly<NoteDoc, Where<NoteDoc.noteID, Equal<Required<NoteDoc.noteID>>>>.Select(Base, invItems.NoteID);
if (noteDoc != null)
{
UploadFile uploadFile = PXSelectReadonly<UploadFile, Where<UploadFile.fileID, Equal<Required<UploadFile.fileID>>>>.Select(Base, noteDoc.FileID);
if (uploadFile != null)
{
extItems.UsrKWJMThumbnailURL =
ControlHelper.GetAttachedFileUrl(null, uploadFile.FileID.ToString());
}
}
}
}
}
}
}
}
I suggest you use PXImageView control instead of PXImageUploader.
<px:PXImageView runat="server" ID="edImage" DataField="UsrKWJMThumbnailURL" />
Also test with an absolute URL first like this one:
https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png
I tested this method and can vouch for it:
Here's the complete code of my test project:
using System;
using PX.Data;
namespace PXImageTest
{
public class TestImage : PXGraph<TestImage>
{
public PXFilter<MasterTable> MasterView;
public void MasterTable_ImageUrl_FieldSelecting(PXCache sender, PXFieldSelectingEventArgs e)
{
e.ReturnValue = "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png";
}
[Serializable]
public class MasterTable : IBqlTable
{
public abstract class imageUrl : IBqlField { }
[PXUIField(DisplayName = "Image")]
[PXDBString(255, IsUnicode = true)]
public virtual String ImageUrl { get; set; }
}
}
}
ASPX:
<%# Page Language="C#" MasterPageFile="~/MasterPages/FormView.master" AutoEventWireup="true" ValidateRequest="false" CodeFile="ZZ999999.aspx.cs" Inherits="Page_ZZ999999" Title="Untitled Page" %>
<%# MasterType VirtualPath="~/MasterPages/FormView.master" %>
<asp:Content ID="cont1" ContentPlaceHolderID="phDS" Runat="Server">
<px:PXDataSource ID="ds" runat="server" Visible="True" Width="100%"
TypeName="PXImageTest.TestImage"
PrimaryView="MasterView">
<CallbackCommands>
</CallbackCommands>
</px:PXDataSource>
</asp:Content>
<asp:Content ID="cont2" ContentPlaceHolderID="phF" Runat="Server">
<px:PXFormView ID="form" runat="server" DataSourceID="ds" DataMember="MasterView" Width="100%" AllowAutoHide="false">
<Template>
<px:PXLayoutRule runat="server" StartRow="True" ID="PXLayoutRule1" />
<px:PXImageView runat="server" DataField="ImageUrl" ID="edImage" Style='left:9px;top:9px;Position:absolute;' />
</Template>
<AutoSize Container="Window" Enabled="True" MinHeight="200" ></AutoSize>
</px:PXFormView>
</asp:Content>
Related
Problem #1
I have a Form with a split panel with a tree view on the left side and a grid on the right side.
The tree view is displaying itemClassCD. When I select an item in the tree, the current selection is always the same itemClassCd (the first entry), or null. The code view from the Tree is as follows "Tree.Current.ItemClassCD".
Form with Tree and Grid
Problem#2
The second issue is related to the display of the tree nodes.
They are showing a "+" sign and they will keep opening if I press the sign.
Node Issue
**This is what I have tried.
**
<%# Page Language="C#" MasterPageFile="~/MasterPages/FormDetail.master" AutoEventWireup="true" ValidateRequest="false" CodeFile="SG302010.aspx.cs" Inherits="Page_SG302010" Title="Untitled Page" %>
<%# MasterType VirtualPath="~/MasterPages/FormDetail.master" %>
<asp:Content ID="cont1" ContentPlaceHolderID="phDS" Runat="Server">
<script language="javascript" type="text/javascript">
function showTreeChanged(owner, args)
{
var visible = owner.getValue();
if (window['px_alls'] && px_alls["sp1"]) px_alls["sp1"].setDisabledPanel(visible ? 0 : 1);
}
function showTreeChk(e)
{
if (!loaded)
{
var px = __px_alls(this);
var TreeView = px_alls["chkShowTree"];
setTimeout(function ()
{
if (window['px_alls'] && px_alls["chkShowTree"] && px_alls["sp1"])
{
TreeView = px_alls["chkShowTree"];
px_alls["sp1"].setDisabledPanel(TreeView.getValue() ? 0 : 1);
}
loaded = true;
}, 1);
}
}
function showTreeLoad(e)
{
if (window['__px_alls'])
{
var pxs = __px_alls(this);
if (pxs)
{
setTimeout(function ()
{
var frm = pxs["form"];
if (frm) frm.events.addEventHandler("afterRepaint", showTreeChk);
}, 100);
}
}
}
var loaded = false;
window.addEventListener("load", showTreeLoad);
</script>
<px:PXDataSource EnableAttributes="True" ID="ds" Width="100%" runat="server" PrimaryView="Filter"
TypeName="ISGoalSetting.SGForecastEntry" Visible="True" PageLoadBehavior="PopulateSavedValues">
<CallbackCommands>
<px:PXDSCallbackCommand Name="Save" CommitChanges="True" RepaintControls="All" RepaintControlsIDs="grid" />
<px:PXDSCallbackCommand Name="distribute" Visible="False" CommitChanges="True" DependOnGrid="grid"
RepaintControls="Bound" />
<px:PXDSCallbackCommand Name="distributeOK" Visible="False" CommitChanges="True"
DependOnGrid="grid" />
<px:PXDSCallbackCommand CommitChanges="True" Visible="False" Name="preload" DependOnGrid="grid" />
<px:PXDSCallbackCommand CommitChanges="True" Name="showPreload" />
<px:PXDSCallbackCommand CommitChanges="True" Name="wNext" />
<px:PXDSCallbackCommand CommitChanges="True" Name="showManage" />
<px:PXDSCallbackCommand Name="manageOK" Visible="False" CommitChanges="True"/>
</CallbackCommands>
<DataTrees>
<px:PXTreeDataMember TreeView="Tree" TreeKeys="ItemClassID" ></px:PXTreeDataMember>
</DataTrees>
</px:PXDataSource>
</asp:Content>
<asp:Content ID="cont2" ContentPlaceHolderID="phF" Runat="Server">
<px:PXFormView ID="form" runat="server" Width="100%" DataMember="Filter" Caption="Forecast Filter"
LinkIndicator="True" BPEventsIndicator="True" DataSourceID="ds">
<Template>
<px:PXLayoutRule runat="server" ID="CstPXLayoutRule1" StartColumn="True" LabelsWidth="SM"
ControlSize="M" ></px:PXLayoutRule>
<px:PXSelector CommitChanges="True" ID="edBranchID" runat="server" DataField="BranchID"
DataSourceID="ds" ></px:PXSelector>
<px:PXSelector CommitChanges="True" ID="edFinYear" runat="server" DataField="FinYear"
DataSourceID="ds" AutoRefresh="True" ></px:PXSelector>
<px:PXCheckBox CommitChanges="True" ID="chkShowTree" runat="server" DataField="ShowTree">
<ClientEvents ValueChanged="showTreeChanged" />
</px:PXCheckBox>
</Template>
<CallbackCommands>
<Save PostData="Page" RepaintControls="All" RepaintControlsIDs="grid, tree" ></Save>
</CallbackCommands>
</px:PXFormView>
</asp:Content>
<asp:Content ID="cont3" ContentPlaceHolderID="phG" Runat="Server">
<px:PXSplitContainer runat="server" ID="sp1" SplitterPosition="220" CollapseDirection="Panel1"
Panel1MinSize="1" DisabledPanel="Panel1">
<AutoSize Enabled="true" Container="Window" />
<Template1>
<px:PXTreeView ID="tree" runat="server" PopulateOnDemand="True" ExpandDepth="1" DataSourceID="ds"
ShowRootNode="false" SelectFirstNode="true" >
<AutoCallBack Target="grid" Command="Refresh" />
<Images>
<ParentImages Normal="tree#Folder" Selected="tree#FolderS" />
<LeafImages Normal="tree#Folder" Selected="tree#FolderS" />
</Images>
<DataBindings>
<px:PXTreeItemBinding DataMember="Tree" TextField="ItemClassCD" ValueField="ItemClassID" ></px:PXTreeItemBinding>
</DataBindings>
<AutoSize Enabled="True" />
</px:PXTreeView>
</Template1>
<Template2>
<px:PXGrid ID="grid" runat="server" DataSourceID="ds" Width="100%" Height="150px" SkinID="Details" Caption="Forecast Details"
SyncPosition="True">
<AutoCallBack Command="Refresh" Target="form" ActiveBehavior="True">
<Behavior RepaintControlsIDs="ds" BlockPage="True" CommitChanges="True" ></Behavior>
</AutoCallBack>
<Levels>
<px:PXGridLevel DataMember="ForecastArticles">
<Columns>
<px:PXGridColumn DataField="BranchID" Width="140" ></px:PXGridColumn>
<px:PXGridColumn DataField="GoalType" Width="140" ></px:PXGridColumn>
<px:PXGridColumn DataField="ItemClass" Width="120" ></px:PXGridColumn>
<px:PXGridColumn DataField="Month" Width="90" ></px:PXGridColumn>
<px:PXGridColumn DataField="Goal" Width="100" ></px:PXGridColumn></Columns>
</px:PXGridLevel>
</Levels>
<AutoSize Container="Window" Enabled="True" MinHeight="150" ></AutoSize>
<ActionBar >
</ActionBar>
<Mode AllowUpload="True" /></px:PXGrid>
</Template2>
</px:PXSplitContainer>
</asp:Content>
public class SGForecastEntry : PXGraph<SGForecastEntry>
{
#region Actions
public PXSave<SGForecastFilter> Save;
public PXCancel<SGForecastFilter> Cancel;
public PXDelete<SGForecastFilter> Delete;
public PXAction<SGForecastFilter> First;
public PXAction<SGForecastFilter> Prev;
public PXAction<SGForecastFilter> Next;
public PXAction<SGForecastFilter> WNext;
public PXAction<SGForecastFilter> Last;
public PXAction<SGForecastFilter> ShowPreload;
public PXAction<SGForecastFilter> Preload;
public PXAction<SGForecastFilter> Distribute;
public PXAction<SGForecastFilter> DistributeOK;
public PXAction<SGForecastFilter> ShowManage;
public PXAction<SGForecastFilter> ManageOK;
#endregion
#region Selects
public PXFilter<SGForecastFilter> Filter;
public SelectFrom<INItemClass>.OrderBy<INItemClass.itemClassCD.Asc>.View Tree;
public SelectFrom<INItemClass>.
Where<INItemClass.itemClassID.IsEqual<INItemClass.itemClassID.FromCurrent>>.View CurrentNode;
/*Everything*/
[PXImport(typeof(ISSGForecast))]
public SelectFrom<ISSGForecast>.
OrderBy<Asc<ISSGForecast.itemClass>>.View ForecastArticles;
#endregion
protected bool suppressIDs;
public override IEnumerable ExecuteSelect(string viewName, object[] parameters, object[] searches, string[] sortcolumns, bool[] descendings, PXFilterRow[] filters, ref int startRow, int maximumRows, ref int totalRows)
{
IEnumerable ret = base.ExecuteSelect(viewName, parameters, searches, sortcolumns, descendings, filters, ref startRow, maximumRows, ref totalRows);
suppressIDs = viewName == nameof(ForecastArticles);
CurrentSelected.ClassCD = Tree.Current?.ItemClassCD;
return ret;
}
private SelectedClass CurrentSelected
{
get
{
PXCache cache = this.Caches[typeof(SelectedClass)];
if (cache.Current == null)
{
cache.Insert();
cache.IsDirty = false;
}
return (SelectedClass)cache.Current;
}
}
[Serializable]
[PXHidden]
public partial class SGForecastFilter : IBqlTable
{
#region BranchID
public abstract class branchID : PX.Data.BQL.BqlInt.Field<branchID> { }
[Branch(Required = true)]
public virtual int? BranchID { get; set; }
#endregion
#region FinYear
public abstract class finYear : PX.Data.BQL.BqlString.Field<finYear> { }
[PXUIField(DisplayName = "Financial Year", Required = true)]
[PXDBString(4)]
[GenericFinYearSelector(typeof(Search3<FinYear.year, OrderBy<Desc<FinYear.year>>>),null)]
public virtual String FinYear { get; set; }
#endregion
#region ShowTree
public abstract class showTree : PX.Data.BQL.BqlBool.Field<showTree> { }
[PXBool]
[PXUnboundDefault(true)]
[PXUIField(DisplayName = "Tree View")]
public virtual Boolean? ShowTree { get; set; }
#endregion
#region ItemClass
[PXDBString(10, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Item Class", Visibility = PXUIVisibility.SelectorVisible)]
[PXSelector(typeof(Search<INItemClass.itemClassCD>))]
public virtual string ItemClass { get; set; }
public abstract class itemClass : PX.Data.BQL.BqlString.Field<itemClass> { }
#endregion
public short? Precision;
}
[Serializable]
[PXHidden]
public partial class SelectedClass : IBqlTable
{
#region ItemClass
[PXInt]
[PXSelector(typeof(Search<INItemClass.itemClassID>))]
public virtual int? ItemClass { get; set; }
public abstract class itemClass : PX.Data.BQL.BqlInt.Field<itemClass> { }
#endregion
#region ClassCD
[PXString]
[PXSelector(typeof(Search<INItemClass.itemClassCD>))]
public virtual string ClassCD { get; set; }
public abstract class classCD : PX.Data.BQL.BqlString.Field<classCD> { }
#endregion
}
}
I have some problems with the fact that when I select a value in the dropbox, or rather steel a checkmark, then it is automatically reset.
[Serializable]
public class KNRWCSAttributeExt : PXCacheExtension<CSAttribute>
{
public static bool IsActive() => true;
#region UsrSchemaField
[PXDBString(512, InputMask = "", IsUnicode = true)]
[PXUIField(DisplayName = "Multi Schema Field")]
//[PXUIVisible(typeof(Where<PX.CS.CSAttribute.controlType, Equal<CSAttribute.AttrType.giSelector>>))]
[PXStringList(new string[] {null}, new string[] {""}, ExclusiveValues = false)]
public virtual string UsrSchemaField { get; set; }
public abstract class usrSchemaField : PX.Data.BQL.BqlString.Field<usrSchemaField>
{
}
#endregion
}
I assume that this is due to the fact that the event is triggered again and the array is filled over and over again. With the usual examples that are already described on stackoverflow it works, but my code does not work
Tell me please how I can get data into DropDown once so that I can then select and the value is not reset.
public class KNRWCSAttributeMaintExt : PXGraphExtension<CSAttributeMaint>
{
public static bool IsActive() => true;
protected virtual void _(Events.RowSelected<CSAttribute> e)
{
if (e.Row == null)
{
return;
}
var el = e.Row as CSAttribute;
if (el.ControlType == CSAttribute.GISelector)
{
if (!string.IsNullOrEmpty(e.Row.ObjectName as string))
{
Type objType = System.Web.Compilation.PXBuildManager.GetType(e.Row.ObjectName, true);
PXCache objCache = Base.Caches[objType];
var fields = objCache.Fields
.Where(f => objCache.GetBqlField(f) != null ||
f.EndsWith("_Attributes", StringComparison.OrdinalIgnoreCase))
.Where(f => !objCache.GetAttributesReadonly(f).OfType<PXDBTimestampAttribute>().Any())
.Where(f => !string.IsNullOrEmpty((objCache.GetStateExt(null, f) as PXFieldState)?.ViewName))
.Where(f => f != "CreatedByID" && f != "LastModifiedByID")
.ToArray();
PXStringListAttribute.SetList<KNRWCSAttributeExt.usrSchemaField>(e.Cache, e.Row, fields, fields);
}
}
}
}
View
<asp:Content ID="cont2" ContentPlaceHolderID="phF" runat="Server">
<px:PXFormView ID="form" runat="server" DataSourceID="ds" Style="z-index: 100" Width="100%" DataMember="Attributes" Caption="Attribute Summary">
<Template>
<px:PXLayoutRule runat="server" StartColumn="True" ControlSize="M" LabelsWidth="SM" />
<px:PXSelector ID="edAttributeID" runat="server" DataField="AttributeID" AutoRefresh="True" DataSourceID="ds">
<GridProperties FastFilterFields="description" />
</px:PXSelector>
<px:PXTextEdit ID="edDescription" runat="server" AllowNull="False" DataField="Description" />
<px:PXDropDown CommitChanges="True" ID="edControlType" runat="server" AllowNull="False" DataField="ControlType" />
<px:PXCheckBox ID="chkIsInternal" runat="server" DataField="IsInternal" />
<px:PXCheckBox ID="chkContainsPersonalData" runat="server" DataField="ContainsPersonalData" />
<px:PXTextEdit ID="edEntryMask" runat="server" DataField="EntryMask" />
<px:PXTextEdit ID="edRegExp" runat="server" DataField="RegExp" />
<px:PXSelector ID="SchemaObject" runat="server" DataField="ObjectName" AutoRefresh="True" CommitChanges="true" />
<px:PXDropDown ID="SchemaField" runat="server" DataField="FieldName" AutoRefresh="True" CommitChanges="True" />
<px:PXDropDown ID="edRegExpMultiSelect" runat="server" AllowMultiSelect="true" DataField="UsrSchemaField" CommitChanges="True"/>
</Template>
</px:PXFormView>
</asp:Content>
Having the field value disappear just means that the custom field was not correctly implemented. When the system can't select/persist a record or a field it disappears when control focus is lost.
The DAC field type appears to be wrong. Usually string list uses small codes of about 2 or 3 letters string with fixed size:
[PXDBString(3, IsFixed = true)]
Since you are setting the list dynamically you don't need to define null string values in the DAC:
[PXStringList]
You need to make sure that your event is always providing the expected code values. This can be checked by removing the conditions and using constants for the SetList method call:
https://stackoverflow.com/a/38089639/7376238
Maybe you missed some steps like creating the field in the database table. You can test with an unbound PXString field instead of a PXDBString like in this example to see if that's the issue:
https://stackoverflow.com/a/49907964/7376238
Thanks for the help, I solved the problem by replacing "e.Row" with "null" in this line
before:
PXStringListAttribute.SetList<KNRWCSAttributeExt.usrSchemaField>(e.Cache, e.Row, fields, fields);
after:
PXStringListAttribute.SetList<KNRWCSAttributeExt.usrSchemaField>(e.Cache, null, fields, fields);
we have requirement to update the selected value in pop up screen in custom screen grid.
can anyone help me on this.
Thanks.
I have worked on the same functionality in other projects. The below code will help you. Please let me know if you get any issues.
Action Button Code
public PXAction<SOAmazonSetup> GetSchema;
[PXButton]
[PXUIField(DisplayName = SOMessages.getSchema, MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select, Enabled = true)]
protected virtual IEnumerable getSchema(PXAdapter adapter)
{
if (setupview.Current != null)
{
if (schemaView.AskExt() == WebDialogResult.OK && !string.IsNullOrEmpty(schemaView.Current.AmazonOrderID))
{
bool isgetSchema = true;
SOSchemaFileDetails objSchemaFileDetails = PXSelectJoin<SOSchemaFileDetails, InnerJoin<SOAmazonSetup, On<SOSchemaFileDetails.integrationID,
Equal<SOAmazonSetup.integrationID>>>, Where<SOAmazonSetup.integrationID, Equal<Current<SOAmazonSetup.integrationID>>>>.Select(this);
if (objSchemaFileDetails != null)
{
if (msgView.Ask(schemaView.Current, SOMessages.getSchema, SOMessages.warningMsg, MessageButtons.YesNo, MessageIcon.Warning) == WebDialogResult.No)
{
isgetSchema = false;
}
}
if (isgetSchema)
{
// get needed information in local variables
string sAmazonOrderID = schemaView.Current.AmazonOrderID;
string sIntegrationID = setupview.Current.IntegrationID;
PXLongOperation.StartOperation(this, delegate ()
{
//Create Instance
SOAmazonSetupMaint setupGraph = PXGraph.CreateInstance<SOAmazonSetupMaint>();
setupGraph.setupview.Current = setupGraph.setupview.Search<SOAmazonSetup.integrationID>(sIntegrationID);
SOHelper.GetSchemaFromAmazon(setupGraph, clientOrder, sAmazonOrderID);
DynamicSchema.ReloadSchema(setupGraph, sIntegrationID);
});
}
}
else
{
throw new Exception(SOMessages.AmwOrderCannotbeEmpty);
}
}
return adapter.Get();
}
SmartPanel code:
<px:PXSmartPanel ID="AMpnlGetSchema" runat="server" Caption="Get Schema"
CaptionVisible="true" DesignView="Hidden" LoadOnDemand="true" Key="schemaView" CreateOnDemand="false" AutoCallBack-Enabled="true"
AutoCallBack-Target="formGetSchema" AutoCallBack-Command="Refresh" CallBackMode-CommitChanges="True" CallBackMode-PostData="Page"
AcceptButtonID="btnOK" Width=" 250px">
<px:PXFormView ID="AMformGetSchema" runat="server" DataSourceID="ds" Style="z-index: 100" Width="100%" CaptionVisible="False"
DataMember="schemaView">
<ContentStyle BackColor="Transparent" BorderStyle="None" />
<Template>
<px:PXLayoutRule ID="AMPXLayoutRuleAmazonAPISettings" StartColumn="true" runat="server" ControlSize="M" />
<px:PXTextEdit CommitChanges="True" runat="server" ID="AMCstPXTextEditAmazonOrderID" DataField="AmazonOrderID"></px:PXTextEdit>
</Template>
</px:PXFormView>
<px:PXPanel ID="AMpnlOK" runat="server" SkinID="Buttons">
<px:PXButton ID="btnOK" runat="server" DialogResult="OK" Text="OK">
<AutoCallBack Target="formGetSchema" Command="Save" />
</px:PXButton>
</px:PXPanel>
</px:PXSmartPanel>
I have a companion table / DAC to Inventory Items:
[Serializable]
public class InventoryItemCompanion : IBqlTable
{
[PXDBInt(IsKey = true)]
[PXParent(typeof(Select<InventoryItem,
Where<InventoryItem.inventoryID, Equal<Current<InventoryItemCompanion.inventoryID>>>>))]
[PXDBDefault(typeof(InventoryItem.inventoryID))]
public virtual int? InventoryID { get; set; }
public abstract class inventoryID : IBqlField { }
[PXDBInt]
[PXUIField(DisplayName = "Custom Data")]
public virtual int? CustomData { get; set; }
public abstract class customData : IBqlField { }
}
I then have a custom Process screen that will operate on these custom records with a Filter and derived class adding a Selection field. In the Process screen I Join in the Inventory Item records to display relevant information in the process grid.
[Serializable]
public class InventoryItemCompanionProcess : InventoryItemCompanion
{
[PXBool]
[PXUIField(DisplayName = "Select")]
public virtual bool? Selected { get; set; }
public abstract class selected : IBqlField { }
}
[Serializable]
public class TestFilter : IBqlTable
{
[PXDBInt]
[PXUIField(DisplayName = "Item Class")]
[PXDimensionSelector(INItemClass.Dimension,
typeof(Search<INItemClass.itemClassID>),
typeof(INItemClass.itemClassCD),
DescriptionField = typeof(INItemClass.descr))]
public virtual int? ItemClassID { get; set; }
public abstract class itemClassID : IBqlField { }
}
public class TestProcess : PXGraph<TestProcess>
{
public PXCancel<TestFilter> Cancel;
public PXFilter<TestFilter> Filter;
public PXFilteredProcessingJoin<
InventoryItemCompanionProcess, TestFilter,
InnerJoin<InventoryItem,
On<InventoryItem.inventoryID, Equal<InventoryItemCompanionProcess.inventoryID>>>,
Where<InventoryItem.itemClassID, Equal<Current<TestFilter.itemClassID>>,
Or<Current<TestFilter.itemClassID>, IsNull>>,
OrderBy<Asc<InventoryItem.inventoryCD>>
> Records;
public TestProcess()
{
Records.SetSelected<InventoryItemCompanionProcess.selected>();
Records.SetProcessDelegate(Process);
}
public static void Process(List<InventoryItemCompanionProcess> Records)
{
foreach(var rec in Records)
{
// Perform custom processing function
}
}
}
And the ASPX page:
<%# Page Language="C#" MasterPageFile="~/MasterPages/FormDetail.master" AutoEventWireup="true" ValidateRequest="false" CodeFile="XX501000.aspx.cs" Inherits="Page_XX501000" Title="Untitled Page" %>
<%# MasterType VirtualPath="~/MasterPages/FormDetail.master" %>
<asp:Content ID="cont1" ContentPlaceHolderID="phDS" Runat="Server">
<px:PXDataSource ID="ds" runat="server" Visible="True" Width="100%" PrimaryView="Filter" TypeName="TestProcessing.TestProcess">
</px:PXDataSource>
</asp:Content>
<asp:Content ID="cont2" ContentPlaceHolderID="phF" Runat="Server">
<px:PXFormView ID="form" runat="server" DataSourceID="ds" Style="z-index: 100" Width="100%" DataMember="Filter" TabIndex="100">
<Template>
<px:PXLayoutRule runat="server" StartRow="True"/>
<px:PXSegmentMask ID="edItemClassID" runat="server" DataField="ItemClassID" />
</Template>
</px:PXFormView>
</asp:Content>
<asp:Content ID="cont3" ContentPlaceHolderID="phG" Runat="Server">
<px:PXGrid ID="grid" runat="server" DataSourceID="ds" Style="z-index: 100" Width="100%" Height="150px" SkinID="Details" TabIndex="900">
<Levels>
<px:PXGridLevel DataMember="Records">
<RowTemplate>
<px:PXCheckBox ID="edSelected" runat="server" AlreadyLocalized="False" DataField="Selected" Text="Select" />
<px:PXNumberEdit ID="edCustomData" runat="server" AlreadyLocalized="False" DataField="CustomData" />
<px:PXSegmentMask ID="edInventoryItem__InventoryCD" runat="server" DataField="InventoryItem__InventoryCD" />
<px:PXTextEdit ID="edInventoryItem__Descr" runat="server" AlreadyLocalized="False" DataField="InventoryItem__Descr" />
<px:PXSegmentMask ID="edInventoryItem__ItemClassID" runat="server" DataField="InventoryItem__ItemClassID" />
</RowTemplate>
<Columns>
<px:PXGridColumn AllowCheckAll="True" DataField="Selected" TextAlign="Center" Type="CheckBox" Width="60px" />
<px:PXGridColumn DataField="CustomData" TextAlign="Right" />
<px:PXGridColumn DataField="InventoryItem__InventoryCD" />
<px:PXGridColumn DataField="InventoryItem__Descr" Width="200px" />
<px:PXGridColumn DataField="InventoryItem__ItemClassID" Width="120px" />
</Columns>
</px:PXGridLevel>
</Levels>
<AutoSize Container="Window" Enabled="True" MinHeight="150" />
</px:PXGrid>
</asp:Content>
The Process does run on the desired records but after doing so the fields within the Grid from the Joined Inventory Item table are blanked.
I need the Item information to still display in case of errors in the processing requiring user attention.
Consider changing InventoryItemCompanion (or the derived class) into a PXProjection, mapping each field to the specific DAC Field intended. Optionally try marking displayed fields like Descr with IsKey=true, such as:
[PXProjection(typeof(
Select2<InventoryItemCompanion,
InnerJoin<InventoryItem, On<InventoryItemCompanion.inventoryID,
Equal<InventoryItem.inventoryID>>>>),
new Type[] { typeof(InventoryItemCompanion) }, Persistent = true)]
public class InventoryItemCompanion : PX.Data.IBqlTable
{
[PXDBInt(IsKey = true,
BqlField=typeof(InventoryItemCompanion.inventoryID))]
[PXParent(typeof(Select<InventoryItem,
Where<InventoryItem.inventoryID,
Equal<Current<InventoryItemCompanion.inventoryID>>>>))]
[PXDBDefault(typeof(InventoryItem.inventoryID))]
public virtual int? InventoryID { get; set; }
public abstract class inventoryID : IBqlField { }
[PXDBString(256, IsKey = true,
BqlField=typeof(InventoryItem.descr))]
[PXUIField(DisplayName="Description", Enabled=false))]
public virtual String Descr{ get; set;
public abstract class descr: IBqlField { }
}
The View would then be PXFilteredProcessing instead of PXFilteredProcessingJoin and the ASPX markup would assign DataField = "Descr" directly instead of InventoryItem__Descr, as example.
When I click upload for Excel, Common Settings dialog appear -> Columns dialog appear-> and when I click final Ok it shows me that "the operation has completed" , but no rows are importing. Excel file is correct, it correctly detects mapping.
Grid : Allow upload = true
Graph :
public class KALCADisposalEntry : PXGraph<KALCADisposalEntry, KALCADisposal>
{
public PXSelect<KALCADisposal> LCADisposals;
[PXImport(typeof(KALCADisposal))]
public PXSelectJoin<KALCADisposalDetail,
LeftJoin<KAAsset, On<KAAsset.assetID, Equal<KALCADisposalDetail.assetID>>,
LeftJoin<KAAssetLocationHistory, On<KAAsset.assetID, Equal<KAAssetLocationHistory.assetID>,
And<KAAsset.locationRevID, Equal<KAAssetLocationHistory.revisionID>>>>>,
Where<KALCADisposalDetail.lCADisposalID, Equal<Current<KALCADisposal.lCADisposalID>>>> LCADisposalDetails;
Where KALCADisposal is a primary graph view.
KALCADisposalDetail DAC:
namespace KA
{
using System;
using PX.Data;
using PX.Objects.GL;
using DAC;
using DAC.Shared;
[System.SerializableAttribute()]
public class KALCADisposalDetail : PX.Data.IBqlTable
{
#region LCADisposalID
public abstract class lCADisposalID : PX.Data.IBqlField
{
}
protected int? _LCADisposalID;
[PXDBInt()]
[PXDBDefault(typeof(KALCADisposal.lCADisposalID))]
[PXParent(typeof(Select<KALCADisposal,
Where<KALCADisposal.lCADisposalID, Equal<Current<KALCADisposalDetail.lCADisposalID>>>>))]
public virtual int? LCADisposalID
{
get
{
return this._LCADisposalID;
}
set
{
this._LCADisposalID = value;
}
}
#endregion
#region LCADisposalDetailID
public abstract class lCADisposalDetailID : PX.Data.IBqlField
{
}
protected int? _LCADisposalDetailID;
[PXDBIdentity()]
//[PXUIField(Enabled = false)]
public virtual int? LCADisposalDetailID
{
get
{
return this._LCADisposalDetailID;
}
set
{
this._LCADisposalDetailID = value;
}
}
#endregion
#region AssetID
public abstract class assetID : PX.Data.IBqlField
{
}
protected int? _AssetID;
[PXDBInt(IsKey = true)]
[PXUIField(DisplayName = "Asset ID")]
[KAAssetSelector(typeof(Search<KAAsset.assetID,
Where<KAAsset.status, NotEqual<KAAssetStatus.hold>,
And<KAAsset.status, NotEqual<KAAssetStatus.open>,
And<KAAsset.status, NotEqual<KAAssetStatus.disposed>>>>>))]
public virtual int? AssetID
{
get
{
return this._AssetID;
}
set
{
this._AssetID = value;
}
}
#endregion
#region tstamp
public abstract class Tstamp : PX.Data.IBqlField
{
}
protected byte[] _tstamp;
[PXDBTimestamp()]
public virtual byte[] tstamp
{
get
{
return this._tstamp;
}
set
{
this._tstamp = value;
}
}
#endregion
#region CreatedByID
public abstract class createdByID : PX.Data.IBqlField
{
}
protected Guid? _CreatedByID;
[PXDBCreatedByID()]
public virtual Guid? CreatedByID
{
get
{
return this._CreatedByID;
}
set
{
this._CreatedByID = value;
}
}
#endregion
#region CreatedByScreenID
public abstract class createdByScreenID : PX.Data.IBqlField
{
}
protected string _CreatedByScreenID;
[PXDBCreatedByScreenID()]
public virtual string CreatedByScreenID
{
get
{
return this._CreatedByScreenID;
}
set
{
this._CreatedByScreenID = value;
}
}
#endregion
#region CreatedDateTime
public abstract class createdDateTime : PX.Data.IBqlField
{
}
protected DateTime? _CreatedDateTime;
[PXDBCreatedDateTime()]
public virtual DateTime? CreatedDateTime
{
get
{
return this._CreatedDateTime;
}
set
{
this._CreatedDateTime = value;
}
}
#endregion
#region LastModifiedByID
public abstract class lastModifiedByID : PX.Data.IBqlField
{
}
protected Guid? _LastModifiedByID;
[PXDBLastModifiedByID()]
public virtual Guid? LastModifiedByID
{
get
{
return this._LastModifiedByID;
}
set
{
this._LastModifiedByID = value;
}
}
#endregion
#region LastModifiedByScreenID
public abstract class lastModifiedByScreenID : PX.Data.IBqlField
{
}
protected string _LastModifiedByScreenID;
[PXDBLastModifiedByScreenID()]
public virtual string LastModifiedByScreenID
{
get
{
return this._LastModifiedByScreenID;
}
set
{
this._LastModifiedByScreenID = value;
}
}
#endregion
#region LastModifiedDateTime
public abstract class lastModifiedDateTime : PX.Data.IBqlField
{
}
protected DateTime? _LastModifiedDateTime;
[PXDBLastModifiedDateTime()]
public virtual DateTime? LastModifiedDateTime
{
get
{
return this._LastModifiedDateTime;
}
set
{
this._LastModifiedDateTime = value;
}
}
#endregion
#region NoteID
public abstract class noteID : PX.Data.IBqlField
{
}
protected Guid? _NoteID;
[PXNote()]
public virtual Guid? NoteID
{
get
{
return this._NoteID;
}
set
{
this._NoteID = value;
}
}
#endregion
}
}
KAAssetSelector :
public class KAAssetSelectorAttribute : PXSelectorAttribute
{
public KAAssetSelectorAttribute() :
base(typeof(Search<KAAsset.assetID>))
{
SubstituteKey = typeof(KAAsset.assetCD);
}
public KAAssetSelectorAttribute(Type search) : base(search)
{
SubstituteKey = typeof(KAAsset.assetCD);
}
}
aspx :
<%# Page Language="C#" MasterPageFile="~/MasterPages/FormTab.master" AutoEventWireup="true"
ValidateRequest="false" CodeFile="KA303000.aspx.cs" Inherits="Page_KA301000" Title="Untitled Page" %>
<%# MasterType VirtualPath="~/MasterPages/FormTab.master" %>
<asp:Content ID="cont1" ContentPlaceHolderID="phDS" runat="Server">
<px:PXDataSource ID="ds" runat="server" Visible="True" Width="100%" TypeName="KA.KALCADisposalEntry" PrimaryView="LCADisposals">
</px:PXDataSource>
</asp:Content>
<asp:Content ID="cont2" ContentPlaceHolderID="phF" runat="Server">
<px:PXFormView ID="form" runat="server" DataSourceID="ds" Style="z-index: 100" Width="100%" DataMember="LCADisposals" TabIndex="5100">
<Template>
<px:PXLayoutRule ID="PXLayoutRule1" runat="server" StartColumn="True" LabelsWidth="S" ControlSize="S" />
<px:PXSelector ID="edLCADisposalCD" runat="server" DataField="LCADisposalCD">
</px:PXSelector>
<px:PXDropDown ID="edStatus" runat="server" DataField="Status">
</px:PXDropDown>
<px:PXCheckBox ID="edHold" Size="S" runat="server" AlreadyLocalized="False" DataField="Hold" Text="Hold" CommitChanges="true">
</px:PXCheckBox>
<px:PXLayoutRule runat="server" ControlSize="S" LabelsWidth="S" StartColumn="True">
</px:PXLayoutRule>
<px:PXTextEdit ID="edDisposalReason" runat="server" AlreadyLocalized="False" DataField="DisposalReason" DefaultLocale="" Size="L">
</px:PXTextEdit>
</Template>
</px:PXFormView>
</asp:Content>
<asp:Content ID="cont3" ContentPlaceHolderID="phG" runat="Server">
<px:PXTab ID="tab" runat="server" Width="100%" Height="150px" DataSourceID="ds" DataMember="LCADisposalDetails">
<Items>
<px:PXTabItem Text="Details">
<Template>
<px:PXGrid ID="PXGrid1" AdjustPageSize="Auto" runat="server" DataSourceID="ds" TabIndex="-14036" Width="100%" Height="300px" SyncPosition="True" SkinID="DetailsInTab" KeepPosition="True" TemporaryFilterCaption="Filter Applied">
<Levels>
<px:PXGridLevel DataKeyNames="LCADisposalDetailID" DataMember="LCADisposalDetails">
<RowTemplate>
<px:PXSelector ID="edAssetID" runat="server" DataField="AssetID" CommitChanges="True" AutoRefresh="True" AllowEdit="true">
</px:PXSelector>
<px:PXTextEdit ID="edKAAsset__Description" runat="server" AlreadyLocalized="False" DataField="KAAsset__Description" DefaultLocale="">
</px:PXTextEdit>
<px:PXDropDown ID="edKAAsset__Status" runat="server" DataField="KAAsset__Status">
</px:PXDropDown>
<px:PXDropDown ID="edKAAsset__Condition" runat="server" DataField="KAAsset__Condition">
</px:PXDropDown>
<px:PXSelector ID="edKAAsset__UOM" runat="server" DataField="KAAsset__UOM">
</px:PXSelector>
<px:PXNumberEdit ID="edKAAsset__Cost" runat="server" AlreadyLocalized="False" DataField="KAAsset__Cost" DefaultLocale="">
</px:PXNumberEdit>
<px:PXSelector ID="edKAAssetLocationHistory__BuildingID" runat="server" DataField="KAAssetLocationHistory__BuildingID">
</px:PXSelector>
<px:PXTextEdit ID="edKAAssetLocationHistory__Floor" runat="server" AlreadyLocalized="False" DataField="KAAssetLocationHistory__Floor" DefaultLocale="">
</px:PXTextEdit>
<px:PXTextEdit ID="edKAAssetLocationHistory__Room" runat="server" AlreadyLocalized="False" DataField="KAAssetLocationHistory__Room" DefaultLocale="">
</px:PXTextEdit>
<px:PXSelector ID="edKAAssetLocationHistory__EmployeeID" runat="server" DataField="KAAssetLocationHistory__EmployeeID">
</px:PXSelector>
<px:PXSelector ID="edKAAssetLocationHistory__Department" runat="server" DataField="KAAssetLocationHistory__Department">
</px:PXSelector>
<px:PXSegmentMask ID="edKAAssetLocationHistory__SiteID" runat="server" DataField="KAAssetLocationHistory__SiteID">
</px:PXSegmentMask>
</RowTemplate>
<Columns>
<px:PXGridColumn DataField="AssetID" CommitChanges="True">
</px:PXGridColumn>
<px:PXGridColumn DataField="KAAsset__Description" Width="200px">
</px:PXGridColumn>
<px:PXGridColumn DataField="KAAsset__Cost" TextAlign="Right" Width="100px">
</px:PXGridColumn>
<px:PXGridColumn DataField="KAAsset__UOM">
</px:PXGridColumn>
<px:PXGridColumn DataField="KAAssetLocationHistory__BranchID">
</px:PXGridColumn>
<px:PXGridColumn DataField="KAAssetLocationHistory__BuildingID">
</px:PXGridColumn>
<px:PXGridColumn DataField="KAAssetLocationHistory__Floor">
</px:PXGridColumn>
<px:PXGridColumn DataField="KAAssetLocationHistory__Room">
</px:PXGridColumn>
<px:PXGridColumn DataField="KAAssetLocationHistory__EmployeeID" Width="120px">
</px:PXGridColumn>
<px:PXGridColumn DataField="KAAssetLocationHistory__Department">
</px:PXGridColumn>
<px:PXGridColumn DataField="KAAssetLocationHistory__SiteID" Width="120px">
</px:PXGridColumn>
<px:PXGridColumn DataField="KAAsset__Status">
</px:PXGridColumn>
<px:PXGridColumn DataField="KAAsset__Condition">
</px:PXGridColumn>
</Columns>
</px:PXGridLevel>
</Levels>
<Mode AllowUpload="True" />
</px:PXGrid>
</Template>
</px:PXTabItem>
</Items>
<AutoSize Container="Window" Enabled="True" MinHeight="150" />
</px:PXTab>
</asp:Content>
As you can see <Mode AllowUpload="True" /> is inside in <px:PXGrid> tag
Page screen after uploaded excel :
As you can see it light's up pagination left arrow on the grid , but no rows are imported.
What am I missing?
After I removed selector(KAAssetSelector) from AssetID , problem fixed.
I think it's a bug