How to route a url to include scrolling down to a div id in Laravel - html

I am validating a contact form. I wrapped it in a div with the id of "contactform". When validation messages appear after submission I want the redirected page to scroll down automatically to the "contactform" div so users don't have to scroll down themselves to correct the form.
I can accomplish this easily by manually typing the url:localhost:8000/#contactform
However I cannot get the routing to work in Laravel.
I tried altering the controller to:
return Redirect::to('/#contactform');
I tried:
return Redirect::to('#contactform');
return Redirect::to('/' . '#contactform');
return view('/')->with('#contactform');
return view('/#contactform');
return view('/pages.index.#contactform');
return view('/pages.index#contactform');
They all return without the #contactform in the url.
I know there is a javascript way to accomplish this, but I was really trying to stay away from javascript for now. There has to be a simpler way I just cannot see it. I'm new to Laravel and completely self-taught. Thanks
***EDIT
I tried a new controller step by step. Without validation it works. Validation seems to break it.
This works:
public function store() {
return (string) Redirect::to('/#contactform');
}
This breaks it:
public function store(Request $request) {
$this->validate($request, [
'first_name' => 'required',
'last_name' => 'required',
'email' => 'required|email',
'telephone' => 'nullable',
'comments' => 'required',
]);
return (string) Redirect::to('/#contactform');
}
The top of the controller page I call the request and redirect like this:
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;
Can anyone help me get down to the reason why I cannot validate without breaking the url route?

On validation failure it will cause a redirect 'back'. It is entirely possible that 'back' is the same URI you want to redirect to, so from your perspective it looks like it is redirecting wrong when it is correct. If you remove the validation you should get the correct redirect.
Side note: On the server side the hash is not part of the URL. It is a client side thing.

A solution that works for me is to compact() a Boolean variable through the controller.
Link example
Passing the variable to the controller
Route::get('/post={post_id}+{scroll}',[PostController::class, 'show']);
If the variable equals 'scroll' then switch the boolean variable to true
public function show($post_id, $scroll){
if($scroll == 'scroll'){
$scroll = true;
}else{
$scroll = false;
}
return view('yourview', compact('scroll'))
}
Run the script if $scroll is true
<script>
#if($scroll)
$(document).ready(function () {
$('html,body').animate({ scrollTop: 99999 }, 'slow');
});
#endif
</script>

Related

Get json data in VueJS

onMounted(() => {
productService.value
.getProducts()
.then((data) => (products.value = data));
console.log((products))
});
When I print products with console.log, here what I have.
capture of the console
I see that the data I want are in RawValue but I don't know how to access them.
I tried Object.values(products) or just console.log(products._rawValue) or console.log(products.rawValue) it print undefined.
Do you know what function call ?
Thanks
There are 2 issues
#1 - you're using console.log(products) which shows you the reactive object, what you need instead is console.log(products.value) which will only show the value, which should match the content of data.produtcs
#2 - you might find that 👆 now shows an empty result. The reason that's happening is that you're calling the console log after the async function, but before it finishes, so you're calling it before it has a chance to update. To fix that, you can log as part of the async function
onMounted(() => {
productService.value
.getProducts()
.then((data) => {
products.value = data;
console.log(products.value);
})
});
If you're using the products inside a template, you don't need to worry about what's before or after the async function since it will re-render the component on change.
Also, you probably don't need to define productService as a ref, the class is likely not something that needs to be reactive, so you can just do simple assignment and then skip the .value to call getProducts
with axios what I do is take out the data with response.data you could try
onMounted(() => {
productService.value.getProducts().then((response) => (
products = response.data
));
console.log(products.length);
});

Trying to add User in Laravel using Angular but it shows me an error

I'm trying to use the post method to pass the user to Laravel using a form in HTML so I can store the user in the UserController into the database. I get an CSRF Token mismatch error.
I have used this Method to store the user:
addUser(user: User):Observable<User>{
return this.http.post<User>(this.apiURL+'/addUser',user, httpOptions);
}
When I console.log the user it works fine. It shows me all attributes when I klick on submit.
I have use this Route in Laravel to store the user:
Route::post('/addUser','UserController#create');
In the Controllermethod I used this code:
public function create(Request $request)
{
$data2 = $request->json()->all();
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
}
Laravel, by default, has VerifyCsrfToken middleware enabled for all routes. This is for security (to avoid cross site attacks) and checks for a CSRF token for all requests. But you can set middlewares for route groups such as web, api',console`.
Try to move VerifyCsrfToken middleware from $middleware variable to web group in $middlewareGroups variable in Http/Kernel.php. By doing this, you only enable this middleware for web routes.
Hope this helps.

