Welcome Guest, Not a member yet? Register   Sign In
ajax & templating issue
#1

[eluser]stoefln[/eluser]
i am a bit confused when it comes to rendering content with ajax. since there is no way to get a subpart of a template i have to generate all content which should be dynamically inserted by ajax in my controller. i am not very convinced of this approach.
for example: on a page i display all comments at startup (without ajax). when someone posts a comment i want to refresh the commentslisting (with ajax). SO where should i generate the HTML?

anyone has experience on this?
#2

[eluser]Randy Casburn[/eluser]
Sure, if you're sending back a JSON formatted string of data that is content that has been pulled from your DB, then you could send that content directly from your Model back to the waiting client with an echo statement.

If it is a view partial (part of an HTML page with HTML content) then your controller could use load->view() normally but the view would only load the the HTML needed without the <HTML><HEAD><BODY> tags etc.

You're script will receive these responses and you should be able to process them just like any other asynchronous response.

Helpful?

Randy
#3

[eluser]stoefln[/eluser]
[quote author="Randy Casburn" date="1217448475"]
If it is a view partial (part of an HTML page with HTML content) then your controller could use load->view() normally but the view would only load the the HTML needed without the <HTML><HEAD><BODY> tags etc.

You're script will receive these responses and you should be able to process them just like any other asynchronous response.

Helpful?

Randy[/quote]
definitely. but i have to save each part of the html (without <head>,<body>...) in a separate file, right?
cause when i user load->view in my ajax request i cant tell the view just to use a subpart of the main htmltemplate.
so imagine a website where i have 8 areas which should be dynamically refreshed by ajax. i would need 1 main template and 8 subtemplates to get this sorted out. thats pretty uncomfortable...
#4

[eluser]Randy Casburn[/eluser]
Quote:uncomfortable…

What precisely is "uncomfortable"? Are you new to asynchronous calls and Ajax?

Try to think of things this way. From a performance perspective, you want all your STATIC content to fly out the door very fast...that means you want it to be stored and CACHED! That way every time someone visits yours site they get nearly immediate response directly out of the CACHE.

It is the 8 areas (or blocks or segments or chunks or snippets etc) that will be "dynamic" on your page that you probably don't want cached...right?

So in your main template file you put all your <html><head><body> stuff that will be mostly static and maybe the placeholders for your 8 areas. Then, in a subfolder (maybe) of your View folder you place your 8 area partial HTML files that only contain the html that will "fill-in" the placeholder areas when they get called via AJAX.

Now someone is likely to call up the term "gracefull degradation". That means what about the .03% of the people that may not be running JS anymore. You still have the option to test for JS, and if the client is not running JS, redirect back to the controller, reload the main template + all the 8 areas into the placeholders as normal load->view() calls.

Still working for you?

Randy
#5

[eluser]stoefln[/eluser]
i m not new to ajax but new to CI.
i dont see what caching has to do with ajax, but anyway lets make it a bit more concrete:

there is a page with a commentform and a commentlist. these 2 parts are in a subtemplate called "comments". when somebody enters the page all comments are rendered in the view with a foreach loop:

Code:
Your comment on this page:<br/>
&lt;?= form_open(site_url(),array("id"=>"commentform"))?&gt;
    &lt;textarea id="commentText"&gt;Feed me with your opinion!&lt;/textarea&gt;&lt;br/>
    &lt;input type="button" name="commentsubmit" value="Submit comment!"/&gt;
&lt;/form&gt;&lt;br/>
There are &lt;?=count($comments)?&gt; comments on this page!<br/>
<div id="commentlisting">
&lt;? foreach($comments as $comment):?&gt;
    <div class="comment">
        by &lt;?=getUserButton($comment->createdById)?&gt; on &lt;? formatDateTime($comment->createdOn)?&gt;<br/><br/>
        &lt;?= format($comment->text)?&gt;<br/>
    </div>
&lt;? endforeach;?&gt;
</div>

when somebody hits the commentsubmit button i want to send a request to the server, save the data and refresh my commentlist.
as far i understood you, i should move these 6 lines to another template:

Code:
&lt;? foreach($comments as $comment):?&gt;
    <div class="comment">
        by &lt;?=getUserButton($comment->createdById)?&gt; on &lt;? formatDateTime($comment->createdOn)?&gt;<br/><br/>
        &lt;?= format($comment->text)?&gt;<br/>
    </div>
&lt;? endforeach;?&gt;

a extra file for just 6 lines makes the huge filelist in CI even longer, and i have to create this file, i have to switch between comments_view.php and comments_list_view.php,... thats what i call uncomfortable.
#6

