diff options
author | Yorhel <git@yorhel.nl> | 2011-03-14 13:12:54 +0100 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2011-03-14 13:12:54 +0100 |
commit | 17d4f695b114f970c3b3c4c17c4b8915a0356297 (patch) | |
tree | 5e12ab47403fcf7919ebbde2a961c92506331850 /data | |
parent | 4582a5dce7c0793fe64806d4cba5ab9d386ea878 (diff) |
chardb: Added Char<->VN linking edit interface
Still somewhat quircky, but it works.
Diffstat (limited to 'data')
-rw-r--r-- | data/global.pl | 1 | ||||
-rw-r--r-- | data/script.js | 207 | ||||
-rw-r--r-- | data/style.css | 12 |
3 files changed, 218 insertions, 2 deletions
diff --git a/data/global.pl b/data/global.pl index 3f1ba3b6..5fd2bf85 100644 --- a/data/global.pl +++ b/data/global.pl @@ -108,6 +108,7 @@ our %S = (%S, vnlist_status => [ 0..4 ], blood_types => [qw| unknown a b ab o |], genders => [qw| unknown m f b |], + char_roles => [qw| main primary side appears |], atom_feeds => { # num_entries, title, id announcements => [ 10, 'VNDB Site Announcements', '/t/an' ], changes => [ 25, 'VNDB Recent Changes', '/hist' ], diff --git a/data/script.js b/data/script.js index f7b6eb1b..1aa60efa 100644 --- a/data/script.js +++ b/data/script.js @@ -1,5 +1,6 @@ /* function/attribute prefixes: * ctr -> Character <-> trait linking + * cvn -> Character <-> VN linking * date -> Date selector * dd -> dropdown * ds -> dropdown search @@ -1774,7 +1775,7 @@ function ctrLoad() { var t = ht.responseXML.getElementsByTagName('item'); for(var i=0; i<t.length; i++) ctrAdd(t[i], v[t[i].getAttribute('id')]); - }); + }, 1); else ctrEmpty(); @@ -1786,7 +1787,7 @@ function ctrLoad() { tr.appendChild(tag('td', tag('b', {'class':'grayedout'}, g), item.firstChild.nodeValue, tag('b', {'class':'grayedout'}, item.getAttribute('meta')=='yes' ? mt('_js_ds_tag_meta') : ''))); - }, ctrFormAdd, function () {}); + }, ctrFormAdd); } function ctrEmpty() { @@ -1884,6 +1885,208 @@ if(byId('traits_tbl')) +/* C H A R A C T E R < - > V N L I N K I N G (/c+/edit) */ + +// TODO: translate! + +function cvnLoad() { + // load current links + var l = byId('vns').value.split(' '); + var v = {}; // vid -> { rid: [ role, spoil ], .. } + var q = []; // list of v=X parameters + for(var i=0; i<l.length; i++) { + if(!l[i]) + continue; + var m = l[i].split(/-/); // vid, rid, spoil, role + if(!v[m[0]]) { + q.push('v='+m[0]); + v[m[0]] = {}; + } + v[m[0]][m[1]] = [ m[3], m[2] ]; + } + if(q.length > 0) + ajax('/xml/releases.xml?'+q.join(';'), function(hr) { + var vns = byName(hr.responseXML, 'vn'); + for(var i=0; i<vns.length; i++) { + var vid = vns[i].getAttribute('id'); + cvnVNAdd(vns[i]); + var rels = byName(vns[i], 'release'); + for(var r=0; r<rels.length; r++) { + var rid = rels[r].getAttribute('id'); + if(v[vid][rid]) + cvnRelAdd(vid, rid, v[vid][rid][0], v[vid][rid][1]); + } + if(v[vid][0]) + cvnRelAdd(vid, 0, v[vid][0][0], v[vid][0][1]); + } + }, 1); + else + cvnEmpty(); + + // dropdown search + dsInit(byId('vns_input'), '/xml/vn.xml?q=', function(item, tr) { + tr.appendChild(tag('td', { style: 'text-align: right; padding-right: 5px'}, 'v'+item.getAttribute('id'))); + tr.appendChild(tag('td', shorten(item.firstChild.nodeValue, 40))); + }, cvnFormAdd); +} + +function cvnEmpty() { + var x = byId('vns_loading'); + var t = byId('vns_tbl'); + if(x) + t.removeChild(x); + var l = byName(t, 'tr'); + var e = byId('vns_empty'); + if(e && l.length > 1) + t.removeChild(e); + else if(!e && l.length < 1) + t.appendChild(tag('tr', {id:'vns_empty',colspan:3}, tag('td', 'No visual novels selected.'))); +} + +function cvnVNAdd(vn, rel) { + var vid = vn.getAttribute('id'); + var rels = byName(vn, 'release'); + byId('vns_tbl').appendChild(tag('tr', {id:'cvn_v'+vid, cvn_vid:vid, cvn_rels:rels}, + tag('td', {'class':'tc_vn',colspan:4}, 'v'+vid+':', + tag('a', {href:'/v'+vid}, vn.getAttribute('title')), + tag('i', '(', tag('a', {href:'#', onclick:cvnRelNew}, 'add release'), ')') + ) + )); + if(rel) + cvnRelAdd(vid, 0, 'primary', 0); + cvnEmpty(); +} + +function cvnRelAdd(vid, rid, role, spoil) { + var rels = byId('cvn_v'+vid).cvn_rels; + var rsel = tag('select', {onchange:cvnRelChange}, tag('option', {value:0}, 'All / others')); + for(var i=0; i<rels.length; i++) { + var id = rels[i].getAttribute('id'); + rsel.appendChild(tag('option', {value: id, selected:id==rid}, + '['+rels[i].getAttribute('lang')+'] '+rels[i].firstChild.nodeValue+' (r'+id+')')); + } + + var lsel = tag('select', {onchange:cvnSerialize}); + for(var i=0; i<char_roles.length; i++) + lsel.appendChild(tag('option', {value: char_roles[i], selected:char_roles[i]==role}, char_roles[i])); + + // l10n /_spoil_\d+/ + var ssel = tag('select', {onchange:cvnSerialize}); + for(var i=0; i<3; i++) + ssel.appendChild(tag('option', {value:i, selected:i==spoil}, mt('_spoil_'+i))); + + var tbl = byId('vns_tbl'); + var l = byName(tbl, 'tr'); + var last = null; + for(var i=1; i<l.length; i++) + if(l[i-1].cvn_vid == vid && l[i].cvn_vid != vid) + last = l[i-1]; + tbl.insertBefore(tag('tr', {id:'cvn_v'+vid+'r'+rid, cvn_vid:vid, cvn_rid:rid}, + tag('td', {'class':'tc_rel'}, rsel), + tag('td', {'class':'tc_rol'}, lsel), + tag('td', {'class':'tc_spl'}, ssel), + tag('td', {'class':'tc_del'}, tag('a', {href:'#', onclick:cvnRelDel}, 'remove')) + ), last); +} + +function cvnRelChange() { + // look for duplicates and disallow the change + var val = this.options[this.selectedIndex].value; + var tr = this; + while(tr.nodeName.toLowerCase() != 'tr') + tr = tr.parentNode; + if(byId('cvn_v'+tr.cvn_vid+'r'+val)) { + alert('Release already selected.'); + for(var i=0; i<this.options.length; i++) + this.options[i].selected = this.options[i].value == tr.cvn_rid; + return; + } + // otherwise, 'rename' this entry + tr.id = 'cvn_v'+tr.cvn_vid+'r'+val; + tr.cvn_rid = val; + cvnSerialize(); +} + +function cvnRelNew() { + var tr = this; + while(tr.nodeName.toLowerCase() != 'tr') + tr = tr.parentNode; + var id = 0; + if(byId('cvn_v'+tr.cvn_vid+'r0')) { + for(var i=0; i<tr.cvn_rels.length; i++) { + id = tr.cvn_rels[i].getAttribute('id'); + if(!byId('cvn_v'+tr.cvn_vid+'r'+id)) + break; + } + if(i == tr.cvn_rels.length) { + alert('All releases already selected'); + return false; + } + } + cvnRelAdd(tr.cvn_vid, id, 'primary', 0); + cvnSerialize(); + return false; +} + +function cvnRelDel() { + var tbl = byId('vns_tbl'); + var tr = this; + while(tr.nodeName.toLowerCase() != 'tr') + tr = tr.parentNode; + tbl.removeChild(tr); + var l = byName(tbl, 'tr'); + var c = 0; + for(var i=0; i<l.length; i++) + if(l[i].cvn_vid == tr.cvn_vid) + c++; + if(c <= 1) + tbl.removeChild(byId('cvn_v'+tr.cvn_vid)); + cvnSerialize(); + cvnEmpty(); + return false; +} + +function cvnFormAdd(item) { + var inpt = byId('vns_input'); + inpt.disabled = true; + + ajax('/xml/releases.xml?v='+item.getAttribute('id'), function(hr) { + inpt.disabled = false; + inpt.value = ''; + + var items = byName(hr.responseXML, 'vn'); + if(items.length < 1) // shouldn't happen + return alert('Oops! Error!'); + + var id = items[0].getAttribute('id'); + if(byId('cvn_v'+id)) + return alert(mt('VN already present.')); + cvnVNAdd(items[0], 1); + cvnSerialize(); + }, 1); + return mt('_js_loading'); +} + +function cvnSerialize() { + var l = byName(byId('vns_tbl'), 'tr'); + var v = []; + for(var i=0; i<l.length; i++) + if(l[i].cvn_rid != null) { + var rol = byName(byClass(l[i], 'tc_rol')[0], 'select')[0]; + var spl = byName(byClass(l[i], 'tc_spl')[0], 'select')[0]; + v.push(l[i].cvn_vid+'-'+l[i].cvn_rid+'-'+ + spl.options[spl.selectedIndex].value+'-'+ + rol.options[rol.selectedIndex].value); + } + byId('vns').value = v.join(' '); +} + +if(byId('jt_box_chare_vns')) + cvnLoad(); + + + + /* F I L T E R S Y S T E M */ diff --git a/data/style.css b/data/style.css index 27d0aeec..de55a177 100644 --- a/data/style.css +++ b/data/style.css @@ -872,6 +872,18 @@ div.chardetails table td.key { width: 80px; } #jt_box_chare_traits td.tc_name { width: 200px } #jt_box_chare_traits td.tc_name input { width: 280px; } #jt_box_chare_traits td.tc_spoil { width: 80px; } +#jt_box_chare_vns table { margin-bottom: 10px; margin-left: 10px; } +#jt_box_chare_vns h2 { margin: 0 0 3px 0px; } +#jt_box_chare_vns td.tc_vn { font-weight: bold; padding: 5px 0 3px 0 } +#jt_box_chare_vns td.tc_vn i{ font-weight: normal; padding-left: 5px; font-style: normal } +#jt_box_chare_vns td.tc_rel { width: 340px; padding-left: 15px } +#jt_box_chare_vns td.tc_rel select { width: 340px; } +#jt_box_chare_vns td.tc_rol, +#jt_box_chare_vns td.tc_spl, +#jt_box_chare_vns td.tc_rol select, +#jt_box_chare_vns td.tc_spl select { width: 100px } +#jt_box_chare_vns td.tc_del { padding-left: 5px } +#jt_box_chare_vns td.tc_vnadd input { width: 280px } /***** Documentation pages *****/ |