Test Vue 1.0 Focus

Correctly functional vue test page that inserts rows at top and focuses on Date field

by barbedCoil

HTML

<!DOCTYPE html>

<!--

    This is a snippet of the much larger page in production so you may see things here
    that make you wonder why?  That's not the point.

    The point is that I can click add, a new row is inserted at the top of the backing data
    array and the cursor is focused on the Date field for the new row.

-->

<body>
    <div id="appView" class="container-fluid" v-cloak>
        <h3>Vue.js 1.x Add Rows Focus - This Works</h3>
        <div class="row">
            <div class="col-sm-12 col-md-12 col-lg-12">

                <!-- this is used in many other places in the production page hence it's location -->
                <datalist id="listJobCodesALL">
                    <option v-for="jobCode in jobCodes" v-bind:value="jobCode.job_code" v-text="jobCode.job"></option>
                </datalist>

                <div class="table-tips">
                    <div>
                        <button v-on:click="onAddTipEntry(90125, 101)" class="btn btn-sm btn-primary">
                            <span>Add</span>
                        </button>
                    </div>
                    <br/>

                    <table id="tableTips" class="table table-bordered table-condensed table-responsive">
                        <thead>
                            <tr class="thead-block">
                                <th class="row_num-hdr">Row</th>
                                <th class="delete_tip-hdr">Delete</th>
                                <th class="business_date-hdr">Date</th>
                                <th class="job_code-hdr">Code</th>
                            </tr>
                        </thead>
                        <tbody id="tbodyTips" class="tbody-block">
                            <tr v-for="tip in tipEntries" :id="$index">
                                <td>
                                    <input :id="$index" 
                                        type="text" readonly
                                    ...

CSS

body {
    padding-top: 1px;
    padding-bottom: 1px;
}

/* Set padding to keep content from hitting the edges */
.body-content {
    padding-left: 15px;
    padding-right: 15px;
}

/* Override the default bootstrap behavior where horizontal description lists 
   will truncate terms that are too long to fit in the left column 
*/
.dl-horizontal dt {
    white-space: normal;
}

/* Set width on the form input elements since they're 100% wide by default */
input,
textarea 
{
    max-width: 240px !important;
    margin-left: 15px;
}

select 
{
    max-width: 280px !important;
    margin-left: 15px;
    cursor: pointer;
}

.selected-command 
{
	color: #0288D1 !important;
	font-weight: bold;
}


/* B O O T S T R A P */

/* fixes animation issues - mostly on mobile */
.collapsing 
{
    -webkit-transition: none;
    transition: none;
}

.fa-trash,
.glyphicon-trash 
{
	color: maroon;
}

a.hover:hover 
{
	font-weight: bolder; 
}


/* V U E */

[v-cloak] 
{
  display: none;
}


/* C O M M O N */

input[type=checkbox].format-checkbox 
{
	text-align: left;
	height: 20px;
	width: 20px;
	cursor: pointer;
}

.el_hide
{
    display: none;
}

.el_show
{
    display: normal;
}

.el_center 
{
	margin: 0 auto;
}

.el_maroon
{
    color: maroon;
}

.el_blue
{
	color: #337ab7;
}

/* scroll container - NOTE: set height: ###px; on dom element otherwise scroll does not work */
.box 
{	
	border: 1px solid lightgray;
	border-radius: 2px;
	overflow-y: scroll;
	overflow-x: hidden;
}


.tbody-block 
{
	display: block;
    height: 133px;
	overflow-x: hidden; 
	overflow-y: visible; 
}

.thead-block
{
    display:block;
}

td { 
    padding: 0;
}


.row_num-hdr
{
	width: 45px !important;
	min-width: 45px !important;
	max-width: 45px !important;
}

.business_date-hdr
{
	width: 136px !important;
	min-width: 136px !important;
	max-width: 136px !important;
}

.job_code-hdr
{
	width: 60px !important;
	min-width: 60px !important;
	max-width: 60px !important;
}

.row_num
{
	width: 34px;
	text-align:...

JavaScript

"use strict";


/*

    This script uses vue.js 1.x - This script and the associated
    html page functions as needed:

    -   User Clicks Add button
    -   onAddTipEntry(..) is called which clones tipEntry below
    -   Cloned tip entry is updated with basic data
    -   Cloned tip entry is added to tipEntries data array by splice

    NOTE:  I need new rows to be added to top so user can add new entries
            in a very fast and efficient way.

*/


// we have several "namespaces" under HS

var HS = HS || {};
HS.Main = {};

HS.Main =
{
    vm: new Vue({
        el: "#appView",
        data:
        {
            businessDate: null,
            jobCodes:
            [
                { job: "100", job_code: "100 - Job 1" },
                { job: "101", job_code: "101 - Job 2" },
                { job: "102", job_code: "102 - Job 3" },
                { job: "103", job_code: "103 - Job 4" },
                { job: "104", job_code: "104 - Job 5" },
                { job: "105", job_code: "105 - Job 6" },
            ],
            tipEntries: [],
            tipEntry:
            {
                row_num: 0,
                person_id: null,
                tip_date: null,
                job_code: "",
                status_code: 0,
                delete_flag: false
            },
            tipAddNew: false,
            status: 
            {
                base_code: 0,
                change_code: 1,
                new_code: 2,
                delete_code: 3
            }
        },

        watch:
        {
            // we just watch to see when new entry by user
            "tipEntries": function (val, oldVal)
            {
                if (this.tipAddNew === false) return;

                // no error side effect even if fails
                //$("#tip-0").focus();

                // uncomment this to see the vue error
                document.getElementById("tip-0").focus();
                
                HS.Main.vm.tipAddNew = false;
...