Access to previous and next records

I'm looking for a way to make it possible to page through a list of records from the view of a single record - that is, to add in BACK and NEXT buttons at the bottom of a single record view rather than returning to the list to reselect the next.

I understand from previous posters that this may be possible if you can access the list's index of the selected record, then decrement or increment into a local variable so your BACK and NEXT buttons will take the user to the correct record.

I have saved the queried list of records to a local variable. How does one access the index values of the records in that variable? Should I instead work from a read-only grid? fv!item will give me the entire record but no value I can reliably decrement or increment to get its neighbors, and fv!identifier will give me its unique identifier, but as records are constantly added and deleted that is also unreliable.

  Discussion posts and replies are publicly visible

Parents
  • 0
    Certified Lead Developer

    Can you clarify - are you trying to add the ability to go to the previous / next record from a certain record's Summary View page?  If so, I think it's doable but I don't think any button will do it - you'd need to use a link.

    Is the fv!identifier the DB primary key?  If so, in your record interface you could simply query single entries from the DB where the primary key is one less than the current (for previous) and one greater (for next), and simply use those queried values in your a!recordLink calls on the interface.

Reply
  • 0
    Certified Lead Developer

    Can you clarify - are you trying to add the ability to go to the previous / next record from a certain record's Summary View page?  If so, I think it's doable but I don't think any button will do it - you'd need to use a link.

    Is the fv!identifier the DB primary key?  If so, in your record interface you could simply query single entries from the DB where the primary key is one less than the current (for previous) and one greater (for next), and simply use those queried values in your a!recordLink calls on the interface.

Children
  • Hi, Mike, thanks for the reply.

    I would be happy to do this from a summary view if possible. I misspoke when I said 'buttons'; I had intended to use a dynamic link.

    The fv!identifier is the unique DB primary key, but these are autogenerated when the records are created, and as records get deleted that identifier is no longer guaranteed to be one number away from its fellows. As an example:

    ID: 1
    Name: Bob

    ID: 2
    Name: Helen

    ID: 3
    Name: Chris

    If Helen is deleted, the IDs are still unique, but when viewing Bob's record, adding 1 to the identifier will not get me to the next (Chris). What I was hoping for is access to the actual index of the array that Appian is creating when I run a filtered query on my records. So I may get:

    ID: 1
    Name: Bob

    ID: 8
    Name: Edward

    ID: 10
    Name: Jane

    But regardless of those ID numbers, within the array the index numbers are what I wish to reference to move around. They'll always be contiguous and specific to the query to ensure my clients only have to page through the selected records.

    EDIT: Ah! I think I've located what I needed with the WHERECONTAINS function - if I can pass in the fv!identifier as the value it should be able to return to me the array index. Thanks for your attention, all. I think I'm all set.

  • 0
    Certified Lead Developer
    in reply to RLacoste01

    I do recommend against hard-deleting database entries (based on hard-earned personal experience), and instead using a flag i.e. "IS_DELETED" and/or "IS_ACTIVE" columns (having essentially equivalent yet opposite meanings). 

    But regardless, you wouldn't simply say "current ID is 8, so the next one will be 8 + 1", but instead you'd run a standard query entity, batch size 1, where pk_id > local!myCurrentId, ascending = true (for getting the next one) and false (for getting the previous one).  This should work in any case and regardless of row deletions (i.e. if your current ID is 8, and you run the query i'm describing, it will grab the row with primary key of 10 since 9 has been deleted).

  • Thank you for this alternative! I will take your advice re: deleting (or NOT deleting) database entries to heart, and this query-based workaround to ensure we get the next viable entry will be my fallback if I can't wrangle the indexes into line. When running my initial record query should I take care to sort by ID to get an accurate result?

  • +1
    Certified Lead Developer
    in reply to RLacoste01
    I think I've located what I needed with the WHERECONTAINS function - if I can pass in the fv!identifier as the value it should be able to return to me the array index.

    This doesn't sound very efficient - it sounds as if you'll be querying the entire data set just for the sake of iterating one back and one next.  Instead you should run two separate surgical queries, tuned to return just the primary key ids of the previous row and next row (as i described in my previous comment).

    When running my initial record query should I take care to sort by ID to get an accurate result?

    You have some flexibility here.  In general I'd suggest you sort on whatever field you use for your record list's primary sort (if something other than primary key).

    Here's a sample of the query I mean, note that here i've sorted by primary key, but you can change this to whatever you're sorting by (last name, etc).

    a!queryEntity(
      entity: cons!my_entity,
      query: a!query(
        pagingInfo: a!pagingInfo(
          startIndex: 1,
          batchSize: 1,
          sort: a!sortInfo(
            field: "primaryKey", 
            ascending: if(ri!fetchingPrevious, false(), true())
          )
        ),
        filter: a!queryFilter(
          field: "primaryKey",
          operator: if(ri!fetchingPrevious, "<", ">"),
          value: ri!currentPrimaryKey
        )
      )
    ).data.primaryKey

  • Re: the sorting, my final goal is to retrieve a list of records that meet a set of criteria (I'm searching on three fields) and then permit the client to click back and forth through each record in that list without having to return to the list to select a new one. 

    Thank you for the code. If I understand you correctly, the wherecontains() would require me to loop through the entire returned list each time the client clicked to a new record to determine its index (and derive the previous and next indices) and that's not appealing. I'll attempt to incorporate the above example instead and see how it goes.

    Edit: It goes *awesome*. Thanks, Mike. This is exactly what I needed.