uadmin.ModelSchema

Back to Customizing Records Page

ModelSchema is a representation of a plan or theory in the form of an outline or model.

Structure:

type ModelSchema struct {
    Name          string // Name of the Model
    DisplayName   string // Display Name of the model
    ModelName     string // URL
    ModelID       uint
    Inlines       []*ModelSchema
    InlinesData   []listData
    Fields        []F
    IncludeFormJS []string
    IncludeListJS []string
    FormModifier  func(*uadmin.ModelSchema, interface{}, *uadmin.User)
    ListModifier  func(*uadmin.ModelSchema, *uadmin.User) (string, []interface{})
    FormTheme     string
    ListTheme     string
}

Here are the following fields and their definitions:

  • Name - The name of the Model
  • DisplayName - A human readable version of the name of the Model
  • ModelName - The same as the Name but in small letters.
  • ModelID - (Data) A place holder to store the primary key of a single row for form processing
  • Inlines - A list of associated inlines to this model
  • InlinesData - (Data) A place holder to store the data of the inlines
  • Fields - A list of uadmin.F type representing the fields of the model
  • IncludeFormJS - A list of string where you could add URLs to javascript files that uAdmin will run when a form view of this model is rendered
  • IncludeListJS - A list of string where you could add URLs to javascript files that uAdmin will run when a list view of this model is rendered
  • FormModifier - A function that you could pass that will allow you to modify the schema when rendering a form. It will pass to you the a pointer to the schema so you could modify it and a copy of the Model that is being rendered and the user access it to be able to customize per user (or per user group). Examples can be found in FM1, FM2.
  • ListModifier - A function that you could pass that will allow you to modify the schema when rendering a list. It will pass to you the a pointer to the schema so you could modify it and the user access it to be able to customize per user (or per user group). Examples can be found in LM1, LM2.
  • FormTheme - Name of the theme for the form
  • ListTheme - Name of the theme for the list

There are 3 functions that you can use in ModelSchema:

  • FieldByName - Calls the name of the field inside the function. It uses this format as shown below:
func(a string) *uadmin.F

Structure:

modelschema.FieldByName("Name").XXXX = Value

XXXX has many things: See uadmin.F for the list. It is an alternative way of changing the feature of the field rather than using Tags. For more information, see Tag Reference.

  • GetFormTheme() - Returns the form theme for this model or the global theme if there is no assigned theme for the model.
  • GetListTheme() - Returns the list theme for this model or the global theme if there is no assigned theme for the model.

Used in the tutorial:

There are 2 ways you can do for initialization process using this function: one-by-one and by group.

One-by-one initialization:

func main(){
    // Some codes
    modelschema := uadmin.ModelSchema{}
    modelschema.Name = "Name"
    modelschema.DisplayName = "Display Name"
}

By group initialization:

func main(){
    // Some codes
    modelschema := uadmin.ModelSchema{
        Name: "Name",
        DisplayName: "Display Name",
    }
}

In this example, we will use “by group” initialization process.

Example #1: IncludeFormJS

Back to Top

Type:

[]string

Let’s create an application that if the user clicks the input Name field in the form, the value of the Progress bar will change to 50.

First of all, run your application, go to the Todo model and click Add New Todo button on the top right corner of the screen. Right click the input Name field then select Inspect.

../../_images/nameinspect.png

Based on the result, the value of the name attribute in the input tag is “Name”. We will use that later in the Javascript code.

../../_images/inspectnamevalue.png

Now let’s get the value of the name in the Progress field as well because this is where we print the result after the user clicks the Name field. Right click the input Progress field then select Inspect.

../../_images/progressinspect.png

Based on the result, the value of the name is “Progress”.

../../_images/inspectprogressvalue.png

Now go to your project folder then select “static”.

../../_images/staticfolderhighlighted.png

Inside the static folder, create a new folder named “js”.

../../_images/staticjshighlighted.png

Inside js folder, create a new file named “form.js”.

../../_images/formjavascriptfile.png

Inside form.js file, apply the following codes below:

(function(win, doc, $){
    "using strict";

    $(doc).ready(function(){
        // Checks whether the user clicks the input Name field
        $("input[name='Name']").on("click", function(){
            // Set the value of the Progress field to 50.
            $("input[name='Progress']").val(50);
        });
    });
})(window, document, $);

Now go to main.go and append the path of the form.js file to the IncludeFormJS field in ModelSchema structure then apply it in Todo model.

