Walkthrough: Creating a login page

Abstract

Learn how to create a form page that enables logging in and out.

This topic describes how to create a form page that enables visitors to log in and out on an extranet. This walkthrough is part two of the Prefilling forms series. To execute the steps of this walkthrough, you must first complete the Walkthrough: Creating a register page.

This walkthrough describes how to

  • Create a login and logout submit action class

  • Create a login action editor control

  • Create the login submit action item

  • Create the logout submit action item

  • Create a login form

  • Create a logout form

  • Add the form to a webpage

To create the login and logout submit action class:

  1. In your Visual Studio Project, go to SubmitActions folder. Create a folder named LoginUser.

  2. In the LoginUser folder, create a LoginUserData class:

    public class LoginUserData
     {
     public Guid UserNameFieldId { get; set; }
     public Guid PasswordFieldId { get; set; }
     }
  3. Create a LoginUserclass:

    public class LoginUser : SubmitActionBase<LoginUserData>
     {
     public LoginUser(ISubmitActionData submitActionData) : base(submitActionData)
     {
     }
    
     protected override bool Execute(LoginUserData data, FormSubmitContext formSubmitContext)
     {
     Assert.ArgumentNotNull(data, nameof(data));
     Assert.ArgumentNotNull(formSubmitContext, nameof(formSubmitContext));
    
     var fields = GetFormFields(data, formSubmitContext);
    
     Assert.IsNotNull(fields, nameof(fields));
    
     if (UsernameOrPasswordFieldIsNull(fields))
     {
     return AbortForm(formSubmitContext);
     }
    
     var values = fields.GetFieldValues();
    
     if (UsernameOrPasswordValueIsNull(values))
     {
     return AbortForm(formSubmitContext);
     }
    
     var user = Login(values.Username, values.Password);
    
     if (user == null)
     {
    
     return AbortForm(formSubmitContext);
     }
    
     return true;
     }
    
     protected virtual User Login(string userName, string password)
     {
     var accountName = string.Empty;
     var domain = Context.Domain;
     if (domain != null)
     {
     accountName = domain.GetFullName(userName);
     }
    
     var result = AuthenticationManager.Login(accountName, password);
     if (!result)
     {
     return null;
     }
    
     var user = AuthenticationManager.GetActiveUser();
     return user;
     }
    
     private LoginUserFormFields GetFormFields(LoginUserData data, FormSubmitContext formSubmitContext)
     {
     Assert.ArgumentNotNull(data, nameof(data));
     Assert.ArgumentNotNull(formSubmitContext, nameof(formSubmitContext));
    
     return new LoginUserFormFields
     {
     Username = FieldHelper.GetFieldById(data.UserNameFieldId, formSubmitContext.Fields),
     Password = FieldHelper.GetFieldById(data.PasswordFieldId, formSubmitContext.Fields)
     };
     }
    
     private bool UsernameOrPasswordFieldIsNull(LoginUserFormFields field)
     {
     Assert.ArgumentNotNull(field, nameof(field));
     return field.Username == null || field.Password == null;
     }
    
     private bool UsernameOrPasswordValueIsNull(LoginUserFieldValues values)
     {
     Assert.ArgumentNotNull(values, nameof(values));
     return string.IsNullOrEmpty(values.Username) || string.IsNullOrEmpty(values.Password);
     }
    
     private bool AbortForm(FormSubmitContext formSubmitContext)
     {
     formSubmitContext.Abort();
     return false;
     }
    
     internal class LoginUserFormFields
     {
     public IViewModel Username { get; set; }
     public IViewModel Password { get; set; }
    
     public LoginUserFieldValues GetFieldValues()
     {
     return new LoginUserFieldValues
     {
     Username = FieldHelper.GetValue(Username),
     Password = FieldHelper.GetValue(Password)
     };
     }
     }
    
     internal class LoginUserFieldValues
     {
     public string Username { get; set; }
     public string Password { get; set; }
     }
     }
  4. Go to the SubmitActions folder and add a folder named LogoutUser. In that folder, create the LogoutUser class:

    public class LogoutUser : SubmitActionBase<string>
     {
     public LogoutUser(ISubmitActionData submitActionData) : base(submitActionData)
     {
     }
    
     protected override bool Execute(string data, FormSubmitContext formSubmitContext)
     {
     Assert.ArgumentNotNull(formSubmitContext, nameof(formSubmitContext));
    
     Logout();
     return true;
     }
    
     protected override bool TryParse(string value, out string target)
     {
     target = string.Empty;
     return true;
     }
    
     protected virtual void Logout()
     {
     AuthenticationManager.GetActiveUser();
     AuthenticationManager.Logout();
     }
     }

The next step is to create a LoginUser action editor to map the form fields to theLoginUserData class.

Note

You must have Visual Studio Sitecore Rocks plugin to complete this task.

To create the LoginUser action editor control:

  1. Create the JavaScript file for the action editor. In Visual Studio, navigate to the scripts folder and create a JavaScript file named LoginUser.js.

  2. Copy the following script to the file:

    	(function (speak) {
    	    var parentApp = window.parent.Sitecore.Speak.app.findApplication('EditActionSubAppRenderer'),
    	        designBoardApp = window.parent.Sitecore.Speak.app.findComponent('FormDesignBoard');
    	    
    	    var getFields = function () {
    	        var fields = designBoardApp.getFieldsData();
    	        
    	        return _.reduce(fields,
    	            function (memo, item) {
    	                if (item && item.model && item.model.hasOwnProperty("value")) {
    	                    memo.push({
    	                        itemId: item.itemId,
    	                        name: item.model.name
    	                    });
    	                }
    	                return memo;
    	            },
    	            [
    	                {
    	                    itemId: '',
    	                    name: ''
    	                }
    	            ],
    	            this);
    	    };
    	    
    	    speak.pageCode(["underscore"],
    	        function (_) {
    	            return {
    	                initialized: function () {
    	                    this.on({
    	                        "loaded": this.loadDone
    	                    },
    	                        this);
    	                    
    	                    this.Fields = getFields();
    	                    
    	                    this.MapLoginUserForm.children.forEach(function (control) {
    	                        if (control.deps && control.deps.indexOf("bclSelection") !== -1) {
    	                            control.IsSelectionRequired = false;
    	                        }
    	                    });
    	                    
    	                    if (parentApp) {
    	                        parentApp.loadDone(this, this.HeaderTitle.Text, this.HeaderSubtitle.Text);
    	                        parentApp.setSelectability(this, true);
    	                    }
    	                },
    	                
    	                setDynamicData: function (propKey) {
    	                    var componentName = this.MapLoginUserForm.bindingConfigObject[propKey].split(".")[0];
    	                    var component = this.MapLoginUserForm[componentName];
    	                    
    	                    var items = this.Fields.slice(0);
    	                    
    	                    if (this.Parameters[propKey] &&
    	                        !_.findWhere(items, { itemId: this.Parameters[propKey] })) {
    	                        var currentField = {
    	                            itemId: this.Parameters[propKey],
    	                            name: this.Parameters[propKey] +
    	                                " - " +
    	                                (this.ValueNotInListText.Text || "value not in the selection list")
    	                        };
    	                        
    	                        items.splice(1, 0, currentField);
    	                        
    	                        component.DynamicData = items;
    	                        $(component.el).find('option').eq(1).css("font-style", "italic");
    	                    } else {
    	                        component.DynamicData = items;
    	                    }
    	                },
    	                
    	                loadDone: function (parameters) {
    	                    this.Parameters = parameters || {};
    	                    _.keys(this.MapLoginUserForm.bindingConfigObject).forEach(this.setDynamicData.bind(this));
    	                    this.MapLoginUserForm.BindingTarget = this.Parameters;
    	                },
    	                
    	                getData: function () {
    	                    var formData = this.MapLoginUserForm.getFormData(),
    	                        keys = _.keys(formData);
    	                    
    	                    keys.forEach(function (propKey) {
    	                        if (formData[propKey] == null || formData[propKey].length === 0) {
    	                            if (this.Parameters.hasOwnProperty(propKey)) {
    	                                delete this.Parameters[propKey];
    	                            }
    	                        } else {
    	                            this.Parameters[propKey] = formData[propKey];
    	                        }
    	                    }.bind(this));
    	                    
    	                    return this.Parameters;
    	                }
    	            };
    	        });
    	})(Sitecore.Speak);
    
  3. Deploy LoginUser.js to your website folder at: YourInstance/Website/sitecore/shell/client/Applications/FormsBuilder/Layouts/Action.

  4. In Sitecore Rocks, expand the core database and go to: /sitecore/shell/client/Applications/FormsBuilder/Layouts/Actions.

  5. Click Add, and click New item.

  6. In the Add New Item dialog box, search for and click the Speak-BasePage template, enter the name: LoginUser.

  7. Update the layout of this item to /sitecore/client/Speak/Layouts/Layouts/Speak-FlexLayout and add the following renderings:

    • PageCode

    • HeaderTitle

    • HeaderSubtitle

    • ValueNotinListText

    • MainBorder

    • MapLoginUserForm

  8. Open the properties window of the PageCode rendering and update the PageCodeScriptFileName to: /sitecore/shell/client/Applications/FormsBuilder/Layouts/Actions/LoginUser.js

  9. Add the parameters based on the templates for the renderings that you have added:

    Item

    Template

    Stylesheet

    Page-Stylesheet-File

    HeaderTitle

    Text Parameters

    HeaderSubtitle

    Text Parameters

    MapLoginUserForm

    Folder

    UserName

    FormDropList Parameters

    Password

    FormDropList Parameters

    ValueNotInListText

    Text Parameters

    Add parameters
  10. Update their fields with the following values:

    Parameter

    Field:Values

    Stylesheet

    Stylesheet: /sitecore/shell/client/Applications/FormsBuilder/Layouts/Actions/Actions.css

    HeaderTitle

    IsVisible: deselect

    Text: Map the fields in the form to the user profile details.

    HeaderSubtitle

    IsVisible: deselected

    Text: Map the fields in the form to the user profile details.

    UserName

    ValueFieldName: itemId

    DisplayFieldName: name

    Form Label: Username

    BindingConfiguration: userNameFieldId / SelectedValue

    Password

    ValueFieldName: itemId

    DisplayFieldName: name

    Form Label: Password

    BindingConfiguration: passwordFieldId / SelectedValue

    ValueNotInListText

    IsVisible: deselected

    Text: Value not in the selection list

