how do basic jquery ajax in typo3 flow? - ajax

I am trying to do some very basic ajax. I just want an onchange event on a select that will call an ajax function that will get the options for another select and fill it in. However I am not sure how to do this in a simple way in Typo3 Flow. My php code for the action just looks like this:
public function getProductsByCategoryAction( $category='' ) {
$postArguments = $this->request->getArguments();
echo __LINE__;
TYPO3\Flow\var_dump($postArguments); die;
}
and my ajax call looks like this:
jQuery('#get_category').change(function(event) {
event.preventDefault();
alert('get products');
var category = jQuery('#get_category').val();
alert(category);
jQuery.ajax({
url: "/admin/orders/getproductsbycategory.html",
data: {
'category': category
},
async: true,
dataType: 'html',
success: function(data) {
alert('hi mom');
...
}
});
});
when I try this url in the browser mysite-dot-com/admin/orders/getproductsbycategory.html?category=17ca6f3e-a9af-da7d-75cd-20f8d6a05ed0
on the page the var_dump just gives me array(empty). Why doesn't the request->getArguments() call work and give the category argument?
The getproductsbycategory.html is created in Neos and has the right plugin for the action call. So I know the right action gets run but it does not get any args. At this point the argument is just a string and not an _identity even though I should eventually do it that way, I'm trying to keep things simple for now for the sake of expediency.
Thanks
Update: as a temp workaround shameless hack I just did this to get the variable:
$categoryID = $_GET['category'];
which works but I'd like to know the proper way especially if it does not involve writing my own view helpers.

First define variable in your html file
<script>
var ajaxUrl = '<f:uri.action action="actionName" controller="(controllername)Ajax"/>';
</script>
Your Ajax code will look like :->
$.ajax({
data: '&lookup='+{somevalue},
type: 'POST',
url: ajaxUrl,
success: function(data) {
$('.lookup-id').append(data);
},
});
Your conroller action will look like :->
public function getLookupIdAction(){
// Get company detail for set logo of company
$companyDetail = $this->getUserCompany();
// Template Name
$templateName = 'GetLookupID.html';
$viewVariables = $this->lookupIdentifierRepository->findByCompany($companyDetail);
$templatepath = 'resource://WIND.Alertregistration/Private/Templates/LookupIdentifier/' . $templateName;
$this->standaloneView->setLayoutRootPath('resource://WIND.Alertregistration/Private/Layouts');
$this->standaloneView->setPartialRootPath('resource://WIND.Alertregistration/Private/Partials');
$this->standaloneView->setFormat('html');
$this->standaloneView->setTemplatePathAndFilename($templatepath);
$this->standaloneView->assignMultiple(array("lookUpValue" => $viewVariables));
$this->standaloneView->setControllerContext($this->getControllerContext());
return $this->standaloneView->render();
}
Your view file look like :->
<f:layout name="Lookup" />
<f:section name="Content">
<label for="lookupId" style="box-sizing: border-box;">Identifier</label>
<div class="select-box" style="box-sizing: border-box;">
// Your Code
</div>
</f:section>

Related

How to make a ajax request using post method

I made an ajax request using post method in django..its wokring perfectly..the problem is its calling the complete html page rahter than a div..i want to call only a div..i tried but unable to find the exact solution..
<script>
$(document).ready(function(){
$('#Category').change(function(event){
event.preventDefault();
var e = document.getElementById("Category");
var value = e.options[e.selectedIndex].value;
$.ajax({
url: "/charts/",
type: "post",
dataType: "html",
data: value,
success: function(data) {
$('#div1').html(data);
}});
return false;
});
});
</script>
I want only div content with id #div1..i already tried find and replace method
What is the nature of the event ? Is it a button ? an Input ?
If it is an input as <input type="submit">, the default action is to reload the page like a form.
Did you check if your div id is really div1?
$("#div1").append("your html code"+data+" your html code")

Using ajax with laravel

