Ok so Ive got this Javascript file, simply:
$(document).ready(function() {
$('.status').prepend("<div class='score_this'>(<a href='#'>score this item</a>)</div>");
$('.score_this').click(function(){
$(this).slideUp();
return false;
});
$('.score a').click(function() {
$(this).parent().parent().parent().addClass('scored');
$.get("/js/Rating.php" + $(this).attr("href") +"&update=true", {}, function(data){
$('.scored').fadeOut("normal",function() {
$(this).html(data);
$(this).fadeIn();
$(this).removeClass('scored');
});
});
return false;
});
});
Where it says /js/Rating.php, that file is in application/modules/recipes/models/Rating.php, this is because it contains some Zend logic that cant be accessed outside the application.
Through the Controller. That is the only reasonable way.
Remember JavaScript is executed on the client side, not the server. You placed your models outside the publicly accessible webroot, because your users are supposed to access your MVC app (e.g. the domain logic in the Rating model) through your app's FrontController and not on the Model directly.
In other words, since .get() issues an Ajax Request, you should direct this request to the Ratings controller in your app and make the Ratings controller call the appropriate model in your application. The model returns something to the controller and the controller then returns this result to the client.
Example:
$.get("/rating/update/someParamId/someParamValue");
This assumes you are using the default rewrite rules. In your controller you could then do $this->getRequest()->getParam('someParamId') and it would contain 'someParamValue'. The controller will return the ViewScript usually rendered by the action back to the client, so you might want to disable the layout to just return the HTML fragment.
Related
Im using OctoberCMS, the user plugin and I want to send data via AJAX to a controller and save the data in the database (in the column of the logged in user).
So I created a new Route in my routes.php
<?php
Route::get('saveHighscore', 'test\Profile\Controllers\HighScore#saveHighscore')
->middleware('web');
And a controller
<?php
namespace Test\Profile\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use October\Rain\Auth\Models\User;
use RainLab\User\Facades\Auth;
class HighScore extends \Illuminate\Routing\Controller
{
function saveHighscore(Request $request) {
DB::table('users')->where(['id' => Auth::getUser()->id])->update(['highscore' => $request]);
}
}
And my jQuery calls
$.ajax({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
url: "/saveHighscore",
type: "POST",
data: highscore
});
But nothing works. If I call /saveHighscore in my browser with dummy data in the controller, it works fine
It should work without any issue.
But I think you are making 2 different requests
In ajax config you specified -> type: "POST" and you are listening for get request
May be you just need to change Route::get -> Route::post
Now it should work expected.
If any doubts please comment.
The AJAX framework only works on the CMS controller or Backend controllers (controllers extending backend/classes/controller). If you're wanting to send data via AJAX without using the built in AJAX framework, then we would have to see more information from your console / network tab of your browser dev tools to see why exactly it's failing.
I'm still a bit new to Vue.js, so I may be fundamentally misunderstanding something about the reactivity of it, but basically, I want to pass some data from PHP Laravel to a Vue.js component and have the Vue.js component automatically update when that data changes.
I've seen several similar posts on SO suggest that I use props to pass the data from a Laravel Blade template to a Vue.js component. Here's an example:
How to pass a PHP variable to Vue component instance in Laravel blade?
I have this working perfectly fine, but now I'm stuck with how to get the component to update when the data dynamically changes after page-load.
Specifically, I have a report table on a particular web page, and when the user clicks certain buttons, etc., I use Ajax to call a Laravel controller action that re-runs a query in my Laravel model to get the new data for the report.
I have the data in a PHP array / JSON, and that data is being properly returned to the client-side and I have access to it in the JS, but now, what do I need to do to force the report component in Vue.js to essentially re-render based on the data I just received? Is there a way to "update props" so that Vue.js detects the change and automatically re-renders the whole report component for me?
This is where I'm stuck, and after quite a bit of research, I can't find how to do this. Thank you.
Are you using Ajax outside of the Vue component? or within it as a method?
I have an example of how I dynamically update the Vue data from within the component itself. I'm not sure how to have external JS update the Vue component directly but I feel this is a good option to look at. I'm using axios instead of Ajax but the principle is the same (Axios is included by default in most Laravel installs past 5.5).
<template>
<div>
<div id="reports">
<!-- Display data -->
{{ reports }}
</div>
<button #click="refreshReports">Refresh</button>
</div>
</template>
<script>
export default {
data() {
return {
endpoint: '/api/MY_ROUTE/'
};
},
props: {
reports: Object
},
methods: {
// Make Axios call to API endpoint
refreshReports() {
// GET version
axios.get(this.endpoint)
.then(({data}) => {
this.reports = data.data;
});
// POST version
axios.post(this.endpoint, {
KEY: 'VALUE',
}).then(({data}) => {
this.reports = data.data;
});
/*
`data.data` assumes the returned response is a JSON Resource
if it's not returning the correct data, put a `console.log(data)` and see how it's getting returned!
*/
}
}
};
</script>
Where in your routes/api.php file you have a route like this:
// GET version
Route::get('MY_ROUTE', 'ReportController#getReports');
// POST version
Route::post('MY_ROUTE', 'ReportController#getReports');
And your Controller would have some method like this:
// app/Http/Controllers/ReportController
public function getReports(Request $request) {
return Reports::all();
}
Does that make sense?
Update:
I'm not sure how to have external JS update the Vue component directly
I know you can import external JS scripts and use their functions in methods but I've never done it that way before.
Something like:
<script>
import { myFunction } from '../external.js'
export default {
methods: {
refreshReports() {
// I have no idea if this is the correct way to do it, just a guess!
this.reports = myFunction();
}
}
};
</script>
I have an existing application that Im moving to Angular and I have some questions. My new Angular app has four routes:
Home
Activity
Login
Signup
In my old app I had AJAX calls to PHP that would query MySQL and return the information as needed, but I could tie everything together using jQuery and call my AJAX calls from one centrally located .js file.
Now, I need to write a call to $HTTP to do the same thing as my AJAX calls did, but I dont know where to put everything!
For example I have the following sample $HTTP function I found online:
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http) {
$http.get("users.php")
.then(function(response) {
$scope.users = response.data;
});
});
</script>
Where does this go in the Angular file structure? I intend to call it from the Activity route, which creates another question. Since the route pages are based on templates how do I call the function from the route or template so I can see the results on the Activity page?
Factory/Service is what you are looking for. Ajax call should be made inside a factory method which in turn returns the data to the controller (myCtrl in your example).
You should bind your controller (myCtrl) with the view (Activity) in the route provider itself.
Here is an example that will give you a clear picture.
How factory works
I am trying to learn a PHP framework. But I'm having some difficulties understanding some of the concepts of routing.
I've chosen to use Flight. Their homepage shows:
require 'flight/Flight.php';
Flight::route('/', function(){
echo 'hello world!';
});
Flight::start();
And I don't understand what they're using Flight::route... for. What am I missing? This question isn't even related to Flight. It's related to just routing in general.
Routing basically maps HTTP requests to your methods/functions.
To put it simply, say you have the route:
Flight::route('/page1', function() {
echo 'page1!';
});
This is was basically happens:
Client requests example.com/page1
Server sends query to PHP
Your PHP framework parses the request URL
Picks the correct route, in our case, page1/
And finally calls the function you passed in, so basically echo 'page1';
What seems to be happening in your file (I'm not familiar with Flight)
the require 'flight/Flight.php'; is more than likely defining a class for all the routing.
Then Flight::route(); Is simply using the route() method from the class Flight without an instance of the class.
Flight::route('/', function(){
echo 'hello world!';
});
What happens here is when a route is matched (by matched means the URI of the user matches the URI on your route, in this case www.yourdomain.com/ will match the '/' route) And then the code inside the function() callback gets executed.
If you add another route
Flight::route('/about', function(){
echo 'About Us';
});
When the user visits www.yourdomain.com/about He will get whats inside that route.
Flightphp has a rather comprehensive explanation on how to set up routes here.
You should see routes as definitions of how to handle different request patterns.
The example on Flight's home page says that if you hit your site root (i.e. /) it will simply return "hello world!" as a response.
If you read further on the Flightphp install page you will notice that all requests are handled by the index.php page. And thus depending on the routes you define it replies with the relevant response defined for that url request pattern.
Flight::route('/', function(){
echo 'hello world!';
});
This snippet is heart of your project.
This will accept two parameters.
Route
Method to call on this route call
Consider below code snippet, If you are having your project directory http://localhost/flight_project/, when anyone requests this directory, function defined as 'function_here' will be called.
Flight::route('/', 'function_here');
If you have defined route like below,
Flight::route('/user/', function(){
// do something here
});
when someone access http://localhost/flight_project/user/, the above in-line function gets called.
More info HERE
route() is a static function it seems, that means it's not specific to the object, i.e. you can't create an object such as
$flight = new Flight();
and then call
$flight->route(...)
but rather you call it via the class (not an object, which is a specific implementation of the class). You call static functions of a class by using ::, in this case
Flight::route(...)
The content of the route just says, when you encounter '/', do 'X'... and in your case 'X' is
function(){
echo 'hello world!';
}
in later stages you get to match stuff like
'/' (homepage, i.e. "mywebsite.com/")
'/about-us' (About Us page, i.e. "mywebsite.com/about-us")
'/user/{id}' (User page, i.e. you can pass a parameter such as "mywebsite.com/user/taylor" and then get the user data)
or whatever you want. And instead of just writing the function into the routing file, you can tell the router to go to a specific function (usually a Controller function) and you can do more stuff there.
I hope this helps!
I am currently using zend framework and working with jquery and php. Trying to implement an autocheck username availability.
For the following code, I need to call my user_availability.php which is in my controller folder. I did /controllers/user_availability, ../user_availability but it doesnt call that page. Can anyone help?
$.post("user_availability.php",{ user_name:$(this).val() } ,function(data)
if you truely want to call a plain php file with zend framework, then you need to put it inside your public folder and call it as /user_availability.php but it should almost certainly be better to make user-availability an action of one of your controllers
Look into Action and View Helpers (depending on where you want to call the script from). Action Helpers can be called from controllers and may be kept in a .../project/library.
From a view you can call a custom View Helper you've written and stored in .../projectname/application/view/helpers.
You may want to restructure your code to fit better within the framework but simply creating a helper that requires (includes) your .php script should work.
View helpers (Survive the Deep End)
Action helpers (from the manual):
It appears you're making a page request to a non-controller item. Anytime you make a request in Zend Framework, it will attempt to match the URL of the request to a route in the system, which corresponds to a controller action. All of this is handled via your application's index.php file - the only way to serve a different php file directly would be through your public folder.
My suggestion is to create a controller action that checks for an Ajax request and returns something in your format of choice (XML, json) (rather than rendering an HTML template).
public function userAvailableAction()
{
if ($this->getRequest()->isXmlHttpRequest()) {
// check user availability
$this->_helper->json($data);
}
}
Thanks everyone. I found the solution to it.
You just need to put the function in the controller page and call the function name.
e.g:
$.post("check",{ user_name:$(this).val() } ,function(data)
Then in your controller file checkusername availability make sure you add the check function.
my controller page is as follows the code:
class RegisterController extends Zend_Controller_Action {
public function checkAction(){
$users = new Users();
$username = $_POST['username'];
if($users->checkUnique($_POST['username'])){
echo "fail";
}
}
In this case, the checkUnique is just an sql statement in my model controller to check if the username exist.
For my jquery code it is:
$("#username").blur(function(){
//remove all the class add the messagebox classes and start fading
$("#msgbox").removeClass().addClass('messagebox').text('Checking...').fadeIn("slow");
//check the username exists or not from ajax
$.post("check",{ user_name:$(this).val() } ,function(data){
if(data=='no'){ //if username not avaiable
$("#msgbox").fadeTo(200,0.1,function(){ //start fading the messagebox
//add message and change the class of the box and start fading
$(this).html('This User name Already exists').addClass('messageboxerror').fadeTo(900,1);
});
}else {
$("#msgbox").fadeTo(200,0.1,function(){ //start fading the messagebox
//add message and change the class of the box and start fading
$(this).html('Username available to register').addClass('messageboxok').fadeTo(900,1);
});
}
});
});
I got this example from this link:
http://roshanbh.com.np/2008/04/check-username-available-ajax-php-jquery.html. Do take a look at it. I hope it helps. =)