On 09/30/2010 09:18 AM, Adam Young wrote:
On 09/29/2010 11:07 PM, Endi Sukma Dewata wrote:
----- "Adam Young"<ayo...@redhat.com>  wrote:

Should have remembered this approach, standard JS way to deal with
undefined values.
   admiyo-freeipa-0048-3-Item-Level-Undo.patch

A few notes:

1. You're replying to the wrong thread :)

Fixed :)

2. The undo button will only appear when the input field loses focus. Ideally it should appear as soon as the value is changed, but I'm not sure if it's
possible to do that in JS. This can be addressed in the future.

Right. I was scared off by the docs that claimedthings were so different between browsers for the keydown and keypress events, but it looks like whatever differences there are are irrelevant here. Change to triggering on keydown.

3. The hint_span doesn't seem to be used consistently in details.js:272-297:

ipa_insert_first_dd(
     jobj, ipa_create_input(obj_name, attr, value[0],hint_span)
);
ipa_insert_other_dd(
     jobj, ipa_create_input(obj_name, attr, value[i],hint_span)
);
ipa_insert_other_dd(
     jobj.next(), _ipa_a_add_template.replace('A', attr)
);
ipa_insert_first_dd(
jobj, _ipa_a_add_template.replace('A', attr) /*.append( hint_span)*/
);
ipa_insert_first_dd(
     jobj, ipa_create_input(obj_name, attr, '')/*.append( hint_span)*/
);

Yeah, but that mirrors the original code. I think figuring out where to put the hintspan and how to trigger it is a different patch. Hintspan should probably not be duplicated like this at all.

4. I think the statement on line 341 should be removed because it redefines
    the input variable:

         var input = $("<label>",{html:value.toString()});

5. There is a trailing whitespace on line 337.
Why, so there is....was.
Thanks!

--
Endi S. Dewata

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

From 232353fa7822d71d4c01569849acee7e1f578d7d Mon Sep 17 00:00:00 2001
From: Adam Young <ayo...@redhat.com>
Date: Wed, 29 Sep 2010 16:57:07 -0400
Subject: [PATCH] Item Level Undo

Also adding some unit tests for details.
Using JQuery UI buttons for update and reset

Now triggers on keydown, not change
---
 install/static/details.js                   |  146 +++++++++++++++++----------
 install/static/test/all_tests.html          |    1 +
 install/static/test/data/json_metadata.json |    2 +-
 install/static/test/details_tests.html      |   22 ++++
 install/static/test/details_tests.js        |   92 +++++++++++++++++
 install/static/test/index.html              |    1 +
 6 files changed, 208 insertions(+), 56 deletions(-)
 create mode 100644 install/static/test/details_tests.html
 create mode 100644 install/static/test/details_tests.js

