Auto Async with use cases

Auto-Async has released a new version 2.1.0. It now also includes a great read-me file with use cases and code examples. I have created a few web applications with cool asynchronous interactions with this library now. This library is speeding up my development cycle since I don’t have to write lots of complex JavaScript over and over again. This also keeps me to using a consistent set of user interface interactions making my applications easy to use. I can’t share some of these applications yet since they are for private company use, but they have great reviews so far.

Usage

Do this anywhere you want to enable autoasync behavior on a page.

    jQuery(document).ready(function() { /*The DOM ready event*/
        $.autoasync.init();
    });

Alternatively you may want to enable autoasync on a page within a module pattern encapsulating all logic for your page such as the following.

    (function ($, window, document, autoasync) {
        var CompanyName = CompanyName || {};
        CompanyName.PageName = function () {
            function init() {
                autoasync.init(function (prms) {
                    _enhance(prms.element);
                });
            };
    		/*This is a locally scoped private function to do custom enhancements as page templates are instantiated.*/
            function _enhance(section) {
                $(section).find("textarea.rich-editor").wmd();
                $(section).find(".resizable").resizable({ handles: 'e,s,se', autoHide: true, preserveCursor: true });
            };
    		/*return the public scope accessible functions.*/
            return {
                init: init
            };
        }(); //end of the module definition
        $(document).ready(function () {
            CompanyName.PageName.init();
        });
    }(jQuery, window, document, autoasync || {}));

What can it do?

Use Case 1: Working a list of items

This use case covers when you are working a list of items and need to toggle over to alternate views for that item on demand. Buttons inside an element that swaps out the entire container element with another template using the same data. Each data item goes in the same element that acts as a list container. The type of html elements used for the list and for the items can be anything. The behaviour is controlled by data- attributes on the elements and the elements of each role require a specific class decorator. You can use this to have a read-only, edit, un-deletable version of an element. Or you can use it to have a different template for each status of a data element. Maybe one view for pending, another for working, another for completed.

Basic Structure of the page:

    <div class="worklist-items inline-editable-host"
    	data-template="WorkRequestView"
    	data-json-url="/Worklist/ByDay?date=20131021">
    </div>

The auto-async script looks for container elements with class “inline-editable-host” and enhances behavior of those elements using options specified on data- attributes.

  • data-json-url: A url to load a list of items from. The returned data structure must either have a property called “Items” or “items”, or the JSON structure must be an array.
  • data-json-var: Optional, defines the same data as data-json-url so an extra server hit is not required for the initial page load. This can supplement or replace the data-json-url attribute.
  • data-template: The template to instantiate for each JSON array item. The example above uses a template called ‘WorkRequestView’, which must be defined on the page in a template script block.

The following two templates are part of a view/edit pair.

Basic structure of a status template (read-only):

    <script id="WorkRequestView" type="text/x-jsrender">
		<div class="inline-editable" id="Request{{>ConfirmationNumber}}">
			<div>
				<!-- TODO: display any desired properties as read-only or editable here -->
				<span class="input-row">
					<span class="confirmation-label">Confirmation Number:</span>
					<span class="confirmation">{{>ConfirmationNumber}} </span>
				</span>
				<!-- TODO: display any desired properties as read-only or editable here -->
				<div class="command-buttons">
					<input type="submit" value="Edit" id="EditAction" name="EditAction" 
						class="inline-editable-button float-left"
						data-template="WorkEditAction" 
						data-url="" />
					<span class="msg clear"></span>
					<br class="clear-fix" />
				</div>
			</div>
		</div>
    </script>

