Creating a Search Box without a Button in Laravel 9 - laravel-blade

I have a page with a several articles and I would like to be able to search the articles by title (words in their title not the whole title). I have created a form in a column side bar on the page. I do not want to be redirected to a new page but rather to have the search filter the articles already on the page. I have tried many different things from my internet research but nothing is working out and I think I am just not seeing something. I have only been working with Laravel for a month or two so it is entirely likely!
Form in the Blade:
<form action="{{ route('search') }}" method="get">
<div class="search-box">
<input type="submit" class="search" name="search" placeholder="Search..." value="">
</div>
</form>
Routes:
Route::get('/news', [ArticleController::class, 'grid'])
->name('news');
Route::get('/news/{article_id}', [ArticleController::class, 'article'])
->where('course', '[0-9]')->name('article');
Route::get('/news/search', [ArticleController::class, 'search'])
->name('search');
Controller:
public function search(Request $request)
{
$articles = Article::all();
$articles = $articles->where('title', 'LIKE', '%' . $request . '%')
->orderBy('created_at', 'desc')
->paginate(4);
return view('search', compact('articles'));
}
public function article($slug)
{
return view('pages/article', ['article' => Article::find($slug)]);
}
public function grid(Request $request)
{
$categories = Category::all();
$users = User::all();
$tags = Tag::all();
$all = Article::with('user')
->orderBy('created_at', 'desc')
->paginate(4);
$columns = Schema::getColumnListing('articles');
return view('pages/news', compact('categories', 'users', 'tags', 'all', 'columns'));
}

Related

Symfony2 InvalidArgumentException: The current node list is empty

I'm doing functional testing and I am getting the error
InvalidArgumentException: The current node list is empty
This is my code
public function testThis(){
$requestContent = [
'val1' => '324343',
'valname' => '"Benjamin"',
'valLast' => '"A"',
'valnum' => '44343',
'hndval1' => '0000',
'hdnval2' => '0000',
'hndval3' => '1111',
'hndref' => '"ThisIsAtest"',
'hdnMessage' => '"I am a message"'
];
$crawler = $this->client->request('GET', '/');
$submitButton = $crawler->selectButton('btnSubmit');
$form = $submitButton->form($requestContent);
print_r($form);
$this->client->followRedirects(true);
$crawler = $this->client->submit($form);
$response = $this->client->getResponse();
$request = $this->client->getRequest();
print_r($crawler->html());
$this->assertRegExp('/\/nextPage', $request->getUri());
print_r($request->getUri());
$a = $crawler->filter('input[name="pageName"]');
$this->assertContains(
"True",
$a->attr('value')
);
}
I think it is getting error in this :
$form = $submitButton->form($requestContent);
Note that $requestContent values are coming from a hidden input type which are all inside the form tag.
You have not posted your HTML so now i assumed your HTML such as :
<html>
<form method='GET' action='your action here'>
/*
* all other html here
*/
<input type='submit' value='Submit' id='btnSubmit' name='btnSubmit'>
</form>
</html>
$submitButton = $crawler->selectButton('btnSubmit');
to change
$submitButton = $crawler->selectButton('Submit');
Because selectButton() accept the button value instead of id or name.
Make sure this is a helpful to you.
You have to provide the text of the button to $crawler->selectButton().
// For a given HTML button:
// <input type="button" value="Upload File" />
// or
// <button type="button">Upload File</button>
$crawler->selectButton("Upload File");
Side note, your regex pattern '/\/nextPage' is invalid. You need to add a closing / --> '/\/nextPage/' // This will match the exact string: "/nextPage"

Render a choice field without form

I often need to render very simple imputs in some of my templates.
I'd like to take advantage of the twig macros & form blocks to render certain HTML inputs without involving the whole Symfony forms machinery.
For example from the controller:
$templateContext = array(
'my_input' = new FormField('my_input', 'choice', array(
'choices' => array('value1', 'value2', 'my_value'),
'value' => 'my_value',
));
);
In the template:
<div>{{ form_widget(my_input) }}</div>
would render:
<div>
<select name="my_input">
<option>value1</option>
<option>value2</option>
<option selected="selected">my_value</option>
</select>
</div>
Is there a simple way to do that ?
Eventually I would also like to be able to reuse these fields elsewhere (like we can reuse form types)
There are many ways to go about this. The easiest would be to write the plain HTML into your twig template.
<form method="post">
<div>
<select name="my_input">
<option>value1</option>
<option>value2</option>
<option selected="selected">my_value</option>
</select>
</div>
</form>
And then in your controller read the values back.
$request = $this->getRequest();
if($request->getMethod() == 'POST'){
$data = $request->get('my_input')
//Do whatever you want with $data
}
If you want you re-use the html, you can build it somewhere in your PHP and pass it into Twig whenever you need it; or you can place it in a separate twig template and read that with the {include ''} command in twig.
Here is what I finally ended up with:
Class MyInput {
public static values = array(
'value1',
'value2',
'my_value',
);
}
class MyInputType extends AbstractType
{
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'choices' => MyInput::$value,
));
}
public function getParent() { return 'choice'; }
public function getName() { return 'my_input_type'; }
}
Field type used from the controller (after having registered it as a service)
public function MyAction(Request $request)
{
$form = $this->createForm('my_input_type');
$form->handleRequest($request);
$templateContext['myForm'] = $form->createView();
// ...
}
Input rendered into the template
<div>{{ form(myForm) }}</div>
To conclude: I've not been able to render an input without the form machinery, but the actual form remains rather simple.
I found my own solution for it since i need to create subforms from existing forms.
create totally empty twig template,
add in it only {{form(form)}}
render this template render()->getContent()
do a preg replace on the result (i do it in js) formView = formView.replace(/<(.*?)form(.*?)>/, '');
Yes yes - i know that regex is not perfect so before someone says it - i say it on my own, change it for youself as it catches "form-group" classes etc as well.
This is just a showcase of my solution