I'd like to know if it's possible to use Ajax with Laravel without writing the code inside a .js file.
Script.js
$('#selectSemestres').change(function(obj){
var anoSemestre = $(this).val();
$.ajax({
type: 'GET',
url: '',
data: ...
});
})
I don't know how to get the URL that I want (which is my currently page,
I just want to change the < select> value then reload the data that's already shown on the page).
Do I have to write the ajax inside my .php files? Is this a 'good practice'?
I'm asking this because I already have another script inside that same .php file.
Update
Following the answer posted by #ohgodwhy
Now nothing happens when the ajax executes.
It hits the success code but nothing happens, the URL does not change. Is it because I'm redirecting to the same page am at?
file.php
<script type="text/javascript">
$('#selectSemestres').change(function(obj){
var anoSemestre = $(this).val();
$.ajax({
type: 'GET',
url: '{{ route('professor') }}',
data: { anoSemestre: anoSemestre },
success: function(){
console.log('HELLO WORLD');
}
});
})
</script>
MyController:
public function getProfessorList()
{
$professor = Professor::all();
if( Request::ajax() )
{
echo 'yolo';
}
$semestres = Horario::distinct()->select('ano_semestre')->get()->toArray();
return View::make('professor', compact('professor', 'semestres'));
}
What I usually do is add a #yield('scripts') section to my layout that I extend.
Then in the child templates that require specific JS, I'll add that in there.
#section('scripts')
<script>
//your javascript here.
</script>
#endsection
There is 1 caveat however. If you use an #include from within a child template, and that included file has it's own javascript, it must invoke the parent first, like this:
#section('scripts')
#parent
<script>
</script>
#endsection.

Using ajax to update the currently page with Laravel

I have this ajax inside my file.php (It hits the success callback):
<script type="text/javascript">
$('#selectSemestres').change(function(obj){
var anoSemestre = $(this).val();
$.ajax({
type: 'GET',
url: '{{ route('professor') }}',
data: {anoSemestre: anoSemestre},
success: function(data){
console.log(data);
}
});
})
</script>
Now on my Controller:
public function getProfessorList()
{
$professor = Professor::all();
$ano_semestre = isset($_GET['anoSemestre']) ? $_GET['anoSemestre'] : Horario::first()->distinct()->pluck('ano_semestre');
$semestres = Horario::distinct()->select('ano_semestre')->get()->toArray();
return View::make('professor', compact('professor', 'semestres', 'ano_semestre'));
}
What I want to do:
I have a LIST with professor and their disciplines. What I need to do is:
Whenever I change the value of that select box, I just remake the function with the new parameter.
I'm trying to use ajax to remake that list but nothing change, not even the URL with the professor.php?anoSemestre=xx.
Also, when I try to use the $_GET['anoSemestre'] the page doesnt show any change or any ECHO.
But If I go to Chrome spector>NEtwork and click the ajax I just made, it shows me the page with the data I sent.
Cant find out what I'm doing wrong.
UPDATE
I did what was suggested me, now I'm working with the data I get from the success callback:
<script type="text/javascript">
$('#selectSemestres').change(function(obj){
var anoSemestre = $(this).val();
$.ajax({
type: 'GET',
url: '{{ route('professor') }}',
data: {anoSemestre: anoSemestre},
success: function(data){
var lista = $(data).find('#list-professores'); //Get only the new professor list and thier disciplines
$('#list-professores').remove(); //Remove old list
$('#professores').append(lista); //Append the new list where the old list was before.
}
});
})
</script>
The return of var lista = $(data).find('#list-professores'); is:
Accordion Effect
#list-professores li input[name='item']:checked ~ .prof-disciplinas {
height: auto;
display:block;
min-height:40px;
max-height:400px;
}
This list is an Accordion Menu (using a checkbox and changing it with js&css), so everytime I click on a professor < li>, it's suppose to open and show a sublist (disciplines of that professor I clicked). But it's not opening anymore and no errors on the console. No idea why.
The issue here is what you are returning in your controller and how you do it, you donĀ“t need to redirect or refresh the entire page. This could be achived using a single blade partial for the piece of code you may want/need to update over ajax. Assuming you have an exlusive view for that info, you could solve this with something like this:
in your view:
<div class="tableInfo">
<!--Here goes all data you may want to refresh/rebuild-->
</div>
In your javascript:
<script type="text/javascript">
$('#selectSemestres').change(function(obj){
var anoSemestre = $(this).val();
$.ajax({
type: 'GET',
url: '{{ route('professor') }}',
data: {anoSemestre: anoSemestre},
success: function(){
$('.tableInfo').html(data); //---------> look at here!
}
});
})
</script>
in your controller:
public function getProfessorList()
{
$professor = Professor::all();
$ano_semestre = isset($_GET['anoSemestre']) ? $_GET['anoSemestre'] : Horario::first()->distinct()->pluck('ano_semestre');
$semestres = Horario::distinct()->select('ano_semestre')->get()->toArray();
if (Request::ajax()) {
return response()->json(view('YourExclusiveDataPartialViewHere', ['with' => $SomeDataHereIfNeeded])->render()); //---------> This is the single partial which contains the updated info!
}else{
return View::make('professor', compact('professor', 'semestres', 'ano_semestre'));//---------> This view should include the partial for the initial state! (first load of the page);
}
}

