I want to display download link button on my view (if my ajax is success)
follwings is my download code to send ajax response and dispaly on view
<div class="blog-moder-button">
<a href="public_path('files').'/'.$request->file_name" class="button-md dark-button downlds">
Download PDF
</a>
</div>
following is my controller
public function
downloadform(Request $request) {
$validator = Validator::make($request->all(),[
'name' => 'required',
'email' => 'required|email',
'file_name' => 'required',
]
);
if ($validator->passes()) {
$msg= array();
// $msg['success'] = '<div class="alert alert-success"> Successfully Registered</div>';//it is working
$msg['success'] = '<div class="blog-moder-button"> Download PDF</div>';//it is not working
}
return response()->json($msg);
}
Do not render html inside your controller, that is the job of your view.
To trigger a file download response use this:
return response()->download($pathToFile);
https://laravel.com/docs/5.6/responses#file-downloads
Related
For example, I have a form:
<form method='post' action='https://test.com'>
<input name='name' value='test'>
<button name='test' type='submit'> </button>
</form>
And after submit this redirects me to another page.
My question is 'how can I do the same thing with guzzle from a controller?' I tried to make:
$client = $client = new GuzzleHttpClient();
$response = $client->post('https://test.com',
form_params => [
'name' => 'test'
]);
return $response->getBody()->read(1024);
And here I am getting a response that I wanted. but I want to redirect my current page to page with the response.
Use return redirect()->back() in method controller
You have to try something like this
$client = $client = new GuzzleHttpClient();
$response = $client->post('https://test.com',
form_params => [
'name' => 'test'
]);
$response_to_return = $response->getBody()->read(1024);
return redirect()->back()->withInput()->with('response_to_return', $response_to_return);
The image is not shown when I display it in the index page.
My view file (index.blade.php):
<div class="row">
#if(App\News::count() > 0)
#foreach($news as $n)
<div class="col-md-8 panel border-right">
<br />
<img src="{{ asset('storage/images/news/'. $n->image) }}" width="200px" height="100px">
--$n->image returns News_1.jpg which is the image name stored in the storage directory.
<h1>First Div</h1>
</div>
#endforeach
#endif
<div class="col-md-4">
<h1>Second Div</h1>
</div>
</div>
My controller:
public function store(Request $request)
{
$this->validate($request,
[
'head' => 'required|max:191',
'title' => 'required|max:191',
'body' => 'required',
'pic' => 'required'
]);
$filename="";
$extension="";
if($request->hasFile('pic'))
{
if((News::orderBy('id', 'desc')->first()) != null)
{
$id = ((News::orderBy('id', 'desc')->first()->id)+1);
$filename = "News_" . $id;
}
else
{
$filename = "News_" . 1;
}
$extension = $request->pic->getClientOriginalExtension();
$filename = $filename . "." . $extension;
//return $request->pic->getClientOriginalName();
$request->pic->storeAs('public/images/news', $filename);
}
else
{
return redirect()->back()->withInput(Input::all())->withErrors(['message' => 'Please select a valid file.']);
}
$news = new News;
$news->head = $request->head;
$news->title = $request->title;
$news->body = $request->body;
$news->image = $filename;
$news->save();
Session::flash('success', 'The record was successfully saved.');
return redirect()->route('news.index');
}
I have already linked the storage directory with the public directory:
My directory structure:
The images are stored properly in both the Application and database but it cannot be displayed properly, when I run the app, I get the following view:
When open the image in new tab, I see the following address bar:
This is the local driver configuration:
Any help is appreciated in advance.
If your current route is /cricket and you reference an image with 'storage/images/news/news1.jpg' then the web browser is going to assume that this image is relative to the cricket resource.
Your image src needs to start with either the full URL or a / to indicate it is relative to the root folder
In this case I would hard code the URL since you have hard coded it in the asset helper anyway
<img src="/storage/images/news/{{ $n->image }}"
You can try setting your local driver to something like this:
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
I have a Single page application in Yii2
the main page contains
1. a column with a list of objects + create button
2. a column for dynamic content of create/update forms
My problem is when loading (through ajax) a create form, and then I am sending data through AjaxSubmitButton which woks fine (db updated) but instead of changing the dynamic content area with the new object data it redirects to a view partial form.
How can I make the new response go into the same div that it is being sent from?
this is the form that is loaded now in #singleObjContainer
<div class="course-form">
<?php
$form = yii\bootstrap\ActiveForm::begin();
?>
<span>
<h4 class='listTitle'>Add Course</h4>
</span>
<span class="form-group pull-right">
<?php
AjaxSubmitButton::begin([
'label' => 'Save',
'ajaxOptions' => [
'type'=>'POST',
'url'=> Url::toRoute(['course/create-form']),
'success' => new \yii\web\JsExpression('function(html)
{
$("#singleObjContainer").empty().append(html);
}'),
],
'options' => ['class' => 'btn btn-success', 'type' => 'submit'],
]);
AjaxSubmitButton::end();
?>
</span>
<hr class='myHr'>
<div>
<?php
echo $form->field($model, 'name')->textInput(['maxlength' => true]);
echo $form->field($model, 'description')->textarea(['rows' => '4']);
echo $form->field($model, 'img')->label(Html::img(Yii::getAlias('#uploadsUrl/').'courses/'.$model->img,['width' => '30%']),['encodeLabel' => false])->fileInput();
?>
</div>
<?php ActiveForm::end(); ?>
and this is the controller action:
public function actionCreateForm()
{
$model = new Course();
if ( $model->load(Yii::$app->request->post()))
{
// get the instance of the image
$image = UploadedFile::getInstance( $model, 'img');
// save image name to the model
$model->img = $image->baseName.".".$image->extension;
// go through validation rule and save
if( $model->save() )
{
// validation ok, save image in the file system
$image->saveAs( Yii::getAlias('#uploads/').'courses/'.$model->img);
// load the details view into the singleObj container
$courseStudents = $this->getCourseStudents($model['id']);
return $this->renderPartial('_viewForm', ['model' => $model, 'courseStudents' => $courseStudents]);
}
}
else
{
return $this->renderPartial('_createForm', ['model' => $model,]);
}
}
If you need that your result is send directly to the ajax request .. just return .. eventually using a json_encode for the array.
return json_encode( $model);
this way you obtain a json answer with struct equivalent to your $model
In your controller add a proper action
public function actionRefreshForm()
{
//your appllication code
$my_new_html_code ='<div>test new html code </div>;
return $my_new_html_code;
}
In your ajaxOptions call the related action
'ajaxOptions' => [
'type'=>'POST',
'url'=> Url::toRoute(['course/refresh-form']),
'success' => new \yii\web\JsExpression('function(html)
{
$("#singleObjContainer").empty().append(html);
}'),
],
You can use yii\widgets\Pjax. It will be easy for you I guess. You can learn more about it in this article. http://blog.neattutorials.com/yii2-pjax-tutorial.
I'm using Laravel 5.4 and trying to submit a form and check if an input is numeric. But when I get to the validation it routes to a different page.If I remove the validation then everything works correctly.
This is my blade form:pin_verification.blade.php
#extends('layouts.master')
#section('title','Verify Order')
#section('extra_head_info')
<meta name="csrf-token" content="{{ csrf_token() }}">
#endsection
#section('content')
#if(count($errors) > 0)
<ul>
#foreach($errors->all() as $error)
<li class="alert alert-danger">{{$error}}</li>
#endforeach
</ul>
#endif
{{ Form::open(['action' => 'PinVerificationController#pinValidation','id'=>'pin_verification_form']) }}
We sent a text message to {{$clean_number}}. You should receive it within a few seconds.<br><br>
{{ Form::label('Pin Code', null, ['class' => 'control-label']) }}
{{ Form::text('pin_number', null,['placeholder' => 'Pin Code'])}}<br><br>
Enter a 4 digit pin you received by phone.
<br>
<br>
{{ Form::submit('Verify',['name'=>'validate'])}}
{{ Form::close() }}
#endsection
When I click my submit button on my pin_verification.blade.php form
I go to my PinVerificationController.php:
class PinVerificationController extends Controller
{
public function pinValidation(Request $request){
if($request->has('validate')){
$validator = $this->validate($request,[
'pin_number' => 'required|numeric'
]);
return redirect("/test/create");
//return $this->validatePin($request);
}else{//choosing verification method
return $this->choosePinVerficationMethod($request);
}
}
public function init(){
...
}
public function choosePinVerficationMethod(Request $request){
...
}
}
My code goes into pinValidation function and into the first if statement but when it hits the
$validator = $this->validate($request,[
'pin_number' => 'required|numeric'
]);
It routes to my init() function to a different controller, CheckoutController.php
If I remove my validation then my code works correctly and I get redirected to redirect("/test/create");
Why is this happening?
My routes are:
Route::get('/order/verify/{encrypted_key}', ['as'=>'pinverification','uses'=>'PinVerificationController#init']);
Route::get('/test/create', ['as'=>'orders_create', 'uses'=>'OrdersController#init']);
Route::post('/order/verify', ['as'=>'pinverification1', 'uses'=>'PinVerificationController#pinValidation']);
Route::get('/order/checkout/{product_id}', ['as'=>'checkout', 'uses'=>'CheckoutController#init']);
It's because you aren't actually checking the validation, you're just performing the method, so then naturally it just routes to /test/create as per the first return redirect instruction.
Try this instead:
public function pinValidation(Request $request){
if($request->has('validate')){
$validator = Validator::make($request->all(), [
'pin_number' => 'required|numeric'
]);
if ($validator->fails()) {
return redirect('test/create')
->withErrors($validator)
->withInput();
} else {
// Success criteria, validation passed.
}
} else {
$this->choosePinVerficationMethod($request);
}
}
The validate method, you have used here redirects you itself:
$validator = $this->validate($request,[
'pin_number' => 'required|numeric'
]);
You should rather use:
$validator = Validator::make($request,[
'pin_number' => 'required|numeric'
]);
and then check for:
if ($validator->fails()) {
//redirect
};
Reference
let's say I have a blog with a module "post".
now I display a post like this: post/index?id=1
in the index-action i generate a new CommentForm and pass it as $this->form to the template and it is being displayed at the bottom of a post (it's just a textfield, nothing special). form action is set to "post/addcomment". How can I display the validation errors in this form? using setTemplate('index') doesn't work because I would have to pass the id=1 to it...
thanks
UPDATE:
here's a sample code:
public function executeIndex(sfWebRequest $request)
{
$post = Doctrine::getTable('Posts')->find($request->getParameter('id'));
$this->post = $post->getContent();
$comments = $post->getComment();
if ($comments->count() > 0)
$this->comments = $comments;
$this->form = new CommentForm();
$this->form->setDefault('pid', $post->getPrimaryKey());
}
public function executeAddComment(sfWebRequest $request) {
$this->form = new CommentForm();
if ($request->isMethod('post') && $request->hasParameter('comment')) {
$this->form->bind($request->getParameter('comment'));
if ($this->form->isValid()) {
$comment = new Comment();
$comment->setPostId($this->form->getValue('pid'));
$comment->setComment($this->form->getValue('comment'));
$comment->save();
$this->redirect('show/index?id='.$comment->getPostId());
}
}
}
and my Comment Form:
class CommentForm extends BaseForm {
public function configure() {
$this->setWidgets(array(
'comment' => new sfWidgetFormTextarea(),
'pid' => new sfWidgetFormInputHidden()
));
$this->widgetSchema->setNameFormat('comment[%s]');
$this->setValidators(array(
'comment' => new sfValidatorString(
array(
'required' => true,
'min_length' => 5
),
array(
'required' => 'The comment field is required.',
'min_length' => 'The message "%value%" is too short. It must be of %min_length% characters at least.'
)),
'pid' => new sfValidatorNumber(
array(
'required' => true,
'min' => 1,
'max' => 4294967295
),
array(
'required' => 'Some fields are missing.'
))
));
}
}
and finally, indexSuccess:
<?php echo $post; ?>
//show comments (skipped)
<h3>Add a comment</h3>
<form action="<?php echo url_for('show/addComment') ?>" method="POST">
<table>
<?php echo $form ?>
<tr>
<td colspan="2">
<input type="submit" />
</td>
</tr>
</table>
</form>
that's it.
If you're using sf 1.4 just put executeAddComments and executeIndex together in one function (executeIndex for example) and you'll be fine. setTemplate won't work here.
Are you using the handleError method in the action ? The id=1 part of your url should not change if inside the handleError method, you do a return sfView::SUCCESS;
UPDATE:
It actually changes, what you need to do is submit the id along with the comment [Which I'm sure you're already doing because a comment that doesn't refer to a post doesn't make much sense], then in your handleError method, instantiate the post object there.
Try to change your form action to
<?php echo url_for('show/addComment?id=' . $post->getId()) ?>
Doing this, your post id parameter should be available even on your post request, and it should work with setTemplate('index') or forward at the end of executeAddComment