Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

trouble clearing rendered lists #28

Closed
briantjacobs opened this issue May 13, 2011 · 26 comments
Closed

trouble clearing rendered lists #28

briantjacobs opened this issue May 13, 2011 · 26 comments
Assignees
Labels
Milestone

Comments

@briantjacobs
Copy link

I'm having issues re-rendering a list with new data that has been already rendered with Tempo. It would be great to see a working example of how you use the clear() in a real context on your site.

I'm rendering a list like this:

var element = Tempo.prepare(renderContainer);
var templateData = $.parseJSON(searchObj.results.contents[dataRequest]);
element.render(templateData);

Which works the first go around. If I reuse that code to populate the same list with new data from an ajax call, I get a list the same length as the original, and with every item being populated by the last element in the old data (even though I can see the new data coming in fine in the console). So, for example:

This:
-Billboards
-Centennial Exhibition 1876

Turns into this
-Centennial Exhibition 1876
-Centennial Exhibition 1876

This all seems to point to me using the .clear() function. But I've tried putting it in a few different places and I either get the same result as above or I get an empty list.

Your example seems to suggest chaining it after rendering:

Tempo.prepare('marx-brothers').render( data ).clear();

But wouldn't that just clear out the list you just rendered rather than clearing it before you render it?

@twigkit
Copy link
Collaborator

twigkit commented May 13, 2011

Hi, thanks for reporting this. I'll look into this and see if spot the problem. I'll keep you posted!!

@twigkit
Copy link
Collaborator

twigkit commented May 14, 2011

Hi sorry for the late reply. This is strange, it works for me. I just did the following with the expected results:

var data='somejson';
var template = Tempo.prepare('some-element');
template.render(data);
// I see the content
template.clear();
// Empty container
template.render(data);
// See same data, structure again?

Am I misunderstanding you?

@briantjacobs
Copy link
Author

Thanks for your help. I was able to figure it out. The difference in my code is that the function I was calling included this:

var template = Tempo.prepare('some-element');

So every time i called my function to load new data, that line above was being executed an additional time on the same container. Instead, If I prepare() the container only once and make reference to that global var inside my function then I can then clear and re-render with no issue.

Maybe in your twitter example you could just add a working "refresh" button, which would demonstrate clearing and re-rendering data without re-declaring the wrong functions, so people can avoid issues like this.

@twigkit
Copy link
Collaborator

twigkit commented May 14, 2011

Sure yeah - that's a good idea. I'll add that for 1.5. Glad you worked it out.

@rieteke
Copy link

rieteke commented May 15, 2011

Hi, I have kind of the same problem. I get data from the database and render it in a template, then I adapt the data in the database (delete item) and render this new data (which is a shorter list). Instead of replacing the old data in the template with the new data, the renderer appends the new data after the previous data.
As you can see in my code below, the first callWebservice loads the initial data, and when clicking yes in the dialog box, the template is rendered again.

    var u_lookup_template = Tempo.prepare("u_lookup");
    var u_info_template = Tempo.prepare("u_info");
    var item_id;
    
    /**
     * Get the list of users from the backend
     */
    callWebservice("","/users",function(data){
        var users = $.parseJSON(data);
        //Render the list of users
        u_lookup_template.render(users.users);
        u_lookup_template.clear();
    });
    
    /**
     * Convert dialog div into dialog and hide it
     * This dialog is a confirmation dialog to delete a user(doctor)
     */
    $('#del_dialog').dialog({
        autoOpen: false,
        width: 'auto',
        buttons: {
            "Yes": function() {
                callWebservice("", "/users/delete/user_id/"+item_id, function(data){
                    var users = $.parseJSON(data);
                    //Reload the doctor list
                    u_lookup_template.render(users.users);
                    u_lookup_template.clear();
                });
                $(this).dialog("close");
            },
            Cancel: function(){
                $(this).dialog("close");
            }
        }
    });

I hope you guys can help me because I don't see what I'm doing wrong.

@mrolafsson
Copy link
Contributor

Shouldn't you clear() the container before rendering?

@rieteke
Copy link

rieteke commented May 16, 2011

As you can see I clear it after every render I do, so it's the same as clearing it before the next render. I've tried putting the clear before the render too, same problem.

@mrolafsson mrolafsson reopened this May 16, 2011
@ghost ghost assigned mrolafsson May 17, 2011
@briantjacobs
Copy link
Author

Yeah I would agree about putting the clear() before rendering. My experience that putting it after yields an empty list in the DOM--as anything that was just rendered gets instantly cleared out. Can you post your non-working code where you have the clear() before the render?

@mrolafsson
Copy link
Contributor

Hey Brian. Thanks for looking at this with me. An important clue might be that he's using a table in his template. I agree it would be good to get a non-working example of the client code for us to debug. I'll try and replicate it here later tonight.

@rieteke
Copy link

rieteke commented May 17, 2011

Thanks for joining on the issue Brian, here's (part of) the code I'm using. I hope you guys can find a solution quickly cause I have to submit my project soon and I'd really like to keep your templating engine.

HTML

Naam Voornaam Telefoon E-mail
Dr. {{lname}} {{fname}} {{phone}} {{email}} Edit icon cross icon

JavaScript