diff --git a/install/static/details.js b/install/static/details.js
index 4e37ed6..e08aac3 100644
--- a/install/static/details.js
+++ b/install/static/details.js
@@ -1,5 +1,6 @@
 /*  Authors:
  *    Pavel Zuna <pz...@redhat.com>
+ *    Adam Young <ayo...@redhat.com>
  *
  * Copyright (C) 2010 Red Hat
  * see file 'COPYING' for use and warranty information
@@ -43,8 +44,8 @@ function ipa_details_create(obj_name, dls, container)
 
     details.append('<div class="details-buttons"></div>');
     var jobj = details.children().last();
-    jobj.append('<a class="details-reset" href="jslink">Reset</a>');
-    jobj.append('<a class="details-update" href="jslink">Update</a>');
+    jobj.append('<a class="details-reset ui-state-default ui-corner-all input_link " href="jslink"><span class="ui-icon ui-icon-refresh" ></span> Reset</a>');
+    jobj.append('<a class="details-update ui-state-default ui-corner-all input_link  " href="jslink"><span class="ui-icon ui-icon-check" ></span>Update</a>');
 
     details.append('<hr />');
 
@@ -58,21 +59,23 @@ function ipa_details_create(obj_name, dls, container)
     jobj.append('<a href="#details-viewtype">Back to Top</a>');
 }
 
-var _ipa_h2_template = '<h2 onclick="_h2_on_click(this)">&#8722; I</h2>';
-var _ipa_dl_template = '<dl id="I" class="entryattrs"></dl>';
-var _ipa_dt_template = '<dt title="T">N:</dt>';
 
 function ipa_generate_dl(jobj, id, name, dts)
 {
     if (!dts)
         return;
 
-    var obj_name = jobj.parent().attr('title');
+    var parent = jobj.parent();
+    var obj_name = parent.attr('title');
 
-    jobj.after(_ipa_h2_template.replace('I', name));
-    jobj = jobj.next();
-    jobj.after(_ipa_dl_template.replace('I', id));
-    jobj = jobj.next();
+    parent.append($("<h2/>",{
+        click: function(){_h2_on_click(this)},
+        html:"&#8722; "+name
+    }));
+
+    var dl = $('<dl></dl>',{
+        id:id,
+        "class":"entryattrs"})
 
     for (var i = 0; i < dts.length; ++i) {
         var label = '';
@@ -83,12 +86,14 @@ function ipa_generate_dl(jobj, id, name, dts)
         }
         if ((!label) && (dts[i].length > 1))
             label = dts[i][1];
-        jobj.append(
-            _ipa_dt_template.replace('T', dts[i][0]).replace('N', label)
+        dl.append(
+            $('<dt/>',{
+                title:dts[i][0],
+                html:label+":"})
         );
     }
-
-    jobj.after('<hr />');
+    parent.append(dl);
+    parent.append('<hr/>');
 }
 
 function ipa_details_load(jobj, pkey, on_win, on_fail)
@@ -210,6 +215,7 @@ function ipa_details_update(obj_name, pkey, on_win, on_fail)
 var _ipa_a_add_template =
     '<a href="jslink" onclick="return (_ipa_add_on_click(this))" title="A">Add</a>';
 var _ipa_span_doc_template = '<span class="attrhint">Hint: D</span>';
+var _ipa_span_hint_template = '<span class="attrhint">Hint: D</span>';
 
 /* populate definition lists with the class 'entryattrs' with entry attributes
  *
@@ -248,26 +254,29 @@ function ipa_details_display(obj_name, entry_attrs)
         } else {
             /* title contains attribute name - default behaviour */
             var multivalue = false;
-            var hint_span = '';
+            var hint_span = null;
 
             var param_info = ipa_get_param_info(obj_name, attr);
             if (param_info) {
                 if (param_info['multivalue'] || param_info['class'] == 'List')
                     multivalue = true;
                 var hint = param_info['hint'];
-                if (hint)
-                    hint_span = _ipa_span_hint_template.replace('D', hint);
+                if (hint){
+                    hint_span = $("<span />",{
+                        "class":"attrhint",
+                        html:"Hint: " + hint});
+                }
             }
 
             var value = entry_attrs[attr];
             if (value) {
                 ipa_insert_first_dd(
-                    jobj, ipa_create_input(obj_name, attr, value[0]) + hint_span
+                    jobj, ipa_create_input(obj_name, attr, value[0],hint_span)
                 );
                 for (var i = 1; i < value.length; ++i) {
                     jobj = jobj.next();
                     ipa_insert_other_dd(
-                      jobj, ipa_create_input(obj_name, attr, value[i])
+                      jobj, ipa_create_input(obj_name, attr, value[i],hint_span)
                     );
                 }
                 if (multivalue) {
@@ -278,11 +287,11 @@ function ipa_details_display(obj_name, entry_attrs)
             } else {
                 if (multivalue) {
                     ipa_insert_first_dd(
-                        jobj, _ipa_a_add_template.replace('A', attr) + hint_span
+                        jobj, _ipa_a_add_template.replace('A', attr) /*.append( hint_span)*/
                     );
                 } else {
                     ipa_insert_first_dd(
-                        jobj, ipa_create_input(obj_name, attr, '') + hint_span
+                        jobj, ipa_create_input(obj_name, attr, '')/*.append( hint_span)*/
                     );
                 }
             }
@@ -290,18 +299,16 @@ function ipa_details_display(obj_name, entry_attrs)
     });
 }
 
-var _ipa_dd_first_template = '<dd class="first">I</dd>';
 
 function ipa_insert_first_dd(jobj, content)
 {
-    jobj.after(_ipa_dd_first_template.replace('I', content));
-}
+    jobj.after( $('<dd class="first"></dd>').append(content))
 
-var _ipa_dd_other_template = '<dd class="other">I</dd>';
+}
 
 function ipa_insert_other_dd(jobj, content)
 {
-    jobj.after(_ipa_dd_other_template.replace('I', content));
+    jobj.after($('<dd class="other"></dd>').append(content));
 }
 
 
