Autor Zpráva
David Klouček
Profil
Potřebuji udělat v textarea několikařádkový placeholder. Jedinné řešení, které jsem našel je pomocí javascriptu a to tímto pluginem https://github.com/bradjasper/jQuery-Placeholder-Newlines, ale placeholder se odesílá jako normální hodnota. Řešil toto už někdo? Nechápu, proč při návrhu HTML5 s tímto nepočítali.
DJ Miky
Profil
Víceřádkový placeholder není běžný a dle mého názoru často zavání uváděním více různých hodnot do jednoho pole, což je obvykle špatně z hlediska návrhu formuláře.

Zmíněný plugin by měl řešit (ne)odesílání – naváže se na submit akci formuláře a v případě, že se hodnota rovná placeholderu, se text smaže.
Další možné řešení je obrázek na pozadí skrývaný při fokusu, ale přináší další problémy (nepřístupnost, nemožnost změnit/zvětšit písmo, obrázek navíc a potenciální nečitelnost, pokud prohlížeč vynutí změnu barev u formulářových polí).
David Klouček
Profil
Nakonec jsem si teda napsal vlastní Javascript. Funguje, ovšem je tam jeden problém - v IE10 se místo řádků zobrazí klasické \n. Když použiji \n\r tak to taky nejde a navíc v ostatních prohlížečích to dělá dvojité řádky. Co s tím?

function addLines(s)
{
    return s.replace(/\\n/g, "\n");
}

function setPlaceholder(el)
{
    el.style.color = 'silver';
    el.value = addLines(el.dataset.placeholder);
}
    
function unsetPlaceholder(el)
{
    if (isPlaceholder(el))
    {
        el.style.color = 'black';
        el.value = '';
    }
}
    
function isPlaceholder(el)
{
    return el.dataset.placeholder !== undefined && addLines(el.dataset.placeholder) == addLines(el.value);
}
    
$(document).ready(function()
{
    $('form').each(function(i, el)
    {
        var form = $(el);
        
        form.submit(function()
        {
            form.find(':input').each(function(i, input) {
                if (input.tagName == 'TEXTAREA' || input.tagName == 'INPUT')
                {
                    unsetPlaceholder(input);
                }
            });
        });

        form.find(':input').each(function(i, input)
        {
            if (input.tagName == 'TEXTAREA' || input.tagName == 'INPUT')
            {
                if (input.placeholder.length > 0)
                {
                    input.dataset.placeholder = input.placeholder;
                    input.placeholder = '';
                    
                    var j_input = $(input);
                    
                    if (input.value == '') {
                        setPlaceholder(input);
                    }
                    
                    j_input.click(function() {
                        unsetPlaceholder(input);
                    });
                    
                    j_input.keyup(function() {
                        if (input.value == '' && ! j_input.is(":focus") && ! isPlaceholder(input)) {
                            setPlaceholder(input);
                        }
                    });

                    j_input.blur(function() {
                        if (input.value == '' && ! isPlaceholder(input)) {
                            setPlaceholder(input);
                        }
                    });
                }
            }
        });
    });
});

http://jsfiddle.net/S2mwY/
David Klouček
Profil
Problém byl jinde. Tady je plně funkční řešení, snad se tam nenajde problém se staršími prohlížeči.
function setMultilinePlaceholder(placeholderClass)
{
    function addLines(s) {
        return s.replace(/\\n/g, "\n");
    }

    function setPlaceholder(el) {
        el.setAttribute('data-onpc', 1);
        el.classList.add(placeholderClass);
        el.value = el.tagName == 'TEXTAREA' ? addLines(el.getAttribute('data-placeholder')) : el.getAttribute('data-placeholder');
    }

    function unsetPlaceholder(el) {
        if (isPlaceholder(el)) {
            el.setAttribute('data-onpc', 0);
            el.classList.remove(placeholderClass);
            el.value = '';
        }
    }

    function isPlaceholder(el) {
        return el.getAttribute('data-onpc') != undefined && el.getAttribute('data-onpc') == 1;
    }

    $(document).ready(function () {
        $(document).find(':input').each(function (i, input) {
            if (input.tagName == 'TEXTAREA' || input.tagName == 'INPUT') {
                if (input.placeholder.length > 0) {
                    input.setAttribute('data-placeholder', input.placeholder);
                    input.setAttribute('data-onpc', 0);
                    input.placeholder = '';

                    var j_input = $(input);

                    if (input.value == '') {
                        setPlaceholder(input);
                    }

                    j_input.click(function () {
                        unsetPlaceholder(input);
                    });

                    j_input.keydown(function () {
                        unsetPlaceholder(input);
                    });

                    j_input.blur(function () {
                        if (input.value == '' && !isPlaceholder(input)) {
                            setPlaceholder(input);
                        }
                    });
                }
            }
        });

        $('form').each(function (i, el) {
            var form = $(el);

            form.submit(function () {
                form.find(':input').each(function (i, input) {
                    if (input.tagName == 'TEXTAREA' || input.tagName == 'INPUT') {
                        unsetPlaceholder(input);
                    }
                });
            });
        });
    });
};

