skip to Main Content

I am trying to create a form/screen that will allow for the updating of INLocation records. A very basic form.

It starts at the first record, and allows the user to move PREV or NEXT. They can change a couple of fields, or delete the record.

I have it sort of working. The form runs correctly, drawing in the first record as expected.
Screen working

But when I hit NEXT or PREV, it is not updating the information on the screen (even tho it is correctly moving to the next or prev record in the data. I confirmed that using breakpoints and examining the data.)

This is my current ASPX:

<%@ Page Language="C#" MasterPageFile="~/MasterPages/FormView.master" AutoEventWireup="true" ValidateRequest="false" CodeFile="IN900100.aspx.cs" Inherits="Page_IN900100" 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="ASGExecuteSQL.INLocationMaint"
        PrimaryView="Locations"
        >
    <CallbackCommands>

    </CallbackCommands>
  </px:PXDataSource>
</asp:Content>
<asp:Content ID="cont2" ContentPlaceHolderID="phF" Runat="Server">
  <px:PXFormView ID="form" runat="server" DataSourceID="ds" DataMember="Locations" Width="100%" AllowAutoHide="false">
    <Template>
      <px:PXLayoutRule runat="server" StartRow="True" ID="PXLayoutRule1" ></px:PXLayoutRule>
      <px:PXLayoutRule runat="server" ID="CstPXLayoutRule6" StartGroup="True" ></px:PXLayoutRule>
      <px:PXLabel runat="server" ID="CstLabel7" Text="INLocation Information" />
      <px:PXSegmentMask runat="server" ID="CstPXSegmentMask9" DataField="SiteID" />
      <px:PXSegmentMask runat="server" ID="CstPXSegmentMask8" DataField="LocationCD" CommitChanges="True" />
      <px:PXTextEdit runat="server" DataField="Descr" ID="edDescr" ></px:PXTextEdit>
      <px:PXTextEdit CommitChanges="True" runat="server" DataField="LocationID" ID="edLocationID" ></px:PXTextEdit></Template>
    <AutoSize Container="Window" Enabled="True" MinHeight="200" ></AutoSize>
  </px:PXFormView>
</asp:Content>

And this is the C# Backend code:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

using PX.Data;
using PX.Data.BQL.Fluent;
using PX.Objects.FS;
using PX.Objects.IN;
using static PX.Data.BQL.BqlPlaceholder;

namespace ASGExecuteSQL
{
    public class INLocationMaint : PXGraph<INLocationMaint>
    {
        // Primary view for INLocation DAC
        public PXCancel<INLocation> Cancel;
        public PXSave<INLocation> Save;
        public SelectFrom<INLocation>.View Locations;

        public INLocationMaint()
        {
            // Optionally load the first record into Locations.Current to initialize data

            if (Locations.Current == null)
            {
                Locations.Cache.AllowInsert = false; // don't let them create a blank record

                INLocation firstRecord = SelectFrom<INLocation>.View.Select(this);
                if (firstRecord != null)
                {
                    Locations.Current = firstRecord;
                }
                if (Locations.Current != null)
                {
                    var onCode = Locations.Current.LocationCD;
                    var onID = Locations.Current.LocationID;
                    var StopHere = 0;
                }
            }
        } 

        protected void _(Events.RowSelected<INLocation> e)
        {
            var cache = e.Cache;
            // the default display for this is Location ID, which is confusing... so...
            PXUIFieldAttribute.SetDisplayName<INLocation.locationCD>(cache, "Location Code");

        }

        // NEXT button action
        public PXNext<INLocation> Next;
        [PXButton(CommitChanges = true)]
        [PXUIField(DisplayName = "Next", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)]
        protected IEnumerable next(PXAdapter adapter)
        {
            INLocation current = Locations.Current;
            INLocation next = PXSelect<INLocation,
                Where<INLocation.locationID, Greater<Required<INLocation.locationID>>>,
                OrderBy<Asc<INLocation.locationID>>>
                .Select(this, current.LocationID)
                .FirstOrDefault();

            if (next != null)
            {
                Locations.Current = next;
                Locations.Cache.Update(next);
                Locations.View.RequestRefresh();
            }

            return adapter.Get();
        }

        // PREVIOUS button action
        public PXPrevious<INLocation> Previous;
        [PXButton(CommitChanges = true)]
        [PXUIField(DisplayName = "Previous", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)]
        protected IEnumerable previous(PXAdapter adapter)
        {
            INLocation current = Locations.Current;
            INLocation prev = PXSelect<INLocation,
                Where<INLocation.locationID, Less<Required<INLocation.locationID>>>,
                OrderBy<Desc<INLocation.locationID>>>
                .Select(this, current.LocationID)
                .FirstOrDefault();

            if (prev != null)
            {
                Locations.Current = prev;
                Locations.Cache.Update(prev);
                Locations.View.RequestRefresh();
            }

            return adapter.Get();
        }