Wordpress Email Form

Wordpress Email Form
Hi all
I've been using this sort of email form in a number of sites and it's always worked.
I've tried to use it in a Wordpress site but it won't
Is there any obvious reason why this approach won't work in a Wordpress site.
I need an email form that doesn't reload the contact page as the form is at the bottom.
html
<form action="#" id="contact_form">
<input type="text" id="name" placeholder="Name:">
<input type="text" id="email" placeholder="Email:">
<textarea id="message" rows="8" cols="40" placeholder="Message:"></textarea>
<input type="submit" id="submit"/>
<div id="status">
<p></p>
</div>
</form>
Jquery
$('#submit').click(function(){
//
var nameVal = $('#contact_form #name').val();
var emailVal = $('#contact_form #email').val();
var messageVal = $('#contact_form #message').val();
//
$.post('/contact_form.php', {name: nameVal, email: emailVal, message: messageVal}, function(data){
$("#status p").html(data);
$("#status p").show().fadeOut(3500);
if(data.indexOf('Thank You')==0) {document.forms[0].reset();}
});
})
php
$errors = array();
$required_fields = array('name','email','message');
foreach($required_fields as $fieldname){
if(!isset($_POST[$fieldname]) || empty($_POST[$fieldname])){
$errors[] = $fieldname;
}
}
if(empty($errors)){
$name_field = Trim(stripslashes($_POST['name']));
$name = explode(' ', $name_field);
$firstname = ucfirst($name[0]);
$email_field = Trim(stripslashes($_POST['email']));
$message = Trim(stripslashes($_POST['message']));
//
$to = "info#ttmt.org.uk";
$subject = "Email from Website";
$body = "From: $name_field\n E-Mail: $email_field\n Message:\n $message";
//
mail($to, $subject, $body);
echo "Thank You $firstname";
}else{
echo "Please complete all.";
}
--- UPDATE ---
I've got part of it working now.
Part of the problem was the jquery couldn't find the php.
I created a 'code' folder inside wp-conntent and put the php there and the jquery looks like this.
$j.post('wp-content/code/contactEngine.php', { theName:nameVal, theEmail:emailVal, theMessage:messageVal }, function(data){
Now I'm getting the returned data form the php file but the email isn't sent.
Will this not work in WP
mail($to, $subject, $body);
You cannot use $_POST['name'] within Wordpress. Using other namings for input fields will fix your issue, eventually you could use the 'Contact Form 7' Wordpress-plugin for a better user experience :-)

Handle two forms in one Controller with Symfony2

Hey I am saving every page in two different languages on my website. I want to manage my pages with an admin area that I am developing with symfony2 at the moment.
Following controller code is able to display two forms on the same page containing the right data from the database. One form to manage the DE language and another for EN:
View:
<form action="{{ path('admin_about') }}" method="post" {{ form_enctype(formEN) }}>
{{ form_widget(formEN) }}
<button type="submit" class="btn btn btn-warning" naem="EN">Save</button>
</form>
<form action="{{ path('admin_about') }}" method="post" {{ form_enctype(formDE) }}>
{{ form_widget(formDE) }}
<button type="submit" class="btn btn btn-warning" name="DE">Save</button>
</form>
Controller:
public function aboutAction(Request $request)
{
$pageEN = $this->getDoctrine()
->getRepository('MySitePublicBundle:Page')
->findOneBy(array('idName' => 'about', 'lang' => 'EN'));
$pageDE = $this->getDoctrine()
->getRepository('MySitePublicBundle:Page')
->findOneBy(array('idName' => 'about', 'lang' => 'DE'));
if (!$pageDE) {
throw $this->createNotFoundException('About page (DE) not found.');
}
if (!$pageEN) {
throw $this->createNotFoundException('About page (EN) not found.');
}
$formDE = $this->createFormBuilder($pageDE)
->add('title', 'text')
->add('content', 'text')
->getForm();
$formEN = $this->createFormBuilder($pageEN)
->add('title', 'text')
->add('content', 'text')
->getForm();
//Save Form here
return $this->render('MySitePublicBundle:Admin:about.html.twig', array(
'aboutPageDE' => $pageDE, 'aboutPageEN' => $pageEN, 'formDE' => $formDE->createView(), 'formEN' => $formEN->createView(),
));
}
My Question is: How to save the form that has been used out of one controller?
Based on the Forms and Doctrine section of the Symfony2 Docs (or in your case, since you're not using a Form class) --
So where you have //save form here assuming you've set up MySitePublicBundle:Page to save the Title and Content (and has the normal getters/setters).
if ($request->getMethod() == 'POST') {
$form->bindRequest($request);
// data is an array with "title" and "content" keys
$data = $form->getData();
// You'll need to have some switch depending on which language you're dealing
// with... (unless its both, then just repeat for $pageDE)
$pageEn->setTitle($data['title']);
$pageEn->setContent($data['content']);
$em = $this->getDoctrine()->getEntityManager();
$em->persist($pageEn);
$em->flush();
}
In your controller you could test if the request contains the forms, such as:
if($this->getRequest()->get('form1')) {
//
} elseif($this->getRequest()->get('form2')) {
//
}

Symfony2: entity field (html SELECT) set SELECTED item

I am using a form (filterForm) to filter entities on a twig view.
The 'filterForm' only has a field of 'entity' type. On the view it shows a HTML-SELECT-OPTIONs tag.
When the user changes the selection, the same controller is called doing the neccesary stuff to filter the entities-list.
All is working fine but I need to show the SELECT-field with the value that is filtering the list. And here is the problem, I don't know how to do it.
A bit of code of the field from the index.html.twig:
{{ form_widget(personalFilterForm.personaFiltrarMail,
{ 'empty_value': 'Todos',
'attr': {'selected': personaFiltrarMail,
'onChange': 'javascript:document.filtrado.submit()' }
}
)
}}
That code is generating this html code:
<select name="test_onebundle_type[personaFiltrarMail]" id="test_onebundle_type_personaFiltrarMail"
onchange="javascript:document.filtrado.submit()"
required="required" selected="two#mail.com">
<option value="">Todos</option>
<option value=one#mail.com">Name One</option>
<option value=two#mail.com">Name Two</option>
<option value=three#mail.com">Name three</option>
The real problem here (I think) is knowing how can I get access to the OPTIONS sub-element to set de SELECTED attribute on a concrete OPTION item.
Thanks.
=== Controller ===
Here the 'Controller'...
All four numbered 'echoes' gives me the mail: 'two#mail.com' But the SELECT html TAG is always located on the first one OPTION tag.
class HorasController extends Controller
{
/**
* Lists all Horas entities.
*
* #Route("/", name="horas")
* #Template()
*/
public function indexAction()
{
$em = $this->getDoctrine()->getEntityManager();
$personas = $em->getRepository('PtGhorgaBundle:Personal')->findAll();
$personalFilterForm = $this->createForm(new PersonalFilterType(), $personas);
$request = $this->getRequest();
$formVars = $request->request->get('pt_ghorgabundle_type');
$personaFiltrarMail = $formVars['personaFiltrarMail'];
//echo "1.- [".$personaFiltrarMail."]<br />";
if (!isset($personaFiltrarMail) || $personaFiltrarMail=="") {
$entities = $em->getRepository('PtGhorgaBundle:Horas')->findAll();
} else {
$criterio = array('persona' => $personaFiltrarMail,);
$entities = $em->getRepository('PtGhorgaBundle:Horas')->findBy($criterio);
$criterio = array('mail' => $personaFiltrarMail,);
$personaFiltrarMail = $em->getRepository('PtGhorgaBundle:Personal')->find($criterio)->getMail();
echo "2.- [".$personaFiltrarMail."]<br />";
$personalFilterForm->personaFiltrarMail = $personaFiltrarMail;
echo "3.- [".$personaFiltrarMail."]<br />";
echo "4.- [".$personalFilterForm->personaFiltrarMail."]<br />";
}
return array('entities' => $entities,
'personas' => $personas,
'personalFilterForm' => $personalFilterForm->createView(),
'personaFiltrarMail' => $personaFiltrarMail,
);
}
In your data you can set the property personaFiltrarMail to the according value.
For example in your controller :
$object = new Object();
$object->personaFiltrarMail = 'two#mail.com';
$form = $this->createFormBuilder($object);
Then render your template.
I have found it:
just belown
echo "4....." line
$data = array('personaFiltrarMail'=> $personaFiltrarMail);
$personalFilterForm->setData($data);
Regards.

Resources