Jquery ajax call not working with relative and absolute urls

This is the code, I don't get any alerts whether, error or success. That ajax call returns a json map, and that map is populated in the select options dynamically.
<body>
<script>
$(document).ready(function() {
var selectValues;
$.ajax({
type: "GET",
url: "http://59.163.254.24:4287/wap/retrieve/hanset/data/",
data: APP_002,
async: false,
success: function(data) {
selectValues = data;
alert("Details saved successfully!!!");
},
error:function (xhr, ajaxOptions, thrownError){
alert(xhr.status);
alert(thrownError);
}
});
var $vendor = $('select.mobile-vendor');
var $model = $('select.model');
$vendor.change(
function() {
$model.empty().append(function() {
var output = '';
$.each(selectValues[$vendor.val()], function(key, value) {
output += '<option>' + key + '</option>';
});
return output;
});
}).change();
// bonus: how to access the download link
$model.change(function() {
$('a#download-link').attr('href', selectValues[$vendor.val()][$model.val()]).show();
});
});
</script>
<div>
<select class="mobile-vendor">
<option value="motorola">Motorola</option>
<option value="nokia">Nokia</option>
<option value="android">Android</option>
</select>
</div>
<div>
<select class="model"></select>
<a id="download-link"> Download </a>
</div>
</body>
Why it can't it send the request to the server, I'm using logs in the server side. No request there.
The page url : http://59.163.254.24:4287/wap/download/
Ajex request Url : http://59.163.254.24:4287/wap/retrieve/hanset/data/
I used both /wap/retrieve/hanset/data/ and http://myhost.com/wap/retrieve/hanset/data/ as the parameter for url in the ajax method, both are not working.
Code on your server (link you provided) is not the same as the one you have posted in your question. Code there has error: SCRIPT1009: Expected '}' meaning that you are missing } from your javascript.
Line:
// bonus: how to access the download link
comments out the rest of javascript as you have not switched it to a new row. This commented js includes some code and closing braces. You should add newline after this comment.
This is why you have javascript error and your browser never calls server.
And your parameter should be 'APP_002', not just APP_002
When you fix this, you will probably be able to make request, but if not, we can check for any other errors when you do this.
I think the problem is you're passing APP_002 using the data parameter, which is equivalent in this case to the querystring. Looking your comments on the OP, you need to actually pass it in directly in the URL so that the request is routed correctly on the server, like this:
$.ajax({
type: "GET",
url: "http://59.163.254.24:4287/wap/retrieve/hanset/data/APP_002",
async: false,
// rest of your code...
});
Example:
http://59.163.254.24:4287/wap/retrieve/hanset/data/?APP_002 -> page not found
http://59.163.254.24:4287/wap/retrieve/hanset/data/APP_002 -> JSON response
Actually, there is not a problem with the code you provided.
Here is jsfiddle:
http://jsfiddle.net/fHtcc/1/
However, there must be an issue with APP_002 (if it is not something defined) or Jquery is not included to page.