var u_lookup_template = Tempo.prepare("u_lookup");
//this data's coming from an AJAX call
data="{ "users" :[ { "id":"1", "lname":"Janssens", "fname":"Willem", "phone":"10381853", "email":"willem.janssens@howest.be" } , { "id":"2", "lname":"Boussy", "fname":"Kim", "phone":"10381853", "email":"Kim.Boussy@howest.be" } , { "id":"3", "lname":"Vermeersch", "fname":"Dieter", "phone":"10381853", "email":"Dieter.Vermeersch@howest.be" } ] }";
var users = $.parseJSON(data);
u_lookup_template.render(users.users);
$('#test_clear').click(function(){
    u_lookup_template.clear();
})

@mrolafsson
Copy link
Contributor

We'll do our best!

@briantjacobs
Copy link
Author

Yeah it definitely has something to do with the table, and might be a Tempo bug? The template wont clear when this is used:

<tr data-template>...</tr>

But if I use this instead, it can be cleared and re-rendered just fine

<div data-template>...</div>

...although its not a proper

structure :)

mrolafsson, I altered his script slightly to successfully render the test data he provided

u_lookup_template = Tempo.prepare("u_lookup");
//this data's coming from an AJAX call
var data = '{ "users" :[ { "id":"1", "lname":"Janssens", "fname":"Willem", "phone":"10381853", "email":"willem.janssens@howest.be" } , { "id":"2", "lname":"Boussy", "fname":"Kim", "phone":"10381853", "email":"Kim.Boussy@howest.be" } , { "id":"3", "lname":"Vermeersch", "fname":"Dieter", "phone":"10381853", "email":"Dieter.Vermeersch@howest.be"}]}';

users = $.parseJSON(data);
$.each(users, function(i, val) {
          u_lookup_template.render(val)
});

@mrolafsson
Copy link
Contributor

Hmmm I actually tried changing the clearContainer method to just wipe it (since the template should be in memory anyway). And that seems to do the trick. Isn't that a safe assumption guys?

@mrolafsson
Copy link
Contributor

I hope this resolution didn't come too late for you. The fix I mentioned yesterday is in the 'dev' branch.

@rieteke
Copy link

rieteke commented May 24, 2011

Unfortunately it did come too late. I had to use Trimpath for some parts of the application but I kept Tempo for the biggest part. I think it could be a good templating engine but it needs to be less fixed to its structure. eg. It would be cool if you check the element itself where the data-template property is set to check if it has a field to fill.
Eg:

<ul data-template>
    <li data-template="subitems" name={{id}}>{{name}}</li>
</ul>

It should be able to get the id from the subitems template instead of the id from the data-template in the ul.
(I'm sorry but I don't seem to get the html code showing ...)
Thanks anyway for all the help and the quick reaction!

@mrolafsson
Copy link
Contributor

Sorry to hear that! I'm not sure I completely understand your proposal - are you proposing a change to the 'nested templates' feature?

@rieteke
Copy link

rieteke commented May 24, 2011

Sorry for not being clear. My example was indeed with a nested template but my proposal is about the templates in general.
I think it might be interesting if the html-tag containing the data-template attribute could contain the first data to be rendered.


  • {{name}}

This example won't work with your actual engine because it searches for {{}} inside the ul, not on the ul itself.
This way the {{name}} will be rendered but the {{id}} not.

@twigkit
Copy link
Collaborator

twigkit commented May 25, 2011

OK I see. I'll close this issue since the one you're describing is a duplicate of #25
I'd appreciate any feedback on whether this way of clearing is too agressive.

@twigkit twigkit closed this as completed May 25, 2011
@twigkit twigkit reopened this May 25, 2011
@twigkit
Copy link
Collaborator

twigkit commented May 25, 2011

This issue needs re-addressing. I had to roll back some of the changes.

@k33g
Copy link

k33g commented Jun 13, 2012

Hi
I've the same bug as rieteke with table tag

@xnopre
Copy link

xnopre commented Jun 13, 2012

Hi,

As k33g said, we have the same problem : displaying "tr" items in a table.

Here is an example showing the problem, comparing the render between "table" and "ul" :
http://jsfiddle.net/xnopre/mj3VR/

The problem is that the table (tbody) content is not cleared. I think it's because the "data-template" attribute is not in the rendered "tr" elements, so there are not cleared in the "clear" method !

Xavier

@mrolafsson
Copy link
Contributor

Hey guys, I'll look into this now! Thanks for your feedback.

@mrolafsson
Copy link
Contributor

Hey, I've added a quick test here: http://jsfiddle.net/unFSh/2/
It now works around the tr.innerHTML read-only issue by checking explicitly for IE and if the template is a tr. I suspect it does not fix it in IE but I could resort to the DOM Table API for this. Can you verify? This is on the 2.0-dev branch.

@k33g
Copy link

k33g commented Jun 13, 2012

Yes !!! it's ok for me with 2.0-dev branch (i've tested with chrome v19 winxp and FF v12 winxp)
cool
thank you vey much :)

@mrolafsson
Copy link
Contributor

Has anyone tested this in IE after the fix?

@mrolafsson
Copy link
Contributor

Hey guys, I FINALLY think this is fixed. Basically when I clear the container I only remove elements with a data-template attribute but IE was not adding this when the template is cloned.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants