I am trying to submit a form using post method, but it does not seem to be working. I have enabled error debug on but still no error is shown. After submitting the form the same page is loaded without any errors.
This is my route
Route::post('/home' , ['as' => 'store-post' , 'uses'=>'FacebookControllers\PostsController#save']);
And my form is
{!! Form::open(['route'=>'store-post' , 'class'=>'form'])!!}
<div class="form-group">
<label for="textarea"></label>
<textarea class="form-control" rows="5" name="textarea">What's on your mind?</textarea>
</div>
<div class="form-group col-sm-12">
<input type="submit" value="Post" class="btn btn-primary pull-right">
</div
{!! Form::close() !!}
This is my Controller
class PostsController extends Controller
{
public function save(PostsRequests $request){
$input = $request->all();
$post = new Post();
$post->user_id = Auth::user()->id;
$post->content =$input;
$post->user()->associate(1);
$post->save();
/*return redirect('home');*/
return ('something');
}
}
After hours of searching and trying, finally, I found the solution. I was using my own request class and path was not correct so I corrected the path of PostsRequests and now it works.
Related
I am working on a project for class where I have to edit starter Code. I keep getting a KeyError code and I am not sure what the issue is.
line 250, in create_venue_submission
name = request.get_json()['name']
KeyError: 'name'
Code Below from new_venue.html
I added id="name", city, etc.. for all the divs . I'm not sure if that is the correct way to do it but thats the only way i figured to pull all the data from the form.
{% extends 'layouts/main.html' %}
{% block title %}New Venue{% endblock %}
{% block content %}
<div class="form-wrapper">
<form id="venueInfo" method="post" class="form">
<h3 class="form-heading">List a new venue <i class="fa fa-home pull-right"></i></h3>
<div id='name' class="form-group">
<label for="name">Name</label>
{{ form.name(class_ = 'form-control', autofocus = true) }}
</div>
<div class="form-group">
<label>City & State</label>
<div class="form-inline">
<div id='city' class="form-group">
{{ form.city(class_ = 'form-control', placeholder='City', autofocus = true) }}
</div>
<div id='state' class="form-group">
{{ form.state(class_ = 'form-control', placeholder='State', autofocus = true) }}
</div>
</div>
</div>
<div id='address' class="form-group">
<label for="address">Address</label>
{{ form.address(class_ = 'form-control', autofocus = true) }}
</div>
<div id='phone_num' class="form-group">
<label for="phone">Phone</label>
{{ form.phone(class_ = 'form-control', placeholder='xxx-xxx-xxxx', autofocus = true) }}
</div>
<div id="genres" class="form-group">
<label for="genres">Genres</label>
<small>Ctrl+Click to select multiple</small>
{{ form.genres(class_ = 'form-control', autofocus = true) }}
</div>
<div id="fb_link" class="form-group">
<label for="genres">Facebook Link</label>
{{ form.facebook_link(class_ = 'form-control', placeholder='http://', autofocus = true) }}
</div>
<input type="submit" value="Create Venue" class="btn btn-primary btn-lg btn-block">
</form>
<script type="text/javascript">
document.getElementById("venueInfo").onsubmit=function(e){
e.preventDefault();
fetch('/venues/create',{
method:'POST',
body:JSON.stringify({
'name': document.getElementById('name').value,
'city': document.getElementById('city').value,
'state': document.getElementById('state').value,
'address': document.getElementById('address').value,
'phone_num': document.getElementById('phone_num').value,
'genres': document.getElementById('genres').value,
'fb_link': document.getElementById('fb_link').value,
}),
headers: {'Content-type': 'application/json'}
})
.then(function(){
})
}
</script>
</div>
{% endblock %}
Code below is from app.py
#app.route('/venues/create', methods=['GET'])
def create_venue_form():
form = VenueForm()
return render_template('forms/new_venue.html', form=form)
#app.route('/venues/create', methods=['POST'])
def create_venue_submission():
name = request.get_json()['name']
print(name)
flash('Venue ' + request.form['name'] + ' was successfully listed!')
return render_template('pages/home.html')
Looks like you're using Flask-WTF to make those form fields, then using a JS function to grab the values from these with getElementById.
The problem is you don't set an id on the form fields. To get a better visualization of this, have a look at the rendered HTML, rather than the template code itself.
So instead of:
{{ form.name(class_ = 'form-control', autofocus = true) }}
You're looking for someting like:
{{ form.name(id='name', class_ = 'form-control', autofocus = true) }}
Then verify that renders to something like:
<input autofocus class="form-control" id="name" name="name" type="text" value="">
Note this now has an id attribute, which should allow your JS function to grab the value.
You'll need to appy this same concept to the other form fields.
I added id="name", city, etc.. for all the divs . I'm not sure if that is the correct way to do it but thats the only way i figured to pull all the data from the form.
Doing this for the divs is no use... document.getElementById('name').value takes the value of an input field, so that's what you'd have to add the id attribute to, as above.
EDIT regarding comment
In your create_venue_submission route, the request.get_json method receives the values submitted by the javascript Fetch request. On the other hand, request.form contains the values if the form is submitted without Javascript.
With the Javascript method: e.preventDefault() prevents that traditional form submission when the button is clicked, and instead submits the Fetch request, with the header {'Content-type': 'application/json'}.
Either by removing that script tag, or running in a browser with javascript disabled it will fall back to the traditional submission method.
So you should probably do some logic in your flask route to test this condition. You can also use request.is_json boolean for this. Remember to do from flask import jsonify. Something like:
if request.is_json:
# Request came in via javascript based on the header provided.
name = request.get_json()['name']
# Add data to database or something
return jsonify({'message':f'{name} was sucessfully listed.'})
else:
# handle traditional form submission
name = request.form['name']
# Add data to database or something
flash('Venue ' + request.form['name'] + ' was successfully listed!')
return render_template('pages/home.html')
Of course you'll then need to handle the returned JSON in your frontend. So insead of:
.then(function(){
})
Something like:
.then(response => response.json())
.then(data => {
console.log(data);
});
Now with the browser's dev tools Console open you should see something like this when submitted:
Object { message: "Burning Man Festival was sucessfully listed." }
Of course you could then swap that console.log line out with anything to manipulate the dom, and access for example data['message'] to get the success string itself.
In my ASP.NET Core 3.1 web application, I have created a very basic Ajax form that makes use of the Unobtrusive Ajax library. When the form us submitted a check is carried out to find if a record with the same name currently exists and if it does, return any records that match that name as a Json Result along with the outcome of the request.
<form asp-controller="Test" asp-action="Create" id="CreateForm"
data-ajax="true"
data-ajax-method="POST">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="md-form form-group">
<label asp-for="Name"></label>
<input type="text" asp-for="Name" />
</div>
<div class="md-form form-group">
<button type="submit" value="Save" class="btn btn-info">Save</button>
</div>
</form>
Here is the controller that handles this form when it's submitted.
[HttpPost]
public IActionResult Create(Test model)
{
if (ModelState.IsValid)
{
bool safetyCheck = _testService.GetTests().Any(x => x.Name == model.Name);
if (safetyCheck == true)
{
var something = _testService.GetTests()
.Where(x => x.Name == model.Name /*&& x.Active == model.Active*/)
.Select(x => new { x.Id, x.Name })
.ToList();
return Json(new { success = false, error = something });
}
else {
//Add Record
_testService.InsertTest(model);
return Json(new { success = true });
}
}
else {
return View();
}
}
As you can see, the model is passed in, the model state is checked for validity and then a check is carried out to find out if the name passed in from the model matches any currently existing record. If the check is true then I create an object that can be sent back to the view via JSON along with the success = false.
If the name doesn't exist then the record is simply created.
What I want to know is, once this JSON data is returned, how do I then use it in my view, for example. If I return a list of all the records with the same name as I do above, how would I show the user this information along with a message?
In short, you'd need to write a custom JS function to process the return data. To hook it up to the AJAX request completion you can specify it in data-ajax-complete attribute value on your form.
It will look approximately like this:
<form asp-controller="Test" asp-action="Create" id="CreateForm"
data-ajax="true"
data-ajax-method="POST"
data-ajax-complete="ajax_handler">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="md-form form-group">
<label asp-for="Name"></label>
<input type="text" asp-for="Name" />
</div>
<div class="md-form form-group">
<button type="submit" value="Save" class="btn btn-info">Save</button>
</div>
</form>
#section Scripts
{
...
<script>
ajax_handler = function (xhr) {
var data = xhr.responseJSON;
// Process returned data here
};
</script>
}
I am having trouble updating a row on my Laravel project. The form receives all the necessary information perfectly, but once I hit the update button, the information parsed from the form is returned as null
My edit (form) file
#extends('layout')
#section('content')
<h1 class = "title">Edit Item</h1>
<form method="post" action="/listings/{{$listing->id}}">
#method('patch')
#csrf
<div>
<label class="label" for="name">Name of Item</label>
<div class="control">
<input required type="text" class="input" name="description" placeholder="Name of Item" value="{{$listing->title}}" >
</div>
</div>
<div>
{!! Form::select('lstatus',$lstatus,null) !!}
</div>
<div class="field">
<div class="control">
<button type="submit" class="button is-link">Update</button>
</div>
</div>
</form>
My controller:
public function edit(listing $listing, lstatus $lstatus)
{
$listing = $listing::find($listing->id);
$lstatus = lstatus::pluck('name','id');
return view('listings.edit', compact('listing','lstatus'));
}
public function update(listing $listing, lstatus $lstatus){
$listing = listing::find($listing->id);
$listing->listing_status_id = request('lstatus');
$listing->title=\request('description');
return back();
}
When I hit the submit button on the form, nothing happens. Nothing changes in the database and I get no error.
The expected result would be for the values to update.
In this case you could use the update() method passing all the inputs from the request with the all() method as a parameter, this will save all the attributes you send it in your request automatically:
$listing = $listing::find($listing->id);
$listing->update($listing->all());
all method:
You may also retrieve all of the input data as an array using the all method:
update method:
The update method expects an array of column and value pairs representing the columns that should be updated.
If you don't use the update() method, you should use the save() method after you make any change:
$listing->listing_status_id = request('lstatus');
$listing->title=\request('description');
$listing->save();
i have weird situation in which data is displayed in json format instead of html !!
At route http://127.0.0.1:8000/addpost form to add post is displayed and the recently added post.
Its show the form to add post and when submit is clicked it returns data in json format insteaad of displaying the form and the post added.
1)why it is returning json data ?
2)how do i display data in html format ?
thats me route
web.php
Route::get('addpost','PostController#index');
Route::post('addpost','PostController#store');
Controller ->
PostController.php
class PostController extends Controller
{
public function index()
{
$posts = Post::latest()->first();
return view('addpost',compact('posts'));
}
public function store(Request $request)
{
$post =new Post();
$post->title= $request->input('title');
$post->body= $request->input('body');
if($request->hasfile('postimage'))
{
$file=$request->file('postimage');
$extention=$file->getClientOriginalExtension();
$filename=time().'.'.$extention;
$file->move('uploads/post',$filename);
$post->postimage=$filename;
}
else{
return $request;
$post->postimage='';
}
$post->save();
return back()->with('success', 'Your images has been successfully Upload');
}
}
and the view
<div class="container">
<div class="jumbotron">
#if(Auth::user())
<h3> Add new post with images</h3>
<form action="{{url('addpost')}}" method="POST" enctype="multipart/form-data">
{{csrf_field()}}
<div class="form-group">
<label>Title</label>
<input type="text" name="title" class="form-control" >
</div>
<div class="form-group">
<label>Body</label>
<input type="text" name="body" class="form-control" >
</div>
<div class="input-group">
<div class="custom-file">
<input type="file" name="image" class="custom-file-input">
<label class="custom-file-label">Choose file</label>
</div>
</div>
<button type="submit" name="submit" class="btn-brn-primary"> Save Post</button>
#if($posts)
#foreach($posts as $post)
<tr>
<td>{{$post->id}}</td>
<td>{{$post->title}}</td>
<td>{{$post->body}}</td>
<!-- <td><img src="{{asset('uploads/post/'.$post->image)}}" style="height: 150px;"></td>
<td>EDIT</td> -->
</tr>
#endforeach
#endif
#else
<h1>no</h1>
#endif
</form>
</div>
</div>
if($request->hasfile('postimage')) // -> you are checking for postimage, in your html
// markup the file filed is called "image",
// therefore you will never enter this if block
{
$file=$request->file('postimage');
$extention=$file->getClientOriginalExtension();
$filename=time().'.'.$extention;
$file->move('uploads/post',$filename);
$post->postimage=$filename;
}
else{
return $request; // here you are returning the $request object that
// causes your unformatted response
$post->postimage='';
}
I tried e.g
<form id='blah' action='myActionController' method='post'>
//fields here
<input type='submit' name='submit' value='button name' />
</form>
after clicking the button, it does land to the www.mydomain.com/site/myActionController
but then, the page content is
Bad Request (#400)
Unable to verify your data submission.
The above error occurred while the Web server was processing your request.
Please contact us if you think this is a server error. Thank you.
I just don't want to use the active form...
so how to do the form in a plain html version without using the built-in yii
active form?
You need to add CSRF data for your submission to be verified.
Easiest way is to use static method \yii\web\Html::beginForm() that will do that for you (and take care of generating proper form tag).
The code to generate your form will be something like:
<?= \yii\web\Html::beginForm('myActionController') ?>
<input type='submit' name='submit' value='button name'>
<?= \yii\web\Html::endForm() ?>
You can of course switch CSRF verification off but this is not recommended. Without this verification your plain form will work.
In yii2 if you want a link for myActionController you should use this notation
(assuming that you have a controller named site and an action named myActionController)
<form id='blah' action='my-action-controller' method='post'>
//fields here
could be you need proper url and for this could be useful the UrlHelper
this way
use yii\helpers\Url;
.....
echo "<form id='blah' action='" . Url::to(['/site/my-action-controller']) .
"' method='post'>";
The best way is to clone existing ContactForm model which is already using sendEmail function and add your own properties, rules and attributeLables. On sendEmail function, you can include all necessary fields that you want to receive in ->setTextBody as a string and using concatenation as below:
public function sendEmail($email)
{
return Yii::$app->mailer->compose()
->setTo($email)
->setFrom([$this->email => $this->name])
->setSubject($this->subject)
->setTextBody($this->name. ' ' .'has requested'. 'space here'. $this->customfield. ' etc.')
->send();
}
After customizing the contactForm model, you can copy the actionContact on site controller and add it to your Form controller as actionIndex or anything, also copy Captcha and error on public function actions()
Now we will create a plain html form in yii2 as follows:
In my example i am using registerForm as my model(take note on how i use that model on id and name fields for yii2 to send the form without problems)
<?php $form = ActiveForm::begin(); ?>
<div class="col-md-12">
<input type="text" id="registerform-name" placeholder="Institution's Name*" name="RegisterForm[name]" required>
</div>
<div class="col-md-12">
<select id="registerform-institution" name="RegisterForm[institution]">
<option value="" disabled selected hidden>Select Institution's Type*</option>
<option value="Secondary School">Secondary School</option>
<option value="High School">High School</option>
<option value="College">College</option>
<option value="University">University</option>
</select>
</div>
<div class="col-md-12">
<input type="tel" id="registerform-number" placeholder="Institution's Phone Number*" name="RegisterForm[number]" required>
</div>
<div class="col-md-12">
<input type="text" id="registerform-pname" placeholder="Principal's Name*" name="RegisterForm[pname]" required>
</div>
<div class="col-md-12">
<input type="email" id="registerform-email" class="form-control" name="RegisterForm[email]" placeholder="Principal's eMail Address*" name="email" required>
</div>
<div class="col-md-12">
<?= $form->field($model, 'verifyCode')->widget(Captcha::className(), ['captchaAction' => '/register/default/captcha', 'template' => '<div class="row"><div class="col-lg-4">{image}</div><div class="col-lg-8">{input}</div></div>',
]) ?>
</div>
<div class="form-group">
<?= Html::submitButton('Register', ['class' => 'theme-btn theme-btn4']) ?>
</div>
Back to my model: i had the following Properties and my form is sending well with proper validation, etc:
<?php
namespace register\models;
use Yii;
use yii\base\Model;
class RegisterForm extends Model
{
public $name;
public $institution;
public $number;
public $pname;
public $email;
public $verifyCode;