Inline Editing

Instant saving of quick text edits can make for a better user experience.

Overview

HQ has a custom component for inline editing, based on Knockout Components. This component is visually lighter weight than a standard text box, and it updates the value immediately via an ajax call.

This component has a number of options that affect the save action and the look and feel; see inline_edit.js for full documentation.

Important: Because most of HQ does not use instant saving, don't use this component near or inside another form. It works well when it's the only style of saving on the page, or when it's clearly separated from other forms.

Usage

The best way to understand how to implement the inline-edit component is to see its use in HQ directly.

The Case Import page is a good example of its usage, and key points are:

Several App Manager pages also use the template tag inline_edit_trans to provide an inline-edit component that handles multiple languages. This is the real-world example of the second example below.

A Working Example

Below is a working example of the inline-edit component. It's working in a sense that it posts to a real URL. However, the edits aren't saved anywhere. Try it out! Note that the demo endpoint will randomly throw an error so that the entire UI can be tested visually here.

Note that the error message displayed is not the same as the errorMessage passed in to the component params. This is because the inline_edit_demo view returns a formatted JSON response that the component expects to find an server-generated error message in.
HTML
<div id="js-inline-edit-example">
  <inline-edit
    data-apply-bindings="false"
    params="
      value: text,
      url: url,
      rows: 1,
      placeholder: gettext('Click here to add a comment'),
      errorMessage: gettext('Error updating comment. Please try again.'),
    "
  ></inline-edit>
</div>
JS
import $ from 'jquery';
import initialPageData from 'hqwebapp/js/initial_page_data';
import 'hqwebapp/js/components/inline_edit';

$(function () {
    // notice how ids referenced in javascript are prefixed with js,
    // so it's clear to someone reading the HTML that there is associated js functionality
    $("#js-inline-edit-example").koApplyBindings(function () {
        let self = {};

        self.text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.';

        self.url = initialPageData.reverse("styleguide_inline_edit_demo");

        return self;
    });
});

Using Language Tags

Below is an example of how language tags (set by the lang parameter) are used with inline-edit. This is also a showcase of using the nodeName: 'input' option.

As with the example above, this component posts to a view that randomly throws an error so that the error message functionality can be observed and tested here.

HTML
<div id="js-inline-edit-lang-example">
  <inline-edit
    data-apply-bindings="false"
    params="
      value: text,
      nodeName: 'input',
      url: url,
      rows: 1,
      lang: 'en',
      placeholder: gettext('Enter in label for english.'),
      errorMessage: gettext('Error updating comment. Please try again.'),
    "
  ></inline-edit>
</div>
JS
import $ from 'jquery';
import initialPageData from 'hqwebapp/js/initial_page_data';
import 'hqwebapp/js/components/inline_edit';

$(function () {
    // notice how ids referenced in javascript are prefixed with js,
    // so it's clear to someone reading the HTML that there is associated js functionality
    $("#js-inline-edit-lang-example").koApplyBindings(function () {
        let self = {};

        self.text = '';

        self.url = initialPageData.reverse("styleguide_inline_edit_demo");

        return self;
    });
});