Zur Navigation

Layer immer im Vordergrund

1 Moritz (Gast)

Hallo Jörg,

nachdem du mir das letzte mal so super weitergeholfen hast, hoffe ich auch diesmal auf eine geniale idee von dir ;-)

Meine Datenbank ist inzwischen fast fertig, ich feile grad noch an den letzten Feinheiten.

Folgendes Problem habe ich selbst nach stundenlangem probieren nicht hinbekommen:
Ein Feld in meiner DB soll nach Klicken auf den statischen Text zum mehrzeiligen Input feld werden was ich mit einem "edit in place" plugin für jQuery auch schon hinbekommen habe.
Da jetzt aber alle diese Felder tabellenbedingt untereinander stehen und damit das gerade angeklickte zwangsweise die darunterstehenden überlagert ergibt sich folgendes problem:
Den statischen Text umgibt ein div das mit position:absolute schwebend über die tabelle gesetzt wird damit sich die tabelle nicht verzieht wenn man auf den text klickt. Nach dem Klick steht leider der Text des darunterliegenden Datensatzes über dem mehrzeiligen eingabefeld. Sieht natürlich sehr unschön aus.

Kennst du eine möglichkeit das aufpoppende Eingabefeld als höchste Ebene zu deklarieren? Mit z-index, also css habe ich es schon versucht allerdings kann ich offenbar nur das div stylen nicht das input feld selbst.

Ich benutze jeditable was du hier finden kannst.
Sämtliche styling vorgaben die darin angeboten werden funktionieren bei mir nicht, oder ich bin zu blöd sie aufzurufen.

Vielen Dank schonmal im vorraus,
Lieben Gruß,
Moritz

18.12.2007 15:41

2 Jörg Kruse

Hallo Moritz,

es wäre gut, wenn du eine Demo-Seite verlinkst oder einen Beispiel-Code postest, damit man die Problematik besser nachvollziehen kann

18.12.2007 15:51

3 Moritz (Gast)

Ok,
hier der code des divs:

<div class="edit" id="<?php echo $ab_Daten_ID; ?>"><?php if($ab_Daten_warum != ""){ echo $ab_Daten_warum_kurz; }else{ echo "n.V."; } ?></div>

der CSS:

.edit {
position: absolute;
height: auto;
width: 48px;
}

der aufruf des javascripts:

<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
     $(".edit").editable("db/update.php?type=bemerkung_db", {
	 	 loadurl  	: "db/load.php?type=bemerkung",
type      : 'textarea',
		 indicator 	: "Speichert...",
		 tooltip   	: 'Bemerkung eintragen?',
		 onblur 	: 'submit',
	 });
});
</script>

Und der jeditable code:

/*
 * Jeditable - jQuery in place edit plugin
 *
 * Copyright (c) 2006-2007 Mika Tuupola, Dylan Verheul
 *
 * Licensed under the MIT license:
 *   http://www.opensource.org/licenses/mit-license.php
 *
 * Revision: $Id: jquery.jeditable.js 285 2007-11-13 14:44:00Z tuupola $
 *
 */

/**
  * Based on editable by Dylan Verheul <dylan@dyve.net>
  * http://www.dyve.net/jquery/?editable
  *
  * Version 1.5.1
  *
  * @name  Jeditable
  * @type  jQuery
  * @param String  target             POST URL or function name to send edited content
  * @param Hash    options            additional options 
  * @param String  options[name]      POST parameter name of edited content
  * @param String  options[id]        POST parameter name of edited div id
  * @param Hash    options[submitdata] Extra parameters to send when submitting edited content.
  * @param String  options[type]      text, textarea or select
  * @param Integer options[rows]      number of rows if using textarea
  * @param Integer options[cols]      number of columns if using textarea
  * @param Mixed   options[height]    'auto', 'none' or height in pixels
  * @param Mixed   options[width]     'auto', 'none' or width in pixels 
  * @param String  options[loadurl]   URL to fetch external content before editing
  * @param String  options[loadtype]  Request type for load url. Should be GET or POST.
  * @param String  options[loadtext]  Text to display while loading external content.
  * @param Hash    options[loaddata]  Extra parameters to pass when fetching content before editing.
  * @param String  options[data]      Or content given as paramameter.
  * @param String  options[indicator] indicator html to show when saving
  * @param String  options[tooltip]   optional tooltip text via title attribute
  * @param String  options[event]     jQuery event such as 'click' of 'dblclick'
  * @param String  options[onblur]    'cancel', 'submit' or 'ignore'
  * @param String  options[submit]    submit button value, empty means no button
  * @param String  options[cancel]    cancel button value, empty means no button
  * @param String  options[cssclass]  CSS class to apply to input form. 'inherit' to copy from parent.
  * @param String  options[style]     Style to apply to input form 'inherit' to copy from parent.
  * @param String  options[select]    true or false, when true text is highlighted
  * @param String  options[placeholder] Placeholder text or html to insert when element is empty.
  *             
  */
