Changeset 3680 in products for quintagroup.plonetabs/branches
- Timestamp:
- Apr 30, 2013 2:34:02 PM (11 years ago)
- Location:
- quintagroup.plonetabs/branches/nokss
- Files:
-
- 7 deleted
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
quintagroup.plonetabs/branches/nokss/quintagroup/plonetabs/browser/configure.zcml
r872 r3680 2 2 xmlns="http://namespaces.zope.org/zope" 3 3 xmlns:browser="http://namespaces.zope.org/browser"> 4 5 <include file="kssactions.zcml" />6 4 7 5 <include file="resources.zcml" /> -
quintagroup.plonetabs/branches/nokss/quintagroup/plonetabs/browser/plonetabs.py
r3673 r3680 1 1 import urllib 2 2 import re 3 import json 3 4 4 5 from Acquisition import aq_inner … … 17 18 from zope.container.interfaces import INameChooser 18 19 19 from zope.viewlet.interfaces import IViewletManager, IViewlet20 21 20 from plone.app.layout.navigation.root import getNavigationRoot 22 from plone.app.kss.plonekssview import PloneKSSView23 from kss.core import kssaction, KSSExplicitError24 21 25 22 from Products.CMFCore.utils import getToolByName … … 50 47 51 48 52 class PloneTabsControlPanel( PloneKSSView):49 class PloneTabsControlPanel(): 53 50 54 51 implements(IPloneTabsControlPanel) … … 70 67 """Perform the update and redirect if necessary, or render the page""" 71 68 postback = True 69 ajaxback = False 72 70 errors = {} 73 71 74 72 form = self.request.form 75 73 submitted = form.get('form.submitted', False) 74 ajax_request = form.get('ajax_request', False) 76 75 77 76 # action handler def handler(self, form) 77 if ajax_request: 78 ajaxback = self.ajax_postback(form, errors) 78 79 if submitted: 79 80 postback = self.submitted_postback(form, errors) … … 86 87 expires=expires) 87 88 88 if postback: 89 if ajaxback: 90 return json.dumps(ajaxback) 91 elif postback: 89 92 return self.template(errors=errors) 90 93 … … 107 110 return postback 108 111 112 113 def ajax_postback(self, form, errors): 114 """ajax_postback ajaxback""" 115 conv_dict = { 116 "edit_moveact": "manage_ajax_moveAction", 117 "category_change": "manage_ajax_changeCategory", 118 "edit_delete": "manage_ajax_deleteAction", 119 "edit_save": "manage_ajax_saveAction", 120 "edit_cancel": "manage_ajax_cancelEditting", 121 "tabslist_visible": "manage_ajax_toggleActionsVisibility", 122 "roottabs_visible": "manage_ajax_toggleRootsVisibility", 123 "generated_tabs": "manage_ajax_toggleGeneratedTabs", 124 "add_add": "manage_ajax_addAction", 125 } 126 127 for method in conv_dict.keys(): 128 if method in form.keys(): 129 method_val = conv_dict.get(method) 130 return getattr(self, method_val)(form, errors) 131 132 return False 133 109 134 @property 110 135 def plone_portal_state(self): … … 122 147 """portal_actions""" 123 148 return getToolByName(self.context, 'portal_actions') 149 150 ######################################## 151 # AJAX Methods 152 ######################################## 153 154 def manage_ajax_addAction(self, form, errs): 155 # extract posted data 156 resp_dict = {} 157 cat_name = form['cat_name'] 158 id, ie7bad_category, data = self.parseAddForm(self.request.form) 159 160 # validate posted data 161 errors = self.validateActionFields(cat_name, data) 162 163 if not errors: 164 action = self.addAction(cat_name, data) 165 # add one more action to actions list 166 content = self.getActionsList(category=cat_name, tabs=[action, ]) 167 resp_dict['content'] = content 168 resp_dict['status_code'] = 200 169 resp_dict['status_message'] = "%s action successfully added." % action.id 170 else: 171 resp_dict['status_message'] = "Please correct the indicated errors." 172 resp_dict['status_code'] = 500 173 resp_dict['content'] = errors 174 return resp_dict 175 176 def manage_ajax_toggleGeneratedTabs(self, form, errs): 177 """Toggle autogenaration setting on configlet""" 178 resp_dict = {} 179 errors = [] 180 181 #TODO: parse, validate form 182 checked = form['generated_tabs'] 183 field = form['field'] 184 185 if not errors: 186 if checked == 'true': 187 self.setSiteProperties(**{field: False}) 188 message = _(u"Generated tabs switched on.") 189 else: 190 self.setSiteProperties(**{field: True}) 191 message = _(u"Generated tabs switched off.") 192 content = self.getGeneratedTabs() 193 resp_dict['content'] = content 194 resp_dict['status_code'] = 200 195 resp_dict['status_message'] = message 196 else: 197 resp_dict['status_message'] = errors 198 resp_dict['status_code'] = 500 199 return resp_dict 200 201 def manage_ajax_toggleRootsVisibility(self, form, errs): 202 #Toggle visibility for portal actions 203 resp_dict = {} 204 errors = [] 205 206 #TODO: parse, validate form 207 id = form['orig_id'] 208 checked = form['visibility'] 209 210 portal = getMultiAdapter((aq_inner(self.context), self.request), 211 name='plone_portal_state').portal() 212 213 # remove prefix, added for making ids on configlet unique ("roottabs_") 214 obj_id = id[len("roottabs_"):] 215 216 if obj_id not in portal.objectIds(): 217 errors.append("Object with %s id doesn't exist in portal root." % obj_id) 218 219 checked = True if checked == 'true' else False 220 221 if not errors: 222 portal[obj_id].update(excludeFromNav=not checked) 223 224 if checked: 225 message = "%s object was included into navigation." % obj_id 226 else: 227 message = "%s object was excluded from navigation." % obj_id 228 resp_dict['status_message'] = message 229 resp_dict['status_code'] = 200 230 else: 231 resp_dict['status_message'] = errors 232 resp_dict['status_code'] = 500 233 return resp_dict 234 235 def manage_ajax_toggleActionsVisibility(self, form, errs): 236 #Toggle visibility for portal actions 237 resp_dict = {} 238 239 #TODO: parse, validate form 240 id = form['orig_id'] 241 cat_name = form['category'] 242 checked = form['visibility'] 243 244 act_id, category, action, errors = self.manage_validateAction(id, cat_name) 245 246 if not errors: 247 self.updateAction(act_id, cat_name, 248 {'id': act_id, 'visible': (checked == 'true') or False}) 249 if checked == 'true': 250 message = "%s action is now visible." % act_id 251 else: 252 message = "%s action is now invisible." % act_id 253 resp_dict['status_message'] = message 254 resp_dict['status_code'] = 200 255 else: 256 resp_dict['status_message'] = errors 257 resp_dict['status_code'] = 500 258 return resp_dict 259 260 def manage_ajax_deleteAction(self, form, errs): 261 """Delete portal action with given id & category""" 262 resp_dict = {} 263 264 #TODO: parse, validate form 265 id = form['orig_id'] 266 cat_name = form['category'] 267 268 act_id, category, action, errors = self.manage_validateAction(id, cat_name) 269 if not errors: 270 self.deleteAction(act_id, cat_name) 271 resp_dict['status_message'] = "%s action successfully removed." % act_id 272 resp_dict['status_code'] = 200 273 else: 274 resp_dict['status_message'] = errors 275 resp_dict['status_code'] = 500 276 return resp_dict 277 278 def manage_ajax_cancelEditting(self, form, errs): 279 """Hide edit form for given action""" 280 resp_dict = {} 281 #TODO: parse, validate form 282 id = form['orig_id'] 283 cat_name = form['category'] 284 285 act_id, category, action, errors = self.manage_validateAction(id, cat_name) 286 287 if not errors: 288 content = self.getActionsList(category=cat_name, tabs=[action, ]) 289 resp_dict['content'] = content 290 resp_dict['status_message'] = "Changes discarded." 291 resp_dict['status_code'] = 200 292 else: 293 resp_dict['status_message'] = errors 294 resp_dict['status_code'] = 500 295 return resp_dict 296 297 def manage_validateAction(self, action_id, cat_name): 298 """Check whether action with given id exists in cat_name category""" 299 errors = [] 300 act_id = "" 301 category = "" 302 action = "" 303 304 act_id = action_id 305 306 try: 307 category = self.getActionCategory(cat_name) 308 except Exception: 309 errors.append("%s action category does not exist." % cat_name) 310 311 try: 312 action = category[act_id] 313 except Exception: 314 errors.append("No %s action in %s category." % 315 (act_id, cat_name)) 316 return (act_id, category, action, errors) 317 318 def manage_ajax_saveAction(self, form, errs): 319 """Manage Method to update action""" 320 # extract posted data 321 resp_dict = {} 322 id, cat_name, data = self.parseEditForm(form) 323 324 # get category and action to edit 325 category = self.getActionCategory(cat_name) 326 action = category[id] 327 328 # validate posted data 329 errors = self.validateActionFields( 330 cat_name, data, allow_dup=(id == data['id'])) 331 332 if not errors: 333 action = self.updateAction(id, cat_name, data) 334 content = self.getActionsList(category=cat_name, tabs=[action, ]) 335 resp_dict['content'] = content 336 resp_dict['status_code'] = 200 337 resp_dict['status_message'] = "%s action successfully updated." % action.id 338 else: 339 resp_dict['status_code'] = 500 340 resp_dict['content'] = errors 341 resp_dict['status_message'] = "Please correct the indicated errors." 342 return resp_dict 343 344 def manage_ajax_moveAction(self, form, errs): 345 resp_dict = {} 346 cat_name = form['cat_name'] 347 category = self.getActionCategory(cat_name) 348 components = urllib.unquote(form['actions']).split('&') 349 if self.sufix == '': 350 ids = [component[len(self.prefix):] for component in components] 351 else: 352 ids = [component[len(self.prefix):-len(self.sufix)] 353 for component in components] 354 # do actual sorting 355 resp = category.moveObjectsByDelta(ids, -len(category.objectIds())) 356 357 if resp: 358 resp_dict['status_code'] = 200 359 resp_dict['status_message'] = "Actions successfully sorted." 360 else: 361 resp_dict['status_code'] = 500 362 resp_dict['status_message'] = "There was error while sorting, or list not changed" 363 return resp_dict 364 365 def manage_ajax_changeCategory(self, form, errs): 366 resp_dict = {} 367 errors = [] 368 369 """Change action category to manage""" 370 cat_name = form['category'] 371 # update actions list 372 resp_dict['actionslist'] = self.getActionsList(category=cat_name) 373 # update autogenerated sections 374 resp_dict['section'] = self.getAutoGenereatedSection(cat_name) 375 # and title 376 ts = getToolByName(self.context, 'translation_service') 377 resp_dict['title'] = ts.translate(self.getPageTitle(cat_name), context=self.context) 378 379 if not errors: 380 resp_dict['status_code'] = 200 381 resp_dict['status_message'] = "Category changed successfully" 382 else: 383 resp_dict['status_code'] = 500 384 resp_dict['status_message'] = "There was error while changed category" 385 386 return resp_dict 387 124 388 125 389 ######################################## … … 504 768 return selected_tabs['portal'] 505 769 506 ##########################507 #508 # KSS Server Actions509 #510 ##########################511 512 @kssaction513 def kss_insertModeLink(self):514 """Insert link which allows change categories between plain and rich"""515 ksscore = self.getCommandSet('core')516 517 html = self.link_template()518 target = ksscore.getCssSelector('.link-parent')519 ksscore.insertHTMLAfter(target, html, withKssSetup='False')520 521 @kssaction522 def kss_changeCategory(self, cat_name):523 """Change action category to manage"""524 ksscore = self.getCommandSet('core')525 526 # update actions list527 actionslist = self.getActionsList(category=cat_name)528 ksscore.replaceInnerHTML(ksscore.getHtmlIdSelector('tabslist'),529 actionslist)530 531 # update autogenerated sections532 section = self.getAutoGenereatedSection(cat_name)533 ksscore.replaceHTML(534 ksscore.getHtmlIdSelector('autogeneration_section'), section)535 # and title536 ts = getToolByName(self.context, 'translation_service')537 title = ts.translate(self.getPageTitle(cat_name), context=self.context)538 ksscore.replaceInnerHTML(539 ksscore.getHtmlIdSelector('plonetabs-form-title'), title)540 541 # update category hidden field on adding form542 ksscore.setAttribute(ksscore.getCssSelector(543 'form[name=addaction_form] input[name=category]'),544 'value',545 cat_name)546 547 # update state variable 'plonetabs-category' on client548 ksscore.setStateVar('plonetabs-category', cat_name)549 550 # hide adding form551 self.kss_hideAddForm()552 553 # issue portal status message554 self.kss_issueMessage(_(u"Category changed successfully."))555 556 @kssaction557 def kss_toggleGeneratedTabs(self, field, checked='0'):558 """Toggle autogenaration setting on configlet"""559 if checked == '1':560 self.setSiteProperties(**{field: False})561 if field == 'disable_nonfolderish_sections':562 message = _(u"Generated not folderish tabs switched on.")563 else:564 message = _(u"Generated tabs switched on.")565 else:566 self.setSiteProperties(**{field: True})567 if field == 'disable_nonfolderish_sections':568 message = _(u"Generated not folderish tabs switched off.")569 else:570 message = _(u"Generated tabs switched off.")571 572 # update client573 ksscore = self.getCommandSet("core")574 content = self.getGeneratedTabs()575 ksscore.replaceInnerHTML(ksscore.getHtmlIdSelector('roottabs'),576 content)577 578 # update global-sections viewlet579 self.updatePortalTabsPageSection()580 581 # issue portal status message582 self.kss_issueMessage(message)583 584 @kssaction585 def kss_toggleRootsVisibility(self, id, checked='0'):586 """Toggle visibility for portal root objects (exclude_from_nav)"""587 portal = self.plone_portal_state.portal()588 589 # remove prefix, added for making ids on configlet unique ("roottabs_")590 obj_id = id[len("roottabs_"):]591 592 if obj_id not in portal.objectIds():593 raise KSSExplicitError("Object with %s id doesn't"594 " exist in portal root." % obj_id)595 596 if checked == '1':597 checked = True598 else:599 checked = False600 601 portal[obj_id].update(excludeFromNav=not checked)602 603 # update client604 ksscore = self.getCommandSet("core")605 if checked:606 ksscore.removeClass(ksscore.getHtmlIdSelector(id),607 value="invisible")608 message = _(u"'${id}' object was included into navigation.",609 mapping={'id': obj_id})610 else:611 ksscore.addClass(ksscore.getHtmlIdSelector(id), value="invisible")612 message = _(u"'${id}' object was excluded from navigation.",613 mapping={'id': obj_id})614 615 # update global-sections viewlet616 self.updatePortalTabsPageSection()617 618 # issue portal status message619 self.kss_issueMessage(message)620 621 @kssaction622 def kss_toggleActionsVisibility(self, id, checked='0', cat_name=None):623 """Toggle visibility for portal actions"""624 # validate input625 act_id, category, action = self.kss_validateAction(id, cat_name)626 self.updateAction(act_id, cat_name,627 {'id': act_id, 'visible': (checked == '1') or False})628 629 # update client630 ksscore = self.getCommandSet("core")631 if checked == '1':632 ksscore.removeClass(ksscore.getHtmlIdSelector(id),633 value="invisible")634 message = _(u"'${id}' action is now visible.",635 mapping={'id': act_id})636 else:637 ksscore.addClass(ksscore.getHtmlIdSelector(id), value="invisible")638 message = _(u"'${id}' action is now invisible.",639 mapping={'id': act_id})640 self.updatePage(cat_name)641 642 # issue portal status message643 self.kss_issueMessage(message)644 645 @kssaction646 def kss_deleteAction(self, id, cat_name):647 """Delete portal action with given id & category"""648 # validate input649 act_id, category, action = self.kss_validateAction(id, cat_name)650 self.deleteAction(act_id, cat_name)651 652 # update client653 ksscore = self.getCommandSet("core")654 # XXX TODO: fade effect during removing, to do this655 # we need kukit js action/command plugin656 ksscore.deleteNode(ksscore.getHtmlIdSelector(id))657 658 # update different sections of page depending on actions category659 self.updatePage(cat_name)660 661 # issue portal status message662 self.kss_issueMessage(_(u"'${id}' action successfully removed.",663 mapping={'id': act_id}))664 665 @kssaction666 def kss_addAction(self, cat_name):667 """KSS method to add new portal action"""668 # extract posted data669 id, ie7bad_category, data = self.parseAddForm(self.request.form)670 671 # validate posted data672 errors = self.validateActionFields(cat_name, data)673 674 # if not errors find (or create) category and set action to it675 ksscore = self.getCommandSet('core')676 if not errors:677 action = self.addAction(cat_name, data)678 679 # update client680 # add one more action to actions list681 content = self.getActionsList(category=cat_name, tabs=[action, ])682 ksscore.insertHTMLAsLastChild(683 ksscore.getHtmlIdSelector('tabslist'),684 content)685 686 # update reorder controls687 # self.kss_checkReorderControls(cat_name)688 689 # hide adding form690 ksscore.removeClass(ksscore.getHtmlIdSelector('addaction'),691 'adding')692 self.kss_toggleCollapsible(693 ksscore.getCssSelector('form[name=addaction_form] '694 '.headerAdvanced'), collapse='true')695 696 # set client state var 'plonetabs-addingTitle' to empty697 # string for correct id autogeneration functionality698 ksscore.setStateVar('plonetabs-addingTitle', '')699 700 # reset adding form701 self.kss_resetForm(ksscore.getHtmlIdSelector('addaction'))702 703 # remove focus from name input704 self.kss_blur(ksscore.getHtmlIdSelector('actname'))705 706 message = _(u"'${id}' action successfully added.",707 mapping={'id': action.id})708 msgtype = "info"709 710 # update page711 self.updatePage(cat_name)712 else:713 # expand advanced section if there are errors in id or condition714 if 'id' in errors or 'available_expr' in errors:715 self.kss_toggleCollapsible(716 ksscore.getCssSelector('form[name=addaction_form] '717 '.headerAdvanced'),718 collapse='false')719 720 message = _(u"Please correct the indicated errors.")721 msgtype = "error"722 723 # update errors on client form724 self.kss_issueErrors(errors)725 726 # issue portal status message727 self.kss_issueMessage(message, msgtype)728 729 @kssaction730 def kss_hideAddForm(self):731 """"Hide Add form, reset it and remove error messages"""732 # no server changes, only update client733 ksscore = self.getCommandSet("core")734 735 # hide form itself736 ksscore.removeClass(ksscore.getHtmlIdSelector('addaction'), 'adding')737 738 # collapse advanced section739 self.kss_toggleCollapsible(740 ksscore.getCssSelector(741 'form[name=addaction_form] .headerAdvanced'),742 collapse='true')743 744 # reset form inputs745 self.kss_resetForm(ksscore.getHtmlIdSelector('addaction'))746 747 # set client state var 'plonetabs-addingTitle' to empty string for748 # correct id autogeneration functionality749 ksscore.setStateVar('plonetabs-addingTitle', '')750 751 # remove form errors if such exist752 self.kss_issueErrors({})753 754 # issue portal status message755 self.kss_issueMessage(_(u"Adding canceled."))756 757 @kssaction758 def kss_showEditForm(self, id, cat_name):759 """Show edit form for given action"""760 act_id, category, action = self.kss_validateAction(id, cat_name)761 762 # fetch data763 action_info = self.copyAction(action)764 action_info["editing"] = True765 766 # update client767 ksscore = self.getCommandSet("core")768 content = self.getActionsList(category=cat_name, tabs=[action_info, ])769 ksscore.replaceHTML(ksscore.getHtmlIdSelector(id), content)770 771 # focus name field772 ksscore.focus(773 ksscore.getCssSelector("#%s input[name=title_%s]" % (id, act_id)))774 775 # issue portal status message776 self.kss_issueMessage(_(u"Fill in required fields and click on Add."))777 778 @kssaction779 def kss_hideEditForm(self, id, cat_name):780 """Hide edit form for given action"""781 act_id, category, action = self.kss_validateAction(id, cat_name)782 783 # update client784 ksscore = self.getCommandSet("core")785 content = self.getActionsList(category=cat_name, tabs=[action, ])786 ksscore.replaceHTML(ksscore.getHtmlIdSelector(id), content)787 788 # issue portal status message789 self.kss_issueMessage(_(u"Changes discarded."))790 791 @kssaction792 def kss_editAction(self):793 """Update action's properties"""794 id, cat_name, data = self.parseEditForm(self.request.form)795 796 # get category and action to edit797 category = self.getActionCategory(cat_name)798 action = category[id]799 800 # validate posted data801 errors = self.validateActionFields(cat_name, data,802 allow_dup=(id == data['id']))803 804 html_id = '%s%s%s' % (self.prefix, id, self.sufix)805 ksscore = self.getCommandSet('core')806 if not errors:807 action = self.updateAction(id, cat_name, data)808 809 # update client810 # replace action item with updated one811 content = self.getActionsList(category=cat_name, tabs=[action, ])812 ksscore.replaceHTML(ksscore.getHtmlIdSelector(html_id), content)813 814 message = _(u"'${id}' action successfully updated.",815 mapping={'id': action.id})816 msgtype = "info"817 818 # update page819 self.updatePage(cat_name)820 else:821 # issue error messages822 self.kss_issueErrors(errors, editform=id)823 824 # expand advanced section if there are errors in id,825 # action url or condition826 if 'id' in errors or 'available_expr' in errors or \827 'url_expr' in errors:828 self.kss_toggleCollapsible(829 ksscore.getCssSelector('#%s .headerAdvanced' % html_id),830 collapse='false')831 832 message = _(u"Please correct the indicated errors.")833 msgtype = "error"834 835 # issue portal status message836 self.kss_issueMessage(message, msgtype)837 838 @kssaction839 def kss_orderActions(self):840 """Update actions order in the given category"""841 form = self.request.form842 cat_name = form['cat_name']843 category = self.getActionCategory(cat_name)844 845 # decode URI components and collect ids from request846 components = urllib.unquote(form['actions']).split('&')847 if self.sufix == '':848 ids = [component[len(self.prefix):] for component in components]849 else:850 ids = [component[len(self.prefix):-len(self.sufix)]851 for component in components]852 853 # do actual sorting854 category.moveObjectsByDelta(ids, -len(category.objectIds()))855 856 # update client857 self.updatePage(cat_name)858 859 # issue portal status message860 self.kss_issueMessage(_(u"Actions successfully sorted."))861 862 770 # 863 771 # Utility Methods … … 1015 923 1016 924 # 1017 # Utility methods for the kss actions management1018 #1019 1020 def kss_validateAction(self, id, cat_name):1021 """Check whether action with given id exists in cat_name category"""1022 try:1023 category = self.getActionCategory(cat_name)1024 except Exception:1025 raise KSSExplicitError(u"%s action category does not exist." %1026 cat_name)1027 1028 # extract action id from given list item id on client1029 action_id = self.sufix and id[len(self.prefix):-len(self.sufix)] or \1030 id[len(self.prefix):]1031 try:1032 action = category[action_id]1033 except Exception:1034 raise KSSExplicitError("No %s action in %s category." %1035 (action_id, cat_name))1036 1037 return (action_id, category, action)1038 1039 def kss_issueErrors(self, errors, editform=False, fields=ACTION_ATTRS):1040 """Display error messages on the client"""1041 ksscore = self.getCommandSet('core')1042 ts = getToolByName(self.context, 'translation_service')1043 for field in fields:1044 self.kss_issueFieldError(ksscore, field,1045 errors.get(field, False), editform, ts)1046 1047 def kss_issueFieldError(self, ksscore, name, error, editform, ts):1048 """Issue this error message for the field"""1049 if editform:1050 id = '%s%s%s' % (self.prefix, editform, self.sufix)1051 field_selector = ksscore.getCssSelector(1052 '#%s .edit-field-%s' % (id, UI_ATTRS.get(name, name)))1053 field_error_selector = ksscore.getCssSelector(1054 '#%s .edit-field-%s .error-container' % (id,1055 UI_ATTRS.get(name,1056 name)))1057 else:1058 field_selector = ksscore.getCssSelector(1059 'form[name=addaction_form] .field-%s' % UI_ATTRS.get(name,1060 name))1061 field_error_selector = ksscore.getCssSelector(1062 'form[name=addaction_form] .field-%s '1063 '.error-container' % UI_ATTRS.get(name, name))1064 1065 if error:1066 error = ts.translate(error, context=self.context)1067 ksscore.replaceInnerHTML(field_error_selector, error)1068 ksscore.addClass(field_selector, 'error')1069 else:1070 ksscore.clearChildNodes(field_error_selector)1071 ksscore.removeClass(field_selector, 'error')1072 1073 def kss_toggleCollapsible(self, selector, collapsed=None,1074 expanded=None, collapse=None):1075 """KSS Server command to add plonetabs-toggleCollapsible client1076 action to response1077 """1078 command = self.commands.addCommand('plonetabs-toggleCollapsible',1079 selector)1080 if collapsed is not None:1081 command.addParam('collapsed', collapsed)1082 if expanded is not None:1083 command.addParam('expanded', expanded)1084 if collapse is not None:1085 command.addParam('collapse', collapse)1086 1087 def kss_resetForm(self, selector):1088 """KSS Server command to reset form on client"""1089 1090 def kss_blur(self, selector):1091 """KSS Server command to remove focus from input"""1092 self.commands.addCommand('plonetabs-blur', selector)1093 1094 def kss_replaceOrInsert(self, selector, parentSelector, html,1095 withKssSetup='True', alternativeHTML='',1096 selectorType='', position='', positionSelector='',1097 positionSelectorType=''):1098 """KSS Server command to execute replaceOrInsert client action"""1099 command = self.commands.addCommand('plonetabs-replaceOrInsert',1100 selector)1101 command.addParam('selector', parentSelector)1102 command.addHtmlParam('html', html)1103 command.addParam('withKssSetup', withKssSetup)1104 if alternativeHTML:1105 command.addHtmlParam('alternativeHTML', alternativeHTML)1106 if selectorType:1107 command.addParam('selectorType', selectorType)1108 if position:1109 command.addParam('position', position)1110 if positionSelector:1111 command.addParam('positionSelector', positionSelector)1112 if positionSelectorType:1113 command.addParam('positionSelectorType',1114 positionSelectorType)1115 1116 def kss_issueMessage(self, message, msgtype="info"):1117 """"Issues portal status message and removes it afte 10 seconds"""1118 ksscore = self.getCommandSet('core')1119 self.getCommandSet('plone').issuePortalMessage(message,1120 msgtype=msgtype)1121 self.kss_timeout(1122 ksscore.getHtmlIdSelector('kssPortalMessage'),1123 delay='10000', repeat='false',1124 cmd_name='setStyle', name='display', value='none'1125 )1126 1127 def kss_timeout(self, selector, **kw):1128 """KSS Server command to execute plonetabs-timeout client action"""1129 self.commands.addCommand('plonetabs-timeout', selector, **kw)1130 1131 def renderViewlet(self, manager, name):1132 if isinstance(manager, basestring):1133 manager = getMultiAdapter((self.context, self.request, self,),1134 IViewletManager, name=manager)1135 renderer = getMultiAdapter((self.context, self.request, self, manager),1136 IViewlet, name=name)1137 renderer = renderer.__of__(self.context)1138 renderer.update()1139 return renderer.render()1140 1141 #1142 925 # Basic API to work with portal actions tool in a more pleasent way 1143 926 # … … 1187 970 return False 1188 971 1189 #1190 # KSS Methods that are used to update different parts of the page1191 # accordingly to category1192 #1193 1194 def updatePage(self, category):1195 """Seek for according method in class and calls it if found1196 Example of making up method's name:1197 portal_tabs => updatePortalTabsPageSection1198 """1199 method_name = 'update%sPageSection' % ''.join(1200 map(lambda x: x.capitalize(), category.split('_')))1201 if hasattr(self, method_name):1202 getattr(self, method_name)()1203 1204 def updatePortalTabsPageSection(self):1205 """Method for updating global-sections on client"""1206 ksscore = self.getCommandSet("core")1207 self.kss_replaceOrInsert(ksscore.getHtmlIdSelector("portal-header"),1208 "portal-globalnav",1209 self.sections_template(),1210 withKssSetup='False',1211 selectorType='htmlid')1212 1213 def updateSiteActionsPageSection(self):1214 """Method for updating site action on client"""1215 ksscore = self.getCommandSet("core")1216 self.kss_replaceOrInsert(ksscore.getHtmlIdSelector("portal-header"),1217 "portal-siteactions",1218 self.renderViewlet("plone.portalheader",1219 "plone.site_actions"),1220 withKssSetup='False',1221 selectorType='htmlid',1222 position="before",1223 positionSelector="portal-searchbox",1224 positionSelectorType="htmlid")1225 1226 # ksszope = self.getCommandSet("zope")1227 # ksszope.refreshViewlet(1228 # self.getCommandSet("core").getHtmlIdSelector("portal-siteactions"1229 # ""),1230 #"plone.portalheader",1231 #"plone.site_actions")1232 1233 def updateUserPageSection(self):1234 """Method for updating site action on client"""1235 ksszope = self.getCommandSet("zope")1236 ksszope.refreshViewlet(1237 self.getCommandSet("core").getHtmlIdSelector(1238 "portal-personaltools-wrapper"),1239 "plone.portaltop",1240 "plone.personal_bar")1241 1242 972 1243 973 class PloneTabsMode(BrowserView): -
quintagroup.plonetabs/branches/nokss/quintagroup/plonetabs/browser/resources.zcml
r872 r3680 45 45 file="./resources/plonetabs.css" 46 46 layer="quintagroup.plonetabs.interfaces.IPloneTabsProductLayer" 47 /> 48 49 <!-- Register kukit stylesheets --> 50 <browser:resource 51 name="plonetabs.kss" 52 file="./resources/plonetabs.kss" 53 layer="quintagroup.plonetabs.interfaces.IPloneTabsProductLayer" 54 /> 55 56 <browser:resource 57 name="plonetabsmode.kss" 58 file="./resources/plonetabsmode.kss" 59 layer="quintagroup.plonetabs.interfaces.IPloneTabsProductLayer" 60 /> 61 62 <!-- Register scriptaculous dragdrop js library --> 63 <browser:resource 64 name="sa_dragdrop.js" 65 file="./resources/dragdrop.js" 66 layer="quintagroup.plonetabs.interfaces.IPloneTabsProductLayer" 67 /> 68 69 <browser:resource 70 name="pt_effects.js" 71 file="./resources/effects.js" 72 layer="quintagroup.plonetabs.interfaces.IPloneTabsProductLayer" 73 /> 74 47 /> 75 48 </configure> -
quintagroup.plonetabs/branches/nokss/quintagroup/plonetabs/browser/templates/plonetabs.pt
r3077 r3680 158 158 159 159 </div> 160 160 <script> 161 (function(a){var b,c=a();a.fn.sortable=function(d){var e=String(d);return d=a.extend({connectWith:!1},d),this.each(function(){if(/^enable|disable|destroy$/.test(e)){var f=a(this).children(a(this).data("items")).attr("draggable",e=="enable");e=="destroy"&&f.add(this).removeData("connectWith items").off("dragstart.h5s dragend.h5s selectstart.h5s dragover.h5s dragenter.h5s drop.h5s");return}var g,h,f=a(this).children(d.items),i=a("<"+(/^ul|ol$/i.test(this.tagName)?"li":"div")+' class="sortable-placeholder">');f.find(d.handle).mousedown(function(){g=!0}).mouseup(function(){g=!1}),a(this).data("items",d.items),c=c.add(i),d.connectWith&&a(d.connectWith).add(this).data("connectWith",d.connectWith),f.attr("draggable","true").on("dragstart.h5s",function(c){if(d.handle&&!g)return!1;g=!1;var e=c.originalEvent.dataTransfer;e.effectAllowed="move",e.setData("Text","dummy"),h=(b=a(this)).addClass("sortable-dragging").index()}).on("dragend.h5s",function(){b.removeClass("sortable-dragging").show(),c.detach(),h!=b.index()&&f.parent().trigger("sortupdate",{item:b}),b=null}).not("a[href], img").on("selectstart.h5s",function(){return this.dragDrop&&this.dragDrop(),!1}).end().add([this,i]).on("dragover.h5s dragenter.h5s drop.h5s",function(e){return!f.is(b)&&d.connectWith!==a(b).parent().data("connectWith")?!0:e.type=="drop"?(e.stopPropagation(),c.filter(":visible").after(b),!1):(e.preventDefault(),e.originalEvent.dataTransfer.dropEffect="move",f.is(this)?(d.forcePlaceholderSize&&i.height(b.outerHeight()),b.hide(),a(this)[i.index()<a(this).index()?"after":"before"](i),c.not(i).detach()):!c.is(this)&&!a(this).children(d.items).length&&(c.detach(),a(this).append(i)),!1)})})}})(jQuery); 162 </script> 163 164 <script> 165 //Functions declaration 166 167 function sortableList() { 168 console.log('sort changed'); 169 var formData = {}; 170 171 //?TODO formData.ajax_request = "edit_moveact" 172 173 formData.ajax_request = true; 174 var liIds = $('#tabslist li').map(function(i,n) { 175 return $(n).attr('id'); 176 }).get().join('&'); 177 cat_name = $('#select_category').val(); 178 formData.cat_name = cat_name; 179 formData.actions = liIds; 180 formData.edit_moveact = 'Move Action'; 181 //formData.push({ name: 'edit.moveact', value: 'Move Action'}); 182 $.ajax({ 183 type:'POST', 184 url: '@@plonetabs-controlpanel', 185 data: formData, 186 success: function(response) { 187 var json = JSON.parse(response) 188 console.log("response from server: "); 189 console.log(json); 190 191 if (json.status_code === 200){ 192 console.log('display success messages'); 193 } 194 else{ 195 console.log('display error messages'); 196 } 197 } 198 }); 199 } 200 201 function toggleCollapsible(el, collapse) { 202 collapse = typeof collapse !== 'undefined' ? collapse : 'default'; 203 204 var node = el.parent(".collapseAdvanced"); 205 206 if(collapse!=='default'){ 207 if (collapse==true){ 208 console.log("removeClass expandedBlock; addClass collapsedBlock"); 209 node.removeClass('expandedBlock'); 210 node.addClass('collapsedBlock'); 211 } 212 else{ 213 console.log("removeClass collapsedBlock; addClass expandedBlock"); 214 node.removeClass('collapsedBlock'); 215 node.addClass('expandedBlock'); 216 } 217 } 218 else{ 219 if (node.hasClass('collapsedBlock')){ 220 console.log("removeClass collapsedBlock; addClass expandedBlock"); 221 node.removeClass('collapsedBlock'); 222 node.addClass('expandedBlock'); 223 } 224 else{ 225 console.log("removeClass expandedBlock; addClass collapsedBlock"); 226 node.removeClass('expandedBlock'); 227 node.addClass('collapsedBlock'); 228 } 229 } 230 231 } 232 233 function startupActions() { 234 console.log('running basic methods'); 235 $(".add-controls input").addClass('allowMultiSubmit'); 236 $(".edit-controls input").addClass('allowMultiSubmit'); 237 $(".collapseAdvanced").removeClass('expandedBlock').addClass('collapsedBlock'); 238 } 239 </script> 240 241 <script> 242 $(document).ready(function() { 243 console.log('document ready'); 244 $("#plonetabs_form").addClass('kssTabsActive'); 245 startupActions() 246 }); 247 </script> 248 249 250 <script> 251 /*CLIENTS METHODS*/ 252 253 //titleWrapper 254 $("#tabslist .titleWrapper").live("click", function() { 255 console.log("#tabslist .titleWrapper clicked"); 256 ($(this).closest('li')).addClass('editing'); 257 }); 258 259 //collapse 260 $(".collapseAdvanced .headerAdvanced").live("click", function(event) { 261 console.log(".collapseAdvanced .headerAdvanced clicked"); 262 toggleCollapsible($(this)); 263 }); 264 </script> 265 266 <script> 267 /*AJAX METHODS*/ 268 269 //save(edit) 270 $('#tabslist .editsave').live("click", function(event) { 271 console.log('.editsave clicked '); 272 event.preventDefault(); 273 var formData = $(this).closest('form').serializeArray(); 274 formData.push({ name: "edit_save", value: this.value }); 275 276 //?TODO formData.ajax_request = "edit_save" 277 278 formData.push({ name: "ajax_request", value: true }); 279 $.ajax({ 280 type:'POST', 281 url: '@@plonetabs-controlpanel', 282 data: formData, 283 success: function(response) { 284 var json = JSON.parse(response) 285 console.log("response from server: "); 286 console.log(json); 287 if (json.status_code === 200){ 288 console.log('display success messages'); 289 290 $(this).closest('li').replaceWith(json.content); 291 } 292 else{ 293 console.log('display error messages'); 294 295 //if 'id' in errors or 'available_expr' in errors or 'url_expr' in errors: 296 toggleCollapsible($(this).find('.headerAdvanced'), false); 297 } 298 } 299 }); 300 }); 301 302 //reset(cancel) 303 $('#tabslist .editcancel').live("click", function(event) { 304 console.log('.editcancel clicked '); 305 event.preventDefault(); 306 var formData={}; 307 formData.ajax_request = true; 308 309 //?TODO formData.ajax_request = "edit_cancel" 310 311 formData.edit_cancel = 'Cancel'; 312 var parentFormSelect = $(this).closest('li'); 313 formData.orig_id = parentFormSelect.find('.editform input[name="orig_id"]').val(); 314 formData.category = parentFormSelect.find('.editform input[name="category"]').val(); 315 $.ajax({ 316 type:'POST', 317 url: '@@plonetabs-controlpanel', 318 data: formData, 319 success: function(response) { 320 var json = JSON.parse(response) 321 console.log("response from server: "); 322 console.log(json); 323 324 if (json.status_code === 200){ 325 console.log('display success messages'); 326 parentFormSelect.replaceWith(json.content); 327 328 } 329 else{ 330 console.log('display error messages'); 331 } 332 } 333 334 }); 335 }); 336 337 //delete 338 $('#tabslist .delete').live("click", function(event) { 339 console.log('.delete clicked '); 340 event.preventDefault(); 341 var formData={}; 342 formData.ajax_request = true; 343 344 //?TODO formData.ajax_request = "edit_delete" 345 346 formData.edit_delete = 'Delete'; 347 var parentFormSelect = $(this).closest('li'); 348 formData.orig_id = parentFormSelect.find('.editform input[name="orig_id"]').val(); 349 formData.category = parentFormSelect.find('.editform input[name="category"]').val(); 350 $.ajax({ 351 type:'POST', 352 url: '@@plonetabs-controlpanel', 353 data: formData, 354 success: function(response) { 355 var json = JSON.parse(response) 356 console.log("response from server: "); 357 console.log(json); 358 if (json.status_code === 200){ 359 console.log('display success messages'); 360 parentFormSelect.remove() 361 } 362 else{ 363 console.log('display error messages'); 364 } 365 366 } 367 368 }); 369 }); 370 371 //visibility 372 $('#tabslist input.visibility').live("click", function(event) { 373 var formData={}; 374 formData.ajax_request = true; 375 console.log('#tabslist input.visibility clicked '); 376 formData.tabslist_visible = 'Set visibillity'; 377 var parentFormSelect = $(this).closest('li'); 378 formData.orig_id = parentFormSelect.find('.editform input[name="orig_id"]').val(); 379 formData.category = parentFormSelect.find('.editform input[name="category"]').val(); 380 formData.visibility = $(this).is(":checked"); 381 382 $.ajax({ 383 type:'POST', 384 url: '@@plonetabs-controlpanel', 385 data: formData, 386 success: function(response) { 387 var json = JSON.parse(response) 388 console.log("response from server: "); 389 console.log(json); 390 391 392 if (json.status_code === 200){ 393 console.log('display success messages'); 394 395 if (formData.visibility === true){ 396 parentFormSelect.removeClass("invisible"); 397 } 398 else{ 399 parentFormSelect.addClass("invisible"); 400 } 401 } 402 else{ 403 console.log('display error messages'); 404 } 405 } 406 407 }); 408 }); 409 410 //changing category 411 $('#select_category').change(function(event) { 412 var formData={}; 413 formData.ajax_request = true; 414 console.log('select_category changed '); 415 formData.category = $(this).val(); 416 formData.category_change = 'Change'; 417 $.ajax({ 418 type: 'POST', 419 url: '@@plonetabs-controlpanel', 420 data: formData, 421 success: function(response) { 422 var json = JSON.parse(response) 423 console.log(json); 424 if (json.status_code === 200){ 425 console.log('display success messages'); 426 $('form[name=addaction_form] input[name=category]').text($('#select_category').val()); 427 $('#tabslist').html(json.actionslist); 428 $('#autogeneration_section').html(json.section); 429 $('#plonetabs-form-title').text(json.title); 430 431 $('#addaction').removeClass('adding'); 432 toggleCollapsible($('form[name=addaction_form] .headerAdvanced'), true); 433 434 //Sorting lists 435 $('#tabslist').unbind(); 436 $('#tabslist').sortable().bind('sortupdate', function(){sortableList()}); 437 438 //Running startupActions 439 startupActions(); 440 } 441 else{ 442 console.log('display error messages'); 443 } 444 } 445 }); 446 }); 447 </script> 448 449 <script> 450 //portal_tabs methods 451 452 //visibility 453 $('#roottabs .visibility').live("click", function(event) { 454 var formData={}; 455 formData.ajax_request = true; 456 console.log('#roottabs .visibility clicked '); 457 formData.roottabs_visible = 'Visibillity'; 458 var parentFormSelect = $(this).closest('li'); 459 formData.orig_id = parentFormSelect.attr('id'); 460 formData.visibility = $(this).is(":checked"); 461 $.ajax({ 462 type:'POST', 463 url: '@@plonetabs-controlpanel', 464 data: formData, 465 success: function(response) { 466 var json = JSON.parse(response) 467 console.log("response from server: "); 468 console.log(json); 469 if (json.status_code === 200){ 470 console.log('display success messages'); 471 $('#portal-globalnav').load(' #portal-globalnav>*'); 472 if (formData.visibility === true){ 473 parentFormSelect.removeClass("invisible"); 474 } 475 else{ 476 parentFormSelect.addClass("invisible"); 477 } 478 479 } 480 else{ 481 console.log('display error messages'); 482 } 483 } 484 485 }); 486 }); 487 488 //General func for toggleGeneratedTabs and nonfolderish_tabs request 489 function sendRequest(field_name, checked_status){ 490 var formData={}; 491 formData.ajax_request = true; 492 formData.field = field_name; 493 formData.generated_tabs = checked_status; 494 $.ajax({ 495 type:'POST', 496 url: '@@plonetabs-controlpanel', 497 data: formData, 498 success: function(response) { 499 var json = JSON.parse(response) 500 console.log("response from server: "); 501 console.log(json); 502 if (json.status_code === 200){ 503 $('#roottabs').html(json.content); 504 $('#portal-globalnav').load(' #portal-globalnav>*'); 505 console.log('display success messages'); 506 } 507 else{ 508 console.log('display error messages'); 509 } 510 } 511 }); 512 } 513 514 //toggleGeneratedTabs 515 $('#generated_tabs').live("click", function() { 516 console.log('#generated_tabs clicked '); 517 var field_name = 'disable_folder_sections'; 518 var checked_status = $(this).is(":checked"); 519 sendRequest(field_name, checked_status); 520 }); 521 522 //nonfolderish_tabs 523 $('#nonfolderish_tabs').live("click", function() { 524 console.log('#nonfolderish_tabs clicked '); 525 var field_name = 'disable_nonfolderish_sections'; 526 var checked_status = $(this).is(":checked"); 527 sendRequest(field_name, checked_status); 528 }); 529 </script> 530 531 532 533 <script> 534 //Add new action methods 535 536 //focus 537 $("#actname").live("focus", function() { 538 console.log("#actname on focus"); 539 $('#addaction').addClass('adding'); 540 }); 541 542 //cancel 543 $('#buttoncancel').live("click", function(event) { 544 console.log('#buttoncancel clicked '); 545 event.preventDefault(); 546 $('#addaction').removeClass('adding'); 547 toggleCollapsible($('form[name=addaction_form] .headerAdvanced'), true); 548 //('#kssPortalMessage').css("display", "none"); 549 }); 550 551 //add 552 //TODO: add #addaction:submit event processing 553 $('#buttonadd').live("click", function(event) { 554 console.log('#buttonadd clicked '); 555 event.preventDefault(); 556 var formData = $(this).closest('form').serializeArray(); 557 formData.push({ name: "add_add", value: this.value }); 558 formData.push({ name: "ajax_request", value: true }); 559 formData.push({ name: "cat_name", value: $('#select_category').val() }); 560 561 $.ajax({ 562 type:'POST', 563 url: '@@plonetabs-controlpanel', 564 data: formData, 565 success: function(response) { 566 var json = JSON.parse(response) 567 console.log("response from server: "); 568 console.log(json); 569 if (json.status_code === 200){ 570 console.log('display success messages'); 571 572 $("#tabslist").append(json.content) 573 $("addaction").removeClass("adding"); 574 toggleCollapsible($('form[name=addaction_form] .headerAdvanced'), true); 575 576 //TODO 577 //self.kss_blur(ksscore.getHtmlIdSelector('actname')) 578 579 } 580 else{ 581 console.log('display error messages'); 582 583 //TODO 584 //if 'id' in errors or 'available_expr' in errors: 585 toggleCollapsible($('form[name=addaction_form] .headerAdvanced'), false); 586 587 588 } 589 } 590 }); 591 }); 592 </script> 161 593 </div> 162 594 -
quintagroup.plonetabs/branches/nokss/quintagroup/plonetabs/configure.zcml
r3598 r3680 20 20 <include package=".browser" /> 21 21 22 <include package=".plugins" />23 24 22 <!-- Javascript testing support --> 25 23 <configure zcml:condition="have kss_demo_version_1_2"> -
quintagroup.plonetabs/branches/nokss/setup.py
r3644 r3680 44 44 install_requires=[ 45 45 'setuptools', 46 'plone.app.kss',47 46 'plone.browserlayer' 48 47 # -*- Extra requirements: -*-
Note: See TracChangeset
for help on using the changeset viewer.