1- import { fnapp , fnbind , fnstate , h } from 'https://cdn.jsdelivr.net/npm/fntags@0.%3Cspan%20class="x x-first x-last">2.10 /src/fntags.min.js'
1+ import { fnapp , fnstate , h } from 'https://cdn.jsdelivr.net/npm/fntags@0.%3Cspan%20class="x x-first x-last">3.2 /src/fntags.min.js'
22
3- let data = fnstate ( [ ] )
3+ let data = fnstate ( [ ] , d => d . id )
44
55function random ( max ) { return Math . round ( Math . random ( ) * 1000 ) % max }
66
7- const A = [ 'pretty' , 'large' , 'big' , 'small' , 'tall' , 'short' , 'long' , 'handsome' , 'plain' , 'quaint' , 'clean' ,
7+ const A = [ 'pretty' , 'large' , 'big' , 'small' , 'tall' , 'short' , 'long' , 'handsome' , 'plain' , 'quaint' , 'clean' ,
88 'elegant' , 'easy' , 'angry' , 'crazy' , 'helpful' , 'mushy' , 'odd' , 'unsightly' , 'adorable' , 'important' , 'inexpensive' ,
9- 'cheap' , 'expensive' , 'fancy' ]
10- const C = [ 'red' , 'yellow' , 'blue' , 'green' , 'pink' , 'brown' , 'purple' , 'brown' , 'white' , 'black' , 'orange' ]
11- const N = [ 'table' , 'chair' , 'house' , 'bbq' , 'desk' , 'car' , 'pony' , 'cookie' , 'sandwich' , 'burger' , 'pizza' , 'mouse' ,
12- 'keyboard' ]
9+ 'cheap' , 'expensive' , 'fancy' ]
10+ const C = [ 'red' , 'yellow' , 'blue' , 'green' , 'pink' , 'brown' , 'purple' , 'brown' , 'white' , 'black' , 'orange' ]
11+ const N = [ 'table' , 'chair' , 'house' , 'bbq' , 'desk' , 'car' , 'pony' , 'cookie' , 'sandwich' , 'burger' , 'pizza' , 'mouse' ,
12+ 'keyboard' ]
1313
1414let nextId = 1
1515
1616function buildData ( count ) {
1717 const newData = new Array ( count )
1818 for ( let i = 0 ; i < count ; i ++ ) {
19- newData [ i ] = fnstate ( {
20- id : nextId ++ ,
21- label : `${ A [ random ( A . length ) ] } ${ C [ random ( C . length ) ] } ${ N [ random ( N . length ) ] } `
22- } )
19+ newData [ i ] = {
20+ id : nextId ++ ,
21+ label : `${ A [ random ( A . length ) ] } ${ C [ random ( C . length ) ] } ${ N [ random ( N . length ) ] } `
22+ }
2323 }
2424 return newData
2525}
@@ -29,49 +29,59 @@ const Button = ( id, title, onclick ) =>
2929 h ( 'button' , { id, type : 'button' , class : 'btn btn-primary btn-block' , onclick : onclick } , title )
3030 )
3131
32- let rowTemplate =
33- h ( 'tr' ,
34- h ( 'td' , { class : 'col-md-1' } ) ,
35- h ( 'td' , { class : 'col-md-4' } , h ( 'a' ) ) ,
36- h ( 'td' , { class : 'col-md-1' } ,
37- h ( 'a' ,
38- h ( 'span' , { class : 'glyphicon glyphicon-remove' , 'aria-hidden' : 'true' } )
39- )
40- ) ,
41- h ( 'td' , { class : 'col-md-6' } )
42- )
43- let selected = null
44-
4532const row = ( item ) => {
46- const tr = rowTemplate . cloneNode ( true )
47- const id = tr . firstChild
48- const label = id . nextSibling . firstChild
49- const removeBtn = id . nextSibling . nextSibling
50-
51- removeBtn . addEventListener ( 'click' , ( e ) => {
52- e . preventDefault ( )
53- e . stopPropagation ( )
54- tr . replaceWith ( '' )
55- item . reset ( )
56- item ( null )
33+ const id = h ( 'td' , {
34+ class : 'col-md-1'
35+ } ,
36+ item ( ) . id
37+ )
38+ let label = h ( 'a' , item ( ) . label )
39+ let removeBtn = h ( 'span' , {
40+ onclick : ( e ) => {
41+ e . preventDefault ( )
42+ e . stopPropagation ( )
43+ data ( data ( ) . filter ( d => d ( ) . id !== item ( ) . id ) )
44+ } ,
45+ class : 'glyphicon glyphicon-remove' , 'aria-hidden' : 'true'
5746 } )
5847
59- tr . addEventListener ( 'click' , ( ) => {
60- if ( selected ) selected . patch ( { selected : false } )
61- item . patch ( { selected : true } )
62- selected = item
63- } )
48+ const tr = h ( 'tr' , {
49+ id : item ( ) . id ,
50+ onclick : ( ) => {
51+ let currentSelection = data ( ) . find ( d => d ( ) . selected )
52+ if ( currentSelection ) currentSelection . patch ( { selected : false } )
53+ item . patch ( { selected : true } )
54+ }
55+ } ,
56+ id ,
57+ h ( 'td' , { class : 'col-md-4' } , label ) ,
58+ h ( 'td' , { class : 'col-md-1' } ,
59+ h ( 'a' ,
60+ removeBtn
61+ )
62+ ) ,
63+ h ( 'td' , { class : 'col-md-6' } )
64+ )
6465
65- tr . setAttribute ( 'id' , item ( ) . id . toString ( ) )
66+ //cache the current values to prevent reading the dom or making the same change over the top of itself
67+ let currentLabel = item ( ) . label
68+ let isSelected = item ( ) . isSelected
6669
67- const update = ( ) => {
68- tr . className = item ( ) . selected ? 'danger' : ''
69- label . innerText = item ( ) . label
70- id . innerText = item ( ) . id
71- }
70+ item . subscribe ( ( ) => {
71+ if ( isSelected && ! item ( ) . selected ) {
72+ tr . className = ''
73+ } else if ( ! isSelected && item ( ) . selected ) {
74+ tr . className = 'danger'
75+ }
76+ isSelected = item ( ) . selected
7277
73- update ( )
74- return fnbind ( item , tr , update )
78+ if ( currentLabel != item ( ) . label ) {
79+ label . innerText = item ( ) . label
80+ currentLabel = item ( ) . label
81+ }
82+ } )
83+
84+ return tr
7585}
7686
7787fnapp ( document . body ,
@@ -85,31 +95,29 @@ fnapp( document.body,
8595 h ( 'div' , { class : 'row' } ,
8696 Button ( 'run' , 'Create 1,000 rows' , ( ) => data ( buildData ( 1000 ) ) ) ,
8797 Button ( 'runlots' , 'Create 10,000 rows' , ( ) => data ( buildData ( 10000 ) ) ) ,
88- Button ( 'add' , 'Append 1,000 rows' , ( ) => {
89- data ( data ( ) . concat ( buildData ( 1000 ) ) )
90- } ) ,
98+ Button ( 'add' , 'Append 1,000 rows' , ( ) => data ( data ( ) . concat ( buildData ( 1000 ) ) ) ) ,
9199 Button ( 'update' , 'Update every 10th row' , ( ) => {
92100 for ( let i = 0 ; i < data ( ) . length ; i += 10 ) {
93101 data ( ) [ i ] . patch ( { label : data ( ) [ i ] ( ) . label + ' !!!' } )
94102 }
95103 } ) ,
96104 Button ( 'clear' , 'Clear' , ( ) => data ( [ ] ) ) ,
97105 Button ( 'swaprows' , 'Swap Rows' , ( ) => {
98- const theData = data ( )
99- if ( theData . length > 998 ) {
100- const a = theData [ 1 ]
101- theData [ 1 ] = theData [ 998 ]
102- theData [ 998 ] = a
103- data ( theData )
106+ const d = data ( )
107+ if ( d . length > 998 ) {
108+ const a = d [ 1 ]
109+ d [ 1 ] = d [ 998 ]
110+ d [ 998 ] = a
104111 }
112+ data ( d )
105113 } )
106114 )
107115 )
108116 )
109117 )
110118 ) ,
111119 h ( 'table' , { class : 'table table-hover table-striped test-data' } ,
112- data . mapChildren ( h ( 'tbody' ) , ( item ) => item ( ) . id , row )
120+ data . bindValues ( h ( 'tbody' ) , row )
113121 ) ,
114122 h ( 'span' , { class : 'preloadicon glyphicon glyphicon-remove' , 'aria-hidden' : 'true' } )
115123)
0 commit comments