(function($) {

    $.fn.editable = function(target, options) {
    	
        var settings = {
            target     : target,
            name       : 'value',
            id         : 'id',
            type       : 'text',
            width      : '200',
            height     : '30',
            event      : 'click',
            onblur     : 'cancel',
            loadtype   : 'GET',
            loadtext   : 'Loading...',
            placeholder: 'n.V.',
			style	   : 'z-index:10;', /* Meine kläglichen Versuche das Feld im aufruf in den Vordergrund zu bringen */
			cssclass   : '.editform',
            loaddata   : {},
            submitdata : {}
        };
        
        if(options) {
            $.extend(settings, options);
        }
    
        /* setup some functions */
        var plugin   = $.editable.types[settings.type].plugin || function() { };
        var submit   = $.editable.types[settings.type].submit || function() { };
        var buttons  = $.editable.types[settings.type].buttons 
                    || $.editable.types['defaults'].buttons;
        var content  = $.editable.types[settings.type].content 
                    || $.editable.types['defaults'].content;
        var element  = $.editable.types[settings.type].element 
                    || $.editable.types['defaults'].element;
        var callback = settings.callback || function() { };
          
        $(this).attr('title', settings.tooltip);
        
        settings.autowidth  = 'auto' == settings.width;
        settings.autoheight = 'auto' == settings.height;

        return this.each(function() {
            
            /* if element is empty add something clickable (if requested) */
            if (!$.trim($(this).html())) {
                $(this).html(settings.placeholder);
            }
            
            $(this)[settings.event](function(e) {

                /* save this to self because this changes when scope changes */
                var self = this;

                /* prevent throwing an exeption if edit field is clicked again */
                if (self.editing) {
                    return;
                }

                /* figure out how wide and tall we are */
                if (settings.width != 'none') {
                    settings.width = 
                        settings.autowidth ? $(self).width()  : settings.width;
                }
                if (settings.height != 'none') {
                    settings.height = 
                        settings.autoheight ? $(self).height() : settings.height;
                }
                
                /* remove placeholder text, replace is here because of IE */
                if ($(this).html().toLowerCase().replace(/;/, '') == 
                    settings.placeholder.toLowerCase().replace(/;/, '')) {
                        $(this).html('');
                }
                                
                self.editing    = true;
                self.revert     = $(self).html();
                $(self).html('');

                /* create the form object */
                var form = $('<form/>');

                /* add created form to self */
                $(self).append(form);
                
                /* apply css or style or both */
                if (settings.cssclass) {
                    if ('inherit' == settings.cssclass) {
                        form.attr('class', $(self).attr('class'));
                    } else {
                        form.attr('class', settings.cssclass);
                    }
                }
        
                if (settings.style) {
                    if ('inherit' == settings.style) {
                        form.attr('style', $(self).attr('style'));
                        /* IE needs the second line or display wont be inherited */
                        form.css('display', $(self).css('display'));                
                    } else {
                        form.attr('style', settings.style);
                    }
                }
        
                /* add main input element to form and store it in input */
                var input = element.apply(form, [settings, self]);

                /* set input content via POST, GET, given data or existing value */
                var input_content;
                
                if (settings.loadurl) {
                    var t = setTimeout(function() {
                        input.disabled = true;
                        content.apply(form, [settings.loadtext, settings, self]);
                    }, 100);

                    var loaddata = {};
                    loaddata[settings.id] = self.id;
                    if ($.isFunction(settings.loaddata)) {
                        $.extend(loaddata, settings.loaddata.apply(self, [self.revert, settings]));
                    } else {
                        $.extend(loaddata, settings.loaddata);
                    }
                    $.ajax({
                       type : settings.loadtype,
                       url  : settings.loadurl,
                       data : loaddata,
                       async : false,
                       success: function(result) {
                       	  window.clearTimeout(t);
                       	  input_content = result;
                          input.disabled = false;
                       }
                    });
                } else if (settings.data) {
                    input_content = settings.data;
                    if ($.isFunction(settings.data)) {
                        input_content = settings.data.apply(self, [self.revert, settings]);
                    }
                } else {
                    input_content = self.revert; 
                }
                content.apply(form, [input_content, settings, self]);

                input.attr('name', settings.name);
        
                /* add buttons to the form */
                buttons.apply(form, [settings, self]);

                /* highlight input contents when requested */
                if (settings.select) {
                    input.select();
                }
         
                /* attach 3rd party plugin if requested */
                plugin.apply(form, [settings, self]);

                /* focus to first visible form element */
                $(':input:visible:enabled:first', form).focus();
        
                /* discard changes if pressing esc */
                input.keydown(function(e) {
                    if (e.keyCode == 27) {
                        e.preventDefault();
                        reset();
                    }
                });

                /* discard, submit or nothing with changes when clicking outside */
                /* do nothing is usable when navigating with tab */
                var t;
                if ('cancel' == settings.onblur) {
                    input.blur(function(e) {
                        t = setTimeout(reset, 500);
                    });
                } else if ('submit' == settings.onblur) {
                    input.blur(function(e) {
                        form.submit();
                    });
                } else if ($.isFunction(settings.onblur)) {
                    input.blur(function(e) {
                        settings.onblur.apply(self, [input.val(), settings]);
                    });
                } else {
                    input.blur(function(e) {
                      /* TODO: maybe something here */
                    });
                }

                form.submit(function(e) {

                    if (t) { 
                        clearTimeout(t);
                    }

                    /* do no submit */
                    e.preventDefault(); 
            
                    /* if this input type has a call before submit hook, call it */
                    submit.apply(form, [settings, self]);

                    /* check if given target is function */
                    if ($.isFunction(settings.target)) {
                        var str = settings.target.apply(self, [input.val(), settings]);
                        $(self).html(str);
                        self.editing = false;
                        callback.apply(self, [self.innerHTML, settings]);
                        /* TODO: this is not dry */                              
                        if (!$.trim($(self).html())) {
                            $(self).html(settings.placeholder);
                        }
                    } else {
                        /* add edited content and id of edited element to POST */
                        var submitdata = {};
                        submitdata[settings.name] = input.val();
                        submitdata[settings.id] = self.id;
                        /* add extra data to be POST:ed */
                        if ($.isFunction(settings.submitdata)) {
                            $.extend(submitdata, settings.submitdata.apply(self, [self.revert, settings]));
                        } else {
                            $.extend(submitdata, settings.submitdata);
                        }          

                        /* show the saving indicator */
                        $(self).html(settings.indicator);
                        $.post(settings.target, submitdata, function(str) {
                            $(self).html(str);
                            self.editing = false;
                            callback.apply(self, [self.innerHTML, settings]);
                            /* TODO: this is not dry */                              
                            if (!$.trim($(self).html())) {
                                $(self).html(settings.placeholder);
                            }
                        });
                    }
                     
                    return false;
                });

                function reset() {
                    $(self).html(self.revert);
                    self.editing   = false;
                    if (!$.trim($(self).html())) {
                        $(self).html(settings.placeholder);
                    }
                }

            });
        });

    };


    $.editable = {
        types: {
            defaults: {
                element : function(settings, original) {
                    var input = $('<input type="hidden">');                
                    $(this).append(input);
                    return(input);
                },
                content : function(string, settings, original) {
                    $(':input:first', this).val(string);
                },
                buttons : function(settings, original) {
                    if (settings.submit) {
                        var submit = $('<input type="submit">');
                        submit.val(settings.submit);
                        $(this).append(submit);
                    }
                    if (settings.cancel) {
                        var cancel = $('<input type="button">');
                        cancel.val(settings.cancel);
                        $(this).append(cancel);

                        $(cancel).click(function() {
                            $(original).html(original.revert);
                            original.editing = false;
                        });
                    }
                }
            },
            text: {
                element : function(settings, original) {
                    var input = $('<input>');
                    if (settings.width  != 'none') { input.width(settings.width);  }
                    if (settings.height != 'none') { input.height(settings.height); }
                    /* https://bugzilla.mozilla.org/show_bug.cgi?id=236791 */
                    //input[0].setAttribute('autocomplete','off');
                    input.attr('autocomplete','off');
                    $(this).append(input);
                    return(input);
                }
            },
            textarea: {
                element : function(settings, original) {
                    var textarea = $('<textarea>');
                    if (settings.rows) {
                        textarea.attr('rows', settings.rows);
                    } else {
                        textarea.height(settings.height);
                    }
                    if (settings.cols) {
                        textarea.attr('cols', settings.cols);
                    } else {
                        textarea.width(settings.width);
                    }
                    $(this).append(textarea);
                    return(textarea);
                }
            },
            select: {
                element : function(settings, original) {
                    var select = $('<select>');
                    $(this).append(select);
                    return(select);
                },
                content : function(string, settings, original) {
                    if (String == string.constructor) { 	 
                        eval ('var json = ' + string);
                        for (var key in json) {
                            if ('selected' == key) {
                                continue;
                            } 
                            var option = $('<option>').val(key).append(json[key]);
                            $('select', this).append(option); 	 
                        }
                    }
                    /* Loop option again to set selected. IE needed this... */ 
                    $('select', this).children().each(function() {
                        if ($(this).val() == json['selected']) {
                            $(this).attr('selected', 'selected');
                        };
                    });
                }
            }
        },

        /* Add new input type */
        addInputType: function(name, input) {
            $.editable.types[name] = input;
        }
    };

})(jQuery);

