From d7faec10cb85ad286673eec266ccc397142bc20c Mon Sep 17 00:00:00 2001 From: Marcin Koziej <marcin.koziej@nowoczesnapolska.org.pl> Date: Wed, 9 May 2012 11:00:24 +0200 Subject: [PATCH] menu shows, time to code js to it --- apps/catalogue/templates/catalogue/base.html | 4 +- .../templates/catalogue/book_list/book.html | 2 + .../catalogue/book_list/book_list.html | 8 + .../templates/catalogue/book_list/chunk.html | 1 + .../templates/catalogue/document_list.html | 9 + apps/catalogue/urls.py | 2 + apps/catalogue/views.py | 21 ++ redakcja/settings/compress.py | 18 +- redakcja/static/contextmenu2/images/cut.png | Bin 0 -> 648 bytes redakcja/static/contextmenu2/images/door.png | Bin 0 -> 412 bytes .../contextmenu2/images/page_white_copy.png | Bin 0 -> 309 bytes .../contextmenu2/images/page_white_delete.png | Bin 0 -> 536 bytes .../contextmenu2/images/page_white_edit.png | Bin 0 -> 618 bytes .../contextmenu2/images/page_white_paste.png | Bin 0 -> 620 bytes redakcja/static/contextmenu2/index.html | 200 +++++++++++++++++ .../contextmenu2/jquery.contextMenu.css | 62 +++++ .../static/contextmenu2/jquery.contextMenu.js | 211 ++++++++++++++++++ redakcja/static/js/catalogue/book_list.js | 56 +++++ 18 files changed, 591 insertions(+), 3 deletions(-) create mode 100644 redakcja/static/contextmenu2/images/cut.png create mode 100644 redakcja/static/contextmenu2/images/door.png create mode 100644 redakcja/static/contextmenu2/images/page_white_copy.png create mode 100644 redakcja/static/contextmenu2/images/page_white_delete.png create mode 100644 redakcja/static/contextmenu2/images/page_white_edit.png create mode 100644 redakcja/static/contextmenu2/images/page_white_paste.png create mode 100644 redakcja/static/contextmenu2/index.html create mode 100644 redakcja/static/contextmenu2/jquery.contextMenu.css create mode 100644 redakcja/static/contextmenu2/jquery.contextMenu.js create mode 100644 redakcja/static/js/catalogue/book_list.js diff --git a/apps/catalogue/templates/catalogue/base.html b/apps/catalogue/templates/catalogue/base.html index f3ebcd98..949b5f29 100644 --- a/apps/catalogue/templates/catalogue/base.html +++ b/apps/catalogue/templates/catalogue/base.html @@ -6,6 +6,7 @@ <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> {% compressed_css 'catalogue' %} <title>{% block title %}{% trans "Platforma Redakcyjna" %}{% endblock title %}</title> + {% block add_css %}{% endblock %} </head> <body> @@ -42,8 +43,9 @@ </div> -<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script> +<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> {% compressed_js 'catalogue' %} +{% block add_js %}{% endblock %} {% block extrabody %} {% endblock %} </body> diff --git a/apps/catalogue/templates/catalogue/book_list/book.html b/apps/catalogue/templates/catalogue/book_list/book.html index 46d5ae12..44534541 100755 --- a/apps/catalogue/templates/catalogue/book_list/book.html +++ b/apps/catalogue/templates/catalogue/book_list/book.html @@ -3,6 +3,7 @@ {% if book.single %} {% with book.0 as chunk %} <tr> + <td><input type="checkbox" name="select_book" value="{{book.id}}"/></td> <td><a href="{% url catalogue_book book.slug %}" title='{% trans "Book settings" %}'>[B]</a></td> <td><a href="{% url catalogue_chunk_edit book.slug chunk.slug %}" title='{% trans "Chunk settings" %}'>[c]</a></td> <td><a target="_blank" @@ -22,6 +23,7 @@ {% endwith %} {% else %} <tr> + <td><input type="checkbox" name="select_book" value="{{book.id}}"/></td> <td class='book-settings-link'><a href="{% url catalogue_book book.slug %}" title='{% trans "Book settings" %}'>[B]</a></td> <td></td> <td>{{ book.title }}</td> diff --git a/apps/catalogue/templates/catalogue/book_list/book_list.html b/apps/catalogue/templates/catalogue/book_list/book_list.html index 73811cab..ad8cbf94 100755 --- a/apps/catalogue/templates/catalogue/book_list/book_list.html +++ b/apps/catalogue/templates/catalogue/book_list/book_list.html @@ -12,8 +12,10 @@ <input type='hidden' name="status" value="{{ request.GET.status }}" /> </form> + <table id="file-list"{% if viewed_user %} class="book-list-user"{% endif %}> <thead><tr> + <th></th> <th></th> <th> <input class='check-filter' type='checkbox' name='all' title='{% trans "Show hidden books" %}' @@ -79,3 +81,9 @@ {% if not books %} <p>{% trans "No books found." %}</p> {% endif %} + +<form name='chunk_mass_edit' action='{% url catalogue_chunk_mass_edit %}' class="hidden"> +{% csrf_token %} +<input type="hidden" name="ids" /> +<input type="hidden" stage="stage" /> +</form> diff --git a/apps/catalogue/templates/catalogue/book_list/chunk.html b/apps/catalogue/templates/catalogue/book_list/chunk.html index 14599428..fc893fdf 100755 --- a/apps/catalogue/templates/catalogue/book_list/chunk.html +++ b/apps/catalogue/templates/catalogue/book_list/chunk.html @@ -1,6 +1,7 @@ {% load i18n %} <tr> + <td><input type="checkbox" name="select_chunk" value="{{chunk.id}}" data-book-id="{{chunk.book.id}}" /></td> <td class='book-settings-column'></td> <td><a href="{% url catalogue_chunk_edit chunk.book.slug chunk.slug %}" title='{% trans "Chunk settings" %}'>[c]</a></td> <td><a target="_blank" href="{{ chunk.get_absolute_url }}"> diff --git a/apps/catalogue/templates/catalogue/document_list.html b/apps/catalogue/templates/catalogue/document_list.html index 920f25a6..294c6299 100644 --- a/apps/catalogue/templates/catalogue/document_list.html +++ b/apps/catalogue/templates/catalogue/document_list.html @@ -2,8 +2,17 @@ {% load i18n %} {% load catalogue book_list %} +{% load compressed %} +{% block add_js %} +{% compressed_js 'book_list' %} +{% endblock %} + +{% block add_css %} +{% compressed_css 'book_list' %} +{% endblock %} + {% block content %} {% book_list %} {% endblock content %} diff --git a/apps/catalogue/urls.py b/apps/catalogue/urls.py index 9bd56bbe..14e4a69a 100644 --- a/apps/catalogue/urls.py +++ b/apps/catalogue/urls.py @@ -39,6 +39,8 @@ urlpatterns = patterns('catalogue.views', 'chunk_edit', name="catalogue_chunk_edit"), url(r'^book_append/(?P<slug>[^/]+)/$', 'book_append', name="catalogue_book_append"), + url(r'^chunk_mass_edit', + 'chunk_mass_edit', name='catalogue_chunk_mass_edit'), url(r'^track/(?P<slug>[^/]*)/$', PublishTrackFeed()), ) diff --git a/apps/catalogue/views.py b/apps/catalogue/views.py index d0213daa..f8ff5996 100644 --- a/apps/catalogue/views.py +++ b/apps/catalogue/views.py @@ -10,6 +10,7 @@ from django.contrib.auth.models import User from django.contrib.auth.decorators import login_required, permission_required from django.core.urlresolvers import reverse from django.db.models import Count, Q +from django.db import transaction from django import http from django.http import Http404, HttpResponse, HttpResponseForbidden from django.shortcuts import get_object_or_404, render, render_to_response @@ -387,6 +388,26 @@ def chunk_edit(request, slug, chunk): }) +@transaction.commit_on_success +def chunk_mass_edit(request): + if request.method == 'POST': + ids = map(int, request.POST.get('ids').split(',')) + chunks = map(lambda i: Chunk.objects.get(id=i), ids) + try: + stage = Chunk.tag_model.objects.get(slug=request.POST.get('stage')) + for c in chunks: c.stage = stage + except KeyError: pass + + try: + user = User.objects.get(username=request.POST.get('user')) + for c in chunks: c.user = user + except KeyError: pass + + for c in chunks: c.save() + else: + raise Http404 + + @permission_required('catalogue.change_book') def book_append(request, slug): book = get_object_or_404(Book, slug=slug) diff --git a/redakcja/settings/compress.py b/redakcja/settings/compress.py index bdcf44bb..d0f0df9f 100644 --- a/redakcja/settings/compress.py +++ b/redakcja/settings/compress.py @@ -24,7 +24,13 @@ COMPRESS_CSS = { 'css/book.css', ), 'output_filename': 'compressed/book_?.css', - } + }, + 'book_list': { + 'source_filenames': ( + 'contextmenu/jquery.contextMenu.css', + ), + 'output_filename': 'compressed/book_list_?.css', + }, } COMPRESS_JS = { @@ -80,7 +86,15 @@ COMPRESS_JS = { 'js/book_text/book.js', ), 'output_filename': 'compressed/book_?.js', - } + }, + 'book_list': { + 'source_filenames': ( + 'contextmenu/jquery.ui.position.js', + 'contextmenu/jquery.contextMenu.js', + 'js/catalogue/book_list.js', + ), + 'output_filename': 'compressed/book_list_?.js', + } } COMPRESS = True diff --git a/redakcja/static/contextmenu2/images/cut.png b/redakcja/static/contextmenu2/images/cut.png new file mode 100644 index 0000000000000000000000000000000000000000..f215d6f6b7c81ab344a3e53e0e5e756c58c82d90 GIT binary patch literal 648 zcmV;30(bq1P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004XF*Lt006JZ zHwB960000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU!8c9S!R5;6H z`2YVu11_wZHB-y3digxb#7V5U)G**Pz^-~(X8XF+PefuTa3YI~Crn}@$^hrOm3edb zT>Sxb0Y6MkDSd{nPwTp^L>b`TxVmKBiF^NLQ>My+_!0?|)hBPe_#}P$?rlUF;M20U z`oNWE|K(DrsR+gN%g)?+`OfqmmmiA8O_U(YfPnV(E$8mN{jZQVJ-L7LxzmTQJ^!PS zHqDyoKn&^H)Oq>Q$Nzns&wsn~^6P)|vPC&W#R9Kw95|FC`?q!91!~-K_R;^uDLWSs zj7A}sG%2IZxvQP(HeS-nn71T-`ku2F9(?#8KXKbp!Qe&~yaot4r%3=c-cDF`=YPn& z3!hUrzxqFO*Ny)VU;p?Y-nniMuVuI+UIUD>=B$ZZdhM^2Z-JeJcb<R3+9&^K@4fSX z>Dl-H)3?9>AG_?ve_7A86r2Wlb?y7)ShoTkzeah}rl)Oq{=a0=sekDkpZ?d4n{v>% zcgJPxg7sgx4Lmup8sO5j^?B5iYcCv|)*VgT_U6A?-trsfIcr`APCfD&B(EM;R_0K# z{lAb!kTg~U<bun?0;eB;6SeHdKeL==r@2f6B}_9`JPcoO@fW9-qnue*-yHkWEq{28 zeFbpFf{1IngqTN`0*tR8H~(1jrsx0tC+&ZlwEFIUqohSQNXm^ohF<K3i3_gVmu>rQ ilDgypkCC?sx*7n<IG)#?gSv?T0000<MNUMnLSTYqRz!RN literal 0 HcmV?d00001 diff --git a/redakcja/static/contextmenu2/images/door.png b/redakcja/static/contextmenu2/images/door.png new file mode 100644 index 0000000000000000000000000000000000000000..369fc46ed259191014664e8a16bea76e7513f8b6 GIT binary patch literal 412 zcmV;N0b~A&P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004XF*Lt006JZ zHwB960000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzE=fc|R5;6} zlRZiVK@@~*{6W{iWkmxO4`O8CF+7B!xmVcSBN%UD<Q)VtG7uGH!Dw{et15#YXIIc! zVIMTFJE{Jv`gLU+%hU>%thM>W-PO4z!6ryTDvQjnlZlgy>*`kliP$?n1x#3mBv=H* zZvSv|{Wk%bFo}=%C%C=cB-|2gZto+r=@*a)F<})kF(DFGf{cEF%qX{I6ar>BlQ09$ zKtwM=E70{BMdbz}7ZEfCIhx`>6H;PlIK|<?8y=sB$c%mqYAtm5Dt$T~p#EI{4?%$0 z{IKx)vH^1yTf6Efh-hXZGTQK3A(cHD3kb4gV3qX0DXj9e3o<Ac2BRa`f|;;XmI<+p z^L$mdF_}zU*EQnyvYYq$`Jep>!Y1xVX8?flcwAM>e&;Vo+<mi;5kDUQ0000<MNUMn GLSTZ8Af{~q literal 0 HcmV?d00001 diff --git a/redakcja/static/contextmenu2/images/page_white_copy.png b/redakcja/static/contextmenu2/images/page_white_copy.png new file mode 100644 index 0000000000000000000000000000000000000000..a9f31a278e17993d8d4e13beac2f9d5f7b42d08f GIT binary patch literal 309 zcmV-50m}Y~P)<h;3K|Lk000e1NJLTq000mG000mO1ONa4wfZ;e00004XF*Lt006JZ zHwB960000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUy$4Nv%R4C7N zkxg#GFcb#A<Q_%21Hw5EM?&g?t8|A@3u~?cLP(?}@sBiJIM^nrnvECZ=aHYZ&`KuJ zs758y%Gp3<<a0AuBoi3uxN#=Xv)!n96GnROTnGd_YE`RJRS2Gu2X{_<aYSpixkobb z-bl|5$Gm3}qO#|`CkX+|H?KVbnL=><kbAD2OTpuD9LPN#xA_FmF`X<uzmw3UZ*H~D z&sl~jAXO8!+C0tSo<jQ6D)&VG5i+*Z@^!UMv3Mh+r9S=u_uEaN=S{!n00000NkvXX Hu0mjfd8B?p literal 0 HcmV?d00001 diff --git a/redakcja/static/contextmenu2/images/page_white_delete.png b/redakcja/static/contextmenu2/images/page_white_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..af1ecaf2981fa37628c8b8b15ee389f9575e5f6b GIT binary patch literal 536 zcmV+z0_XjSP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004XF*Lt006JZ zHwB960000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzs!2paR5;6( zlRHa7VHn5NqaUEDhHgSb1WkrbLTI-60g9F=A_y89lv>(?iiXTHIMmcoLoO94I8;j@ zv^2DJ5#orqydFJX|Gm$_Bi_vyew+j6{r}$Qc@D1%fQqeAhJj)1!z4pP83k2MV2~s! zSt^w(<#HLFVBg_#xz1W8ioi(WY&Hu~6zil?DI^jJgu`K35(<UD^L&$pmYM{#A)n8q zP$<YxB9qA=nM@)QiO7OnE(bcq?RLwOHUWhdNI-#fI*n*F+SXESCh8^uYooq_-l=b; zl~^n$S0V^PcR?$S5~_se5s%0JFKCodJ2Vp#4J06n#iBeHk`Mz6sEY4fCtlWO;J4`T zv@!vHUc>hkP)H%@Imesbg#5!Ps_$Ni*SiR8&sKb9?M`0-mH)gtg&YgRX#*TXz@Z+| z;|2H@xzE0TfuORhuO2k6#K8#sW^J`mQ0+E@$K`QkFV+DTlI$w{GJ;zid{*v9xeIe_ z$|Bp`@iKkgoFK3{4Z)#DWKV~W4K@5WZN+Ql_7%YxNqSx7%cWud&cX>)_PvD*UzxZg a%Kia9Rjz_59@~-t0000<MNUMnLSTY4li~gV literal 0 HcmV?d00001 diff --git a/redakcja/static/contextmenu2/images/page_white_edit.png b/redakcja/static/contextmenu2/images/page_white_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..b93e77600def75c9a144d3d0a5088a62c02cbb0b GIT binary patch literal 618 zcmV-w0+s!VP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004XF*Lt006JZ zHwB960000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUz{7FPXR5;6x zliy2IVHn3(e?>$>5Y&axjp2O=VLu>*f>1L;s0)kkvKC!*u?s6CVL=HJ6oP~pNfZc; zsKr=bq;7MITw8NXw{SZ<XXl*#?9=-mwz0{k9{6w$ywCS@-simMu>m%59TId2x_9BQ zV86`NuvG<J`Fvg}l}eRzxlAj>I!>o^V!Na!=$7GJE{Cq`b+XwknM{UcGHFTTfmuS+ zm-zYC!P3+zmY;SG$?!fYkOih`QYaLxyF}A86h$GGN}<Kyu;Cg-S$PLqg3QV+p2xkL zO#&INAq9qEpsFgHKW0d;KA^BZ&&H=m7`{2mQ8&I9*UTn?Xrtb<e3pGH>kFj)_o*0e zjPMP%zTG7FYMAfO2Nn1D`D0Cj?Wl>5q<wd(m>%@CE10nX)KxpNmwk+!IWkzywiYD( zqUXiYYIq3qcRyMGJ;IY`(Gz~E$J$zu2+R{)xGlE*88b3WK6V*J>}2iPY1HH|tER0W z_+^^FdppY?o)Gt5M2`%xwRDH@R3G}^i1l4|6uchm0X0f!@&YdVLB5K&dd7Rv{)DXX zt^&vP;}kqj3f>94j+4xd93>s|Q!Ezi>?r8(Il$P}PFxSqu{d*!Y%*#cX(R0f|Juz# z3o0_xI14Al->1uky@W-rCI_%l&><yz80Q*t^gCqsKOt_NEc}hgZ~y=R07*qoM6N<$ Ef@@nDvH$=8 literal 0 HcmV?d00001 diff --git a/redakcja/static/contextmenu2/images/page_white_paste.png b/redakcja/static/contextmenu2/images/page_white_paste.png new file mode 100644 index 0000000000000000000000000000000000000000..5b2cbb3fd02a5e708d9f9de4ea118965972a02b0 GIT binary patch literal 620 zcmV-y0+aoTP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004XF*Lt006JZ zHwB960000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUz{z*hZR5;6Z zk~?TrQ4of|lY6;w$wtB@#23+sogj#yT`Fr|!OC)7$QB{Bq)AG<1uKQ^1R;e%5DS}t zSSbiLwk}CPNOpy+y6EQ2nX$O{?juVE4s(k0e>4A_ab^a<i|Xa8z&FODv)pLTa6-7} zj~8wL8^E1%dWJ`9>vY?n0hpS-#mn_4{O$e%cm-@NH=3`90Wq+3`~HKArSdfX`&Z12 z(CY$VW-MNtXX4xy%<SR&H*fC(V}MJg@@bBKA0R3;H|t;q7;XE4n&J2NI5m4AF-V+q z&I;c-05o7COw61`gJ7ooXm|P9`G*0ze~8-?c3M4vo6fldVAsqv1~64r1ob`C_rQ!+ z>yUeE?}*~0-|iByA@ZrwXgph4S*bhcc5{HB!DFVm_v}P*g7+Q~K}7K0lcp(^N@X>U zV`{ZpeIf${R6Hgg4FL^`X$Eu75k(PE6ycl$AW0Ic)#@rR7Z(7;V?i-dR1K935Jgcx zPfkwK>2wGokf!Nih^ARp6-6arYFG#(9Ta!x93nFEjoA==z(g?#sDg?Owk?Mg7K+>l zWYsf(<`#+$h9Sp6gFOg_dd+80SkUpk&xM7h0`Sov9W73spU;G<m_o_7`j3VdZ=`ww zc=};`dm6aj7XUl09!n>P073|VfZ&Gd$J$*0<~TV5aPS|qWH57|VJz+d0000<MNUMn GLSTY;sS5i5 literal 0 HcmV?d00001 diff --git a/redakcja/static/contextmenu2/index.html b/redakcja/static/contextmenu2/index.html new file mode 100644 index 00000000..4efa62b8 --- /dev/null +++ b/redakcja/static/contextmenu2/index.html @@ -0,0 +1,200 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml"> + + <head> + <title>jQuery Context Menu Plugin Demo</title> + <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> + + <style type="text/css"> + BODY, + HTML { + padding: 0px; + margin: 0px; + } + BODY { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 11px; + background: #FFF; + padding: 15px; + } + + H1 { + font-family: Georgia, serif; + font-size: 20px; + font-weight: normal; + } + + H2 { + font-family: Georgia, serif; + font-size: 16px; + font-weight: normal; + margin: 0px 0px 10px 0px; + } + + #myDiv { + width: 150px; + border: solid 1px #2AA7DE; + background: #6CC8EF; + text-align: center; + padding: 4em .5em; + margin: 1em; + float: left; + } + + #myList { + margin: 1em; + float: left; + } + + #myList UL { + padding: 0px; + margin: 0em 1em; + } + + #myList LI { + width: 100px; + border: solid 1px #2AA7DE; + background: #6CC8EF; + padding: 5px 5px; + margin: 2px 0px; + list-style: none; + } + + #options { + clear: left; + } + + #options INPUT { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 11px; + width: 150px; + } + + </style> + + <script src="../js/lib/jquery-1.4.2.min.js" type="text/javascript"></script> + <script src="jquery.contextMenu.js" type="text/javascript"></script> + <link href="jquery.contextMenu.css" rel="stylesheet" type="text/css" /> + + <script type="text/javascript"> + + $(document).ready( function() { + + // Show menu when #myDiv is clicked + $("#myDiv").contextMenu({ + menu: 'myMenu' + }, + function(action, el, pos) { + alert( + 'Action: ' + action + '\n\n' + + 'Element ID: ' + $(el).attr('id') + '\n\n' + + 'X: ' + pos.x + ' Y: ' + pos.y + ' (relative to element)\n\n' + + 'X: ' + pos.docX + ' Y: ' + pos.docY+ ' (relative to document)' + ); + }); + + // Show menu when a list item is clicked + $("#myList UL LI").contextMenu({ + menu: 'myMenu' + }, function(action, el, pos) { + alert( + 'Action: ' + action + '\n\n' + + 'Element text: ' + $(el).text() + '\n\n' + + 'X: ' + pos.x + ' Y: ' + pos.y + ' (relative to element)\n\n' + + 'X: ' + pos.docX + ' Y: ' + pos.docY+ ' (relative to document)' + ); + }); + + // Disable menus + $("#disableMenus").click( function() { + $('#myDiv, #myList UL LI').disableContextMenu(); + $(this).attr('disabled', true); + $("#enableMenus").attr('disabled', false); + }); + + // Enable menus + $("#enableMenus").click( function() { + $('#myDiv, #myList UL LI').enableContextMenu(); + $(this).attr('disabled', true); + $("#disableMenus").attr('disabled', false); + }); + + // Disable cut/copy + $("#disableItems").click( function() { + $('#myMenu').disableContextMenuItems('#cut,#copy'); + $(this).attr('disabled', true); + $("#enableItems").attr('disabled', false); + }); + + // Enable cut/copy + $("#enableItems").click( function() { + $('#myMenu').enableContextMenuItems('#cut,#copy'); + $(this).attr('disabled', true); + $("#disableItems").attr('disabled', false); + }); + + }); + + </script> + </head> + + <body> + + <h1>jQuery Context Menu Plugin Demo</h1> + <p> + This plugin lets you add context menu functionality to your web applications. + </p> + + <p> + <strong>Tip:</strong> Try using your keyboard to make a selection. + </p> + + <p> + <a href="http://abeautifulsite.net/2008/09/jquery-context-menu-plugin/">Back to the project page</a> + </p> + + <h2>Demo</h2> + + <div id="myDiv"> + Right click to view the context menu + </div> + + <div id="myList"> + <ul> + <li>Item 1</li> + <li>Item 2</li> + <li>Item 3</li> + <li>Item 4</li> + <li>Item 5</li> + <li>Item 6</li> + </ul> + </div> + + <div id="options"> + <p> + <input type="button" id="disableItems" value="Disable Cut/Copy" /> + <input type="button" id="enableItems" value="Enable Cut/Copy" disabled="disabled" /> + </p> + + <p> + <input type="button" id="disableMenus" value="Disable Context Menus" /> + <input type="button" id="enableMenus" value="Enable Context Menus" disabled="disabled" /> + </p> + </div> + + <ul id="myMenu" class="contextMenu"> + <li class="edit"><a href="#edit">Edit</a></li> + <li class="cut separator"><a href="#cut">Cut</a> + <ul> + <li class="pe"><a href="#pe">Pe</a></li> + </ul> + </li> + <li class="copy"><a href="#copy">Copy</a></li> + <li class="paste"><a href="#paste">Paste</a></li> + <li class="delete"><a href="#delete">Delete</a></li> + <li class="quit separator"><a href="#quit">Quit</a></li> + </ul> + + </body> +</html> diff --git a/redakcja/static/contextmenu2/jquery.contextMenu.css b/redakcja/static/contextmenu2/jquery.contextMenu.css new file mode 100644 index 00000000..5b2dd906 --- /dev/null +++ b/redakcja/static/contextmenu2/jquery.contextMenu.css @@ -0,0 +1,62 @@ +/* Generic context menu styles */ +.contextMenu { + position: absolute; + width: 120px; + z-index: 99999; + border: solid 1px #CCC; + background: #EEE; + padding: 0px; + margin: 0px; + display: none; +} + +.contextMenu LI { + list-style: none; + padding: 0px; + margin: 0px; +} + +.contextMenu A { + color: #333; + text-decoration: none; + display: block; + line-height: 20px; + height: 20px; + background-position: 6px center; + background-repeat: no-repeat; + outline: none; + padding: 1px 5px; + padding-left: 28px; +} + +.contextMenu LI.hover A { + color: #FFF; + background-color: #3399FF; +} + +.contextMenu LI.disabled A { + color: #AAA; + cursor: default; +} + +.contextMenu LI.hover.disabled A { + background-color: transparent; +} + +.contextMenu LI.separator { + border-top: solid 1px #CCC; +} + +/* + Adding Icons + + You can add icons to the context menu by adding + classes to the respective LI element(s) +*/ + +.contextMenu LI.edit A { background-image: url(images/page_white_edit.png); } +.contextMenu LI.cut A { background-image: url(images/cut.png); } +.contextMenu LI.copy A { background-image: url(images/page_white_copy.png); } +.contextMenu LI.paste A { background-image: url(images/page_white_paste.png); } +.contextMenu LI.delete A { background-image: url(images/page_white_delete.png); } +.contextMenu LI.quit A { background-image: url(images/door.png); } diff --git a/redakcja/static/contextmenu2/jquery.contextMenu.js b/redakcja/static/contextmenu2/jquery.contextMenu.js new file mode 100644 index 00000000..59c1737d --- /dev/null +++ b/redakcja/static/contextmenu2/jquery.contextMenu.js @@ -0,0 +1,211 @@ +// jQuery Context Menu Plugin +// +// Version 1.01 +// +// Cory S.N. LaViska +// A Beautiful Site (http://abeautifulsite.net/) +// +// More info: http://abeautifulsite.net/2008/09/jquery-context-menu-plugin/ +// +// Terms of Use +// +// This plugin is dual-licensed under the GNU General Public License +// and the MIT License and is copyright A Beautiful Site, LLC. +// +if(jQuery)( function() { + $.extend($.fn, { + + contextMenu: function(o, callback) { + // Defaults + if( o.menu == undefined ) return false; + if( o.inSpeed == undefined ) o.inSpeed = 150; + if( o.outSpeed == undefined ) o.outSpeed = 75; + // 0 needs to be -1 for expected results (no fade) + if( o.inSpeed == 0 ) o.inSpeed = -1; + if( o.outSpeed == 0 ) o.outSpeed = -1; + // Loop each context menu + $(this).each( function() { + var el = $(this); + var offset = $(el).offset(); + // Add contextMenu class + $('#' + o.menu).addClass('contextMenu'); + // Simulate a true right click + $(this).mousedown( function(e) { + var evt = e; + evt.stopPropagation(); + $(this).mouseup( function(e) { + e.stopPropagation(); + var srcElement = $(this); + $(this).unbind('mouseup'); + if( evt.button == 2 ) { + // Hide context menus that may be showing + $(".contextMenu").hide(); + // Get this context menu + var menu = $('#' + o.menu); + + if( $(el).hasClass('disabled') ) return false; + + // Detect mouse position + var d = {}, x, y; + if( self.innerHeight ) { + d.pageYOffset = self.pageYOffset; + d.pageXOffset = self.pageXOffset; + d.innerHeight = self.innerHeight; + d.innerWidth = self.innerWidth; + } else if( document.documentElement && + document.documentElement.clientHeight ) { + d.pageYOffset = document.documentElement.scrollTop; + d.pageXOffset = document.documentElement.scrollLeft; + d.innerHeight = document.documentElement.clientHeight; + d.innerWidth = document.documentElement.clientWidth; + } else if( document.body ) { + d.pageYOffset = document.body.scrollTop; + d.pageXOffset = document.body.scrollLeft; + d.innerHeight = document.body.clientHeight; + d.innerWidth = document.body.clientWidth; + } + (e.pageX) ? x = e.pageX : x = e.clientX + d.scrollLeft; + (e.pageY) ? y = e.pageY : y = e.clientY + d.scrollTop; + + // Show the menu + $(document).unbind('click'); + $(menu).css({ top: y, left: x }).fadeIn(o.inSpeed); + // Hover events + $(menu).find('A').mouseover( function() { + $(menu).find('LI.hover').removeClass('hover'); + $(this).parent().addClass('hover'); + }).mouseout( function() { + $(menu).find('LI.hover').removeClass('hover'); + }); + + // Keyboard + $(document).keypress( function(e) { + switch( e.keyCode ) { + case 38: // up + if( $(menu).find('LI.hover').size() == 0 ) { + $(menu).find('LI:last').addClass('hover'); + } else { + $(menu).find('LI.hover').removeClass('hover').prevAll('LI:not(.disabled)').eq(0).addClass('hover'); + if( $(menu).find('LI.hover').size() == 0 ) $(menu).find('LI:last').addClass('hover'); + } + break; + case 40: // down + if( $(menu).find('LI.hover').size() == 0 ) { + $(menu).find('LI:first').addClass('hover'); + } else { + $(menu).find('LI.hover').removeClass('hover').nextAll('LI:not(.disabled)').eq(0).addClass('hover'); + if( $(menu).find('LI.hover').size() == 0 ) $(menu).find('LI:first').addClass('hover'); + } + break; + case 13: // enter + $(menu).find('LI.hover A').trigger('click'); + break; + case 27: // esc + $(document).trigger('click'); + break + } + }); + + // When items are selected + $('#' + o.menu).find('A').unbind('click'); + $('#' + o.menu).find('LI:not(.disabled) A').click( function() { + $(document).unbind('click').unbind('keypress'); + $(".contextMenu").hide(); + // Callback + if( callback ) callback( $(this).attr('href').substr(1), $(srcElement), {x: x - offset.left, y: y - offset.top, docX: x, docY: y} ); + return false; + }); + + // Hide bindings + setTimeout( function() { // Delay for Mozilla + $(document).click( function() { + $(document).unbind('click').unbind('keypress'); + $(menu).fadeOut(o.outSpeed); + return false; + }); + }, 0); + } + }); + }); + + // Disable text selection + if( $.browser.mozilla ) { + $('#' + o.menu).each( function() { $(this).css({ 'MozUserSelect' : 'none' }); }); + } else if( $.browser.msie ) { + $('#' + o.menu).each( function() { $(this).bind('selectstart.disableTextSelect', function() { return false; }); }); + } else { + $('#' + o.menu).each(function() { $(this).bind('mousedown.disableTextSelect', function() { return false; }); }); + } + // Disable browser context menu (requires both selectors to work in IE/Safari + FF/Chrome) + $(el).add($('UL.contextMenu')).bind('contextmenu', function() { return false; }); + + }); + return $(this); + }, + + // Disable context menu items on the fly + disableContextMenuItems: function(o) { + if( o == undefined ) { + // Disable all + $(this).find('LI').addClass('disabled'); + return( $(this) ); + } + $(this).each( function() { + if( o != undefined ) { + var d = o.split(','); + for( var i = 0; i < d.length; i++ ) { + $(this).find('A[href="' + d[i] + '"]').parent().addClass('disabled'); + + } + } + }); + return( $(this) ); + }, + + // Enable context menu items on the fly + enableContextMenuItems: function(o) { + if( o == undefined ) { + // Enable all + $(this).find('LI.disabled').removeClass('disabled'); + return( $(this) ); + } + $(this).each( function() { + if( o != undefined ) { + var d = o.split(','); + for( var i = 0; i < d.length; i++ ) { + $(this).find('A[href="' + d[i] + '"]').parent().removeClass('disabled'); + + } + } + }); + return( $(this) ); + }, + + // Disable context menu(s) + disableContextMenu: function() { + $(this).each( function() { + $(this).addClass('disabled'); + }); + return( $(this) ); + }, + + // Enable context menu(s) + enableContextMenu: function() { + $(this).each( function() { + $(this).removeClass('disabled'); + }); + return( $(this) ); + }, + + // Destroy context menu(s) + destroyContextMenu: function() { + // Destroy specified context menus + $(this).each( function() { + // Disable action + $(this).unbind('mousedown').unbind('mouseup'); + }); + return( $(this) ); + } + + }); +})(jQuery); \ No newline at end of file diff --git a/redakcja/static/js/catalogue/book_list.js b/redakcja/static/js/catalogue/book_list.js new file mode 100644 index 00000000..1ff5f064 --- /dev/null +++ b/redakcja/static/js/catalogue/book_list.js @@ -0,0 +1,56 @@ +(function($) { + $(function() { + // clicking on book checks chunks, too + $("input[name=select_book]").change(function(ev) { + $book = $(this); + $book.closest("table").find("input[name=select_chunk][data-book-id=" + $book.val() + "]").attr("checked", $book.is(':checked')); + }); + + // initialize context menu + + var get_ids = function() { + return $.map($("input[name=select_chunk]:checked"), function(ele, idx) { + return ele.value; + }).join(); + }; + + var set_stage = function(key, opt) { + var stage = $("select[name=stage] option[value!=]").eq(key).val(); + $.post($('input[name=chunk_mass_edit_url]').val(), + { + ids: get_ids(), + stage: stage, + }, + function(data, status) { + location.reload(true); + } + ); + }; + + $.contextMenu({ + selector: '#file-list', + items: { + "stage": { + name: "Set stage", + items: $.map($("select[name=stage] option[value!=]"), + function(ele, idx) { + return { + name: $(ele).text(), + callback: set_stage, + }; + }), + }, +/* "user": { + name: "Set user", + + }, + "status": { + name: "Set status", + items: + },*/ + + }, + }); + + }); +})(jQuery); -- 2.20.1