record id from rowselect listener returns generated id

Page 1 of 2 12 LastLast
  1. #1

    record id from rowselect listener returns generated id

    I tried to understand where the problem is, but I really don't know how to resolve this.

    I have a gridpanel which is bound after a first trip with fresh new records form the database.
    I will try to post a working sample if needed, however I suspect that i just don't look for the right record property.
    In a page I have a formpanel and a master gridpanel sharing the same store.
    In the formpanel I have a detail grid with other data and a separate store.
    In the first step the user compiles the form and submit data.
    In this first step (i.e. when the page is first loaded) the store have no dataBind().
    I successfully obtained the changeddata of both stores and saved master-detail informations to the database via direct event.
    After saving I follow these steps in order to have records back from database, since my objects must include extra informations:

    //retrieve data for the master grid/store
    var partProvider = new ParticellePif02CollectionProvider();
    var partcoll = partProvider.Find(terreno.IdPif01Pif02);
    
    //retrieve data for the detail grid
    var varProvider = new VarietaPif08CollectionProvider();
    varietacoll = varProvider.Find(terreno.IdPif02);
    
    //otherwise records are marked dirty, I don't know why
    StoreTerreni.CommitChanges();
    storeVarieta.CommitChanges();
    
    //databind both stores
    StoreTerreni.DataSource = partcoll;
    storeVarieta.DataSource = varietacoll;
    
    StoreTerreni.DataBind();
    storeVarieta.DataBind();
    After this first insert user could modify other records selecting them from the master grid.
    I can easily fill the form using the

    .getForm().loadRecord(record)
    in the rowselect listener.

    I implemented a direct method to retrieve the related details for the other grid, trying to pass the id of the master record to the direct method, but looking at its value I see that it is a client generated id (something like -200 etc.).
    here is the code for the grid and the master store:

                       <ext:GridPanel 
                            runat="server" 
                            ID="grdTerreni"
                            TrackMouseOver="true"
                            StripeRows="true"
                            Title="Elenco Terreni"
                            AnchorHorizontal="100%"
                            Height="350">
                             <Store>
                                <ext:Store runat="server" ID="StoreTerreni" SkipIdForNewRecords="false">
                                <Reader>
                                <ext:JsonReader IDProperty="IdPif02">
                                <Fields>
                                <ext:RecordField Name="IdPif01Pif02" ServerMapping="IdPif01Pif02.Value" />
                                <ext:RecordField Name="DescrizionePif07" ServerMapping="DescrizionePif07.Value"  />
                                <ext:RecordField Name="ComunePif07Pif02" ServerMapping="ComunePif07Pif02.Value"/>
                                <ext:RecordField Name="DesccondimpallPif02" ServerMapping="DesccondimpallPif02.Value" />
                                <ext:RecordField Name="DescondambPif02" ServerMapping="DescondambPif02.Value" />
                                <ext:RecordField Name="FoglioPf02" ServerMapping="FoglioPf02.Value" />
                                <ext:RecordField Name="ParticellaPif02" ServerMapping="ParticellaPif02.Value"/>
                                <ext:RecordField Name="SuphaPif02" ServerMapping="SuphaPif02.Value" />
                                <ext:RecordField Name="SupaaPif02" ServerMapping="SupaaPif02.Value" />
                                <ext:RecordField Name="SuptotPif02" ServerMapping="SuptotPif02.Value" />
                                <ext:RecordField Name="PrPif02" ServerMapping="PrPif02.Value" />
                                </Fields>
                                </ext:JsonReader> 
                                </Reader>
                                </ext:Store>
                             </Store>
                             <ColumnModel ID="ColumnModel1" runat="server">
                                <Columns>
                                    <ext:Column Header="Località" DataIndex="DescrizionePif07" />
                                    <ext:Column Header="Foglio" DataIndex="FoglioPf02" />                  
                                    <ext:Column Header="Particella" DataIndex="ParticellaPif02"/>
                                    <ext:Column Header="Superficie HA" DataIndex="SuphaPif02"/>
                                    <ext:Column Header="Superficie AA" DataIndex="SupaaPif02"/>
                                    <ext:Column Header="Superficie Totale" DataIndex="SuptotPif02"/>
                                </Columns>
                            </ColumnModel>
                            <SelectionModel>
                                <ext:RowSelectionModel runat="server" SingleSelect="true" >
                                <Listeners>
                                <RowSelect Handler="#{frmpnlTerreni}.getForm().loadRecord(record);Ext.net.DirectMethods.LoadVarieta(this.getSelected().id);"/>
                                </Listeners>
                                </ext:RowSelectionModel>
                            </SelectionModel>
                             </ext:GridPanel>
    this is the direct method to fill the detail grid related to the selected master record:

    [DirectMethod(ShowMask = true)]
            public void LoadVarieta(string idpart) //the parameter passed results in a negative integer as id for the record from the selected grid row 
            {
                var varietaProv = new VarietaPif08CollectionProvider();
                var varietacoll = varietaProv.Find(idpart);
                this.storeVarieta.DataSource = varietacoll;
                this.storeVarieta.DataBind();
            }
    the method runs correctly, but since the id has no correspondence in the db, I get an empty collection for the detail store.

    the parameter idpart is correctly sent from the direct method but it is not the record id I expected.
    As far as i could understand I thought that if the IDProperty is set, then this is used also as id for the record... is the same id for the gridpanel bound to the store, or am I looking at the wrong property?
    All the examples i have seen refer to this property to identify the selected record.
    Thanks in advance!
    Last edited by lapix; Feb 24, 2012 at 12:21 AM.
  2. #2
    Hi,

    <ext:JsonReader IDProperty="IdPif02">
    I can't see the RecordField with the "IdPif02" Name.
  3. #3
    Hi Daniil,
    yes, I did not include it in the recordfield's list, I thought it was enough to set it as IdProperty; you mean that if I don't include it in the recordfield list it won't be updated from the db?
  4. #4
    Yes, you are right, I forgot the fact that it's not required to have a RecordField with "IDProperty" Name.

    Well, then you should ensure the "IdPif02" is in a data that you bind to the Store.
  5. #5
    Ok, it seems that I was misled by this old post (see link), probably is outdated or I did not understand if it is applied only in case that id confirmation and save() method are applied:

    http://forums.ext.net/showthread.php...IdConfirmation

    According to that post, since I did not want manually manage id for new records, I set idProperty without including it in the reader's recordfields.
    As you could see in the following snippet code i used ConfirmationList, but just as utility class to keep track of generated id for the records; i m not using id confirmation logic because having master-detail data to insert at once, I prefer to manage them in direct event using my provider object's Save() method that allows me to set a unique transaction with consistent commit and rollback handles for all the related multiple tables insert, update and delete operations.
    After saving, I would update the new id records and back to store (even if I m stuck here since I have still some doubts about update all the fields of the object... so I preferred for now to bind the Store again with fresh data).
    protected void btnSaveTerreno_Click(object sender, DirectEventArgs e)
    {
      string datiVar = "{" + e.ExtraParams["varietadata"] + "}";
      string datiTer = "{" + e.ExtraParams["terrenodata"] + "}";
    
      StoreDataHandler partDatahandler = new StoreDataHandler(datiTer);
      StoreDataHandler varDatahandler = new StoreDataHandler(datiVar);
    
      ChangeRecords<ParticellePif02> terrData = partDatahandler.ObjectData<ParticellePif02>();
      ChangeRecords<VarietaPif08> varData = varDatahandler.ObjectData<VarietaPif08>();
    
    
      ConfirmationList confirmterrList = partDatahandler.BuildConfirmationList("IdPif02");
      ConfirmationList confirmvarList = varDatahandler.BuildConfirmationList("IdPif08");
         
    
      terreno = terrData.Created[0];
      terreno.IdPif01Pif02 = txtIdOlivicoltore.Text;
    
      foreach(VarietaPif08 rec in varData.Created)
      {
        varietacoll.Add(rec);
      }          
    
      //Here I call my object' save method to handle insert of more tables at once using a unique db transaction    
      //it returns a nested Dictionary with the correspondence between oldid and NewId    (Dictionary<"objectname", Dictionary<Oldid, NewId>>)          
      var ckeys = prodProv.SaveTerreni(terreno, varietacoll);
      var terrkeys = ckeys["terreno"];
      var varkeys = ckeys["varieta"];
    
    //here it should be the routine for updating new id... I found that I don't need to use ConfirmationList as utility since my Dictionary is enough
    
                //foreach (VarietaPif08 varc in varData.Created)
                //{
                    
                //    confirmvarList[varc.IdPif08].ConfirmRecord(varkeys[varc.IdPif08].ToString());
    
                //}
    
                //foreach (ParticellePif02 parc in terrData.Created)
                //{
                //    confirmterrList[parc.IdPif02].ConfirmRecord(varkeys[parc.IdPif02].ToString());
                //}
    
    
    //here i Bind again from database since having still on how to synchronize store content....
      var partProvider = new ParticellePif02CollectionProvider();
      var partcoll = partProvider.Find(terreno.IdPif01Pif02);
    
      var varProvider = new VarietaPif08CollectionProvider();
      varietacoll = varProvider.Find(terreno.IdPif02);
    
    
      StoreTerreni.CommitChanges();
      storeVarieta.CommitChanges();
    
    
      this.StoreTerreni.DataSource = partcoll;
      storeVarieta.DataSource = varietacoll;
    
      StoreTerreni.DataBind();
      storeVarieta.DataBind();
    }
    Button with Direct Event and Listener to add records and pass data to server side:

    <ext:Button runat="server" ID="btnSaveTerreno" Icon="Disk" Text="Salva" >
                  <DirectEvents>
                    <Click OnEvent="btnSaveTerreno_Click" >
                        <ExtraParams>
                           <ext:Parameter Name="varietadata" Value="#{storeVarieta}.getChangedData()" Mode="Raw" />
                           <ext:Parameter Name="terrenodata" Value="#{StoreTerreni}.getChangedData()" Mode="Raw" />
                        </ExtraParams>
                        <EventMask Msg="Salvataggio in corso..." ShowMask="true" />
                    </Click>
                  </DirectEvents>
                  <Listeners>
                    <Click Handler="#{StoreTerreni}.addRecord(#{frmpnlTerreni}.getForm().getFieldValues(false, 'dataIndex'),false, true);" />
                  </Listeners>
                  </ext:Button>
    But i tried what you suggested me, i included idPif02 as recordfield, and generated id logic works anyway! In the ChangedData() store's parameter I pass to the page, the generated Id is still present, and correctly put in the ConfirmationList as OldId value.
    here's the parameter value passed by the ChangedData(), adding the IdPif02 field to the recordfields; the generated id is still present, as i wished:


    {"Created":[{"IdPif02":-217,"IdPif01Pif02":"96","DescrizionePif07":"","ComunePif07Pif02":6314,"DesccondimpallPif02":"descrizione","DescondambPif02":"descrizione","FoglioPf02":"1","ParticellaPif02":"1","SuphaPif02":"23","SupaaPif02":"12","SuptotPif02":"35","PrPif02":""}]}
    so probably since that post the behaviour of the grid/store has changed, or probably what I have read is referred only in case I use id confirmation and store's save() method?
    Last edited by Daniil; Feb 24, 2012 at 1:26 PM. Reason: Please use [CODE] tags for any code
  6. #6
    so probably since that post the behaviour of the grid/store has changed, or probably what I have read is referred only in case I use id confirmation and store's save() method?
    Yes, that post is related to the save method and the UseIdConfirmation mechanism. Though, anyways, the logic described in that post is really deprecated.

    Now, there are the following main points in Ext.NET v1 related to our discussion:

    1. No matter you set up IDProperty or not, no matter there is a RecordField with "IDProperty" Name or not.

    2. When a JSON object for new records ("Created") is populated (it's implemented in the Store getChangedData method), a generated id for a new record is put to that JSON object with the "IDProperty" property (defaults to "id").

    3. Then, if UseIdConfirmation="false (by default) and SkipIdForNewRecords is not "false" (defaults to undefined which really means "true") that "IDProperty" property is removed from that JSON object for new records. It's also the part of the Store getChangedData.

    4. The save method internally uses the getChangedData method.

    Hope this helps.


    record id from rowselect listener returns generated id
    Please clarify is the initial problem related to new records only?

    Just to clarify - you can avoid auto-generating id if pass an "IDProperty" value into the addRecord/instertRecord methods.

    Example
    GridPanel1.addRecord({
        idPropertyField : "Hello! I am id."
    });
    Last edited by Daniil; Mar 02, 2012 at 8:56 AM.
  7. #7
    Ok, I suspected that that post was obsolete, anyway I implemented my logic in a direct event associated to the save button so this problem was solved.

    regarding the points you correctly stated:

    1. No matter you set up IDProperty or not, no matter there is a RecordField with "IDProperty" Name or not.
    Ok for this point, although it depends how we want the id for new records be handled (i did not test without iDProperty).

    2. When a JSON object for new records ("Created") is populated (it's implemented in the Store getChangedData method), a generated id for a new record is put to that JSON object with the "IDProperty" property (defaults to "id").
    Ok, I got it, I just need to understand if IDProperty is a property associated to the record or to the JSON object (I think JSON object, looking at the source code).

    3. Then, if UseIdConfirmation="false (by default) or SkipIdForNewRecords="false" (defaults to undefined) that "IDProperty" property is removed from that JSON object for new records. It's also the part of the Store getChangedData.
    Ok, tested for UseIdConfirmation="false" while for SkipIdForNewRecords="false" I noticed the opposite: when true (I think it's default, I ve read it in some other post) IDProperty is removed, when false it's put in the record; I set it at "false" because I want it for new records.


    Please clarify is the initial problem related to new records only?
    Regarding your question, the answer is: it happens for updated records too.

    To verify this behaviour I added this recordfield to the store:

    <ext:Store runat="server" ID="StoreTerreni" SkipIdForNewRecords="false">
         <Reader>
           <ext:JsonReader IDProperty="IdPif02">
                <Fields>
                     <ext:RecordField Name="IdPif02" ServerMapping="IdPif02.Value" />
                        .
                        .
                        .
                      --other recordfields--
    When I click the save button the related direct event is called, and I get ChangedData from the parameters (see code in the previous post).

    without IdPif02 recordfield (json object puts autogenerated id):
    {"Updated":[{"IdPif02":-222, ........(all the other fields)......]}

    with IdPif02 recordfield (json object puts db record id):

    {"Updated":[{"IdPif02":80,........(all the other fields)......]}
    I created separate buttons for test purposes, the update button is this one:

    <ext:Button runat="server" ID="btnupdateTerreno" Text="update">
    <Listeners>
    <Click Handler="#{frmpnlTerreni}.getForm().updateRecord(#{grdTerreni}.getSelectionModel().getSelected())" />
    </Listeners>
    <DirectEvents>
    <Click OnEvent="btnSaveTerreno_Click" >
    <ExtraParams>
        <ext:Parameter Name="varietadata" Value="#{storeVarieta}.getChangedData()" Mode="Raw" />
        <ext:Parameter Name="terrenodata" Value="#{StoreTerreni}.getChangedData()" Mode="Raw" />
    </ExtraParams>
    </Click>
    </DirectEvents>
    </ext:Button>
    the save button for a new record is this one:

    <ext:Button runat="server" ID="btnSaveTerreno" Icon="Disk" Text="Salva" >
    <DirectEvents>
    <Click OnEvent="btnSaveTerreno_Click" >
        <ExtraParams>
           <ext:Parameter Name="varietadata" Value="#{storeVarieta}.getChangedData()" Mode="Raw" />
           <ext:Parameter Name="terrenodata" Value="#{StoreTerreni}.getChangedData()" Mode="Raw" />
        </ExtraParams>
        <EventMask Msg="Salvataggio in corso..." ShowMask="true" />
    </Click>
    </DirectEvents>
    <Listeners>
    <Click Handler="if(#{txtIdTerreno}.getValue()=='')
                    {#{StoreTerreni}.addRecord(#{frmpnlTerreni}.getForm().getFieldValues(false, 'dataIndex'),false, true)}
                    else{#{frmpnlTerreni}.getForm().updateRecord(#{grdTerreni}.getSelectionModel().getSelected())};" />
    </Listeners>
    </ext:Button>
    the txtIdTerreno is a hidden field with DataIndex mapped to the Pif02 id field:

    <ext:Hidden runat="server" ID="txtIdTerreno" DataIndex="IdPif02" />
    I put another test button on the form to alert me the id and idProperty of the selected record:

    </ext:Button>
     <ext:Button runat="server" ID="Button1" Icon="Application" Text="show id record" >
    <Listeners>
        <Click Handler="alert('value id: ' + #{grdTerreni}.getSelectionModel().getSelected().id + ' ' + 'idProperty: ' + #{grdTerreni}.getSelectionModel().getSelected().idProperty);" />
    </Listeners>
    </ext:Button>
    the alert confirms the behaviour resulting from adding or removing the IdPif02 recordfield.
    The idProperty instead in both cases results always "Undefined"; maybe it's not a record property? (forgive my poor knowledge about ExtJS)

    I understand that these are newbie questions, but i want to have an exact idea of the Id handling... since it's 90% of data management. :)
    anyway, the behaviour I would obtain is this one:

    1. Get an auto-generated Id for new records that I can handle server side
    2. Get the db generated Id for existing records to avoid inconsistency between db data and client manipulated data.

    Adding the IdPif02 recordfield made the bill, so I just want to be sure that I need to always implement this logic for the rest of the application to achieve this behaviour.
    Last edited by Daniil; Mar 02, 2012 at 8:40 AM. Reason: Please use [CODE] tags for any code
  8. #8
    Quote Originally Posted by lapix View Post
    Ok, tested for UseIdConfirmation="false" while for SkipIdForNewRecords="false" I noticed the opposite: when true (I think it's default, I ve read it in some other post) IDProperty is removed, when false it's put in the record; I set it at "false" because I want it for new records.
    Yes, thanks, it's my fault, I've described it wrong.

    Quote Originally Posted by Daniil View Post
    3. Then, if UseIdConfirmation="false (by default) or SkipIdForNewRecords="false" (defaults to undefined) that "IDProperty" property is removed from that JSON object for new records. It's also the part of the Store getChangedData.
    It must be:

    3. Then, if UseIdConfirmation="false (by default) and SkipIdForNewRecords is not "false" (defaults to undefined which really means "true") that "IDProperty" property is removed from that JSON object for new records. It's also the part of the Store getChangedData.

    I will change it in my initial post to avoid any inconvience in the future when someone will read the post.
  9. #9
    Hi Daniil,
    thanks for the further explanation, now the behaviour is more clear, I added the id to the reader whenever I want to manage new record's id as desired,
    thanks a lot!

    Francesco
  10. #10
    Quote Originally Posted by lapix View Post
    Regarding your question, the answer is: it happens for updated records too.

    To verify this behaviour I added this recordfield to the store:

    <ext:Store runat="server" ID="StoreTerreni" SkipIdForNewRecords="false">
         <Reader>
           <ext:JsonReader IDProperty="IdPif02">
                <Fields>
                     <ext:RecordField Name="IdPif02" ServerMapping="IdPif02.Value" />
                        .
                        .
                        .
                      --other recordfields--
    When I click the save button the related direct event is called, and I get ChangedData from the parameters (see code in the previous post).

    without IdPif02 recordfield (json object puts autogenerated id):
    {"Updated":[{"IdPif02":-222, ........(all the other fields)......]}

    with IdPif02 recordfield (json object puts db record id):

    {"Updated":[{"IdPif02":80,........(all the other fields)......]}
    the txtIdTerreno is a hidden field with DataIndex mapped to the Pif02 id field:

    <ext:Hidden runat="server" ID="txtIdTerreno" DataIndex="IdPif02" />
    Well, that
    "IdPif02":80
    comes from the <ext:Hidden> when you call the updateRecord and there is the RecordField with Name="IdPif02" which matches the <ext:Hidden> DataIndex.
    Last edited by Daniil; Mar 02, 2012 at 9:10 AM.
Page 1 of 2 12 LastLast

Similar Threads

  1. [CLOSED] ROWEXPANDER: not able to read record from listener on expand
    By ashton.lamont in forum 1.x Legacy Premium Help
    Replies: 5
    Last Post: May 08, 2013, 4:28 AM
  2. Replies: 2
    Last Post: Apr 09, 2012, 2:13 PM
  3. [CLOSED] Add record server side to dynamically generated store
    By rthiney in forum 1.x Legacy Premium Help
    Replies: 1
    Last Post: Aug 01, 2011, 7:36 PM
  4. Replies: 7
    Last Post: Jun 15, 2011, 7:34 PM
  5. [CLOSED] adding listener to dynanically generated accordion
    By SymSure in forum 1.x Legacy Premium Help
    Replies: 5
    Last Post: Apr 12, 2011, 4:37 PM

Tags for this Thread

Posting Permissions