Eine Beispielseite kann ich leider momentan nicht posten da zuviele sensible Unternehmensdaten in der Datenbank stehen.

Hoffe ich habe dich mit dem vielen Code nicht überfordert und es ist auch nicht zu unverschämt dich mit solchen problemen von der Arbeit abzuhalten *liebguck*

Lieben Gruß,
Moritz

18.12.2007 16:20

4 Jörg Kruse

Hallo Moritz,

richtig nachvollziehen kann ich die von dir beschriebene Problematik mit dem Code leider noch nicht. Du schreibst z.B: etwas von einer Tabelle, die überlagert wird?

Eine Beispielseite kann ich leider momentan nicht posten da zuviele sensible Unternehmensdaten in der Datenbank stehen.

In so einem Fall könntest du ja eine Demoseite erstellen, indem du eine Seite auf den problematischen Bereich kürzt und die sensiblen Daten rauslöscht.

An dem bisherigen Code kann ich nur erkennen, dass das div.edit links oben positioniert wird, da Positions-Angaben zu top und left fehlen. Dieser Bereich müsste entspechend freigehalten werden, damit nichts überlagert wird.

18.12.2007 18:13 | geändert: 18.12.2007 18:14

5 Moritz (Gast)

Hallo Jörg,

In so einem Fall könntest du ja eine Demoseite erstellen, indem du eine Seite auf den problematischen Bereich kürzt und die sensiblen Daten rauslöscht.
Demoseite ;-)

