mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2026-10-13 17:02:02 -05:00
Extract the shared dynamic edit code.
Rename groupeditsearch.kid to dynamiceditsearch.kid
This commit is contained in:
1 parent
8323959c3c
commit
b02e9bfd1f
4 files changed
+181
-142
No files matched your search
@@ -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 = []
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
+6
@@ -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>
|
||||
@@ -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"
|
||||
|
||||
Reference in new issue
Block a user