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;
...