Tuesday, December 29, 2009

[jQuery] Re: jQuery + OOP + AJAX

On Dec 29, 5:23 am, fran23 <f...@lavabit.com> wrote:
>> But even here, there is still something strange. On each click of the
>> div, you're binding another event handler to do the same job.
>
> that's the CENTER OF MY TROUBLE. I did speak about the reason for using the
> show() function above.
> But maybe I can get your patience for one more special example that desribes
> my intention and trouble more precisely: Let's assume I work on a web site
> that should display the paragraphs of a book. The book has chapters and each
> chapter has <p>s. I start displaying the first <p> (of the first chapter).
> When read by the user he clicks on the <p> and the next paragraph will
> shown.
> [ ... ]
> I can go on this way until the last <p> of the current chapter is
> added/shown. Now I should start with the first <p> of the second chapter.
> Therefore I have to delete all <p>'s (of chapter 1) and show the first <p>
> of chapter 2. This is what my show()-function should do (that bothers you
> [and me too]): replace all current shown <p>'s and RE-START with one <p> -
> the first one of chapter 2.
>
> Do you have any hint how to do it better ?

Well, first of all, it's a somewhat strange UI. I certainly wouldn't
want to click for every paragraph; and even if I did, I would think a
"Next" button would be a better place to click than on the paragraph
itself. But that aside, I'm sure it can be done.

First of all, does the click have to be in the last paragraph itself?
Or could it be in some parent container of the paragraphs? That would
make it easier to handle. You can then check the event target to see
if the user has clicked in the final paragraph. This allows you to
register only one click handler, on the container of the paragraphs.
You will need some additional logic to ... oh hell with it. Let me
give this a try.

Tinker, tinker, tinker. Ok. Done.

Something like this should work:

var $content = $("#content");

function showNextChapter() {
chapter = getNextChapter();
$content.empty().append("<h2>" + chapter.title + "<\/h1>");
$content.append(chapter.paragraphs[paragraphIdx]);
}

function showNextParagraph() {
if (!moreParagraphsForChapter()) {
showNextChapter();
return;
}
$content.append(getNextParagraph());
}

$content.click(function(event) {
showNextParagraph();
});

showNextChapter();

and if you want to allow only a click on the last paragraph, you can
replace the event handler with something like this:

$content.click(function(event) {
var handleEvent = false;
var $target = $(event.target);
if ($target.is("p:last-child")) {
handleEvent = true;
} else {
var $para = $target.parents("p");
if ($para.length && $para.is("p:last-child")) handleEvent
= true;
}
if (handleEvent) {
showNextParagraph();
}
});

Obviously, you would need to write the code for getNextChapter(),
moreParagraphsForChapter(), and getNextParagraph() with your Ajax
code.

You can see this in effect here:

http://scott.sauyet.com/Javascript/Demo/2009-12-29a/

or, with that last addition, here

http://scott.sauyet.com/Javascript/Demo/2009-12-29a/?last

This may be oversimplified, because I have no error handling on last
chapter, simply looping back to the first, but I think this captures
the gist of it.

Good luck,

-- Scott

No comments: