Front-End Patterns:

Inline Edit & BCP KO

Inline Edit

Purpose of Inline Edit

  • Manage UI state
  • Collect user input
  • Submit data

Managing UI State


    <div class="bcp-inline-edit" data-component="bcp-inline-edit">

        <div class="bcp-inline-edit-display" data-role="display">

        </div>

        <div class="bcp-inline-edit-group" data-role="edit-group">

        </div>

    </div>

Display / Edit Mode

Inline Edit Attributes

  • data-component="bcp-inline-edit"
  • data-role="display"
  • data-role="edit-group/edit-form"
  • data-role="edit"
  • data-role="cancel"
  • data-role="submit"

Cancel / Undo



    <input type="text" data-role="input" data-value="John Smith" />

    <select data-role="input" data-value="Tuesdays"></select>

    <input type="checkbox" data-role="checkbox-input" data-value="true"/>

    <input type="radio" data-role="radio-input" data-value="false"/>

Collecting User Input



    <input type="text" data-role="input" data-id="FullName" />

    <select data-role="input" data-id="SelectedOption"></select>

    <input type="checkbox" data-role="checkbox-input" data-id="IsActive"/>

    <input type="radio" data-role="radio-input" data-id="FeatureEnabled"/>

    {
        "FullName": "John Smith",

        "SelectedOption": "Tuesdays",

        "IsActive": "true",

        "FeatureEnabled": "false"
    }

Inline Edit Attributes

  • data-role="input"
  • data-role="checkbox-input"
  • data-role="radio-input"
  • data-role="input-group"
  • data-id="RuleName"
  • data-value="New Name"
  • data-path="Settings"
  • data-type="number/boolean"

Submitting Data

  • data-options="dataurl: /myaccount/api/controller/action"
  • BCP Validation
  • BCP AJAX
  • BCP KO

BCP KO

Purpose of BCP KO

  • Bind server Model to UI
  • Create Knockout ViewModel
  • Update server Model

Data Binding



    <div data-component="bcp-ko" 
         data-options="dataurl: /myaccount/api/controller/action">
     {...}
    </div>

    <div data-component="bcp-ko" data-model-id="Feature">
     {...}
    </div>

    <script>
      window.BCP = {ViewModels: {}};
      BCP.ViewModels.Feature = {"Message": "Hello"};
    </script>

Component Structure



    <div data-component="bcp-ko">

      <div data-component="bcp-ko-loading-indicator">
        <!-- Loading indicator goes here -->
      </div>
      
      <div data-component="bcp-ko-alert">
        <!-- Error message goes here -->
      </div>

      <div data-component="bcp-ko-component">
        <!-- Data bindings go here -->
      </div>

    </div>

Good Data / Bad Data


  {
    GreetingType: "Standard",

    Announcement: true,

    CustomGreeting: {
      AudioFileName: "greeting.wav"
    },

    FullName: "John Smith",

    PhoneNumber: "5551234567",

    FormattedPhoneNumber: "(555) 123-4567"
  }

  {
    GreetingType: 0,

    Announcement: "Enabled",

    CustomGreeting: {
      AudioFile: {
        Name: "greeting.wav"
      }
    },

    FirstName: "John",

    LastName: "Smith",

    PhoneNumber: "(555) 123-4567"
  }

BCP KO Attributes

  • data-ko-path="Response.Users"
  • data-ko-index="0"
  • data-ko-role="section"
  • data-ko-role="add"
  • data-ko-role="delete"
  • data-ko-role="update/update-all"

BCP KO Add


  <div data-component="bcp-inline-edit" 
       data-ko-role="add" 
       data-ko-path="Response.SpeedDialEntries" 
       data-ko-add="IsActive: true"
       data-options="dataurl: /myaccount/api/SpeedDial/ConfigureSpeedDial">
  
    <div class="bcp-inline-edit-group" data-role="edit-group">
      <div class="bcp-form-field">
        <label>Speed Dial Name</label>
        <input data-role="input" data-id="Description" />
      </div>
  
      <div class="bcp-form-field">
        <label>Phone Number</label>
        <input data-role="input" data-id="PhoneNumber" />
      </div>
  
      <button data-role="cancel" type="button">Cancel</button>
      <button data-role="submit" type="button">Submit</button>
    </div>
  
  </div>

Add to Collection


  {
    SpeedDialEntries: [
      {
        Description: "Home",
        PhoneNumber: "5551118080"
      },
      {
        Description: "John Smith",
        PhoneNumber: "5552522589"
      }
    ]
  }
   

  {
    SpeedDialEntries: [
      {
        Description: "Home",
        PhoneNumber: "5551118080"
      },
      {
        Description: "John Smith",
        PhoneNumber: "5552522589"
      },
      {
        Description: "The Boss",
        PhoneNumber: "5551234567",
        IsActive: true
      }
    ]
  }
   

BCP KO Delete


    <tbody data-bind="foreach: Response.SpeedDialEntries">
      {...}
      <tr data-bind="attr: {'data-ko-index': $index() }">
        <td data-bind="text: Description">The Boss</td>
        <td data-bind="formatPhone: PhoneNumber">(555) 123-4567</td>
        <td>
          <button data-ko-role="delete" 
                  data-options="type: DELETE;
                    dataurl: /myaccount/api/SpeedDial/ConfigureSpeedDial;
                    submitData: Response">
              Delete
          </button>
        </td>
      </tr>
    </tbody>

Delete from Collection


  {
    SpeedDialEntries: [
      {
        Description: "Home",
        PhoneNumber: "5551118080"
      },
      {
        Description: "John Smith",
        PhoneNumber: "5552522589"
      },
      {
        Description: "The Boss",
        PhoneNumber: "5551234567"
      }
    ]
  }
   

  {
    SpeedDialEntries: [
      {
        Description: "Home",
        PhoneNumber: "5551118080"
      },
      {
        Description: "John Smith",
        PhoneNumber: "5552522589"
      }
    ]
  }
   

BCP KO Update


  <div data-component="bcp-inline-edit" 
       data-ko-role="update" 
       data-ko-path="Response.SpeedDialEntries" 
       data-ko-include="UserId"
       data-ko-ignore="DeviceNumber"
       data-options="dataurl: /myaccount/api/SpeedDial/ConfigureSpeedDial">
  
    <div class="bcp-inline-edit-group" data-role="edit-group" data-ko-index="1">
      <div class="bcp-form-field">
        <label>Speed Dial Name</label>
        <input data-role="input" data-id="Description" />
      </div>

      
      <div data-role="input-group" data-path="Settings">
        <input type="hidden" data-id="IsActive" value="true" />
      </div>
  
      <button data-role="cancel" type="button">Cancel</button>
      <button data-role="submit" type="button">Submit</button>
    </div>
  
  </div>

Update Data


  {
    UserId: "rjames7200",
    DeviceNumber: "1234567890",
    SpeedDialEntries: [
      {
        Description: "Home",
        PhoneNumber: "5551118080"
      },
      {
        Description: "John Smith",
        PhoneNumber: "5552522589"
      },
      {
        Description: "The Boss",
        PhoneNumber: "5551234567"
      }
    ]
  }
   

  {
    UserId: "rjames7200",
    SpeedDialEntries: [
      {
        Description: "Home",
        PhoneNumber: "5551118080"
      },
      {
        Description: "A New Name",
        PhoneNumber: "5552522589",
        Settings: {
          IsActive: "true"
        }
      },
      {
        Description: "The Boss",
        PhoneNumber: "5551234567"
      }
    ]
  }
   

Questions?

Thank You

Made with Slides.com