0

Can I control the order in which Ninox displays my tables?

When I open my database, it appears Ninox orders my tables in the order in which I created them. (see attached). Is there a way for me to re-order them a bit more logically for my users?

30 replies

null
    • Fred
    • 11 days ago
    • Reported - view

    I would recommend that you don’t allow users to navigate the tables directly. Create dashboards that allow users to do what they need to do. Can never trust those users to do what they are supposed to do. :)

      • John_Halls
      • 8 days ago
      • Reported - view

       Life would be so much easier if we didn't have users. Or customers eh  ?

      • Fred
      • 8 days ago
      • Reported - view

       sadly, I'm my only user and I have to keep myself from doing stupid things.

      • Dave_Airel
      • 6 days ago
      • Reported - view

        Thanks for that pointer, I honestly hadn't thought of that. The pop up forms seem so easy and intuitive ...  I guess it makes sense to put a little security between our users and the basic structure of the database. I've been thinking about this for a couple days and keep coming back to this ... other than removing the chance of deleting an entire table, are there really any other protections provided by building edit capabiities into a separate dashboard table? (serious question)

      • Fred
      • 6 days ago
      • Reported - view

       off the top of my head, dashboards/pages can:

      1) data validation before you write the data to a record

      2) you make an easy UI for your users  

      3) simpler data access protection, keep people from accessing data they shouldn’t  

      4) you don’t have to worry about the dynamic choice bug since you never use it to store data  

      5) can update many tables at once

      6) if you create the UI at the data table then all that ui stuff appears on each record, you are mixing the roles of UI and data storage . Also you don’t have to make your data tables look pretty.

      • Dave_Airel
      • 6 days ago
      • Reported - view

       Yeah. Ok. Tail between my legs pulling open the training videos on dashboards now. Thanks, Fred.

      • Fred
      • 6 days ago
      • Reported - view

       it took me awhile to understand the advantages of dashboards. I’m the only user but even for me I’m finding them helpful. Plus I don’t trust myself. 🤣

      • Fred
      • 6 days ago
      • Reported - view

       You probably have all the knowledge already to setup your dashboards. If you uses Pages then all you need is to create the fields that make up the UI. No special training needed.

      • Dave_Airel
      • 6 days ago
      • Reported - view

       I think I'm ok. I used a Nioxus training video from a couple years ago to get started. I began with a "Control Panel" table, created a form view and am building out tabs for the different stuff users will need to do. So far I have "Add a new contact" working, moving on to the others over the next couple days. Thx for your support -- as always, suggestions welcome.

      • Fred
      • 5 days ago
      • Reported - view

       That looks great! You are on your way. I know it seems like too much extra work, but you will soon find that going into the tables directly to be too much trouble and wished you had created a dashboard to do what you needed.

      • Dave_Airel
      • 5 days ago
      • Reported - view

       OK, stuck on a script again. A few weeks ago, you and  helped me build a script to process an imported .csv file into two tables (Contacts and Events). That script has been working fine. In this latest dashboard effort, I want to create a dashboard tab to manage this entire process - eventually launching the import (into the Attendance_Staging table) from the dashboard, and then using the "Process Data" script to move the data.

      I started by manually importing a test .csv with 3 records into Attendance_Staging. From my perspective, it seemed like the original script might work so I just copied it over to a button on the dashboard. It does process the Attendance_Staging table, but only the last record is saved. The script is below. I'd be happy to send you a copy of the database, but now that it's populated with real data I don't want to post it here. Can I get it to you some other way?

      Here's the script (again, it works when the button on the Attendance_Staging table, but only the last record is saved when I launch it from the Control Panel (Import - Events tab, BTW)

      do as server
          let allContacts := (select Contacts);
          let allEvents := (select Events);
          let allRSVP := (select RSVP);
          for i in select Attendance_Staging do
              let contact := if contains(allContacts.lower(Email), i.lower(Email)) then
                      first(allContacts[lower(Email) = i.lower(Email)])
                  else
                      let newContact := (create Contacts);
                      newContact.(
                          Email := i.lower(Email);
                          Lastname := i.'Last name';
                          Firstname := i.'First name';
                          'Mobile Phone' := i.'Mobile number';
                          Zip := i.Zip
                      );
                      allContacts := array(allContacts, [newContact.Id]);
                      newContact.Id
                  end;
              let event := if contains(allEvents.'Event ID', i.'Event ID') then
                      first(allEvents['Event ID' = i.'Event ID'])
                  else
                      let newEvent := (create Events);
                      newEvent.(
                          'Event ID' := i.'Event ID';
                          'Event Name' := i.'Event name';
                          'Event Type' := i.'Event type';
                          'Date / Time' := i.'Timeslot start'
                      );
                      allEvents := array(allEvents, [newEvent.Id]);
                      newEvent.Id
                  end;
              if count(allRSVP[Attended_Import = i.Attended and Contacts = number(contact.Id) and
                              Events = number(event.Id)]) = 0 then
                  (create RSVP).(
                      Contacts := number(contact.Id);
                      Events := number(event.Id);
                      Attended_Import := i.Attended;
                      'RSVP Status' := i.'Attendance Status'
                  )
              end
          end;
          delete (select Attendance_Staging)
      end

      • Fred
      • 5 days ago
      • Reported - view

       Can you copy your DB and remove all personal data and put in fake data?

      • Dave_Airel
      • 5 days ago
      • Reported - view

       Just went to do that & realized in my testing I had deleted 7 'real' contacts ... no idea how I did that. I need to fix that first so give me a little time. I have to run out this afternoon so I'll work on it over the weekend and send you the latest DB with some fake data. Thanks, Fred.

      • John_Halls
      • 4 days ago
      • Reported - view

       Hi Dave

      I can't see anything in your code that would be affected by where you run it. I hope you don't mind but I had a go at tidying it up to this

      do as server
         let allContacts := (select Contacts);
         let allEvents := (select Events);
         let allRSVP := (select RSVP);
         for i in select Attendance_Staging do
            let contact := first(allContacts[lower(Email) = i.lower(Email)]);
            if not contact then
               contact := (create Contacts);
               contact.(
                  Email := i.lower(Email);
                  Lastname := i.'Last name';
                  Firstname := i.'First name';
                  'Mobile Phone' := i.'Mobile number';
                  Zip := i.Zip
               );
               allContacts := array(allContacts,[contact])
            end;
            let event := first(allEvents['Event ID' = i.'Event ID']);
            if not event then
               event := (create Events);
               event.(
                  'Event ID' := i.'Event ID';
                  'Event Name' := i.'Event name';
                  'Event Type' := i.'Event type';
                  'Date / Time' := i.'Timeslot start'
               );
               allEvents := array(allEvents,[event])
            end;
            if count(allRSVP[Attended_Import = i.Attended and Contacts = contact and Events = event]) = 0 then
               (create RSVP).(
                  Contacts := contact;
                  Events := event;
                  Attended_Import := i.Attended;
                  'RSVP Status' := i.'Attendance Status'
                )
            end
         end;
         delete (select Attendance_Staging)
      end
      

      Regards John

      • Dave_Airel
      • 4 days ago
      • Reported - view

        Well, this all turned out to be bad test data. Both scripts for processing imports (one for event attendance, the other for donations) are working fine. I wasn't careful enough prepping my test data - there were no deleted contacts yesterday - 3 hours wasted because I didn't take an extra 15 minutes to fully prep my test data. Didn't really delete anything yesterday, just went down a rabbit hole trying to find my mistakes.

      So I think my control panel is nearly completed. Now I just need to figure out a better way to do the actual .csv imports into my staging tables. In the attached DB, I can either go to one of the staging tables and do a simple import, or do it from the Import tabs on the Control Panel (which is error-prone since I have to change the import table) ... would appreciate any thoughts on this one. DB and two .csvs (one event attendance and one donations) are attached. All data is fake test data.

      • Dave_Airel
      • 4 days ago
      • Reported - view

       Hi, John - thanks for this. You may have seen from my earlier reply to Fred that my scripts were working, I was thrown off by wonky test data. Thanks for this cleanup, I'll take a look at it later. I'm a newbie when it comes to anything but 1-line scripts and I struggle mightily with Ninox's scripting language. So a side by side comparison will be like study hall for me :) Much appreciated

      • John_Halls
      • 4 days ago
      • Reported - view

       Hi Dave. In that case you have picked up some decent techniques pretty quickly. I haven't tested the revised code but the changes were was mostly swapping out things like Contacts := number(contact.Id) for Contacts := contact (it's the same thing but simpler) and trying to remove the duplication in finding a contact and event etc.

      Regards John

      • Dave_Airel
      • 4 days ago
      • Reported - view

       Thanks - I've built a few databases & websites before but the Ninox scripting language is making me old before my time :) I've relied alot on this forum, on the Ninox & Nioxus training videos and a bit of ChatGPT (with mixed success).

      • John_Halls
      • 4 days ago
      • Reported - view

       Hi Dave

      I've had a quick look at your solution. Impressive stuff. I did notice that you are using a select statement to get the full name of the donor in the Donations table

      let e := lower(trim(this.Email));
      let c := first(select Contacts where lower(trim(Email)) = e);
      if c != null then c.Full_Name else "" end
      

      As many of us have found out to our cost, this becomes a serious overhead as your database grows. I would add a reference field to the Donations table, and join this to the Contacts table. It only needs an extra line in your processing script to then make the link. This

                      newDonation.(
                          LineitemID := i.LineitemID;
                          Date := i.Date;
                          Amount := i.Amount;
                          Email := i.Email
                      );
      

      becomes this

                      newDonation.(
                          LineitemID := i.LineitemID;
                          Date := i.Date;
                          Amount := i.Amount;
                          Email := i.Email;
                          contacts := contact
                      );
      

      Your formula can then become

      contacts.Full_Name

      BTW It is perfectly OK to use select in the processing scripts, an ideal use case.

      Regards John

    • Mel_Charles
    • 8 days ago
    • Reported - view

    AGred with Fred but to answer your question directly - yes you can

    in edit mode - hover over the the table name and you will see 6 dots appear. click and hold and drag table up or down the list - 🙂 

      • Dave_Airel
      • 6 days ago
      • Reported - view

       Got it - thanks, Mel.

    • Fred
    • 3 days ago
    • Reported - view

    Have you tried  ChatGPT? It is better than the general version, but still not perfect.

      • Dave_Airel
      • 3 days ago
      • Reported - view

       Yes, I've used it multiple times. Definite improvement - thanks.

    • Fred
    • 3 days ago
    • Reported - view
     said:
    It does process the Attendance_Staging table, but only the last record is saved.

    I tested it out with just the contacts part and it created the two records (Lynn and Jeff) that are not in the contacts.

      • Dave_Airel
      • 3 days ago
      • Reported - view

       Yep, I think everything I have in the Control Panel is now working, all I have left is to simplify the .csv import process for event attendance and donations.

      My hope is to make it 'push button simple' for my users. I'm not smart enough to undertake a custom .csv import and I want to maintain the idea of a staging table, so here's what I'm thinking today - feedback welcome.

      1. split Control Panel into 3 separate view forms: Contacts (the first 3 forms you currently see ... Basic, Interest, Volunteering), then two separate view forms for Event Attendance and Donations.

      2. From the Event Attendance form, add a button:
      openTable("Attendance_Staging", "Event Attendance Import Instructions")
      This takes me to my current attendance staging table, directly to the tab with instructions. I'd amend those to go through the .csv import (standard wizard, directly into this staging table).

      3. at the bottom of this view form, add a button that takes me back to the Control Panel tab that is now dedicated to processing the event attendance, including the view into the staging table. Button Script:
      openTable("Control Panel", "Event Attendance Import Processing"

      4. Do the review of the imported data here, and add a button to cancel the import and clear the stating table (forgot about that until just now). Leave the existing button on the Control Panel Event Attendance tab to merge the staging table data into the contacts & events table if everything looks good.

      Although I'd be jumping around tables, it seems like a 4-step process (button, import, button, button) for my users that's fairly simple and relatively error-proof? Can you suggest a better approach that doesn't require coding a dedicate .csv import process?

Content aside

  • yesterdayLast active
  • 30Replies
  • 145Views
  • 5 Following