        // DELETE button action
        public PXDelete<INLocation> Delete;
        [PXButton(CommitChanges = true)]
        [PXUIField(DisplayName = "Delete", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)]
        protected IEnumerable deleteLocation(PXAdapter adapter)
        {
            INLocation current = Locations.Current;
            if (current != null)
            {
                Locations.Delete(current);
                this.Actions.PressSave();
            }

            return adapter.Get();
        }
    }
}

I feel like I am missing something simple in a binding or a setup or something, but I cannot find it if I did.

2

Answers


  1. I don’t have your ORM, but say this markup:

        <asp:FormView ID="FormView1" runat="server" Width="16%" 
            AllowPaging="true"
            PagerSettings-Mode="NextPrevious"
            OnPageIndexChanging="FormView1_PageIndexChanging"
            >
            <ItemTemplate>
                <label>Hotel Name</label>
                <asp:TextBox ID="txtHotel" runat="server" Text='<%# Eval("HotelName")%>'>
                </asp:TextBox>
                <br />
                <br />
    
                <label>First Name</label>
                <asp:TextBox ID="txtFirst" runat="server" Text='<%# Eval("FirstName")%>'>
                </asp:TextBox>
                <br />
                <br />
    
                <label>Last Name</label>
                <asp:TextBox ID="txtLast" runat="server" Text='<%# Eval("LastName")%>'>
                </asp:TextBox>
            </ItemTemplate>
            <PagerTemplate>
    
                <div style="float:left;margin-top:20px">
                    <asp:Button ID="cmdPrevious" runat="server" Text="Previous"
                        CommandName="Page"
                        CommandArgument="Prev"                        
                        CssClass="btn-info"
                        style="float:left;width:80px"
                        />
    
                    <div style="float:left;margin-left:14px">
    
                        Record <%# FormView1.PageIndex + 1 %> of 
                        <%# FormView1.PageCount %>
    
                    </div>
                    <asp:Button ID="cmdNext" runat="server" Text="Next"
                        CommandName="Page"
                        CommandArgument="Next"                        
                        CssClass="btn-info"
                        style="margin-left:20px;width:80px"
                        />
                </div>
            </PagerTemplate>
        </asp:FormView>
    

    And code behind:

        DataTable dtHotels = new DataTable();
        string strSQL =
            "SELECT * FROM tblHotelsA ORDER BY HotelName";
        
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                GetData();
                FormView1.DataSource = dtHotels;
                FormView1.DataBind();
                Session["dtHotels"] = dtHotels;
            }
            else
            {
                dtHotels = (DataTable)Session["dtHotels"];
            }
        }
    
        void GetData()
        {
           string sConn = Properties.Settings.Default.TEST4;
            using (SqlConnection conn = new SqlConnection(sConn))
            {
                conn.Open();
                using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
                {
                    dtHotels.Load(cmdSQL.ExecuteReader());
                }
            }
        }
    
        protected void FormView1_PageIndexChanging(object sender, FormViewPageEventArgs e)
        {
            SaveEdits();
    
            FormView1.PageIndex = e.NewPageIndex;
            FormView1.DataSource = dtHotels;
            FormView1.DataBind();
    
        }
    
        void SaveEdits()
        {
            FormViewRow fRow = FormView1.Row;
            DataRow EditRow = dtHotels.Rows[FormView1.DataItemIndex];
    
            EditRow["HotelName"] = ((TextBox)fRow.FindControl("txtHotel")).Text;
            EditRow["FirstName"] = ((TextBox)fRow.FindControl("txtFirst")).Text;
            EditRow["LastName"] = ((TextBox)fRow.FindControl("txtLast")).Text;
            
            using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
            {
                conn.Open();
                SqlCommand cmd = new SqlCommand(strSQL, conn);
                SqlDataAdapter da = new SqlDataAdapter(cmd);
                SqlCommandBuilder dau = new SqlCommandBuilder(da);
                da.Update(dtHotels);
            }
        }
    

    And the result is this:

    enter image description here

    So, note the PageIndexChanging event. We have to add code to that event to save the record before we navigate.

    Login or Signup to reply.
  2. What you need is already implemented in the framework; simply add the DAC type as the second parameter when declaring the graph—no additional coding is required.
    Also, it’s better to change a field label in the CacheAttached event.

    using System; 
    using PX.Data; 
    using PX.Objects.IN;
    
    namespace ASGExecuteSQL 
    {
        public class INLocationMaint : PXGraph<INLocationMaint, INLocation/>
        {
            public PXSelect<
                INLocation,
                Where<INLocation.locationID, Greater<Required<INLocation.locationID>>>,
                OrderBy<Asc<INLocation.locationID>>
            > Locations;
    
            [PXMergeAttributes(Method = MergeMethod.Merge)]
            [PXUIField(DisplayName = "Location Code")]
            protected void _(Events.CacheAttached<INLocation.locationCD> e) { }
        } 
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search