I have a Ajax call like following:
$.post("/user/signindo",{'username':username,"password":password},function(data)
{
// this is what I would like to be able to have in my data object, to be able to access these properties and display them once response is there
alert(data.id);
alert(data.username);
alert(data.firstname);
}
And this is my Zend controller action:
public function signindoAction()
{
// doing something here with the values passed from the view
}
The action doesn't needs to return anything basically since it just checks whether the login data is OK. However, what I need to do here is to somehow say in the action that when the response is returned by Javascript, that it somehow fetches the data that I need to work with within the JS script file. How can I do this with Zend framework? Can someone help me out please?
First you need to ban the layout in response. For that, put the following code in your method Module::onBootstap() :
public function onBootstrap(MvcEvent $e)
{
$sharedEvents = $e->getApplication()->getEventManager()->getSharedManager();
$sharedEvents->attach(__NAMESPACE__, 'dispatch', function($e) {
$result = $e->getResult();
if ($result instanceof \Zend\View\Model\ViewModel) {
// ban the layout only for ajax
$result->setTerminal($e->getRequest()->isXmlHttpRequest());
// To ban the layout for all requests
// set true : $result->setTerminal(true);
} else {
throw new \Exception('SbmAjax\Module::onBootstap() the result isn't a \Zend\View\Model\ViewModel');
}
});
}
Then in your controller build the html response like :
public function signindoAction()
{
// doing something here with the values passed from the view
return $this->getResponse()->setContent(Json::encode(array(
'data' => ...something,
'success' => 1
)));
// to handle errors return response with 'success' => 0
}
Personally I includes all ajax actions in a particular module with as setting for the entire module :
$result->setTerminal(true);
Related
I'm not so much of a framework fan but I have been made to use it because I am working on a project that others may edit later.
I am using the CodeIgniter framework (I'm kinda new on it).
I am using jquery $.post(url, function() {}) to asynchronously call a login parser that is in the root directory under a folder called php-parser I realized this folder does not make use of any of the CodeIgniter's ready made class. I decided to move the folder php-parser into application/libraries but when I tried to use jQuery to call it referencing the full path /application/libraries/php-parser/the-script.php, it return a 403 forbidden error
What do you think I can do? Some people said I could make the script a controller but here is what is going on, It's a popup modal login page. From any page if you click the login / register button, the modal pops up, how can I make a controller and a model for that (if I'm to follow that procedure).
Added: I put the modal content at the end of the footer which is included on all pages, how do I get to create a controller for that kind of modal? Any help!
When dealing with MVC (at least the way you are using it) you have three parts:
The Model - in this case this is the code which interacts with your database.
The View - the code which formats the data you are sending back to the browser
The Controller - the code which connects the two together and might have some business logic in it.
You also have some routing code which maps a URL onto the right controller for that URL.
Browsers (and other clients) only interact with web servers through URLs.
So you absolutely need to have a Controller set up to handle the request from the browser.
If you are doing this the quick and dirty way, then your controller will just get the username and password from the POST request, check it against the database with the model, and then squirt either "Success!" or "Fail!" into the view (which is probably best written as something that returns JSON formatted back to the browser).
If you are being sensibly robust about this then the view will have logic something along the lines of:
Does the browser explicitly include JSON in the accept header?
If so, send back a bit of JSON saying "success" or "failure" (or true / false, or whatever makes sense for you).
Does it not? Then either return a "Sorry, you failed to login!" HTML document or a redirect back to the page they came from (so it will reload in the logged in state).
That way, if the JavaScript fails for any reason, the plain HTML form which was progressively enhanced with the Ajax JavaScript will still function. (NB: You have to write it that way!).
jQuery will automatically include a JSON friendly Accept header if you say dataType: "json" in the Ajax options.
Yes, you will need to put your file inside the libraries folder(if the class is separate from codeigniter or is shared among many controllers, if not a Model would suffice), then create a controller for it.
class Ajax_Controller extends CI_Controller
{
public $statusCode = 200;
public $response = array();
public function __construct()
{
parent::__construct();
if(!$this->is_ajax_request()){
return; // direct access not allowed
}
$this->response = array(
'error' => false,
'text' => "",
'fields' => array()
);
}
public function sendResponse()
{
return $this->output
->set_status_header($this->statusCode)
->set_content_type('application/json')
->set_output(json_encode($this->response));
}
}
class Auth extends Ajax_Controller
{
public function __construct()
{
parent::__construct();
$this->load->library('php-parser/script', 'authentication');
}
public function login()
{
if(!$this->form_validation->run()){
$this->response = array(
'error' => true,
'text' => "The form has some errors",
'fields' => array(
'username' => form_error('username'),
'password' => form_error('password')
)
);
return $this->sendResponse();
}
$username= $this->input->post('username');
$password= $this->input->post('password');
if(!$this->authentication->login($username, $password)){
$this->response = array(
'error' => true,
'text' => "incorrect username/password combination",
'fields' => array()
);
$this->statusCode = 401;
return $this->sendResponse();
}
}
}
I'm trying to create a game with symfony in which there are warriors. Each warrior has a level. To understand jquery and ajax which i'm new with, i want to create a simple button which when clicked use jquery ajax to get the warrior id and make him lvl up. Here is the level up method controller :
public function warriorLevelUpAction(Warrior $warrior){
$warrior->levelUp();
return $this->render('StormbladesWarriorBundle:Warrior:homepage.html.twig', array(
'warrior' => $warrior
));
}
Here is my Jquery ajax method
$('#cpt').click(function() {
$.ajax({
url: "/stormblades/web/app_dev.php/warriors/levelUp/"+{{ warrior.id }},
error: function(xhr, error){
console.debug(xhr);
console.debug(error);
}
});
And here is my routing :
stormblades_warrior_leveluppage:
path: /warriors/levelUp/{id}
defaults: { _controller: StormbladesWarriorBundle:Warrior:warriorLevelUp }
requirements:
id: \d+
Obviously, this doesn't work, i got a beautiful error 500. Any help and suggestion on what's wrong would be appreciate.
A couple of things stand out to me.
Firstly, your warriorLevelUpAction function requires a warrior object, but in the request you are only passing an id. Therefore, you require an extra step to get the warrior by it's ID then level up. For example:
public function warriorLevelUpAction($id){
$warrior = $this->getDoctrine()
->getRepository('StormbladesWarriorBundle:Warrior')
->find($id);
$warrior->levelUp();
return $this->render('StormbladesWarriorBundle:Warrior:homepage.html.twig', array(
'warrior' => $warrior
));
}
Secondly, if you are only ever going to call this function through AJAX, then you could just return a HTTP 200 Status OK, rather then render homepage.html.twig. You don't have to but, I just find it more efficient. Something like this should be fine:
$response = new Response(Response::HTTP_OK);
return $response;
Lastly, in your AJAX code, the url should be: "/warriors/levelUp/"+{{ warrior.id }}, unless there is a specific reson you are using the full path. This path will work in both development and production, whereas your current code will always run in Debug Mode.
everything said above +....
allow POST in your route through the method : POST attribute like this ( probably the reason of the 500)
defaults : ......
requirements:
_method: POST
As jrmck said , in your controller, either return a Reponse object or
return $this->container->get('templating')->renderResponse('..:page.html.twig',
array( 'var' => $var ));
If you can, use FOSJSRoutingBundle (symfony routes for javascript). Calling routes by URL is not that great if you change of adress or anything. https://github.com/FriendsOfSymfony/FOSJsRoutingBundle.
Or also
url: "{{ path('my_route_php")}}",
So, I am running into a 403 forbidden error in a JavaScript call I am making in Yii. I am using XAMPP and I'm not exactly sure what the problem is. This is my first time using JavaScript/jQuery in Yii - so I don't know if there is something obvious that I should change.
A lot of posts have talked about using .htaccess - but I'm not entirely sure how that works, or where I would put that file.
Here is the call in my view
<script>
function getBalance(){
$.get("protected/views/account/balance.php", "", function(data){
alert(data);
});
}
getBalance();
</script>
And the page balance.php simply has the number 7000 (to test with). However, it is denied with 403 (Forbidden). Thank you for any help you can provide!
In Yii, you cannot call the PHP files directly like that. You have to set up an action in the controller like this:
protected/controllers/CustomController.php
<?php
class CustomController extends Controller {
public function balanceAction() {
// Return a string
echo "7000";
// or, render a view file.
// This example will render protected/views/custom/index.php
$this->render('index');
}
then the access control filter and rules in the controller has to be set to allow that new action you just created,
<?php
class CustomController extends Controller {
public function filters() {
return array(
'accessControl',
);
}
public function accessRules() {
return array(
array('allow',
// add the action name in lowercase in this array
// (without the word 'action')
'actions' => array('balance'),
'users' => array('*'),
),
// deny all other actions
array('deny',
'users' => array('*'),
),
);
}
and then in your ajax call or hyperlinks, you will need to call the file using a URL that should look like "controllerName/actionName", in the example above, I would be using "custom/balance"
$.get("custom/balance", function(){ });
I use a common httpRequest to login, so I could use Redirect::intended(); to lead the user to a url before them being lead to the login page. That all works well.
Now I've changed login to ajax request I can only redirect the url in javascript now. So I've to pass the intended url to front end then do the window.location=url
The problem is I can't get the intended/original url. Can any kind laravel expert help me out ?
In your controller action use:
$url = Redirect::intended( ... )->getTargetUrl();
(Where ... is the fallback url)
Then return it in the JSON response, and use window.location or other to do the redirect.
When you are showing the form foe log in, you can grab the intended url from session if available and pass it to the view then redirect using window.location.
So. how to grab the intended url ?
$intended_url = Session::get('url.intended', url('/'));
Session::forget('url.intended');
Here, first argument is intended url if available in the session and default is set to home page using url('/') helper method, so the $intended_url will always contain a url, intended or defaulr. Then when you are loading the view, pass the $intended_url using this:
return View::make('login')->with('intended_url', $intended_url);
Then use it from the view like:
window.location = $intended_url;
Alternatively, you may setup a View Composer so whenever the login view/form is displayed the intended url will be available in that view and you can do it using this:
View::composer('login', function($view){
$intended_url = Session::get('url.intended', url('/'));
Session::forget('url.intended');
return $view->with('intended_url', $intended_url);
});
Here, login is the view name for login page, if this is something else in your case then change it to the appropriate name of your login view. You can keep this code in your app/start folder inside the 'global.php' file or keep it in a separate file and include this fie inside global.php file using this (at the end):
require 'view_composer.php';
Assumed that, file name would be view_composer.php, present in the app/start folder.
In Laravel 5.7:
$url = redirect()->intended()->getTargetUrl();
I am using the following approach with a custom login controller and middleware for Laravel 5.7, but I hope that works in any of laravel 5 versions
inside middleware
if (Auth::check()){
return $next($request);
}
else{
return redirect()->guest(route('login'));
}
if you are not passing the intented url to client side use the following inside controller login method
if (Auth::attempt(['email' => $email, 'password' => $password])) {
return redirect()->intended('/default');
}
If you need to pass the intented url to client side, you can try the following
if (Auth::attempt(['username' => $request->username, 'password' => $request->password])) {
$intended_url= redirect()->intended('/default')->getTargetUrl();
$response = array(
'status' => 'success',
'redirectUrl' => $intended_url,
'message' => 'Login successful.you will be redirected to home..', );
return response()->json($response);
} else {
$response = array(
'status' => 'failed',
'message' => 'username or password is incorrect', );
return response()->json($response);
}
Redirect to the intented url from clientside
success: function (data) {
if(data.redirectUrl){
window.location.href = data.redirectUrl;
}
},
I have a Ajax form in my asp.net mvc application, which has a onSuccess callback as below:
function onSuccessReport(context)
{
$('reportChart').empty();
var line1=#Html.GetStrippedString(context.Expenses);
}
I defined a html helper which accept an string an manipulte it and return a string.
What I pass to onSuccessReport, is a json result which has a structure like this:
But I cant send context.Expenses and the application throws syntax error.
How can I send a javascript variable to my helper?
Thanks
Edited:
The error in my view
****Error 1 The name 'context' does not exist in the current context****
C# method
json = json.Replace("\"Date\":", string.Empty);
json = json.Replace("\"Total\":", string.Empty);
json = json.Replace('}', ']');
json = json.Replace('{', '[');
return MvcHtmlString.Create(json);
You are mixing client side code (javascript) with server side code (HtmlHelper). You cannot pass client side variables to server side helpers. If the context variable is known only on the client then you will have to write a client side javascript function instead of server side helper. So move to logic you wrote in this Html.GetStrippedString helper into a javascript function that you could call from your script.
Actually, you can send javascript values over to the server side if you use Ajax. Instead of using your helper method the way you are, just change it into an action within the Controller to return you some Json (could just be a string, number, object, etc, etc). Here is an example of what you might try out.
View
function onSuccessReport(context)
{
$('reportChart').empty();
var expenses = context.Expenses;
$.getJSON('#Url.Action("GetStrippedString", "ControllerName")', { expenses: expenses }, function (data) {
//pending what you pass back as data, do whatever with it
alert(data);
});
}
Controller
public JsonResult GetStrippedString(string expenses)
{
var result = string.Empty;
//Do something to string
return Json(result, JsonRequestBehavior.AllowGet);
}