Sample numbers or unique identifiers are numbers that are generated using a particular method and are meant to be different from all previously generated numbers. They are important because they allow certain fields to be distinguished from each other. These numbers are especially useful in a database, where calling information using unique identifier numbers ensures that the correct information is brought up as opposed to other information in the database.


There are many different methods to create unique identifiers, and these methods can be translated into NextGen Designer by implementing some code in the form script. In this article, we will discuss 3 methods to create unique identifiers and how these methods can be implemented in NextGen Designer. 


These methods will be demonstrated by showing screenshots of an example form. This example form is a simple inspection form with a few fields. A "sample" in this form consists of a material value and a measurement value. Once these values are entered, the Add button records that entry into the Collected Samples grid, where all the inspections data is saved. Note that the first column in the grid is a sample number/unique identifier which is also shown above as a read-only form field; this number is automatically generated based on one of three options:


Option 1:  Date/Time Stamp 

In the first option, the unique identifier number is formed by taking the initials of the selected inspector and then adding a date/time stamp, which is the distinguishing factor. The date/time stamp is in the format: year - month - day - hour - minute - second as recorded in the "Date and Time" form field. Each time the Add button is used to record a sample collection in the grid, the "Date and Time" field updates itself to the current moment in time, ensuring that each sample has a unique sample number. Two inspections would have the same unique identifier number if and only if they were entered within the same second, which is highly unlikely. Depending on the business needs, it may be sufficient to just record the stamp down to the minute rather than the second. Also, a two-digit year could be used to further reduce the length of the identifier. 



Option 2: Increment 

In the second option, the unique identifier number is equal to the initials plus a counter that begins at some arbitrary value (100 in this case) and increments on every inspection. Each number is unique because the counter increments and will never decrease. This counter is saved to the local device when exiting Mi-Apps, such that when the inspector comes back at a later time and performs their next inspection, the counter will pick up where it left off and there are no duplicates. This method closely resembles what is often seen on printed forms, which are taken off physical pads of paper where each report has the sample number pre-printed. The disadvantage of this method in the digital world is that if an inspector needs to switch from one mobile device to another, the numbering system does not transfer between devices so there could be overlap. One solution to this problem is to assign a block of numbers to each device, e.g. iPad A begins at index 1000, iPad B begins at index 2000, etc.



Option 3: Globally Unique Identifier 

In the third option, the unique identifier number is equal to the initials plus a random value. This alphanumeric string is a "globally unique identifier" meaning it is guaranteed to be unique, therefore no two inspections will have the same sample number regardless of where or when the numbers are created. Each time the Add button is used to record a sample collection, a new GUID is generated. The advantage of this approach is that devices do not need to be synchronized against each other in order to maintain separate sample numbers. The disadvantage is that the numbers are long and unsightly, and very difficult to record by hand.



The code below is the script for the example form used in the above screenshots:

// Triggered when the form is opened
function EH_AfterOpen() {
    _form.setValue("SampleNumberType", "1");
    _form.setMomentValue("DateAndTime", new Date());
    _form.setValue("Inspector", "John Doe - JOD");
    _form.setValue("SampleId", "100");
    _form.fieldHidden("SampleId", true);
}


// Triggered when a field's value changes
function EH_AfterSetData(fieldName) {
    if ((fieldName == "SampleNumberType") || (fieldName == "DateAndTime") || (fieldName == "Inspector") || (fieldName == "SampleId")) {
        updateSampleNumber();
    }
}


// Triggered when a hotspot is pressed
function EH_HotspotPressed(fieldName) {
    if (fieldName == "Add") {
        AddSample();
    }
}


function updateSampleNumber() {

    var type = _form.getNumericValue("SampleNumberType");
    var num = getInspectorInitials() + "-";

    if (type == 1) {
        num += _form.getMomentValue("DateAndTime").format("YYYYMMDDHHmmss");
    }
    else if (type == 2) {
        num += _form.getValue("SampleId");
    }
    else if (type == 3) {
        num += generateGuid();
    }


    _form.setValue("SampleNumber", num);
}


function getInspectorInitials() {
    var insp = _form.getValue("Inspector");
    if (insp == "") { return ""; }

    var parts = insp.split(" - ");
    if (parts.length < 2) { return ""; }

    return parts[1];
}


function generateGuid() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
  });
}


function AddSample() {
    // add row
    var rows = _form.gridRowData("Grid");
    rows.push([_form.getValue("SampleNumber"), _form.getValue("Material"), _form.getValue("Measurement")]);
    _form.gridRowData("Grid", rows);

    // reset fields
    _form.setValue("Material", "");
    _form.setValue("Measurement", "");

    // update/increment sample number
    var type = _form.getNumericValue("SampleNumberType");
    
    if (type == 1) {
        // update date/time stamp
        _form.setMomentValue("DateAndTime", new Date());
    }
    else if (type == 2) {
        // update sample ID
        var id = _form.getNumericValue("SampleId")
        _form.setValue("SampleId", (id+1).toString());
    }
    else if (type == 3) {
        // trigger generation of new GUID
        updateSampleNumber();
    }
}