Yii2 Functional test send ajax get request not working

I am trying to test an ajax request with a basic install of Yii2. I am just using the SiteController::actionAbout() method to try this out.
public function actionAbout()
{
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
return [
'message' => 'hello world',
'code' => 100,
];
}
And in the test:
public function sendAjax(\FunctionalTester $I)
{
$I->sendAjaxGetRequest('site/about');
$r = $I->grabResponse();
die(var_dump($r));
}
The grab response method is one I wrote myself in a \Helper\Functional.php file:
public function grabResponse()
{
return $this->getModule('Yii2')->_getResponseContent();
}
When I dump out the response, I just see the html from the site/index page.
This happens for any route except the site default. If I try to do the same thing using site/index then it returns:
string(36) "{"message":"hello world","code":100}"
What am I missing / doing wrong?
Note the difference between a Yii route and the actual URL.
The argument to sendAjaxGetRequest() is the URL, not the route (at least if you pass it as a string, see below).
Dependent on your UrlManager config you might have URLs like /index.php?r=site/about, where the route is site/about. You can use the Url helper of Yii to create the URL:
$I->sendAjaxGetRequest(\yii\helpers\Url::to(['site/about']));
I am not sure about this but if you have the Codeception Yii2 module installed you should also be able to pass the route like this:
$I->sendAjaxGetRequest(['site/about']);

Add supported header type to JsonOutputFormatter

My company uses a standard format for healthcheck responses in internal apis etc. We either return the status with a content type of application/status+json on success or application/problem+json if we have an issue (part of this proposed spec).
But if i set the content type to either of these my response becomes an emptu 406 response.
So, how can I tell the JsonOutputFormatter that it can add these Json header types to it's SupportedMediaTypes collection?
I would expect I could do something like:
services.AddMvc().AddJsonOptions(jsonOptions => {
jsonOptions.SerializerSettings.SupportedMediaTypes.Add("application/problem+json");
});
But of course I can't find a way to do that.
Okay, so here is a way to do it. I found the OutputFormatters collection and was able to pull out the JsonOutputFormatter. From there you can add a supported media type:
services.AddMvc(mvcOptions => {
//TODO: make extension method
var jFormatter = mvcOptions.OutputFormatters.FirstOrDefault(f => f.GetType() == typeof(JsonOutputFormatter)) as JsonOutputFormatter;
jFormatter?.SupportedMediaTypes.Add("application/problem+json");
jFormatter?.SupportedMediaTypes.Add("application/status+json");
});
Or, as an extension method:
public static IMvcBuilder AddStatusJsonSupport(this IMvcBuilder builder) {
builder.AddMvcOptions(options => {
var jFormatter = options.OutputFormatters.FirstOrDefault(f => f.GetType() == typeof(JsonOutputFormatter)) as JsonOutputFormatter;
jFormatter?.SupportedMediaTypes.Add("application/problem+json");
jFormatter?.SupportedMediaTypes.Add("application/status+json");
});
return builder;
}
called like so:
services.AddMvc().AddStatusJsonSupport();

Ajax in Laravel 5.3 accessible by everyone

I am new to Laravel, so sorry for my code..
I am trying to integrate a jquery library with my Laravel project.
Controller
public function index()
{
return view('products');
}
public function data()
{
$products = Product::all();
return $products->toJson();
}
Route
Route::get('/products', ['as' => 'products', 'uses' => 'ProductController#index']);
Route::get('/products/data', ['as' => 'products.data', 'uses' => 'ProductController#data']);
View
<script>
var CSRF_TOKEN = $('meta[name="csrf-token"]').attr('content');
$.ajax({
url: '/products/data/',
type: 'GET',
data: {_token: CSRF_TOKEN},
dataType: 'JSON',
success: function (data) {
console.log(data);
}
});
</script>
Everything works, but if I go to /products/data/ I can see the json on the browser. That should not happen!
Am I doing it right? It this the right way of getting json data from the database into the view?
Thank you.
As long this information is not usefull for an attacker you've nothing to worry about. Product information is most likely not a thing you want if you want to do some harm to a website.
Make sure information about users doesn't transfer over a GET Request. Because this way someone who wants to do harm to your website has access to information they want to achieve. Make sure this data travels over a POST Request so they can't get access to the information very easy. Also make sure you hash information that should be only in the hands of the user him or herself or other trusted sources.
In this situation i don't really see anything wrong with your approach at first sight.
A little more information about this subject can be found here: HTTP Methods: GET vs. POST
You can use Request wantsJson or ajax method
Controller
use Illuminate\Http\Request;
public function data(Request $request)
{
$products = Product::all();
if ($request->wantsJson()) {
return $products;
}
return abort(404);
}