//použití, parametr je CSS třída předstírající placeholder
setMultilinePlaceholder('xxx');
Chamurappi
Profil
Reaguji na Davida Kloučka:
Tady je plně funkční řešení, snad se tam nenajde problém se staršími prohlížeči.
Samozřejmě, že najde, vždyť používáš classList.

Je to docela dlouhý kód. K čemu v něm je atribut data-onpc?
joe
Profil
$('form').each(function (i, el) {

Nebude jednodušší hledat rodiče form toho konkrétního inputu, kde chceš placeholder, než znovu prohledávat všechny formuláře a hledat v nich, jestli se v nich náhodou neobjevuje nějaký input, který placeholder má?
David Klouček
Profil
Chamurappi:
Samozřejmě, že najde, vždyť používáš classList.
Změněno na jQuery setClass() a getClass().

Je to docela dlouhý kód. K čemu v něm je atribut data-onpc?
Teď už není.

joe:
$('form').each(function (i, el) {
Dobrej nápad, upraveno.

function setMultilinePlaceholder(placeholderClass)
{
    function addLines(s) {
        return s.replace(/\\n/g, "\n");
    }

    function setPlaceholder(el) {
        el.value = el.tagName == 'TEXTAREA' ? addLines(el.getAttribute('data-placeholder')) : el.getAttribute('data-placeholder');
        el.setAttribute('data-placeholder', '');
        $(el).addClass(placeholderClass);
    }

    function unsetPlaceholder(el) {
        if (isPlaceholder(el)) {
            el.setAttribute('data-placeholder', el.value);
            el.value = '';
            $(el).removeClass(placeholderClass);
        }
    }

    function isPlaceholder(el) {
        return el.getAttribute('data-placeholder') != undefined && el.getAttribute('data-placeholder') == '';
    }

    $(document).ready(function () {
        $(document).find(':input').each(function (i, input) {
            if (input.tagName == 'TEXTAREA' || input.tagName == 'INPUT') {
                if (input.placeholder.length > 0) {
                    input.setAttribute('data-placeholder', input.placeholder);
                    input.placeholder = '';

                    var jInput = $(input);

                    if (input.value == '')
                        setPlaceholder(input);
                    
                    jInput.focusin(function () {
                        unsetPlaceholder(input);
                    });
                    
                    jInput.blur(function () {
                        if (input.value == '' && !isPlaceholder(input)) {
                            setPlaceholder(input);
                        }
                    });
                }
                
                var form = $(jInput).parents('form');
                
                if (form.length > 0) {
                    form.submit(function() {
                        unsetPlaceholder(input);
                    });
                }
            }
        });
    });
};

//použití, parametr je třída předstírající placeholder
setMultilinePlaceholder('ph');

Jen nechápu, proč jInputjInput.parents('form') hlásí Uncaught TypeError: Cannot call method 'parents' of undefined, když je instancí jQuery. Musel jsem to obalit do $().
joe
Profil
David Klouček:
Jen nechápu, proč jInputjInput.parents('form') hlásí Uncaught TypeError: Cannot call method 'parents' of undefined, když je instancí jQuery. Musel jsem to obalit do $().

Pokud ti to tu chybu hlásí, pak jInput je právě undefined, protože to nemáš v té podmínce if (input.placeholder.length > 0) {, ale mimo ni.

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: