diff options
author | Kevin McCarthy <kmccarth@redhat.com> | 2007-09-28 11:55:56 -0700 |
---|---|---|
committer | Kevin McCarthy <kmccarth@redhat.com> | 2007-09-28 11:55:56 -0700 |
commit | b02e9bfd1f666d5106816118c0e67edc98beb652 (patch) | |
tree | fd1bfc6222c4f2d54be1d320d4632ecf2277d58f /ipa-server | |
parent | 8323959c3c4f7a4c561b695fc8ef85c5c92918a7 (diff) | |
download | freeipa-b02e9bfd1f666d5106816118c0e67edc98beb652.tar.gz freeipa-b02e9bfd1f666d5106816118c0e67edc98beb652.tar.xz freeipa-b02e9bfd1f666d5106816118c0e67edc98beb652.zip |
Extract the shared dynamic edit code.milestone_4
Rename groupeditsearch.kid to dynamiceditsearch.kid
Diffstat (limited to 'ipa-server')
-rw-r--r-- | ipa-server/ipa-gui/ipagui/controllers.py | 6 | ||||
-rw-r--r-- | ipa-server/ipa-gui/ipagui/static/javascript/dynamicedit.js | 171 | ||||
-rw-r--r-- | ipa-server/ipa-gui/ipagui/templates/dynamiceditsearch.kid (renamed from ipa-server/ipa-gui/ipagui/templates/groupeditsearch.kid) | 6 | ||||
-rw-r--r-- | ipa-server/ipa-gui/ipagui/templates/groupeditform.kid | 140 |
4 files changed, 181 insertions, 142 deletions
diff --git a/ipa-server/ipa-gui/ipagui/controllers.py b/ipa-server/ipa-gui/ipagui/controllers.py index a982cb593..45a94e023 100644 --- a/ipa-server/ipa-gui/ipagui/controllers.py +++ b/ipa-server/ipa-gui/ipagui/controllers.py @@ -444,13 +444,11 @@ class Root(controllers.RootController): turbogears.flash("Group add failed: " + str(e) + "<br/>" + str(e.detail)) return dict(form=group_new_form, tg_template='ipagui.templates.groupnew') - @expose("ipagui.templates.groupeditsearch") + @expose("ipagui.templates.dynamiceditsearch") @identity.require(identity.not_anonymous()) def groupedit_search(self, **kw): """Searches for users+groups and displays list of results in a table. - This method is used for the ajax search on the group edit page. - It's not re-usable because the ajax/dom manipulation is tightly - bound to the groupedit page""" + This method is used for the ajax search on the group edit page.""" client.set_krbccache(os.environ["KRB5CCNAME"]) users = [] groups = [] diff --git a/ipa-server/ipa-gui/ipagui/static/javascript/dynamicedit.js b/ipa-server/ipa-gui/ipagui/static/javascript/dynamicedit.js new file mode 100644 index 000000000..b25fb6c4a --- /dev/null +++ b/ipa-server/ipa-gui/ipagui/static/javascript/dynamicedit.js @@ -0,0 +1,171 @@ +/** + * dynamicedit.js + * + * Shared code, data, and functions for the dynamic add/remove lists on the + * edit group/user pages. + * + * These functions have specific expectations of the page they are used on: + * + * - If you want to preserve the dn_to_info_hash on round trip: + * - The form must have a 'form_dn_to_info_json' hidden field. + * - The form must have onsubmit="preSubmit()" set in its tag. + * - Restoring the contents of add/remove lists on round trip unfortunately + * can't be shared because it is a mixture of python and javascript. See + * the bottom part editgroup.kid for example code on this. + * + * - The page must have a div: 'newmembers' + * that new members are dynamically added to. + * + * - The page must have a div: 'delmembers' + * that removed members are dynamically added to. + * + * - Hidden fields called 'dnadd' and 'dndel' will be dynamically created, + * holding the values of the 'dn' passed to addmember() and removemember() + * + * Other Notes: + * + * - Many of the fields refer to 'dn'. There is no intrinsic reason this has + * to be a dn (it can hold any "unique id" for the objects to add/remove) + * + * - Similarly, the word 'member' is used because the code was originally + * written for editgroup. A 'member' is just a 'thing' to add/remove. + * On the useredit pages, for example, a 'member' is actually a group. + */ + +// Stored as the values in the dn_to_info_hash +MemberDisplayInfo = Class.create(); +MemberDisplayInfo.prototype = { + initialize: function(name, descr, type) { + this.name = name; + this.descr = descr; + this.type = type; + }, +}; + + +// this is used for round-trip recontruction of the names. +// the hidden fields only contain dns. +var dn_to_info_hash = new Hash(); + +// used to filter search results. +// records dns already in the group +var member_hash = new Hash(); + +// used to prevent double adding +// records dns to be added +var added_hash = new Hash(); + +// Tracks the div ids that each member belongs to. +// Since dn's will contain illegal characters for div ids, this is used +// to map them to the correct div +var dn_to_member_div_id = new Hash(); + + + +/* + * Renders the information about the member into the passed in + * element. This is used by addmember and removemember to + * consistently create the dom for the member information + * (name, descr) and add icons/font changes correct for each type. + */ +function renderMemberInfo(newdiv, info) { + if (info.type == "user") { + newdiv.appendChild(document.createTextNode( + info.name.escapeHTML() + " " + info.descr.escapeHTML() + " ")); + } else if (info.type == "group") { + ital = document.createElement('i'); + ital.appendChild(document.createTextNode( + info.name.escapeHTML() + " " + + info.descr.escapeHTML() + " ")); + newdiv.appendChild(ital); + } +} + +/* + * Callback used for afterFinish in scriptaculous effect + */ +function removeElement(effect) { + Element.remove(effect.element); +} + +function addmember(dn, info) { + dn_to_info_hash[dn] = info; + + if ((added_hash[dn] == 1) || (member_hash[dn] == 1)) { + return null; + } + added_hash[dn] = 1; + + var newdiv = document.createElement('div'); + renderMemberInfo(newdiv, info); + + var undolink = document.createElement('a'); + undolink.setAttribute('href', ''); + undolink.setAttribute('onclick', + 'new Effect.Fade(Element.up(this), {afterFinish: removeElement});' + + 'added_hash.remove("' + jsStringEscape(dn) + '");' + + 'return false;'); + undolink.appendChild(document.createTextNode("undo")); + newdiv.appendChild(undolink); + + var dnInfo = document.createElement('input'); + dnInfo.setAttribute('type', 'hidden'); + dnInfo.setAttribute('name', 'dnadd'); + dnInfo.setAttribute('value', dn); + newdiv.appendChild(dnInfo); + + newdiv.style.display = 'none'; + $('newmembers').appendChild(newdiv); + + return newdiv +} + +function addmemberHandler(element, dn, info) { + var newdiv = addmember(dn, info) + if (newdiv != null) { + new Effect.Fade(Element.up(element)); + new Effect.Appear(newdiv); + /* Element.up(element).remove(); */ + } +} + +function removemember(dn, info) { + dn_to_info_hash[dn] = info; + + var newdiv = document.createElement('div'); + renderMemberInfo(newdiv, info); + + orig_div_id = dn_to_member_div_id[dn]; + var undolink = document.createElement('a'); + undolink.setAttribute('href', ''); + undolink.setAttribute('onclick', + 'new Effect.Fade(Element.up(this), {afterFinish: removeElement});' + + "new Effect.Appear($('" + orig_div_id + "'));" + + 'return false;'); + undolink.appendChild(document.createTextNode("undo")); + newdiv.appendChild(undolink); + + var dnInfo = document.createElement('input'); + dnInfo.setAttribute('type', 'hidden'); + dnInfo.setAttribute('name', 'dndel'); + dnInfo.setAttribute('value', dn); + newdiv.appendChild(dnInfo); + + newdiv.style.display = 'none'; + $('delmembers').appendChild(newdiv); + + return newdiv +} + +function removememberHandler(element, dn, info) { + var newdiv = removemember(dn, info); + new Effect.Fade(Element.up(element)); + new Effect.Appear(newdiv); + /* Element.up(element).remove(); */ +} + +function preSubmit() { + var json = dn_to_info_hash.toJSON(); + $('form_dn_to_info_json').value = json; + return true; +} diff --git a/ipa-server/ipa-gui/ipagui/templates/groupeditsearch.kid b/ipa-server/ipa-gui/ipagui/templates/dynamiceditsearch.kid index 1e24cf14e..f69b11213 100644 --- a/ipa-server/ipa-gui/ipagui/templates/groupeditsearch.kid +++ b/ipa-server/ipa-gui/ipagui/templates/dynamiceditsearch.kid @@ -2,6 +2,12 @@ <?python from ipagui.helpers import ipahelper +# +# This file is used to render the results from an AJAX search onto a page. +# It has many expectations of the page being rendered into: +# - Source page must have included dynamicedit.js and followed all of its +# requirements +# ?> <div id="search-results-count"> </div> diff --git a/ipa-server/ipa-gui/ipagui/templates/groupeditform.kid b/ipa-server/ipa-gui/ipagui/templates/groupeditform.kid index e543b5fa5..ef33ec337 100644 --- a/ipa-server/ipa-gui/ipagui/templates/groupeditform.kid +++ b/ipa-server/ipa-gui/ipagui/templates/groupeditform.kid @@ -7,40 +7,12 @@ from ipagui.helpers import ipahelper ?> + <script type="text/javascript" charset="utf-8" + src="${tg.url('/static/javascript/dynamicedit.js')}"></script> <?python searchurl = tg.url('/groupedit_search') ?> <script type="text/javascript"> - - // Stored as the values in the dn_to_info_hash - MemberDisplayInfo = Class.create(); - MemberDisplayInfo.prototype = { - initialize: function(name, descr, type) { - this.name = name; - this.descr = descr; - this.type = type; - }, - }; - - - // this is used for round-trip recontruction of the names. - // the hidden fields only contain dns. - var dn_to_info_hash = new Hash(); - - // used to filter search results. - // records dns already in the group - var member_hash = new Hash(); - - // used to prevent double adding - // records dns to be added - var added_hash = new Hash(); - - // Tracks the div ids that each member belongs to. - // Since dn's will contain illegal characters for div ids, this is used - // to map them to the correct div - var dn_to_member_div_id = new Hash(); - - function toggleProtectedFields(checkbox) { var gidnumberField = $('form_gidnumber'); if (checkbox.checked) { @@ -52,108 +24,6 @@ from ipagui.helpers import ipahelper } } - /* - * Renders the information about the member into the passed in - * element. This is used by addmember and removemember to - * consistently create the dom for the member information - * (name, descr) and add icons/font changes correct for each type. - */ - function renderMemberInfo(newdiv, info) { - if (info.type == "user") { - newdiv.appendChild(document.createTextNode( - info.name.escapeHTML() + " " + info.descr.escapeHTML() + " ")); - } else if (info.type == "group") { - ital = document.createElement('i'); - ital.appendChild(document.createTextNode( - info.name.escapeHTML() + " " + - info.descr.escapeHTML() + " ")); - newdiv.appendChild(ital); - } - } - - /* - * Callback used for afterFinish in scriptaculous effect - */ - function removeElement(effect) { - Element.remove(effect.element); - } - - function addmember(dn, info) { - dn_to_info_hash[dn] = info; - - if ((added_hash[dn] == 1) || (member_hash[dn] == 1)) { - return null; - } - added_hash[dn] = 1; - - var newdiv = document.createElement('div'); - renderMemberInfo(newdiv, info); - - var undolink = document.createElement('a'); - undolink.setAttribute('href', ''); - undolink.setAttribute('onclick', - 'new Effect.Fade(Element.up(this), {afterFinish: removeElement});' + - 'added_hash.remove("' + jsStringEscape(dn) + '");' + - 'return false;'); - undolink.appendChild(document.createTextNode("undo")); - newdiv.appendChild(undolink); - - var dnInfo = document.createElement('input'); - dnInfo.setAttribute('type', 'hidden'); - dnInfo.setAttribute('name', 'dnadd'); - dnInfo.setAttribute('value', dn); - newdiv.appendChild(dnInfo); - - newdiv.style.display = 'none'; - $('newmembers').appendChild(newdiv); - - return newdiv - } - - function addmemberHandler(element, dn, info) { - var newdiv = addmember(dn, info) - if (newdiv != null) { - new Effect.Fade(Element.up(element)); - new Effect.Appear(newdiv); - /* Element.up(element).remove(); */ - } - } - - function removemember(dn, info) { - dn_to_info_hash[dn] = info; - - var newdiv = document.createElement('div'); - renderMemberInfo(newdiv, info); - - orig_div_id = dn_to_member_div_id[dn]; - var undolink = document.createElement('a'); - undolink.setAttribute('href', ''); - undolink.setAttribute('onclick', - 'new Effect.Fade(Element.up(this), {afterFinish: removeElement});' + - "new Effect.Appear($('" + orig_div_id + "'));" + - 'return false;'); - undolink.appendChild(document.createTextNode("undo")); - newdiv.appendChild(undolink); - - var dnInfo = document.createElement('input'); - dnInfo.setAttribute('type', 'hidden'); - dnInfo.setAttribute('name', 'dndel'); - dnInfo.setAttribute('value', dn); - newdiv.appendChild(dnInfo); - - newdiv.style.display = 'none'; - $('delmembers').appendChild(newdiv); - - return newdiv - } - - function removememberHandler(element, dn, info) { - var newdiv = removemember(dn, info); - new Effect.Fade(Element.up(element)); - new Effect.Appear(newdiv); - /* Element.up(element).remove(); */ - } - function enterDoSearch(e) { var keyPressed; if (window.event) { @@ -178,12 +48,6 @@ from ipagui.helpers import ipahelper evalScripts: true }); return false; } - - function preSubmit() { - var json = dn_to_info_hash.toJSON(); - $('form_dn_to_info_json').value = json; - return true; - } </script> <div py:for="field in hidden_fields" |