Load ajax/jquery JSON array into Twig Template - php

I am currently building a program using Symfony2 framework and also taking advantage of the many nice new features that come with the platform such as Doctrine, Twig etc.
One of my pages requires me to load a big load of data via AJAX after pageload is complete. This is easily achieved uing JQuery/Ajax but i'd like to think that something like this would have a way of injecting ajax directly into the Twig template maybe via JSON and have it populate in a for loop.
<table>
<tr><td>header</td></tr>
{% for row in rows %}
<tr><td>{{row.data}}</td></tr>
{%endfor%}
</table>
Something like this crude example.
I did browse the docs quickly for this but there search is down and i couldn't find anything directly. A link to documentation could suffice if its what im looking for.

I think the cleanest way would be to generate your Json in the controller.
Something around:
/**
* #route("/json", name="json_generator")
*/
public function jsonAction() {
// do your for loop and build up a $jsonArray
return new Response( json_encode($jsonArray) );
}
And then test the response of this in the browser and load this with Javascript in the twig template.
Don't have the specific code right now, but from the top of my head:
$(document).ready(function() {
$.ajax({
ajax: true,
url: "{{ path('/json') }}"
});
};
Just so you get the idea. Hopefully it serves you as a base example-

There is 2 ways:
1. Make AJAX request, in controller render html and return it to the script. Then add when it is needed.
2. Make AJAX request, return JSON and build html in the script, then add ready html to your specific place.
I think better way is render html in your action and return it to your AJAX script

Related

OctoberCMS using Ajax API with no-script fallback in page php section

My current base for a simple contact form is:
A page containing the form and the form validation in the php section with a native function like so:
function onStart(){if(Request::isMethod('post')) /* do stuff */}
Above is my "no-script" solution.
Now, when I want to enable OctoberCMS' Javascript API I have to call a self defined function in the php section, for example:
function onSubmit(){/* do stuff */}
How could I combine both in one function so that /* do stuff */ triggers, regardless if the request was send via Ajax or pure php?
I found the answer.
OctoberCMS provides a native method to let a form trigger a custom onMyfunction(), just by using another way of implementing the form.
For anybody who might get into the same problem, here's the code:
<?php
function onMyfunction(){}
?>
==
<html>
{{ form_open({ request: 'onMyfunction', id: 'my-form' }) }}
</html>
This will send the post data to the php handler, regardless if Javascript is enabled or not.
Now you only need to initiate your Ajax API with:
<script>
$('#my-form').submit(function(evt){
evt.preventDefault();
$(this).request('onMyfunction',{})
});
</script>
Could you use the html <noscript> tag?? In your css you would put .noscript {display:none;} .script {display:block;} then in your pages, component template, layout etc you could have two forms that change depending on if the user is using script or not. They can use the same onSubmit function.
Any user interaction with any of the sites I have made assume some might not use Javascript so I default to use standard forms and not js or ajax.

Some questions about CodeIgniter with Javascript and AJAX

Just getting into Codeigniter and I'm planning out a large application. I'm a bit confused about how CI handles JS files and AJAX requests.
I am using mod_rewrite with my project.
In a regular webpage, I'd reference separate JS scripts at the header of my doc to keep my code segregated and clean. Since I'm using mod_rewrite, I need functions from the url helper to find my files. This is a problem in separate js docs because they don't execute php. So when it comes to AJAX calls, how am I supposed to reference a PHP controller function from my JS file when I don't have use of the site_url() function?
How would I go about writing functions that can be accessed through AJAX but not through the address bar? So, let's say I have a User Controller. You can go to user/pictures and you can see their pictures. You go to user/friends and you can see their friends. But I don't want you to be able to go to User/getData and see all the printed out raw data.
tl;dr What is standard JS and AJAX practice when using separate docs and mod_rewrite?
Cheers guys.
What I personally do is declare a js variable in the header section of my template before any js declaration like this:
var base_url = <?=base_url()?>
This base_url will then be accessible by any js file you integrate. About the second point you can always redirect the user from your controller like this:
public function some_function(){
if($this->input->post(null)){
//your ajax code here
}else{
redirect(base_url(), 'refresh')
}
}
I also declare a js variable in the <head> like
var baseUrl = '<?php print(base_url()); ?>';
Then when you do your AJAX call you can call the controller like
baseUrl + 'controller/method'
In terms of making sure that methods can only be called from AJAX calls and not through the address bar one option is to send a post value and check for this before you do anything like
if($this->input->post('ajax_call'))
{
//Do something
}
If you put all your ajax methods into the same controller you'd only have to have this check once in the __construct()

How to include assets (JS) into the layout from a controller - CakePHP

This is probably a duplicate, but I am struggling to find the same question and certainly the answer.
I'm a little unsure and confused on how assets are handled in Cake (2). I want to include some JS on a specific page, not on every page of the app, so I would assume I would need to add that to my controller method? I can't find how I would do that. The close I have come is the JsHelper, but that seems more for constructing JS using PHP rather than just loading an assets.
I am well aware I can do $this->Html->script('script'), but this does not work in the controller, only in the view.
Although not needed right now, it would also be useful to be able to pass variables through to the included JavaScript. A good example of this may be an AJAX request on an 'edit' screen for something: $.ajax({ url: "/pages/edit_ajax/<?= $page->id ?>" });
Any help is gladly received.
In order to do this you will want to use Blocks (providing you are in v2.1+).
In your layout file you will no doubt have a line $this->fetch('script') which will go find the script block and output it into your layout.
Next, in the view for the Controller action, let's say index() you will have a matching view index.ctp. In this view you can append your script to the script block.
So in the view,
<?php $this->append('script'); // we want to append to the script block ?>
<script>
$(function() {
alert('Hey there, Im only on this page!');
})
</script>
<?php $this->end();?>
When you visit your controller action you will see that this will be output, hopefully at the bottom of your page, along with your other javascript.
As you've appended the script in the view, it will only ever execute when this view is loaded.
In regard to your second question, you can just set variables to the view in your controller, and then echo them into your javascript.
// Controller
$this->set('jsVar', 'JavascriptInBlocks');
// View
<?php $this->append('script'); // we want to append to the script block ?>
<script>
$(function() {
alert('Hey there <?php echo $jsVar;?>');
})
</script>
<?php $this->end();?>

How to update an array in TWIG template?

Currently, I am using TWIG to display all my information(articles and comments). So, I first retrieve the articles and comments from my database and pass it into an array. This is then passed into my twig template. Then, I load each article and underneath each article I load in the comments of that article. These comments and the buttons associated with it(aka the new comment button) are all made in my macro.
The macro just gets the array that contains the comments that I need to display. It display the comments for the article and with each comment it makes a reply button, so the user can reply to any comment or start a new thread.
I have used AJAX and jQuery to store the new comments in my database without refreshing the page. However, I need to figure out a way to display the new comment without refreshing the whole page. Does anyone have any idea on how to do this in TWIG?
The problem I am facing with TWIG right now is how to post comments asynchronously. I load the array of the current database of comments initially when I load the page. However, if my database updates, how do I update my array with it. Any suggestions? I was thinking of grabbing my array whenever a new comment is added, which is why my question is "How to retrieve an array in TWIG template?", but I am open to other suggestions.
Your issues isnt a twig issue, twig only is a templating engine and is only used on the initial render of the page. What you should be doing is when you get a successful response from your ajax save is create a new DOM element using jquery and add it to the page using your same schema. Something like:
<script>
$.post(
TheUrlThatYouPostTo,
TheDataThatYouPassWithThePost,
function(returnData, textStatus){
//assuming that your return data is an array conatianing a boolean successful key
if(returnData.successful){
$('#YourCommentsWrapperElement').append('<div class="comment">#some other elements containing the posted values</div>');
}
}
);
</script>
Or if you want twig to generate the comment HTML for you and you dont want to have it hard coded into your javascript you can have the controller action that your are posting to with the AJAX post return a rendered version of the comment. Something like this:
#Your Controller file
public function ajaxPostAction(Request $request){
//Handle post data to create a new commentObject
return array(
'comment' => $commentObject
);
}
Then you create a view file for that action:
#your view for the controller action ajaxPost.html.twig
<div class="comment">
<h3>{{comment.author}}</h3>
<p>{{comment.content}}</p>
</div>
Then your javascript will just take the return data and append it to the existing list:
<script>
$.post(
TheUrlThatYouPostTo,
TheDataThatYouPassWithThePost,
function(returnData, textStatus){
//Now your return data is the HTML for the new comment so just append it to the rest
$('#YourCommentsWrapperElement').append(returnData);
}
);
</script>

Access html elements data and send to controller in PHP

I'm a super beginner in php, and I'm using a MVC php framework called Yii. I can't seem to find any articles that explain how to get values of html elements with PHP. Everywhere I look it's all about how to get values from form fields after a POST in some other view. Is there anyway to get field values and send them to a controller in PHP and just come back to the original view.
In .Net MVC I just use jquery to get form fields and do an ajax call. It's not sensitive data so I'm not worried about security. I like ajax because I don't do any page post back, I just send my data over and remain on the same page I was on.
Is there any way to do MVC AJAX kind of thing with PHP? Read html element values and send them to a controller for data manipulation?
It works the same way. Yii comes bundled with jquery, so you
just use jquery to get form fields and do an ajax call
to some controller function, do whatever you want with it, and return a response, with php's echo.
If you already know some jquery, then the client-side shouldn't be much different from .net mvc.
Edit:
To add a <script> to the generated html see registerScript.
To create urls use the createUrl function.
To add ajax options to html tags code looks similar to:
echo CHtml::checkBox('mybox',false,
array(// array for htmloptions, we also pass ajax options in here
'class'=>'checkBoxes_class',
'ajax'=>array(// this is ajax options for jquery's ajax
'type'=>'POST',
'url'=>Yii::app->createUrl('xyz',array('clickedboxid'=>'mybox')), // here you passed clickedboxid as a get variable
'beforeSend'=>'function(){}',
'success'=>'',
// etc etc
)
)
);
Every html tag generator helper function takes htmlOptions array, where we can also pass ajax options.
While reading these values in the controller:
public function actionSomeAction($id){
// $id is mybox
echo "Hello"; // this is returned as response to the client
}
Hope this is enough for you to get started.

Categories