I have a problem.
I'm using a Form Request but also Vue on my form. My problem is that old('') variables does not work together with Vue v-model.
Here is an example of the input field.
<div class="form-group">
<label for="name">{{ trans('messages.name') }}</label>
<input type="text" name="name" v-model="name" id="name" value="{{ old('name') }}" class="form-control">
#if($errors->has('name'))
<span class="help">
{{trans('Validations.name')}}
</span>
#endif
</div>
If I remove the v-model="name" the {{ old('name') }} variable works.
This is the error i get from Vue in the browser.
<input v-model="name" value="asdasdasd">:
inline value attributes will be ignored when using v-model. Declare initial values in the component's data option instead.
vue file
<script>
import RangeSlider from './RangeSlider.vue';
export default {
components: {
RangeSlider,
},
props: ['fields'],
data() {
return {
name: '',
email: '',
phone: '',
loading: false,
errors: {},
};
},
methods: {
onSubmit() {
this.loading = true;
}
}
};
</script>
Vue does not allow you to initialise model data from the HTML, because Vue expects you to retrieve data from an API and set it from the Vue instance, which can be a pain when using it in conjunction with blade. The simplest way around this is to create a directive to make the init yourself:
Vue.directive('init', {
bind: function(el, binding, vnode) {
vnode.context[binding.arg] = binding.value;
}
})
Then use as:
<input type="text" name="name" v-model="name" id="name" v-init:name="'{{old('name')}}'" class="form-control">
Here's the JSFiddle: https://jsfiddle.net/0uvqmodc/
You should try this with the help of v-bind, which dynamically bind one or more attributes.
<input type="text" name="name" v-model="name" id="name" v-bind:value="old('name')" class="form-control">
However if you want to set an initial value to the input field, you can just set the data variable name as the value (old('name')) you want to set.
HTML
<input type="text" name="name" v-model="name" id="name" class="form-control">
JS
data() {
return {
name: 'oldValue',
email: '',
phone: '',
loading: false,
errors: {},
};
},
Related
<form method="POST" action="{{ route('storeCompany') }}">
#csrf
<label>{{ __('Website URL') }}</label>
<input type="text" name="url" value="{{ old('url') }}" placeholder="{{ __('http://example.com') }}" class="form-control" required="required">
<label>{{ __('Website Title') }}</label>
<input type="text" name="name" value="{{ old('name') }}" placeholder="{{ __('Example Ltd') }}" class="form-control" required="required">
<input type="submit" name="sbNewReviewItem" class="btn btn-block btn-primary" value="{{ __('Submit New Company') }}">
</form>
I want the "Website Title" field to be auto-filled when the user types the "Website URL" also "Website Title" must be editable if the user want to. How can I do this? Please help :(
Example: When the user enters https://stackoverflow.com/ URL in the "Website URL" field "Website Title" filed must auto-filled as Stack Overflow - Where Developers Learn, Share, & Build Careers
You have a change event on the url-field element which does a fetch request to an api website that returns the html contents of that website, and then it uses regex to extract the html title and then it adds it to the name field.
Also while the fetching is executing we show a Fetching text to let the user know what's going on. And the form submit event has been stopped with the preventDefault() function. Here you can do what ever you want after the user submits the form.
Instead of using https://api.codetabs.com/v1/proxy/?quest= which will limit your requests and show you a Too many requests error, you should use your own code that fetches the website contents and then return the response. To optimize this you can return just the website title, to save on bandwidth and cpu cycles.
The reason you need an api to fetch the website content is because of CORS. You can't just use fetch resources from any website you want. You can only do this from the current website or from websites that have allowed you to do so.
document.addEventListener('submit', event => {
event.preventDefault()
})
document.addEventListener('change', async (event) => {
if (event.target.classList.contains('url-field')) {
await changeUrl(event.target.closest('form').elements)
}
})
async function changeUrl (fields) {
try {
if (!fields.url.value) return
fields.output.removeAttribute('hidden')
const response = await fetch('https://api.codetabs.com/v1/proxy/?quest=' + encodeURI(fields.url.value))
const html = await response.text()
const match = /<title[\s\S]*?>([\s\S]*?)<\/title>/gi.exec(html)
if (!match || !match[1]) throw new Error('No title found')
fields.name.value = match[1].trim()
fields.output.setAttribute('hidden', '')
} catch (error) {
console.error(error)
}
}
<form method="POST" action="">
<p>
<label>Website URL</label>
<input type="url" name="url" value="" placeholder="http://example.com" class="form-control url-field" required>
<output name="output" hidden>Fetching</output>
</p>
<p>
<label>Website Title</label>
<input type="text" name="name" value="" placeholder="Example Ltd" class="form-control">
</p>
<input type="submit" name="sbNewReviewItem" class="btn btn-block btn-primary" value="Submit New Company">
</form>
Because you're example look like Laravel.
I found it appropriate to write an answer in PHP.
example.blade.php
<title>{{ $title ?? 'Default title' }}</title>
<form method="POST" action="{{ route('storeCompany') }}">
#csrf
<label>{{ __('Website URL') }}</label>
<input type="text" name="url" value="{{ $url ?? old('url') }}" placeholder="{{ __('http://example.com') }}" class="form-control" required="required">
<label>{{ __('Website Title') }} <small>(Leave blank to retrieve from URL)</small></label>
<input type="text" name="name" value="{{ $title ?? old('name') }}" placeholder="{{ __('Example Ltd') }}" class="form-control">
<input type="submit" name="sbNewReviewItem" class="btn btn-block btn-primary" value="{{ __('Submit New Company') }}">
</form>
CompanyController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
class CompanyController extends Controller
{
public function index(){
return view('example');
}
public function storeCompany(Request $request){
$title = $request->name;
if (empty($title) && filter_var($request->url, FILTER_VALIDATE_URL)){
$response = HTTP::get($request->url);
if ($response->ok()){
preg_match('/<title>(.*)<\/title>/i', $response->body(), $matches);
$title = $matches[1] ?? null;
}
}
$data = [
'url' => $request->url,
'title' => $title
];
return view('example', $data);
}
}
As soon as user has entered the data.
Get the value using $("#text_field").val();
Have an ajax call and get the value using the below function, pass the url to t
require 'simple_html_dom.php';
function dataParser($url){
$html = new simple_html_dom();
$html->load_file($url);
$title = $html->find('title',0)->innertext;
return $title;
}
// something like $_GET['user_url'];
echo $title = dataParser('https://stackoverflow.com');
this code will output the title, set it to the div where you want to show the title, something like this
var ajaxCallResponse = ""//store the response here
$("#title_div").val(ajaxCallResponse);
Here is how to:
Read the website url.
Send an ajax request to codetabs api to get full html.
Get the title from the html.
Do whatever you need with the title.
function gettitle(website) {
if(website.trim() == ''){
return false;
}
var url = 'https://api.codetabs.com/v1/proxy/?quest=' + website;
$.ajax({
url: url,
success: function(responseHtml) {
var newTitle = $(responseHtml).filter('title').text();
document.getElementById('title').innerHTML = 'Title: ' + newTitle
},
error: function() {
document.getElementById('title').innerHTML = newTitle = 'Sorry that page doesn\'t';
}
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input placeholder='Website' oninput='gettitle(this.value)' type='url' id='url'>
<div id='title'></div>
I am using a html form to get user data using laravel php. On form submit I am executing an api which in Web.php is defined as
Route::post('/register_user', 'UserRegistrationController#registerUser');
which executes,
public function registerUser(Request $request){
$apiResult = $this->executeApi($request->input('mobile_no'));
if($apiResult === "Success"){
return view('further_view');
}else{
toastr()->error('Registration Failed. Please check mobile number.');
return back();
}
}
html code
<div class="form-group{{ $errors->has('mobile_no') ? ' has-error' : '' }}">
<label for="mobile_no">Mobile No</label>
<input type="text" name="mobile_no" class="form-control" id="mobile_no" value="{{ old('mobile_no') }}" placeholder="Enter Mobile No" required>
<small class="text-danger">{{ $errors->first('mobile_no') }}</small>
</div>
My issue here is , whenever my $apiResult === "Success" condition goes false, i get toast message on screen but my page get refreshed and all the data user has typed gets cleared from the input box.
Hence my question is how can I show the toast messages without form being cleared or how would I prevent the input box getting cleared on such conditions.
I am using this Toast library
https://github.com/yoeunes/toastr
I would suggest that you use a session to store the data. For example:
session()->put('forms.mobile_no', $request->get('mobile_no'));
Your HTML:
<input value="{{ $mobile_no }}" type="text" name="mobile_no" class="form-control" id="mobile_no" placeholder="Enter Mobile No" required>
Try to return the error message back with this after the toastr call:
return redirect->back()->withInput();
I'm validating laravel forms and old input does not preserve after validation fail.
I'm using laravel 5.8 form request validation and html input fields are filled with default values :
public function store(ProyectoRequest $request){
$input = $request->validated();
DB::transaction(function () use($input) {
$proyecto = new Proyecto();
$proyecto->fill($input);
$proyecto->save();
});
return redirect(route('proyectos.index'));
}
<div class="form-group">
<label for="nombre">Nombre</label>
<input type="text" class="form-control input-lg" value="{{$proyecto_nombre}}" name="nombre">
</div>
When the form is validated the page reloads with the default values. I expect that input fields values are preserved. That is what I have understood from the documentation.
I am looking for the docs and there is not written if this is the normal behaviour or not.
Anyway you can do yourself with this code:
<div class="form-group">
<label for="nombre">Nombre</label>
<input type="text" class="form-control input-lg" value="{{ old('proyecto_nombre', $proyecto_nombre) }}" name="nombre">
</div>
In laravel the old function retrieves input fields.
I am having a registration form that uses vue inside Laravel blade file. I'm using a validator for invalid inputs of user and I want to get the old value of the field but now I can't make it work since some of the fields are using vue. Here's my code:
regist.blade.php
<div class="regist_input">
<input type="email" name="email" v-model="email" v-bind:placeholder="placeholder_email" v-bind:class="{ error: emailError }">
<p class="error_text" v-bind:class="{ active: emailError2 }">Invalid email.</p>
#if($errors->has('email'))
<p class="alert-error">
{{ $errors->first('email') }}
</p>
#endif
</div>
<dd>
<div class="regist_input">
<input class="input_company" type="text" name="company" value="{{ old('company') }}" placeholder="company"> //this one works
</div>
</dd>
controller
if($validator->fails()) {
return redirect()->back()->withInput()->withErrors($validator->errors());
}
I can display its old value if out side the field, which means that my php function that validates is working.
I tried using v-bind:value="{{ old('email') }}" or :value="{{ old('email') }}" but is not working.For this one, how can I display the old value in the input field that has a vue component?
You could pass the blade email data to vue using data attributes.
First should add an id to an HTML element with data attribute on it. Then use blade to parse your data and set the data attribute to email data.
<div id="email-data" data-email="{{ old('email') }}"></div>
TO BE EXACT (OP)
<input type="email" value="{{ old('email') }}" name="email" v-model="email" id="email-data" data-email="{{ old('email') }}" v-bind:placeholder="placeholder_email"
v-bind:class="{ error: emailError }">
Then in the created / mounted hook in vue extract the data and set to the email state.
created() {
const el = document.getElementById('email-data')
const email = el.dataset.email
this.email = email
}
v-bind:value="{{ old('email') }}" or :value="{{ old('email') }} don't work because you are using v-model="email"
When you use v-model, it means that there should be an "email" property in the "data" attribute of a Vue component, and any value set to that "email" property will be what is displayed as the value of the input field.
See this Pen I created to illustrate both scenarios.
So, you'll need to remove the v-model if you want to use the v-bind:value. And now that I'm writing this, I don't think you need the v-bind:value and can just simply use value (just as you're doing with the company input.
I just started learning Laravel and would like to make a dummy Account Manager. My first goal is to be able to add accounts to the mysql db via an html form/Eloquent model/controller/migration. Coming from JavaScript, I'm not really sure how to pass the data from the name or value attr to the correct method and on to the migration. Here's my code from the form:
<form method="POST" action="/addAccount">
{{ csrf_field() }}
<input class="inputs" type="text" name="fname" placeholder="First Name">
<input class="inputs" type="text" name="lname" placeholder="Last Name">
<input class="inputs" type="email" name="email" placeholder="Email">
<h3>Account Types and ID's:</h3>
<ul class="list">
<li>Confirmation: 1</li>
<li>Setup: 2</li>
<li>Activated: 3</li>
<li>Deactivated: 4</li>
</ul>
<input class="inputs" type="number" name="ati" placeholder="Enter Account Type ID">
<input class="inputs" type="checkbox" name="active"><p>Click to Activate!</p>
<button class="button">Submit</button>
</form>
web.php: Route::post('addAccount', 'AccountsController#store');
Code for AccountsController:
public function store(Request $request)
{
$accounts = new Account;
$accounts->first_name = $fname;
$accounts->last_name = $lname;
$accounts->email = $email;
$accounts->account_type_id = $ati;
$accounts->active = $active;
$accounts->save();
return redirect('/');
}
Currently getting an ErrorException of "Undefined variable: fname". Any hints would be greatly appreciated!
You just need to use
$request->fname
instead of
$fname
In your form, please add :
{{ csrf_field() }}
Laravel checks if a form has a token to protect the application from CSRF attack. See link for more details. CSRF Protection
Also, add a name attr in your input types like so:
<input class="inputs" type="text" name="fname" placeholder="First Name">
In your web.php :
Route::post('addAccount', 'controllerName#controllerFunction');
In your controller:
function controllerFunction(Request $request){
//$request contains all sent data.
$fname= $request->input('fname'); #you can use this way
$fname = $request->fname; #or this one
....
//code for storing in DB using Eloquent
$users= new Users;
$users->first_name = $fname;
....
$users->save();
}
Please check the document for using Laravel Eloquent