Wenn du rechts neben dem Status auf den Text klickst müsstest du sehen was ich meine...

Code ist wie oben schon geposted.

19.12.2007 15:06

6 Jörg Kruse

Hallo Moritz,

schön - so kann man das Problem gut nachvollziehen :)

Allerdings ist nur sehr schwer durch die vielen Scripte durchzusteigen, die dort eingebunden sind.

Kennst du eine möglichkeit das aufpoppende Eingabefeld als höchste Ebene zu deklarieren? Mit z-index, also css habe ich es schon versucht allerdings kann ich offenbar nur das div stylen nicht das input feld selbst.

Mir scheint das Eingabefeld bereits in einer höheren Position - der Rahmen wird ja vollständig angezeigt. Das Problem scheint mir vielmehr, dass der dahinterliegende Text durchscheint, vielleicht weil der Hintergrund transparent ist?.

Ich würde versuchen das Problem zu lösen, indem dem input oder aushilfsweise dem umgebenden div eine Hintergrundfarbe zugewiesen wird. Also z.B.:

.edit {
/* sonstige Eigenschaften */
background-color:#fff;
}

19.12.2007 15:51

7 Moritz (Gast)

Hallo Jörg,

Mir scheint das Eingabefeld bereits in einer höheren Position - der Rahmen wird ja vollständig angezeigt. Das Problem scheint mir vielmehr, dass der dahinterliegende Text durchscheint, vielleicht weil der Hintergrund transparent ist?.
Leider ist es genau anders herum. Nachdem ich den css tag eingefügt hab kann man das sehr gut erkennen.