To create the login submit action item:

  1. In the Content Editor, go to /system/Settings/Forms/Submit Actions, insert a Submit Action item, and name it Login User.

  2. Update the fields with the following values:

    Field

    Value

    Model Type

    ValueProviderSample.SubmitActions.LoginUser

    Error Message

    Login failed!

    Editor

    LoginUser

To create the logout submit action item:

  1. Insert a submit action item to the Submit Actions folder and name it Logout User.

  2. Update the fields with the following values:

    Field

    Value

    Model Type

    ValueProviderSample.SubmitActions.LogoutUser

    Error Message

    Logout failed!

    Note

    Do not forget to save the items.

To create the login form:

  1. Open the Sitecore Forms application from the Sitecore Launchpad.

  2. Create a form and add the following sections:

    Section name

    Css class

    LoginSection

    form-group col-md-6

    SubmitSection

    form-group col-md-12

  3. Add the following fields:

    Type

    Label

    Field name

    Section

    Single-line text

    Username

    Username

    LoginSection

    Password

    Password

    Password

    LoginSection

    Submit button

    Login

    Login

    SubmitSection

  4. Add the Login User submit action to the Login button. Map the form fields accordingly. Then click OK.

    The login form
  5. Save the form and name it Login Form.

To create a logout form:

  1. Create a blank form.

  2. From the Form Elements pane, drag the submit button to the page.

  3. Edit the submit button properties with the following values:

    • Label: Logout

    • Field name: Submit Button

    • CSS class: btn btn-link

  4. In the Submit actions section, add the Logout User submit action.

  5. Save the form with name Logout Form.

With the Sitecore Forms application, you can easily create a new form or use a template. You can insert your form in a webpage in both the Content Editor and the Experience Editor. First, you must replace the default sample layout with the MVC layout and then you can insert your form in a webpage.

To add a form to a webpage:

  1. Navigate tositecore/Content/Home, and insert a Sample Item. Name it Login.

  2. Change the Login item's default layout to MVC Layout (the MVC layout you created in the previous walkthrough.

  3. Remove all the sample controls and add the MVC form renderings. Add it to the main placeholder.

  4. Edit the MVC form rendering you just added, and update its Data Source to Login Form.

  5. Save and publish the items.

You can now view your login page. Go the next walkthrough to learn how to set up a value provider.

The finished login form