How do I perform a jQuery ajax request in CakePHP?

I'm trying to use Ajax in CakePHP, and not really getting anywhere!
I have a page with a series of buttons - clicking one of these should show specific content on the current page. It's important that the page doesn't reload, because it'll be displaying a movie, and I don't want the movie to reset.
There are a few different buttons with different content for each; this content is potentially quite large, so I don't want to have to load it in until it's needed.
Normally I would do this via jQuery, but I can't get it to work in CakePHP.
So far I have:
In the view, the button control is like this:
$this->Html->link($this->Html->image('FilmViewer/notes_link.png', array('alt' => __('LinkNotes', true), 'onclick' => 'showNotebook("filmNotebook");')), array(), array('escape' => false));
Below this there is a div called "filmNotebook" which is where I'd like the new content to show.
In my functions.js file (in webroot/scripts) I have this function:
function showNotebook(divId) {
// Find div to load content to
var bookDiv = document.getElementById(divId);
if(!bookDiv) return false;
$.ajax({
url: "ajax/getgrammar",
type: "POST",
success: function(data) {
bookDiv.innerHTML = data;
}
});
return true;
}
In order to generate plain content which would get shown in the div, I set the following in routes.php:
Router::connect('/ajax/getgrammar', array('controller' => 'films', 'action' => 'getgrammar'));
In films_controller.php, the function getgrammar is:
function getgrammar() {
$this->layout = 'ajax';
$this->render('ajax');
}
The layout file just has:
and currently the view ajax.ctp is just:
<div id="grammarBook">
Here's the result
</div>
The problem is that when I click the button, I get the default layout (so it's like a page appears within my page), with the films index page in it. It's as if it's not finding the correct action in films_controller.php
I've done everything suggested in the CakePHP manual (http://book.cakephp.org/view/1594/Using-a-specific-Javascript-engine).
What am I doing wrong? I'm open to suggestions of better ways to do this, but I'd also like to know how the Ajax should work, for future reference.
everything you show seems fine. Double check that the ajax layout is there, because if it's not there, the default layout will be used. Use firebug and log function in cake to check if things go as you plan.
A few more suggestions: why do you need to POST to 'ajax/getgrammar' then redirect it to 'films/getgrammar'? And then render ajax.ctp view? It seems redundant to me. You can make the ajax call to 'films/getgrammar', and you don't need the Router rule. You can change ajax.ctp to getgrammar.ctp, and you won't need $this->render('ajax');
this is ajax call
$(function() {
$( "#element", this ).keyup(function( event ) {
if( $(this).val().length >= 4 ) {
$.ajax({
url: '/clients/index/' + escape( $(this).val() ),
cache: false,
type: 'GET',
dataType: 'HTML',
success: function (clients) {
$('#clients').html(clients);
}
});
}
});
});
This the action called by ajax
public function index($searchterm=NULL) {
if ( $this->RequestHandler->isAjax() ) {
$clients=$this->Client->find('list', array(
'conditions'=>array('LOWER(Client.lname) LIKE \''.$searchterm.'%\''),
'limit'=>500
));
$this->set('clients', $clients);
}
}
This is a function I use to submit forms in cakephp 3.x it uses sweet alerts but that can be changed to a normal alert. It's very variable simply put an action in your controller to catch the form submission. Also the location reload will reload the data to give the user immediate feedback. That can be taken out.
$('#myForm').submit(function(e) {
// Catch form submit
e.preventDefault();
$form = $(this);
// console.log($form);
// Get form data
$form_data = $form.serialize();
$form_action = $form.attr('action') + '.json';
// Do ajax post to cake add function instead
$.ajax({
type : "PUT",
url : $form_action,
data : $form_data,
success: function(data) {
swal({
title: "Updated!",
text: "Your entity was updated successfully",
type: "success"
},
function(){
location.reload(true);
});
}
});
});

Resources