@@ -317,32 +324,37 @@ var _ipa_param_type_2_handler_map = {
  * arguments:
  *   attr - LDAP attribute name
  *   value - the attributes value */
-function ipa_create_input(obj_name, attr, value)
+function ipa_create_input(obj_name, attr, value,hint)
 {
+    var input = $("<label>",{html:value.toString()});
     var param_info = ipa_get_param_info(obj_name, attr);
     if (!param_info) {
         /* no information about the param is available, default to text input */
-        return (_ipa_create_text_input(attr, value, null));
-    }
-
-    /* check if the param value can be modified */
-    if (param_info['primary_key'] || ('no_update' in param_info['flags']))
-        return (value.toString());
-
-    /* call handler by param class */
-    var handler = _ipa_param_type_2_handler_map[param_info['class']];
-    if (handler) {
-        if (param_info['multivalue'] || param_info['class'] == 'List') {
-            return (
-                handler(attr, value, param_info) +
-                    _ipa_create_remove_link(attr, param_info)
-            );
+        input = _ipa_create_text_input(attr, value, null);
+        if (hint){
+            input.after(hint);
+        }
+    }else if (param_info['primary_key'] || 
+              ('no_update' in param_info['flags'])){
+        /* check if the param value can be modified */
+        input = (value.toString());
+        var input = $("<label>",{html:value.toString()});
+    }else{
+        /* call handler by param class */
+        var handler = _ipa_param_type_2_handler_map[param_info['class']];
+        if (handler) {
+            if (param_info['multivalue'] || param_info['class'] == 'List') {
+                input = handler(attr, value, param_info) +
+                    _ipa_create_remove_link(attr, param_info);
+            }else{
+                input =  (handler(attr, value, param_info));
+                if (hint){
+                    input.after(hint);
+                }
+            }
         }
-        return (handler(attr, value, param_info));
     }
-
-    /* no handler for this type? don't allow modification */
-    return (value.toString());
+    return input;
 }
 
 /* HTML template for _ipa_create_remove_link() */
@@ -363,24 +375,48 @@ function _ipa_create_remove_link(attr, param_info)
     return (_ipa_a_remove_template.replace('A', attr));
 }
 
-/* HTML template for _ipa_create_text_input() */
-var _ipa_input_text_template =
-    '<input type="text" name="A" value="V" />';
 
 /* creates a input box for editing a string attribute */
 function _ipa_create_text_input(attr, value, param_info)
 {
-    return (
-        _ipa_input_text_template.replace('A', attr).replace(
-            'V', value.toString()
-        )
-    );
+    return $("<input/>",{
+        type:"text",
+        name:attr,
+        value:value.toString(),
+        keypress: function(){
+            var validation_info=param_info;
+            var undo_link=this.nextElementSibling;
+            undo_link.style.display ="inline";
+            if(false){
+                var error_link = undo_link.nextElementSibling;
+                error_link.style.display ="block";
+            }
+        }
+    }).after($("<a/>",{
+        html:"undo",
+        "class":"ui-state-highlight ui-corner-all",
+        style:"display:none",
+        click: function(){
+            var key = this.previousElementSibling.name;
+            var entity_divs = $(this).parents('.details-container');
+            var entry_attrs = ipa_details_cache[entity_divs[0].id];
+            var previous_value = entry_attrs[key] || "";
+            this.previousElementSibling.value =  previous_value;
+            this.style.display = "none";
+        }
+    })).after($("<span/>",{
+        html:"Does not match pattern",
+        "class":"ui-state-error ui-corner-all",
+        style:"display:none",
+    }));
+
 }
 
 function ipa_details_reset(obj_name)
 {
-    if (ipa_details_cache[obj_name])
+    if (ipa_details_cache[obj_name]){
         ipa_details_display(obj_name, ipa_details_cache[obj_name]);
+    }
 
 }
 
diff --git a/install/static/test/all_tests.html b/install/static/test/all_tests.html
index 93c4de2..aede08e 100644
--- a/install/static/test/all_tests.html
+++ b/install/static/test/all_tests.html
@@ -15,6 +15,7 @@
     <script type="text/javascript" src="../associate.js"></script>
     <script type="text/javascript" src="../navigation.js"></script>
     <script type="text/javascript" src="ipa_tests.js"></script>
+    <script type="text/javascript" src="details_tests.js"></script>
     <script type="text/javascript" src="entity_tests.js"></script>
     <script type="text/javascript" src="association_tests.js"></script>
     <script type="text/javascript" src="navigation_tests.js"></script>
diff --git a/install/static/test/data/json_metadata.json b/install/static/test/data/json_metadata.json
index ef8c77b..b4f9798 100644
--- a/install/static/test/data/json_metadata.json
+++ b/install/static/test/data/json_metadata.json
@@ -3103,7 +3103,7 @@
                         "doc": "User login",
                         "exclude": null,
                         "flags": [],
-                        "hint": null,
+                        "hint": "Numeric user Identifer",
                         "include": null,
                         "label": "User login",
                         "length": null,
diff --git a/install/static/test/details_tests.html b/install/static/test/details_tests.html
new file mode 100644
index 0000000..e1b3525
--- /dev/null
+++ b/install/static/test/details_tests.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>Details Test Suite</title>
+    <link rel="stylesheet" href="qunit.css" type="text/css" media="screen">
+    <script type="text/javascript" src="qunit.js"></script>
+    <script type="text/javascript" src="../jquery.js"></script>
+    <script type="text/javascript" src="../jquery.ba-bbq.js"></script>
+    <script type="text/javascript" src="../jquery-ui.js"></script>
+    <script type="text/javascript" src="../ipa.js"></script>
+    <script type="text/javascript" src="../details.js"></script>
+    <script type="text/javascript" src="details_tests.js"></script>
+</head>
+<body>
+    <h1 id="qunit-header">Details Test Suite</h1>
+    <h2 id="qunit-banner"></h2>
+    <div id="qunit-testrunner-toolbar"></div>
+    <h2 id="qunit-userAgent"></h2>
+    <ol id="qunit-tests"></ol>
+    <div id="qunit-fixture">test markup</div>
+</body>
+</html>
diff --git a/install/static/test/details_tests.js b/install/static/test/details_tests.js
new file mode 100644
index 0000000..ee5d396
--- /dev/null
+++ b/install/static/test/details_tests.js
@@ -0,0 +1,92 @@
+/*  Authors:
+ *    Adam Young <ayo...@redhat.com>
+ *
+ * Copyright (C) 2010 Red Hat
+ * see file 'COPYING' for use and warranty information
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 only
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+
+test("Testing ipa_details_create().", function() {
+
+    var details = [
+        ['identity', 'Entity Details', [
+            ['cn', 'Entity Name'],
+            ['description', 'Description'],
+            ['number', 'Entity ID']
+        ]]
+    ];
+
+    var identity = details[0];
+    var attrs=identity[2];
+    var key = 'entity';
+
+    var container = $("<div/>",{id: "container"});
+    ipa_details_create(key, details, container)
+
+    same(container[0].title,key);
+    var dl = container.find('dl#identity');
+    ok(dl );
+
+    same(dl[0].children.length, attrs.length);
+
+});
+
+
+test("Testing  _ipa_create_text_input().", function(){
+
+    var name = "name";
+    var value="value";
+    var input = _ipa_create_text_input(name, value);
+    ok(input,"input not null");
+
+    same(input[0].name,name );
+    same(input[0].value,value );
+    same(input[0].type,"text" );
+});
+
+
+
+test("Testing ipa_generate_dl()",function(){
+
+    var details = [
+        ['cn', 'Entity Name'],
+        ['description', 'Description'],
+        ['number', 'Entity ID']
+    ];
+    var name = 'NAMENAMENAME';
+    var identity = 'IDIDID';
+    var parent = $("<div/>");
+    var jobj = $("<div title='entity'/>");
+    parent.append(jobj);
+    ipa_generate_dl(jobj, identity,name, details);
+
+    ok(parent.find('hr'));
+
+    var h2= parent.find('h2');
+    ok(h2);
+    ok(h2[0].innerHTML.indexOf(name) > 1,"find name in html");
+
+    var dl = parent.find('dl');
+    ok(dl);
+    same(dl[0].children.length,3);
+    same(dl[0].id, identity);
+    same(dl[0].children[0].title,details[0][0]);
+    same(dl[0].children[0].innerHTML,details[0][1]+":");
+    same(dl[0].children[2].title,details[2][0]);
+    same(dl[0].children[2].innerHTML,details[2][1]+":");
+
+});
\ No newline at end of file
diff --git a/install/static/test/index.html b/install/static/test/index.html
index 5c4607a..a71ee60 100644
--- a/install/static/test/index.html
+++ b/install/static/test/index.html
@@ -26,6 +26,7 @@
         <ul>
         <li><a href="ipa_tests.html">Core Test Suite</a>
         <li><a href="entity_tests.html">Entity Test Suite</a>
+        <li><a href="details_tests.html">Details Test Suite</a>
         <li><a href="association_tests.html">Association Test Suite</a>
         <li><a href="navigation_tests.html">Navigation Test Suite</a>
 
-- 
1.7.1

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to