[eluser]Randy Casburn[/eluser]
OK...I get you...

Sorry about the tangent about the cache...I just didn't know where you were experience wise ;-)

No, I don't use that method at all. This is one of the shortcomings IMHO of our environment. Sometimes we forget that we have an entire architecture to draw from and we try to rely on the wrong parts to do the wrong jobs (again, IMHO).

You have client with a very powerful scripting language that can manipulate the daylights out of the DOM. Why would you come all the way back to the server, go through all the overhead of the HTML construction process by CI to create and recreate these posts? You are absolutely correct in your thinking that this is crazy.

So now our thoughts have finally converged and I've caught up with you ;-) ...

This is how I do what you want to do:

1) I us JavaScript to manipulate the DOM by creating new DOM element (<div> <span> whatever) tags that appropriate for the structure of the content that will be returned from my XMLHttpRequest. I send the

2) I send the XMLHttpRequest to a controller just like any other CI request. I always send extra parameters with my ajax calls that I use for security purposes because testing the headers is not sufficient to guarantee security. The controller checks security and forwards the request on the appropriate Model to gather the required data...

3) The Model (as in your example) gathers the required data (in your example the posts) packages the data into a JSON string and immediately echos that output to the client.

4) The client recieves the JSON string and places the contents into the newly created DOM element.

5) Process complete.

That's the way I do it. I'm considered somewhat of a heretic for this method...but this is efficient and the most direct route to achieving your goal.

More helpful?

Randy
#7

[eluser]Randy Casburn[/eluser]
A quick note for clarity....This process is the same whether sending the comment to be stored by the model, with a confirmation sent back, or just a request to retrieve a single comment, or a request to retrieve the last X number of comments.

I'm sure you get the drift.

Randy
#8

[eluser]stoefln[/eluser]
yeah i think we are talking bout the same issue, but the solution which i would like to have is a bit different. thanks for your help anyway, its great to get fast,competent feedback.
my goal would be to have just ONE place for my layout definitions, so e.g. a designer could edit a template. with your JSON approach i would have to provide layout information from server (initial rendering) AND from the client too (after refresh).
dunno if you know TYPO3 (CMS): there its possible to mark subparts in your template like this:

Code:
blabla
###COMMENT_LIST###
<div>"my list template which i could retrieve in my controller"</div>
###COMMENT_LIST###
blabla
in my controller i can do something like this
Code:
//called by ajax
function disp(){
   $data = $this->model->getCurrentData();
   $templateHTML = $this->template->getSubpart("COMMENT_LIST");
   $ajaxResponse->html = $this->substituteMarkers($templateHTML,$data);
   return $ajaxResponse;
}
the benefit from this is that you can take the same html-layout for initial rendering of the page AND for updates per ajax...
#9

[eluser]beemr[/eluser]
I don't think multiple views are nearly as uncomfortable as multiple controllers to run Ajax CRUD for each subsection. If you write tidy markup, the approach I recommend is "Graceful Degradation" but not necessarily for the reasons that Randy gave above.

1. Write the controller and views as if you had no Ajax.
2. In your views, use XHTML that is as terse and strict as you can manage. Use id or class attributes to identify the updated content.
3. When the app flow is complete, pick an unobtrusive Javascript library (CI will be using jQuery in 2.0)
4. Use the JS lib to unobtrusively rewrite your submits, links, etc. with Ajax calls to the same URI that you would have used without JS.
5. Your JS lib should be able to parse the return page as an XML DOM, at least if you're using jQuery.
6. Use the DOM traversal methods of the JS lib to pluck out the updated portion and add it to the page.

A variation on this is to use XSLT stylesheets to filter out all but the updated portion of the page. This reqires some class extensions, though.

The big win here is that you are using the same controller as your regular page requests to serve up your Ajax. This will keep you from having to write a controller for each subsection, duplicating validation rules, etc. The added bonus is that users without JS will always have access to your app.
#10

[eluser]stoefln[/eluser]
[quote author="beemr" date="1217455818"]
5. Your JS lib should be able to parse the return page as an XML DOM, at least if you're using jQuery.
6. Use the DOM traversal methods of the JS lib to pluck out the updated portion and add it to the page.[/quote]

this is quite cool! i use xajax, have to look if this one is supported. the only disadvantage is that the hole site has to be rendered and the whole bunch of html has to be transfered, but anyway...
my site doesnt have to be unobtrusive, its just for webdevelopers, i assume they have their JS switched on Smile




Theme © iAndrew 2016 - Forum software by © MyBB