I'd like to have simple "Search" input field in base.html.twig. Normally I would need to write code to maintain form in every route. To solve this problem I decided to create separate controller with route to render it directly in base.html.twig template:
<div class="top-middle col-12 col-md-6 d-flex order-2 order-md-1">
{{ render(controller("App\\Controller\\SearchController::searchProduct"))}}
</div>
It works find except nothing happens when the form is submitted. I tried it in normal way in one of my routes and it was working fine. So don't know where the problem is.
My SearchController with route which is rendered in twig :
class SearchController extends AbstractController
{
#[Route('search-product', name: 'search_product')]
public function searchProduct(Request $request)
{
$searchForm = $this->createForm(SearchProductType::class);
$searchForm->handleRequest($request);
if ($searchForm->isSubmitted() && $searchForm->isValid()) {
dump('Form submitted');
}
return $this->render('components/search-input.html.twig', [
'searchForm' => $searchForm->createView()
]);
}
}
Search input.html.twig component:
<div class="top-search">
<i class="bi-search top-search__icon"></i>
{{ form(searchForm) }}
</div>
and the main controller which renders index.html.twig with base.html.twig:
#[Route('/', name: 'home')]
public function index(FileHandler $fileHandler, SessionInterface $session, Request $request): Response
{
$products = $this->doctrine->getRepository(Product::class)->getProducts('Dresses', 4);
$products = $this->addPathToImages($products, 'Dresses');
return $this->render('shop/index.html.twig', [
'products' => $products
]);
}
The line
dump('Form submitted');
is not executed when the form is submitted. Page refreshes but nothing happens.
I think the whole logic should stay in this route/controller or I am missing something?
As requested I publish my solution:
Instead of embedding controller directly in Twig file and decided to handle my little form (just Search input, submitted by pressing "enter") with js. The reason for this is that it's impossible to redirect from embedded controller.
Code in twig:
<form id="top-search-form">
<div class="top-search">
<input id="search-string"
class="top-search__input" type="search"
placeholder="Search shop">
</div>
</form>
and code written in Javascript (requires FOSJSRouting Bundle):
const routes = require('/public/js/fos_js_routes.json');
import Routing from '/vendor/friendsofsymfony/jsrouting-bundle/Resources/public/js/router.min.js';
Routing.setRoutingData(routes);
document.addEventListener('DOMContentLoaded', function() {
const searchForm = document.getElementById('top-search-form');
searchForm.addEventListener('submit', function(e) {
e.preventDefault();
const searchString = document.getElementById('search-string').value;
var url = Routing.generate('items_filter', {
'searchText': searchString
});
location.href = url;
});
})
I am writing a prestashop 1.7 module and I am returning a view in the getContent() method like this:
public function getContent()
{
return $this->display(__FILE__, 'views/templates/admin/product_crawler.tpl');
}
My product_crawler.tpl file looks like this:
<form method="POST" action="{$this->context->link->getAdminLink('ProductCrawlerGet')}">
<input type="text" name="url">
<input type="submit">
</form>
And in modules/product_crawler/controllers/admin I have a getproducts.php file which looks like this:
<?php
/**
*
*/
class ProductCrawlerGetController extends ModuleAdminControllerCore
{
public function postProcess()
{
if (Tools::isSubmit('url'))
{
// form processing
return 'success';
}
}
}
?>
When I remove the getAdminLink() it shows the form just right, but when I add action to the controller it shows a white page
What am I doing wrong
You must use {$link->getAdminLink('ProductCrawlerGet')} instead.
Another alternative is to assign the link in the php, inside the getContent
$this->smarty->assign(array(
'this_link' => $this->context->link->getAdminLink('ProductCrawlerGet'),
));
Then use {$this_link} in the tpl
I am working on a project which deals with lots of forms. I searched and tried the search results, but none of them worked.
My code view code "uprofile.php" is as follows:
<form class="form-horizontal" method="post" action='<?php echo base_url() . "home/addnewagency" ?>'>
<div class="form-group">
<label for="company" class="col-sm-3 control-label">New Agency Name:</label>
<div class="col-sm-4">
<input type="text" class="form-control" id="newagency" name="newagency" placeholder="Plase Enter New Agency Name">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-9">
<button type="submit" class="btn btn-primary">Add</button>
</div>
</div>
</form>
My Controller "home.php" code is as follows:
public function addnewagency() {
$newagency = $this->input->post('newagency');
$this->dis_model->newagency_model(strtoupper($newagency));
$this->loadprofile();
}
public function loadprofile() {
$data['inscompanyname'] = $this->dis_model->getcompany();
$data['agentname'] = $this->dis_model->getagent();
$data['agencyname'] = $this->dis_model->getagency();
$data['clientname'] = $this->dis_model->getclient();
$data['deptname'] = $this->dis_model->getdept();
$this->load->view('uprofile', $data);
}
when I submit the form, the control is passed to addnewagency() data gets inserted in the database and the URL is http://localhost/dis/home/addnewagency. After getting back to the calling function, it goes to loadprofile() and loads the view uprofile. But, the URL still remains the same. But, I want it as http://localhost/dis/home/login and also want to pass the data. Does anyone have any idea regarding how to achieve this?
All positive suggestion are welcomed...
Thanks in advance...
Now you are calling $this->loadprofile() within addnewagency(). If you want to change URL, you need to use redirect() function of CodeIgniter.
Replace
$this->loadprofile()
with below line of code and it will work for you.
redirect(base_url() . 'home/loadprofile');
if you want to change the url use redirect(base_url() . 'home/loadprofile'); in your controller addnewagency(); as suggested by others and refer this question to know whether you can send data in redirect function or not,
Sending data along with a redirect in CodeIgniter
I found a alternative option to get this done.
You can't change URL string with $this->load->view function but you can redirect to target controller function using redirect method. Before you call redirect, set flash session data using $this->session->set_flashdata that will only be available for the next request, and is then automatically cleared. You can read it from official codeiginter documentation .
Example :
class Login extends CI_Controller {
public function index()
{
if ($this->session->login_temp_data) {
$data = $this->session->login_temp_data;
} else {
$data = array();
$data['name'] = 'Guest' ;
}
$this->load->view('login', $data);
}
public function get_name()
{
$data = [];
$data['name'] = 'John Doe';
$this->session->set_flashdata('login_temp_data', $data);
redirect("login");
}
}
You want to use the redirect() function
At the bottom of your addnewagency() method like so:
public function addnewagency() {
$newagency = $this->input->post('newagency');
$this->dis_model->newagency_model(strtoupper($newagency));
redirect(base_url() . 'home/loadprofile');
}
I have a problem with codeigniter:
I have in my view
<input type="text" name="code" style="width:310px;">
My controller
$code = $this->input->get('code');
and after i call a function from my models:
$this->model->add($code);
The problem is codeigniter don't take value in controller(i make a test with $this->model->add('342432'); and it's works. So i think the problem is between view and controller.
Has anybody a solution? Thanks!.
It depends upon form submit method.
From your code: $code = $this->input->get('code'); it is get.
If you want form with post method, use
$code = $this->input->post('code');
If you are using get method in Codeignitor make your
$config['allow_get_array'] = TRUE;
In your config.php file
$config['allow_get_array'] is FALSE(default is TRUE), destroys the global GET array.
In View
<form action="<?php echo base_url()?>/conteroller/method" method="post">
<input type="text" name="code" style="width:310px;">
<input type="submit" name="submit" >
</form>
In conteroller
if(isset($_POST['submit']))
{
$code = $_POST['code'];
$result = $this->model_name->add($code);
print_r($result);//to check the output
}
Note :
to use base_url() function, in config/autoload.php
$autoload['helper'] = array('url');
In conteroller load model in __construct
public function __construct()
{
parent::__construct();
$this->load->library('session');
$this->load->model('Model_name');//Ex: Product_Model
}
i'm stuck at this very basic form, that i could not accomplish, which i want to build a search form with an text input, and two select controls, with a route that accept 3 parameters, the problem that when the i submit the form, it map the parameters with the question mark, not the Laravel way,
Markup
{{ Form::open(['route' => 'search', 'method' => 'GET'])}}
<input type="text" name="term"/>
<select name="category" id="">
<option value="auto">Auto</option>
<option value="moto">Moto</option>
</select>
{{ Form::submit('Send') }}
{{ Form::close() }}
Route
Route::get('/search/{category}/{term}', ['as' => 'search', 'uses' => 'SearchController#search']);
When i submit the form it redirect me to
search/%7Bcategory%7D/%7Bterm%7D?term=asdasd&category=auto
How can i pass these paramters to my route with the Laravel way, and without Javascript ! :D
The simplest way is just to accept the incoming request, and pull out the variables you want in the Controller:
Route::get('search', ['as' => 'search', 'uses' => 'SearchController#search']);
and then in SearchController#search:
class SearchController extends BaseController {
public function search()
{
$category = Input::get('category', 'default category');
$term = Input::get('term', false);
// do things with them...
}
}
Usefully, you can set defaults in Input::get() in case nothing is passed to your Controller's action.
As joe_archer says, it's not necessary to put these terms into the URL, and it might be better as a POST (in which case you should update your call to Form::open() and also your search route in routes.php - Input::get() remains the same)
I was struggling with this too and finally got it to work.
routes.php
Route::get('people', 'PeopleController#index');
Route::get('people/{lastName}', 'PeopleController#show');
Route::get('people/{lastName}/{firstName}', 'PeopleController#show');
Route::post('people', 'PeopleController#processForm');
PeopleController.php
namespace App\Http\Controllers ;
use DB ;
use Illuminate\Http\Request ;
use App\Http\Requests ;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Redirect;
public function processForm() {
$lastName = Input::get('lastName') ;
$firstName = Input::get('firstName') ;
return Redirect::to('people/'.$lastName.'/'.$firstName) ;
}
public function show($lastName,$firstName) {
$qry = 'SELECT * FROM tableFoo WHERE LastName LIKE "'.$lastName.'" AND GivenNames LIKE "'.$firstName.'%" ' ;
$ppl = DB::select($qry);
return view('people.show', ['ppl' => $ppl] ) ;
}
people/show.blade.php
<form method="post" action="/people">
<input type="text" name="firstName" placeholder="First name">
<input type="text" name="lastName" placeholder="Last name">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="submit" value="Search">
</form>
Notes:
I needed to pass two input fields into the URI.
I'm not using Eloquent yet, if you are, adjust the database logic accordingly.
And I'm not done securing the user entered data, so chill.
Pay attention to the "_token" hidden form field and all the "use" includes, they are needed.
PS: Here's another syntax that seems to work, and does not need the
use Illuminate\Support\Facades\Input;
.
public function processForm(Request $request) {
$lastName = addslashes($request->lastName) ;
$firstName = addslashes($request->firstName) ;
//add more logic to validate and secure user entered data before turning it loose in a query
return Redirect::to('people/'.$lastName.'/'.$firstName) ;
}
I had same problem. I need show url for a search engine
I use two routes like this
Route::get('buscar/{nom}', 'FrontController#buscarPrd');
Route::post('buscar', function(){
$bsqd = Input::get('nom');
return Redirect::action('FrontController#buscarPrd', array('nom'=>$bsqd));
});
First one used to show url like we want
Second one used by form and redirect to first one
So you're trying to get the search term and category into the URL?
I would advise against this as you'll have to deal with multi-word search terms etc, and could end up with all manner of unpleasantness with disallowed characters.
I would suggest POSTing the data, sanitising it and then returning a results page.
Laravel routing is not designed to accept GET requests from forms, it is designed to use URL segments as get parameters, and built around that idea.
An alternative to msturdy's solution is using the request helper method available to you.
This works in exactly the same way, without the need to import the Input namespace use Illuminate\Support\Facades\Input at the top of your controller.
For example:
class SearchController extends BaseController {
public function search()
{
$category = request('category', 'default');
$term = request('term'); // no default defined
...
}
}
Router
Route::get('search/{id}', ['as' => 'search', 'uses' => 'SearchController#search']);
Controller
class SearchController extends BaseController {
public function search(Request $request){
$id= $request->id ; // or any params
...
}
}
Alternatively, if you want to specify expected parameters in action signature, but pass them as arbitrary GET arguments. Use filters, for example:
Create a route without parameters:
$Route::get('/history', ['uses'=>'ExampleController#history']);
Specify action with two parameters and attach the filter:
class ExampleController extends BaseController
{
public function __construct($browser)
{
$this->beforeFilter('filterDates', array(
'only' => array('history')
));
}
public function history($fromDate, $toDate)
{
/* ... */
}
}
Filter that translates GET into action's arguments :
Route::filter('filterDates', function($route, Request $request) {
$notSpecified = '_';
$fromDate = $request->get('fromDate', $notSpecified);
$toDate = $request->get('toDate', $notSpecified);
$route->setParameter('fromDate', $fromDate);
$route->setParameter('toDate', $toDate);
});