func main(){
    // Some codes

    // Model schema configurations
    modelschema := uadmin.ModelSchema{
        Name:          "Todo", // Model name
        ModelName:     "todo", // URL
        IncludeFormJS: []string{"/static/js/form.js"},
    }

    // Call the schema of "todo" model
    // modelschema.ModelName = "todo"
    todo := uadmin.Schema[modelschema.ModelName]

    // Include Javascript file for the form
    todo.IncludeFormJS = modelschema.IncludeFormJS
}

Run your application, go to the Todo model and click Add New Todo button on the top right corner of the screen. Click the input Name field and see what happens.

../../_images/clickinputnamefield.png

Result:

../../_images/clickinputnamefieldresult.png

Example #2: IncludeListJS

Back to Top

Type:

[]string

Let’s create an application that if the user enters the mouse in the first record, the value of that record will change. Otherwise, the value of that record will go back to normal.

First of all, run your application and go to the Todo model. Suppose you have “Read a book” existing record inside that model. Right click the “Read a book” in the Todo column then select Inspect.

../../_images/firstrecordinspect.png

Based on the result, the value of the data-id attribute in the a tag is “1”. We will use that later in the Javascript code.

../../_images/inspectdataidvalue.png

Now go to your project folder then select “static”.

../../_images/staticfolderhighlighted.png

Inside the static folder, create a new folder named “js”.

../../_images/staticjshighlighted.png

Inside js folder, create a new file named “list.js”.

../../_images/listjavascriptfile.png

Inside list.js file, apply the following codes below:

(function(win, doc, $){
    "using strict";

    // Checks whether the mouse enters in the first record
    $("a[data-id='1']").on("mouseenter", function(){
        // Change the text to "Read a magazine".
        $("a[data-id='1']").text("Read a magazine");
    });
    // Checks whether the mouse leaves in the first record
    $("a[data-id='1']").on("mouseleave", function(){
        // Change the text to "Read a book".
        $("a[data-id='1']").text("Read a book");
    });
})(window, document, $);

Now go to main.go and append the path of the list.js file to the IncludeListJS field in ModelSchema structure then apply it in Todo model.

func main(){
    // Some codes

    // Model schema configurations
    modelschema := uadmin.ModelSchema{
        Name:          "Todo", // Model name
        ModelName:     "todo", // URL
        IncludeListJS: []string{"/static/js/list.js"},
    }

    // Call the schema of "todo" model
    // modelschema.ModelName = "todo"
    todo := uadmin.Schema[modelschema.ModelName]

    // Include Javascript file for the list
    todo.IncludeListJS = modelschema.IncludeListJS
}

Run your application and go to the Todo model. Hover your mouse to “Read a book” value in Todo column and see what happens.

../../_images/readabookhighlighted.png

Result:

../../_images/readamagazinepointed.png

If you leave the cursor, the name of the first record will go back to normal.

../../_images/readabookhighlighted.png

Example #3: Fields

Back to Top

Type:

[]uadmin.F

See uadmin.F for the examples.

Example #4: FormModifier and ListModifier

Back to Top

Functions:

// FormModifier
func(*uadmin.ModelSchema, interface{}, *uadmin.User)

// ListModifier
func(*uadmin.ModelSchema, *uadmin.User) (string, []interface{})

uadmin.ModelSchema has the following fields and their definitions:

  • Name - The name of the Model
  • DisplayName - A human readable version of the name of the Model
  • ModelName - The same as the Name but in small letters.
  • ModelID - (Data) A place holder to store the primary key of a single row for form processing
  • Inlines - A list of associated inlines to this model
  • InlinesData - (Data) A place holder to store the data of the inlines
  • Fields - A list of uadmin.F type representing the fields of the model
  • IncludeFormJS - A list of string where you could add URLs to javascript files that uAdmin will run when a form view of this model is rendered
  • IncludeListJS - A list of string where you could add URLs to javascript files that uAdmin will run when a list view of this model is rendered
  • FormModifier - A function that you could pass that will allow you to modify the schema when rendering a form. It will pass to you the a pointer to the schema so you could modify it and a copy of the Model that is being rendered and the user access it to be able to customize per user (or per user group).
  • ListModifier - A function that you could pass that will allow you to modify the schema when rendering a list. It will pass to you the a pointer to the schema so you could modify it and the user access it to be able to customize per user (or per user group).

interface{} is the parameter used to cast or access the model to modify the fields.

