Problém

Je potřeba provést refresh/reload ajaxového obsahu načteného pomocí JQuery, např. pomocí metody load. Toto je užitečné velmi často, asi nejtypičtější případ je aktualizace obsahu po submitu formuláře. HTML div a kód JQuery může vypadat např. takto:

Javascript

$(document).ready(function() {
        $("#ajaxObsah").load('<vase_url_pro_nacteni_obsahu>');
}

HTML

<div id="ajaxObsah"></div>

A nyní přidáme na stránku tlačítko a po kliknutí na něj budeme chtít provést refresh divu:

Javascript

$(document).ready(function() {
        $("#ajaxObsah").load('<vase_url_pro_nacteni_contentu>');
        $("button#tlacitko").click(function() {
           //tady bude kod pro refresh divu s id "ajaxObsah"
         });
});
}

HTML

<div id="ajaxObsah"></div>
<button id="tlacitko"></button>

Řešení teoreticky

Řešení by bylo velmi jednoduché, kdyby šlo napsat něco jako $(„ajaxObsah“)­.refresh(), ale to samozřejmě nejde. Další relativně jednoduchá možnost by byla zjistit si url načteného DIVu a zavolat znovu JQuery metodu load(). Jenže jsem nenašel způsob, jak se k url po načtení dostat, myslím si, že to ani nejde. Můj způsob řešení (rozhodně ne jediný) je následující workaround: při načtení divu pomocí metody load() využijeme toho, že v tuto chvíli ještě známe URL (zadáváme ho jako argument metody load()) a vytvoříme hidden s odvozeným ID (např. ajaxObsahHidden) a do value uložíme url. Takto se vždy k url dostaneme a můžeme pak znovu zavolat metodu load(). K tomu je nejideálnější vytvořit novou metodu load, která bude kromě načtení obsahu automaticky vytvářet hidden a nazveme ji např. loadContent. K tomu využijeme další JQuery kostrukci pro vytvoření nové metody. Takže kompletní řešení bude vypadat následovně:

Řešení prakticky

Javascript

$(document).ready(function() {

  /**
   * Vytvoří hidden, pokud již ale dle konvenčního ID existuje, pouze provede update hodnoty value
   */
  function vytvorHidden(idHidden, name, value) {
        if ($("#" + idHidden).length > 0) {
                $("#" + idHidden).val(value);
        } else {
                $("<input></input>").attr({id: idHidden, type: "hidden", name: name, value: value}).insertAfter($("body"));
        }
  }

  /**
   * Provede refresh ajaxového divu
   */
  function refreshAjaxDiv(idDiv) {
        if (idDiv != undefined && idDiv != '') {
                var href = $("#" + idDiv + 'Hidden').val();
                $("#" + idDiv).load(href);
        }
  }

/**
* Definice nové metody, kterou nyní budeme používat místo standardní "load". Provede to stejné, jako standardní metoda "load", ale navíc ještě vytvoří hidden, do kterého uloží url. ID tohoto hidden je vygenerované podle konvence <idDiv>Hidden a znalost této konvence využívá funkce "refreshAjaxDiv"  definovaná výše
*/
  $.fn.loadContent = function(url) {
                return this.each(function() {
                        vytvorHidden(this.id + "Hidden", "", url);
                        $(this).load(url);
                });
        }

        $("#ajaxObsah").loadContent('<vase_url_pro_nacteni_contentu>'); //Načte obsah divu "ajaxObsah" a současně vygeneruje hidden s id "ajaxDivHidden"

        $("button#tlacitko").click(function() {
           refreshAjaxDiv("ajaxObsah");
        });

});
}

HTML

<div id="ajaxObsah"></div>
<button id="tlacitko"></button>

Závěr

Toto je zatím nejlepší funkční řešení, na které jsem přišel. Byť je v tom trošku „magie“ (kdesi se vytváří nějaký hidden s nějakým konvenčním ID, ke kterému se později „magicky“ přistupuje), tak přesto se nejedná úplně o špatné řešení, protože vývojář-uživatel je od této magie úplně odstíněn a jen si volá intuitivně funkce loadContent a refreshAjaxDiv. Budu velmi rád, když se v diskuzi podělíte o případné elegantnější řešení provedení refresh ajax DIVu.

Komentáře

Tomáš před 5 lety

úžasný článek, google ví proč mě sem přivedl :).

Proč dělat z DOMu databázi? No fuj. Není mnohem jednodušší si prostě držet v paměti ukazatele na element a url (cca autoReloadLis­t.push({el: this, url: url})?

Když už to takhle ohýbat, proč nepoužít data atribut a prostě si url neuložit k samotnému elementu?

reagovat

Lukáš Knápek před 5 lety

Ano, díky za dobrou radu, máš pravdu. V době, kdy jsem to řešil, mě prostě napadlo jen tohle řešení a moc jsem se nezamýšlel nad nějakým jiným :-) Aktualizuji článek na základě tvého komentáře.

reagovat

James před 3 měsíci

Fantastic website. A lot of useful information here. I'm sending it to a few pals ans also sharing in delicious. And naturally, thank you in your sweat!

reagovat

James před 3 měsíci

Fantastic website. A lot of useful information here. I'm sending it to a few pals ans also sharing in delicious. And naturally, thank you in your sweat!

reagovat

James před 30 dny

I'm truly enjoying the design and layout of your blog. It's a very easy on the eyes which makes it much more pleasant for me to come here and visit more often. Did you hire out a developer to create your theme? Outstanding work!

reagovat

Přidat komentář

  • Můžete použít Texy syntaxi, HTML není povoleno
  • Například: *kurzíva*, **tučně**, "text odkazu":adresa
 

Autor článku Lukáš Knápek

Od roku 2008 věnuji víceméně dobrovolně třetinu života vyvíjení webových aplikací, především prostřednictvím těchto jazyků a nástrojů: Java, Struts2, Hibernate, Spring, Maven, Dojo, JQuery, Tomcat a Eclipse. A to vše s vírou, že to bude užitečné nejen k vydělávání peněz pro potřeby Lukáše Knápka :-)