How do I need a field to be required on the NAV page?

It seems that the basic nature of NAV is to counter the requirement that the field be required. In the case of our business logic, certain fields must be filled in order for the data to be valid. For example, a customer record must have at least a name and a phone number. I searched for a few places but did not find a suitable solution. So how can this be done?

+4
source share
3 answers

After trying to find a concise way to require certain fields on the map to be filled out, I came up with the following, and it (so far) works for me. I began to realize that NAV should not have required fields, but I need them for our business logic. Anyway, here we go ...

Step one: - We have a code block for various verification logic, in which I added a function for reading a user table, which lists the tables and their fields, which are required. This function takes a table number, a key field, and a "create mode". It returns the text value "completion status". I find a table for the record that I am checking. I scroll through the required fields, if the field is empty, I add it to the list of incomplete fields. If the list of incomplete fields is empty, the completion status is "completed". If the list of incomplete fields is filled in, a message is displayed indicating the missing fields and allows the user to cancel the creation of a new record or to remain in the (new or existing) record and enter the missing data, as well as the completion status is set to "delete" to cancel the creation, or "return "to stay on record. Logic follows:

CheckMadatoryFields(TableNumber : Integer;KeyField : Code[10];CreateMode : Boolean) Completion Status : Text[30] // Read the 'LockoutFields' table to find the manditory fields for the table passed in. LockoutFields.RESET; LockoutFields.SETRANGE("Table No.", TableNumber); LockoutFields.SETFILTER("Filter ID", 'MANDITORY_FIELD'); // Get a record reference for the table passed in RecRef.OPEN(TableNumber); RecRef.SETVIEW('WHERE("No." = FILTER(' + KeyField + '))'); // Set this to done, ie data is complete (don't delete by mistake). CompletionStatus := 'done'; IF RecRef.FINDFIRST THEN BEGIN // Check the record manditory field(s) listed in the 'LockoutFields' table to see if they're blank. IF LockoutFields.FINDSET THEN BEGIN REPEAT FldRef := RecRef.FIELD(LockoutFields."Field No."); IF FORMAT(FldRef.VALUE) = '' THEN FldList := FldList + ' - ' + FldRef.CAPTION + '\'; UNTIL LockoutFields.NEXT = 0; END; IF FldList <> '' THEN BEGIN // If creating the record, add the 'Cancel Create' message, otherwise don't. IF CreateMode THEN DeleteRecord := CONFIRM(Text_ManditoryField + '\' + FldList + '\' + Text_CancelCreate, FALSE) ELSE BEGIN DeleteRecord := FALSE; MESSAGE(Text_ManditoryField + '\' + FldList, FALSE); END; // Return a 'delete' status when deleting, or a 'return' status to stay on the record. IF DeleteRecord THEN CompletionStatus := 'delete' ELSE CompletionStatus := 'return'; END; END; RecRef.CLOSE;` 

Step 2: - On the card that you want to check for the required fields, in my case on the client card I added a function to call the check function in the encoder described above. I also added logic to the OnQueryClosePage call to call my local function. All this worked fine, as the user could not close the clientโ€™s card without filling in the required fields or canceling the creation of the client, except if the user had to use Ctrl + PgUp or Ctrl + PgDn, which removed them from the record. The trick put the correct logic into the OnNextRecord trigger to perform the check, and Ctrl + PgUp or Ctrl + PgDn are still functioning (note: I found this bit somewhere on mibuso, thanks a lot!). Logic follows:

 OnNextRecord(...) IF CheckManditoryFields = TRUE THEN BEGIN Customer := Rec; CurrentSteps := Customer.NEXT(Steps); IF CurrentSteps <> 0 THEN Rec := Customer; EXIT(CurrentSteps); END; OnQueryClosePage(...) EXIT(CheckManditoryFields); CheckMandatoryFields() ExitValue : Boolean // Check for manditory fields on this table. If there are missing manditory // fields, the user can cancel this create, in which case, a 'TRUE' value is // returned and we'll delete this record. ExitValue := TRUE; IF Rec."No." <> '' THEN BEGIN // This is blank if user quits immediately after page starts. CompletionStatus := HHValidation.CheckManditoryFields(18,Rec."No.",CreateMode); IF (CompletionStatus = 'delete') AND (CreateMode = TRUE) THEN // User cancelled create (not edit), delete the record and exit. Rec.DELETE(TRUE) ELSE IF CompletionStatus = 'done' THEN // User completed manditory fields, OK to exit. ExitValue := TRUE ELSE ExitValue := FALSE; //User did not complete manditory fields and wants to return and add them. END; 

I think about this. The details of the user table really depend on how you want to encode it. The verification code module may be what you want. Using a table allows you to add or remove required fields without changing any logic, and this "general" verification logic can be placed on any page. The key is two triggers on the card and having a common verification procedure for calling.

+4
source

I used this code in the form (classic client), but there is one error in the OnNextRecord code.

 OnNextRecord(...) IF CheckManditoryFields = TRUE THEN BEGIN Customer := Rec; CurrentSteps := Customer.NEXT(Steps); IF CurrentSteps <> 0 THEN Rec := Customer; EXIT(CurrentSteps); END; 

You should also pay attention to the situation when CheckMandatoryFields returns FALSE. Otherwise, when I request the next entry, it shows me an empty entry. It should be like this:

 OnNextRecord(...) IF CheckManditoryFields = TRUE THEN BEGIN Customer := Rec; CurrentSteps := Customer.NEXT(Steps); IF CurrentSteps <> 0 THEN Rec := Customer; EXIT(CurrentSteps); END ELSE EXIT(Steps); 
+1
source

There is another error in the OnNextRecord function:

 OnNextRecord(...) IF CheckManditoryFields = TRUE THEN BEGIN Customer := Rec; CurrentSteps := Customer.NEXT(Steps); IF CurrentSteps 0 THEN Rec := Customer; EXIT(CurrentSteps); END ELSE EXIT(Steps); 

Filters installed on the sourcetable page of the page (or form) are not copied to the entry on which the steps are performed. Thus, you can go to a record that is not in your filter set.

Instead of assigning Rec to the client, you need to copy it:

 OnNextRecord(...) IF CheckManditoryFields THEN BEGIN Customer.COPY(Rec); CurrentSteps := Customer.NEXT(Steps); IF CurrentSteps 0 THEN Rec := Customer; EXIT(CurrentSteps); END ELSE EXIT(Steps); 
0
source

All Articles