Basic structure of an action template (edit form):

    <script id="WorkEditAction" type="text/x-jsrender">
        <div class="inline-editable">
    		<form action="/Worklist/ByDay?date=20131021" method="post">
                <input type="hidden" name="ConfirmationNumber" id="ConfirmationNumber" value="{{>ConfirmationNumber}}" />
                <span class="input">
                    <label for="Comment">Comment</label>
                    <input id="Comment" name="Comment" value="" type="text">
                </span>
                <div class="command-buttons">
                    <input type="submit" value="Approve" id="Approve" name="Approve" class="inline-editable-button left-float"
                        data-template="WorkRequestView" />
                    <input type="submit" value="Cancel" id="Cancel" name="Cancel" class="inline-editable-button right-float"
                        data-template="WorkRequestView" data-url="" />
                    <span class="msg clear"></span>
                    <br class="clear-fix" />
                </div>
    		</form>
        </div>
    </script>

Note the template syntax for inserting data item property values into the generated html. Each button that can toggle over to another view must have the “inline-editable-button” class applied. data- attributes contol the behavior of the buttons.

  • data-url: defines where to post the form containing this button to, which you use to tell the server about the change in state and persist anything the user did on this view. If this attribute is missing, then it will use the parent form action url. If there is no form, and no data-url attribute, then no post occurs and it just swaps to the next view.
  • data-template: The name of the template to be switched over to when the button is clicked. The same item the current view was bound to will also be bound to the new view.
  • Update Oct 27,2013: Added documentation for the following options:
  • data-editable-container: Optional, defines a container elsewhere in document where the template should be inserted. This is intended for things like an ‘add’ button to the list. If not specified, the target container is the closest parent with class ‘inline-editable-host’. See use case 4 for example usage.
  • data-editable-element: Optional, A selector to an inline-editable element. It is for edge cases when the button does not exist within the element being toggled to another state. When not specified, the closest parent element with class ‘inline-editable’ is used.
  • data-insert-order: Optional, when specified as ‘first’ it sets if the replacement view template as the first inline editable within the target container inline editable host. Any other value, or when missing puts the replacement template in the same order as the view being replaced, or if an insert/add it goes at the end by default.
  • data-url-method: Optional. If specified it determines the http transport method to call the data-url. ‘get’ by default.

Once the post to data-url is complete, the defined data-template will be bound again to the JSON item returned from the server. This accounts for the server updating a calculated property, or just checking if it was updated by another user.

Note how ‘cancel’ is implemented to not send any data to the server and just toggle back over to the read-only view. It does this by setting data-url to an empty value to override the form action url.

Use Case 2: Filter a list of editable items from a list of links:

This use case covers when you have a very large list of items to be modified in use case 1, but you want that list filtered by some other criteria on the page, such as a link for each date or each category, or whatever other generic filters you have. You start by defining your list of items and their various status templates per use case 1. Then you can layer this use case on top by defining a list of filters.

Container Element: A list of top level filters:

    <div class="worklist-months inline-editable-host" 
    	data-json-url="/Worklist/MonthSummaryByRange?date=20131001&pastMonths=4&totalMonths=9" 
    	data-template="WorklistMonthPagerItem">
    </div>

This references a template called ‘WorklistMonthPagerItem’ which should be defined on the page in a template script block. auto-async will load the data-json-url and use the returned json format data to instantiate the data-template and put an instance in the inline-editable-host for each result item. The JSON data can either be returned as an object with an Items property, items property, or the result can be a JSON list. So far this is the same as in use case 1.

Basic structure of the worklist month pager item:

    <script id="WorklistMonthPagerItem" type="text/x-jsrender">
        <span class="worklist-month {{>UrgencyStyle}}">
            <span class="inline-editable-host-updater worklist-month-pager {{>RelativeMonthStyle}}" 
                  data-host-selector="#worklist-date-title, .worklist-items, .worklist-days, .worklist-months" 
                  data-date="{{>RequestYear}}/{{>RequestMonth}}/01" 
                  title="{{>OpenRequests}} Open Requests, {{>ExpiringRequests}} Expiring Requests">
                {{>MonthName}} 
            </span>
        </span>
    </script>