Allerdings ist nur sehr schwer durch die vielen Scripte durchzusteigen, die dort eingebunden sind.
Ausser dem jquery.js und dem jeditable.js sollten diese aber keinen einfluss haben.

Habe schon mit den verschiedensten methoden versucht das input feld bei aufruf zu stylen, hatte aber keinen erfolg.

19.12.2007 16:27

8 Jörg Kruse

Ein Problem bei .edit ist, dass es sich auf die gesamte Klasse bezieht - ein z-index würde hier also gar nicht helfen. Man müsste schon gezielt das eine Element ansprechen können, in welchem das input angezeigt wird

Ausser dem jquery.js und dem jeditable.js sollten diese aber keinen einfluss haben.

Wenn nur diese beiden eingebunden sind, tritt das Problem nicht auf, da dann die Tabellenzeile entsprechend gestreckt wird

Wo werden denn die CSS-Eigenschaften definiert?

19.12.2007 16:44 | geändert: 19.12.2007 16:45

9 Moritz (Gast)

Hallo Jörg,

Wo werden denn die CSS-Eigenschaften definiert?
In einer zentralen css datei.

Ich finde nur leider keine Stelle im javascript code der ich eine neue Klasse zuordnen könnte.

Wenn nur diese beiden eingebunden sind, tritt das Problem nicht auf, da dann die Tabellenzeile entsprechend gestreckt wird
Das Eingabefeld soll ja auch über der Tabelle schweben was ich mit einem position:absolute in der style.css realisiert habe.

19.12.2007 17:15

10 Jörg Kruse

So jetzt habe ich die CSS-Datei gefunden - die war etwas verstekct oberhalb des title ;)

Das Eingabefeld soll ja auch über der Tabelle schweben was ich mit einem position:absolute in der style.css realisiert habe.

Ja, aber du lässt dann ja automatisch alle Elemente der Klasse edit schweben, so dass es kein übereinander gibt

Man muss wohl .editform direkt ansprechen. Dass die bereits hierfür definierten Eigenschaften in der CSS-Datei nicht übernommen werden, ist natürlich merkwürdig.

Ich habe mal in der jquery.editable.js etwas rumprobiert. Kommentier mal diesen Bereich aus wie folgt:
/* apply css or style or both */
                if (settings.cssclass) {
                    /*if ('inherit' == settings.cssclass) {*/
                        form.attr('class', $(self).attr('class'));
                    /*} else {
                        form.attr('class', settings.cssclass);
                    }*/
                }
... danach übernimmt das Script die Eigenschaften für .editform

Also irgendwo im Script scheint da noch etwas nicht ordentlich definiert zu sein...

19.12.2007 18:10 | geändert: 19.12.2007 18:14