uadmin.User has the following fields and their definitions:

  • Username - The username that you can use in login process and CreatedBy which is a reserved word in uAdmin
  • FirstName - The given name of the user
  • LastName - The surname of the user
  • Password - A secret word or phrase that must be used to gain admission to something. This field is automatically hashed for security protection.
  • Email - A method of exchanging messages between people using electronic devices.
  • Active - Checks whether the user is logged in
  • Admin - Checks whether the user is authorized to access all features in the system
  • RemoteAccess - Checks whether the user has access to remote devices
  • UserGroup - Returns the GroupName
  • UserGroupID - An ID to access the UserGroup
  • Photo - Profile picture of the user
  • LastLogin - The date when the user last logged in his account
  • ExpiresOn - The date when the user account expires
  • OTPRequired - Checks whether the OTP is Active
  • OTPSeed - Private field for OTP
../../_images/userfields.png

First of all, make sure that your non-admin account has Read and Add access user permission to the Todo model.

../../_images/userpermissionjohndoe.png

Go to the main.go. Inside the main function, create a Schema Form Modifier that calls the Todo model. Place it after the Register functions.

func main(){
    // Initialize docS variable that calls the Todo model in the schema
    docS := uadmin.Schema["todo"]

    // FormModifier makes Name and Description required if the user is not
    // an admin and the Name and Description fields are empty strings.
    docS.FormModifier = func(s *uadmin.ModelSchema, m interface{}, u *uadmin.User) {
        // Casts an interface to the Todo model
        t, _ := m.(*models.Todo)

        // Check whether the user is not an admin and the Name and
        // Description fields are empty strings
        if !u.Admin && t.Name == "" && t.Description == "" {
            // Set the Name and Description required fields
            s.FieldByName("Name").Required = true
            s.FieldByName("Description").Required = true
        }
    }

    // Pass back to the schema of Todo model
    uadmin.Schema["todo"] = docS
}

Use any of your existing accounts that is not an admin. Here’s the result if you are adding a new record:

../../_images/namedescriptionrequired.png

Now let’s apply the ListModifier in todo.go. As an admin, you want your non-admin user to limit the records that they can see in the Todo model. In order to do that, let’s add another field called “AssignedTo” with the type uadmin.User.

// Todo model ...
type Todo struct {
    uadmin.Model
    Name         string
    Description  string `uadmin:"html"`
    TargetDate   time.Time
    Progress     int `uadmin:"progress_bar"`
    AssignedTo   uadmin.User
    AssignedToID uint
}

Go to the main.go. Inside the main function, create a Schema List Modifier that calls the Todo model. Place it after the docs.FormModifier declaration.

func main(){
    // Some codes

    // ListModifier is based on a function that assigns the user ID to the
    // query. If they match, the user can see the record assigned to him.
    docS.ListModifier = func(m *uadmin.ModelSchema, u *uadmin.User) (string, []interface{}) {
        // Check whether the user is not an admin
        if !u.Admin {
            // Returns the AssignedToID with the value of UserID
            return "assigned_to_id = ?", []interface{}{u.ID}
        }
        // Returns nothing
        return "", []interface{}{}
    }
}

Login your admin account and create at least five records with the AssignedTo value.

../../_images/todofiverecordsassignedto.png

Now login any of your non-admin account and see what happens.

../../_images/assignedtovisible.png

Example #5: FormTheme and ListTheme

Back to Top

Type:

string

Suppose you have form.html and list.html in templates/uadmin/custom path.

../../_images/formlistcustomtheme.png

Go to the main.go and apply the following codes below:

func main() {
    // Some codes

    // Model schema configurations
    modelschema := uadmin.ModelSchema{
        Name:      "Todo", // Model name
        ModelName: "todo", // URL

        // Inside the templates/uadmin path, assign the folder name
        // containing form.html and list.html to be called
        FormTheme: "custom",
        ListTheme: "custom",
    }

    // Call the schema of "todo" model
    // modelschema.ModelName = "Todo"
    todo := uadmin.Schema[modelschema.ModelName]

    // Assign the form theme and list theme to the todo model
    todo.FormTheme = modelschema.FormTheme
    todo.ListTheme = modelschema.ListTheme

    // Print the value of the form and list theme
    uadmin.Trail(uadmin.DEBUG, "Form Theme: %s", modelschema.GetFormTheme())
    uadmin.Trail(uadmin.DEBUG, "List Theme: %s", modelschema.GetListTheme())
}

Run your application and see the result in your terminal to check if we are getting the correct form and list theme that we have assigned.

[  DEBUG ]   Form Theme: custom
[  DEBUG ]   List Theme: custom