diff options
author | Yorhel <git@yorhel.nl> | 2010-11-27 13:30:55 +0100 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2010-11-27 13:30:55 +0100 |
commit | 5f9aea8e9877b71b4372a8fde569367db6bb44e1 (patch) | |
tree | 98d12e246f36ad069a5478bcf0de7e559de563b7 | |
parent | 156a362991ac6922f33e61a08f39f31048310183 (diff) |
Replaced old VN advanced options with the new filter selection system
Had to fix some bugs here and there and add some new functionality to
the abstractions at some places, but it appears to be working now. There
are still a few TODOs left, I'll get to those in a bit.
-rw-r--r-- | ChangeLog | 2 | ||||
-rw-r--r-- | data/lang.txt | 67 | ||||
-rw-r--r-- | data/script.js | 94 | ||||
-rw-r--r-- | data/style.css | 25 | ||||
-rw-r--r-- | lib/VNDB/DB/VN.pm | 10 | ||||
-rw-r--r-- | lib/VNDB/Func.pm | 2 | ||||
-rw-r--r-- | lib/VNDB/Handler/Releases.pm | 2 | ||||
-rw-r--r-- | lib/VNDB/Handler/VNBrowse.pm | 112 |
8 files changed, 131 insertions, 183 deletions
@@ -1,5 +1,5 @@ 2.14 - ? - - Improved release filter selection interface + - Improved filter selection interface for the release and VN browser - New release filters: voiced and animation - Added Atom feeds for the recent announcements, changes and posts (located in /www/feeds and updated every 15 min. by Multi::Feed) diff --git a/data/lang.txt b/data/lang.txt index 4a37e999..f5fec672 100644 --- a/data/lang.txt +++ b/data/lang.txt @@ -5656,19 +5656,19 @@ cs : nenalezeny takové tagy hu : nem található ilyen címke nl : tag niet gevonden -:_vnbrowse_advsearch -en : advanced search -ru : расширенный поиск -cs : pokročilé hledání -hu : bővített keresés -nl : geavanceerd zoeken +:_vnbrowse_fil_title +en : Visual Novel Filters +ru*: +cs*: +hu*: +nl : :_vnbrowse_tags -en : Tag filters -ru : Фильтры тегов -cs : Filtry tagů -hu : címke szűrők -nl : Tagfilters +en : Tags +ru*: +cs*: +hu*: +nl : :_vnbrowse_booland en : boolean and, selecting more gives less results @@ -5712,40 +5712,19 @@ cs : Ukázat všechny spoilery hu : Nagyobb spoilerek megjelenítése nl : Toon alle spoilers -:_vnbrowse_lang -en : Languages -ru : Языки -cs : Jazyky -hu : Nyelvek -nl : Talen - -:_vnbrowse_boolor -en : boolean or, selecting more gives more results -ru : логическое 'или', чем больше выбрано, тем больше даёт результатов -cs : boolean nebo, výběr více dá více výsledků -hu : Boole féle értékhalmaz(igaz/hamis), ha többet választasz ki akkor több találatot ad ki -nl : booleaanse 'of', meerdere selecties geven meer resultaten - -:_vnbrowse_plat -en : Platforms -ru : Платформы -cs : Platformy -hu : Platformok -nl : Platformen +:_vnbrowse_language +en : Language +ru*: Языки +cs*: Jazyky +hu*: Nyelvek +nl : Taal -:_vnbrowse_apply -en : Apply -ru : Применить -cs : Použít -hu : Alkalmazás -nl : Toepassen - -:_vnbrowse_clear -en : Clear -ru : Очистить -cs : Začít znovu -hu : Törlés -nl : Wissen +:_vnbrowse_platform +en : Platform +ru*: Платформы +cs*: Platformy +hu*: Platformok +nl : # VN add/edit form (/v+/edit) diff --git a/data/script.js b/data/script.js index 8cf49e97..2c2e0f6a 100644 --- a/data/script.js +++ b/data/script.js @@ -632,7 +632,7 @@ function dsKeyDown(ev) { if(obj.ds_selectedId != 0) obj.value = obj.ds_serFunc(byId('ds_box_'+obj.ds_selectedId).ds_itemData, obj); if(obj.ds_returnFunc) - obj.ds_returnFunc(); + obj.ds_returnFunc(obj); setClass(byId('ds_box'), 'hidden', true); setContent(byId('ds_box'), tag('b', mt('_js_loading'))); @@ -1728,8 +1728,8 @@ if(byId('prodrelations')) * Where: * <title> human-readable title of the filter box * <category_name> human-readable name of the category. ignored if there's only one category - * <fieldcode> code of this field, refers to the <field> in the filter format - * <fieldname> human-readanle name of the field. Empty to not display a label + * <fieldcode> code of this field, refers to the <field> in the filter format. Empty string for just a <tr> + * <fieldname> human-readanle name of the field. Empty to not display a label. Space for always-enabled items (without checkbox) * <fieldcontents> tag() object, or an array of tag() objects * <fieldreadfunc> function reference. argument: <fieldcontents>; must return data to be used in the filter format * <fieldwritefunc> function reference, argument: <fieldcontents>, data from filter format; must update the contents with the passed data @@ -1749,7 +1749,7 @@ if(byId('prodrelations')) var fil_cats; // [ <object with field->tr mapping>, <category-link1>, .. ] var fil_escape = "_ !\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~".split(''); function filLoad() { - var l = filReleases(); + var l = byId('filselect').href.match(/#r$/) ? filReleases() : filVN(); fil_cats = [ new Object ]; var p = tag('p', {'class':'browseopts'}); @@ -1768,13 +1768,14 @@ function filLoad() { var fd = l[i][j]; var lab = typeof fd[1] == 'object' ? fd[1][0] : fd[1]; var f = tag('tr', {'class':'newfield', fil_code: fd[0], fil_contents: fd[2], fil_readfunc: fd[3], fil_writefunc: fd[4]}, - tag('td', {'class':'check'}, tag('input', {type:'checkbox', id:'fil_check_'+fd[0], name:'fil_check_'+fd[0], onclick: filSelectField })), + fd[0] ? tag('td', {'class':'check'}, tag('input', {type:'checkbox', id:'fil_check_'+fd[0], 'class':fd[1]==' '?'hidden':'', name:'fil_check_'+fd[0], onclick: filSelectField })) : tag('td', null), fd[1] ? tag('td', {'class':'label'}, tag('label', {'for':'fil_check_'+fd[0]}, lab), typeof fd[1] == 'object' ? tag('b', fd[1][1]) : null ) : null, tag('td', {'class':'cont' }, fd[2])); - fil_cats[0][fd[0]] = f; + if(fd[0]) + fil_cats[0][fd[0]] = f; t.appendChild(f); } c.appendChild(t); @@ -1782,6 +1783,7 @@ function filLoad() { fil_cats[i] = a; } + // TODO: _rbrowse_ -> generalize (this isn't specific to the release browser) addBody(tag('div', { id: 'fil_div', 'class':'hidden' }, tag('a', {href:'#', onclick:filShow, 'class':'close'}, mt('_rbrowse_close')), tag('h3', l[0]), @@ -1820,6 +1822,8 @@ function filSelectField(obj) { var c = byId('fil_check_'+o.fil_code); if(c != t) c.checked = true; + if(hasClass(c, 'hidden')) + c.checked = true; setClass(byName(o, 'label')[0], 'active', c.checked); // update category link @@ -1828,7 +1832,7 @@ function filSelectField(obj) { var l = byName(o, 'input'); var n=0; for(var i=0; i<l.length; i++) - if(l[i].type == 'checkbox' && l[i].id.substr(0, 10) == 'fil_check_' && l[i].checked) + if(l[i].type == 'checkbox' && l[i].id.substr(0, 10) == 'fil_check_' && !hasClass(l[i], 'hidden') && l[i].checked) n++; setClass(fil_cats[o.fil_num], 'active', n>0); @@ -1839,9 +1843,12 @@ function filSelectField(obj) { function filSerialize() { var l = []; + var num = 0; for(var f in fil_cats[0]) { if(!byId('fil_check_'+f).checked) continue; + if(!hasClass(byId('fil_check_'+f), 'hidden')) + num++; var v = fil_cats[0][f].fil_readfunc(fil_cats[0][f].fil_contents); var r = []; for(var h=0; h<v.length; h++) { @@ -1859,8 +1866,7 @@ function filSerialize() { l.push(fil_cats[0][f].fil_code+'-'+r.join('~')); } byId('fil').value = l.join('.'); - var cnt = byName(byId('filselect'), 'i')[1]; - setText(cnt, l.length > 0 ? ' ('+l.length+')' : ''); + setText(byName(byId('filselect'), 'i')[1], num > 0 ? ' ('+num+')' : ''); } function filDeSerialize() { @@ -1880,7 +1886,7 @@ function filDeSerialize() { c.checked = f[fn] == '' ? false : true; var v = f[fn].split('~'); for(var i=0; i<v.length; i++) - v[i] = v[i].replace(/_([0-9]{2})/g, function (a, e) { return fil_escape[e] }); + v[i] = v[i].replace(/_([0-9]{2})/g, function (a, e) { return fil_escape[Math.floor(e)] }); fil_cats[0][fn].fil_writefunc(fil_cats[0][fn].fil_contents, v); // not very efficient: filSelectField() does a lot of things that can be // batched after all fields have been updated, and in some cases the @@ -1985,6 +1991,50 @@ function filReleases() { ]; } +function filVN() { + var lang = languages; + for(var i=0; i<lang.length; i++) // l10n /_lang_.+/ + lang[i] = [ lang[i], mt('_lang_'+lang[i]) ]; + var plat = platforms; + for(var i=0; i<plat.length; i++) // l10n /_plat_.+/ + plat[i] = [ plat[i], mt('_plat_'+plat[i]) ]; + + // tag include/exclude dropdown search + var taginc = tag('input', {type:'text', 'class':'text', style:'width:350px', onfocus:filSelectField}); + var tagexc = tag('input', {type:'text', 'class':'text', style:'width:350px', onfocus:filSelectField}); + var trfunc = function(item, tr) { + tr.appendChild(tag('td', shorten(item.firstChild.nodeValue, 40), + item.getAttribute('meta') == 'yes' ? tag('b', {'class': 'grayedout'}, ' '+mt('_js_ds_tag_meta')) : null, + item.getAttribute('state') == 0 ? tag('b', {'class': 'grayedout'}, ' '+mt('_js_ds_tag_mod')) : null + )); + }; + var serfunc = function(item, obj) { + var tags = obj.value.split(/ *, */); + tags[tags.length-1] = item.firstChild.nodeValue; + filSelectField(obj); + return tags.join(', '); + }; + var retfunc = function(o) { filSelectField(o); false }; + var parfunc = function(val) { return (val.split(/, */))[val.split(/, */).length-1]; }; + var readfunc = function(c) { return c.value.split(/, */) }; + var writefunc = function(c,v) { c.value = v.join(', ') }; + dsInit(taginc, '/xml/tags.xml?q=', trfunc, serfunc, retfunc, parfunc); + dsInit(tagexc, '/xml/tags.xml?q=', trfunc, serfunc, retfunc, parfunc); + + return [ + mt('_vnbrowse_fil_title'), + [ mt('_vnbrowse_tags'), + [ '', ' ', tag('('+mt('_vnbrowse_booland')+')') ], + [ 'taginc', mt('_vnbrowse_taginc'), taginc, readfunc, writefunc ], + [ 'tagexc', mt('_vnbrowse_tagexc'), tagexc, readfunc, writefunc ], + // TODO: get/set cookie + filFSelect('tagspoil', ' ', 1, [[0, mt('_vnbrowse_spoil0')],[1, mt('_vnbrowse_spoil1')],[2, mt('_vnbrowse_spoil2')]]) + ], + [ mt('_vnbrowse_language'), filFSelect('lang', mt('_vnbrowse_language'), 20, lang) ], + [ mt('_vnbrowse_platform'), filFSelect('plat', mt('_vnbrowse_platform'), 20, plat) ] + ]; +} + if(byId('filselect')) filLoad(); @@ -2035,13 +2085,14 @@ if(byId('advselect')) { } // Spoiler filters -> cookie (/v/*) +/* TODO: unused if(byId('sp_0')) { byId('sp_0').onclick = function() { setCookie('tagspoil', 0) }; byId('sp_1').onclick = function() { setCookie('tagspoil', 1) }; byId('sp_2').onclick = function() { setCookie('tagspoil', 2) }; var spoil = getCookie('tagspoil'); byId('sp_'+(spoil == null ? 0 : spoil)).checked = true; -} +}*/ // NSFW VN image toggle (/v+) if(byId('nsfw_show')) { @@ -2212,27 +2263,6 @@ if(byId('expandprodrel')) { }; } -// auto-complete tag search (/v/*) -if(byId('advselect') && byId('ti')) { - var trfunc = function(item, tr) { - tr.appendChild(tag('td', shorten(item.firstChild.nodeValue, 40), - item.getAttribute('meta') == 'yes' ? tag('b', {'class': 'grayedout'}, ' '+mt('_js_ds_tag_meta')) : null, - item.getAttribute('state') == 0 ? tag('b', {'class': 'grayedout'}, ' '+mt('_js_ds_tag_mod')) : null - )); - }; - var serfunc = function(item, obj) { - var tags = obj.value.split(/ *, */); - tags[tags.length-1] = item.firstChild.nodeValue; - return tags.join(', '); - }; - var retfunc = function() { false; }; - var parfunc = function(val) { - return (val.split(/, */))[val.split(/, */).length-1]; - }; - dsInit(byId('ti'), '/xml/tags.xml?q=', trfunc, serfunc, retfunc, parfunc); - dsInit(byId('te'), '/xml/tags.xml?q=', trfunc, serfunc, retfunc, parfunc); -} - // Language selector if(byId('lang_select')) { var d = byId('lang_select'); diff --git a/data/style.css b/data/style.css index 243e15e5..b4f3a9ad 100644 --- a/data/style.css +++ b/data/style.css @@ -751,6 +751,7 @@ a.addnew { border-top: none; background-color: $secbg$; cursor: pointer; + z-index: 2 } #ds_box b { padding: 2px 0 0 10px; @@ -789,35 +790,13 @@ div.scr_uploader { visibility: hidden; overflow: hidden; width: 1px; height: 1px .vnbrowse .tc3 { padding: 0; } .vnbrowse .tc5 { text-align: right; padding-right: 10px } .vnbrowse .tc6 { width: 80px } -#advselect, #filselect { +#filselect { text-align: center; display: block; margin: 10px auto 3px auto; border: none; outline: none; } -#advoptions { - width: 90%; - padding: 0 30px 5px 30px; - margin: 0 auto; - border-top: 1px solid $border$; -} -#advoptions h2 { - clear: left; - padding-top: 10px; - margin-left: -20px; - margin-top: 0; - margin-bottom: 3px; -} -#advoptions span { - display: block; - float: left; - width: 170px; -} -#advoptions span input { - margin-right: 3px; -} - diff --git a/lib/VNDB/DB/VN.pm b/lib/VNDB/DB/VN.pm index 6d99ba8a..11b7c29a 100644 --- a/lib/VNDB/DB/VN.pm +++ b/lib/VNDB/DB/VN.pm @@ -10,7 +10,7 @@ use Encode 'decode_utf8'; our @EXPORT = qw|dbVNGet dbVNRevisionInsert dbVNImageId dbScreenshotAdd dbScreenshotGet dbScreenshotRandom|; -# Options: id, rev, char, search, lang, platform, tags_include, tags_exclude, results, page, what, sort, reverse +# Options: id, rev, char, search, lang, plat, tags_include, tags_exclude, results, page, what, sort, reverse # What: extended anime relations screenshots relgraph rating ranking changes # Sort: id rel pop rating title tagscore rand sub dbVNGet { @@ -29,10 +29,10 @@ sub dbVNGet { 'LOWER(SUBSTR(vr.title, 1, 1)) = ?' => $o{char} ) : (), defined $o{char} && !$o{char} ? ( '(ASCII(vr.title) < 97 OR ASCII(vr.title) > 122) AND (ASCII(vr.title) < 65 OR ASCII(vr.title) > 90)' => 1 ) : (), - $o{lang} && @{$o{lang}} ? ( - 'v.c_languages && ARRAY[!l]::language[]' => [ $o{lang} ]) : (), - $o{platform} && @{$o{platform}} ? ( - '('.join(' OR ', map "v.c_platforms ILIKE '%%$_%%'", @{$o{platform}}).')' => 1 ) : (), + $o{lang} ? ( + 'v.c_languages && ARRAY[!l]::language[]' => [ ref $o{lang} ? $o{lang} : [$o{lang}] ]) : (), + $o{plat} ? ( + '('.join(' OR ', map "v.c_platforms ILIKE '%%$_%%'", ref $o{plat} ? @{$o{plat}} : $o{plat}).')' => 1 ) : (), $o{tags_include} && @{$o{tags_include}} ? ( 'v.id IN(SELECT vid FROM tags_vn_inherit WHERE tag IN(!l) AND spoiler <= ? GROUP BY vid HAVING COUNT(tag) = ?)', [ $o{tags_include}[1], $o{tags_include}[0], $#{$o{tags_include}[1]}+1 ] diff --git a/lib/VNDB/Func.pm b/lib/VNDB/Func.pm index 11d442f4..65b66f9e 100644 --- a/lib/VNDB/Func.pm +++ b/lib/VNDB/Func.pm @@ -13,7 +13,7 @@ our @EXPORT = (@VNDBUtil::EXPORT, qw| liststat clearfloat cssicon tagscore mt mi # three ways to represent the same information our $fil_escape = '_ !"#$%&\'()*+,-./:;<=>?@[\]^`{}~'; our @fil_escape = split //, $fil_escape; -our %fil_escape = map +($fil_escape[$_], $_), 0..$#fil_escape; +our %fil_escape = map +($fil_escape[$_], sprintf '%02d', $_), 0..$#fil_escape; # Argument: hashref with rstat and vstat diff --git a/lib/VNDB/Handler/Releases.pm b/lib/VNDB/Handler/Releases.pm index 497c96de..cd3ea73c 100644 --- a/lib/VNDB/Handler/Releases.pm +++ b/lib/VNDB/Handler/Releases.pm @@ -511,7 +511,7 @@ sub browse { div class => 'mainbox'; h1 mt '_rbrowse_title'; $self->htmlSearchBox('r', $f->{q}); - a id => 'filselect', href => '#'; + a id => 'filselect', href => '#r'; lit '<i>▸</i> '.mt('_rbrowse_filters').'<i></i>'; end; input type => 'hidden', class => 'hidden', name => 'fil', id => 'fil', value => $f->{fil}; diff --git a/lib/VNDB/Handler/VNBrowse.pm b/lib/VNDB/Handler/VNBrowse.pm index f3193b57..3a8ae7d5 100644 --- a/lib/VNDB/Handler/VNBrowse.pm +++ b/lib/VNDB/Handler/VNBrowse.pm @@ -21,14 +21,12 @@ sub list { { name => 'p', required => 0, default => 1, template => 'int' }, { name => 'q', required => 0, default => '' }, { name => 'sq', required => 0, default => '' }, - { name => 'ln', required => 0, multi => 1, enum => $self->{languages}, default => '' }, - { name => 'pl', required => 0, multi => 1, enum => $self->{platforms}, default => '' }, - { name => 'ti', required => 0, default => '', maxlength => 200 }, - { name => 'te', required => 0, default => '', maxlength => 200 }, - { name => 'sp', required => 0, default => $self->reqCookie($self->{cookie_prefix}.'tagspoil') =~ /^([0-2])$/ ? $1 : 0, enum => [0..2] }, + { name => 'fil',required => 0, default => '' }, ); return 404 if $f->{_err}; $f->{q} ||= $f->{sq}; + my $fil = fil_parse $f->{fil}, qw|taginc tagexc tagspoil lang plat|; + _fil_compat($self, $fil); if($f->{q}) { return $self->resRedirect('/'.$1.$2.(!$3 ? '' : $1 eq 'd' ? '#'.$3 : '.'.$3), 'temp') @@ -37,9 +35,11 @@ sub list { # for URL compatibilty with older versions (ugly hack to get English strings) my @lang; $f->{q} =~ s/\s*$VNDB::L10N::en::Lexicon{"_lang_$_"}\s*//&&push @lang, $_ for (@{$self->{languages}}); - $f->{ln} = $f->{ln}[0] ? [ @{$f->{ln}}, @lang ] : \@lang; + $fil->{lang} = $fil->{lang} ? [ ref($fil->{lang}) ? @{$fil->{lang}} : $fil->{lang}, @lang ] : \@lang; } + $f->{fil} = fil_serialize $fil; + # TODO: this should be moved to dbVNGet() in order for savable VN filters to be useful my @ignored; my $tagfind = sub { return map { @@ -47,10 +47,10 @@ sub list { push @ignored, [$_, 0] if !$i; push @ignored, [$_, 1] if $i && $i->{meta}; $i && !$i->{meta} ? $i->{id} : (); - } grep $_, split /\s*,\s*/, $_[0]; + } grep $_, ref $_[0] ? @{$_[0]} : ($_[0]||'') }; - my @ti = $tagfind->($f->{ti}); - my @te = $tagfind->($f->{te}); + my @ti = $tagfind->(delete $fil->{taginc}); + my @te = $tagfind->(delete $fil->{tagexc}); $f->{s} = 'title' if !@ti && $f->{s} eq 'tagscore'; $f->{o} = $f->{s} eq 'tagscore' ? 'd' : 'a' if !$f->{o}; @@ -62,28 +62,15 @@ sub list { results => 50, page => $f->{p}, sort => $f->{s}, reverse => $f->{o} eq 'd', - $f->{pl}[0] ? ( platform => $f->{pl} ) : (), - $f->{ln}[0] ? ( lang => $f->{ln} ) : (), - @ti ? (tags_include => [ $f->{sp}, \@ti ]) : (), + @ti ? (tags_include => [ delete $fil->{tagspoil}, \@ti ]) : (), @te ? (tags_exclude => \@te) : (), + %$fil ); $self->resRedirect('/v'.$list->[0]{id}, 'temp') if $f->{q} && @$list == 1 && $f->{p} == 1; $self->htmlHeader(title => mt('_vnbrowse_title'), search => $f->{q}); - _filters($self, $f, $char, \@ignored); - - my $url = "/v/$char?q=$f->{q};ti=$f->{ti};te=$f->{te}"; - $_ and $url .= ";pl=$_" for @{$f->{pl}}; - $_ and $url .= ";ln=$_" for @{$f->{ln}}; - $self->htmlBrowseVN($list, $f, $np, $url, scalar @ti); - $self->htmlFooter; -} - - -sub _filters { - my($self, $f, $char, $ign) = @_; form action => '/v/all', 'accept-charset' => 'UTF-8', method => 'get'; div class => 'mainbox'; @@ -95,68 +82,41 @@ sub _filters { } end; - if(@$ign) { + if(@ignored) { div class => 'warning'; h2 mt '_vnbrowse_tagign_title'; ul; - li $_->[0].' ('.mt('_vnbrowse_tagign_'.($_->[1]?'meta':'notfound')).')' for @$ign; + li $_->[0].' ('.mt('_vnbrowse_tagign_'.($_->[1]?'meta':'notfound')).')' for @ignored; end; end; } - a id => 'advselect', href => '#'; - lit '<i>▸</i> '.mt('_vnbrowse_advsearch'); + a id => 'filselect', href => '#v'; + lit '<i>▸</i> '.mt('_rbrowse_filters').'<i></i>'; # TODO: it's not *r*browse end; - div id => 'advoptions', class => 'hidden vnoptions'; - - h2; - txt mt '_vnbrowse_tags'; - b ' ('.mt('_vnbrowse_booland').')'; - end; - table class => 'formtable', style => 'margin-left: 0'; - $self->htmlFormPart($f, [ input => short => 'ti', name => mt('_vnbrowse_taginc'), width => 350 ]); - $self->htmlFormPart($f, [ radio => short => 'sp', name => '', options => [map [$_, mt '_vnbrowse_spoil'.$_], 0..2]]); - $self->htmlFormPart($f, [ input => short => 'te', name => mt('_vnbrowse_tagexc'), width => 350 ]); - end; - - h2; - txt mt '_vnbrowse_lang'; - b ' ('.mt('_vnbrowse_boolor').')'; - end; - for my $i (@{$self->{languages}}) { - span; - input type => 'checkbox', name => 'ln', value => $i, id => "lang_$i", - (scalar grep $_ eq $i, @{$f->{ln}}) ? (checked => 'checked') : (); - label for => "lang_$i"; - cssicon "lang $i", mt "_lang_$i"; - txt mt "_lang_$i"; - end; - end; - } + input type => 'hidden', class => 'hidden', name => 'fil', id => 'fil', value => $f->{fil}; + end; + end; # /form - h2; - txt mt '_vnbrowse_plat'; - b ' ('.mt('_vnbrowse_boolor').')'; - end; - for my $i (sort @{$self->{platforms}}) { - next if $i eq 'oth'; - span; - input type => 'checkbox', id => "plat_$i", name => 'pl', value => $i, - (scalar grep $_ eq $i, @{$f->{pl}}) ? (checked => 'checked') : (); - label for => "plat_$i"; - cssicon $i, mt "_plat_$i"; - txt mt "_plat_$i"; - end; - end; - } + $self->htmlBrowseVN($list, $f, $np, "/v/$char?q=$f->{q};fil=$f->{fil}", scalar @ti); + $self->htmlFooter; +} - div style => 'text-align: center; clear: left;'; - input type => 'submit', value => mt('_vnbrowse_apply'), class => 'submit'; - input type => 'reset', value => mt('_vnbrowse_clear'), class => 'submit', onclick => 'location.href="/v/all"'; - end; - end; - end; - end; + +sub _fil_compat { + my($self, $fil) = @_; + my $f = $self->formValidate( + { name => 'ln', required => 0, multi => 1, enum => $self->{languages}, default => '' }, + { name => 'pl', required => 0, multi => 1, enum => $self->{platforms}, default => '' }, + { name => 'ti', required => 0, default => '', maxlength => 200 }, + { name => 'te', required => 0, default => '', maxlength => 200 }, + { name => 'sp', required => 0, default => $self->reqCookie($self->{cookie_prefix}.'tagspoil') =~ /^([0-2])$/ ? $1 : 0, enum => [0..2] }, + ); + $fil->{lang} //= $f->{ln} if $f->{ln}[0]; + $fil->{plat} //= $f->{pl} if $f->{pl}[0]; + $fil->{taginc} //= $f->{ti} if $f->{ti}; + $fil->{tagexc} //= $f->{te} if $f->{te}; + $fil->{tagspoil} //= $f->{sp}; } |