Notice the jsRender syntax to put JSON data item properties into the template instance. The only class that must be on elements here is the “inline-editable-host-updater”, the rest are for style of this example. The element with the “inline-editable-host-updater” can control what the autoasync does with data attributes.

  • data-host-selector: A jQuery selector(s) of the elements to be reloaded when this item is clicked.
  • data-?: any number of other attribute values to be passed onto the items being updated when loading data. See example below.

An example of an updated item:

    <div class="worklist-days inline-editable-host" 
		data-json-url="/Worklist/SummaryByRange?date=20131001" 
		data-template="WorklistSummaryByDayMini">
    </div>

The above item has a class of “worklist-days” which is one of the selectors in the worklist month pager example above, in attribute ‘data-host-selector’. When auto-async refreshes an “inline-editable-host”, it does so by running the same logic that occurs when the section is initialized after page load. See use case 1 for the logic again. This refers to yet another template on the page for showing a day of the month.

    <script id="WorklistSummaryByDayMini" type="text/x-jsrender">
    	<span class="worklist-day {{>UrgencyStyle}}">
    		<span class="inline-editable-host-updater worklist-day-number {{>RelativeDayStyle}}" 
    			data-host-selector=".worklist-items" 
    			data-date="{{>~formatDateNumeric(RequestDate)}}"
    			title="{{>OpenRequests}} Open Requests, {{>ExpiringRequests}} Expiring Requests">
    			{{>RequestDay}}
    		</span>
    	</span>
    </script>

As you can see this is yet another filter that when a date is clicked will again filter the main list of items from use case 1. The data-date in this template and in the month list above both are parameter values passed to the data-json-url of the parent ‘inline-editable-host’ container element. The server side code looks for the date parameter to know what values to return in the list. For instance the date parameter tells the /Worklist/SummaryByRange API call what month to return days of the month for. You may see a conflict in that the date parameter is already specified on the data-json-url path querystring. auto-async handles this by removing prior values in the querystring of the same name as any
data attribute values being passed. Basically the data- extra parameter values are overrides for the default url parameters.

Here are the filters above in action, when the current date is October 21, 2013; October 22-23 both have an urgent style applied via model property “UrgencyStyle” giving them a red outline.

20131021-Async-MonthDayFilters

Use case 3: data repeaters (example: radio button list):

There is another special element type enhanced by auto-async, similar to inline-editable-host. However, the ‘datarepeater’ behaves slightly different. It does not have any buttons inside it to toggle a given view item. The repeater is meant primarily for the use case of a radio button list. These are generally used inside of a inline-editable template.

Basic structure of a data repeater:

	<span class="datarepeater"
        data-json-url="/Worklist/NextStatusTypes?date=20131021&confirmationNumber={{>ConfirmationNumber}}"
        data-template="NextStatusRadioList">
	</span>

This is as simple as it gets. Generally this is used to add a list of inputs to a form. It supports these attributes.

  • data-json-url: A url to load a list of items from. The returned data structure must either have a property called “Items” or “items”, or the JSON structure must be an array.
  • data-template: The template to instantiate for each JSON array item. The example above uses a template called ‘NextStatusRadioList’, which must be defined on the page in a template script block.

Example called by the above repeater:

    <script id="NextStatusRadioList" type="text/x-jsrender">
        <input type="radio" name="NextStatusId" value="{{>NextStatusId}}" {{if IsSelected}}checked{{/if}} />
        <span class="name">{{>Name}}</span>
        <span class="desc">Desc: {{>Description}}</span><br/>
    </script>



References

Github Project
https://github.com/michael-lang/jquery-auto-async/

Use case 4: Auto Async Adds Template Dialog

Auto Async adds Template Dialog

AsyncUI MVC with Progressive Enhancement

AsyncUI MVC with Progressive Enhancement

About the Author

Michael Lang

Co-Founder and CTO of Watchdog Creative, business development, technology vision, and more since 2013, Developer, and Mentor since 1999. See the about page for more details.

1 Comment