Laravel 5.4 how to exclude empty field in url when GET form? - forms

I built form with GET method but when i submit form empty field also pass to url, can i exclude empty field from passing to url ?
For example > when i submit my form url changed to :
?jobTitle=Title&jobCompany=CompanyName&jobGovernorate=&jobLocation=&postingDate=ad
Here in this example jobGovernorate and jobLocation is empty so i want form skip those when i submit the form.
If there's a way to get url like this
?jobTitle=Title&jobCompany=CompanyName&postingDate=ad
Because jobGovernorate and jobLocation is empty
Sorry for poor english, Thank you.

You can use middleware for your problem
class StripEmptyParams
{
public function handle($request, Closure $next)
{
$query = request()->query();
$querycount = count($query);
foreach ($query as $key => $value) {
if ($value == '') {
unset($query[$key]);
}
}
if ($querycount > count($query)) {
$path = url()->current() . (!empty($query) ? '/?' . http_build_query($query) : '');
return redirect()->to($path);
}
return $next($request);
}
}
then call for specific route like code below
Route::get('/search','YourController#search')->middleware(StripEmptyParams::class);

Assuming you have a form as below
<form>
<input type="text" class="url_params" name="jobTitle" value="">
<input type="text" class="url_params" name="jobCompany" value="">
<input type="text" class="url_params" name="jobGovernorate" value="">
<input type="text" class="url_params" name="jobLocation" value="">
<input type="text" class="url_params" name="postingDate" value="">
<input type="submit" name="submit" id="submit">
</form>
<script type="text/javascript">
$(document).ready(function () {
$("#submit").on("click", function(e) {
e.preventDefault();
var url = '{{ url('/') }}?';
var total = $(".url_params").length;
$(".url_params").each(function (index) {
if ($(this).val().trim().length) {
if (index === total - 1) {
url += $(this).attr('name') + '=' + $(this).val();
} else {
url += $(this).attr('name') + '=' + $(this).val() + "&";
}
}
});
window.location.href = url;
});
});
</script>
The above code will generate an URL based on the field value and redirect to the url. So it won't generate a url with the empty field value key.
And having an empty field value shouldn't make a difference as you could check for the url values in the controller using $request->input('key')
Hope this helps!

Go through array like this, you will just check if your array has empty, will not add the key.
$data = array('foo'=>'bar',
'baz'=>'boom',
'cow'=>'milk',
'php'=>'hypertext processor');
echo http_build_query($data) . "\n";
//echo http_build_query($data, '', '&'); // only for use &amp instead & if needed

I have applied the next middleware on a Laravel 8.x project to solve a related problem. This may be helpful to other ones...
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class StripEmptyParamsFromQueryString
{
/**
* Remove parameters with empty value from a query string.
*
* #param \Illuminate\Http\Request $request
* #param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* #return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
*/
public function handle(Request $request, Closure $next)
{
// Get the current query and the number of query parameters.
$query = request()->query();
$queryCount = count($query);
// Strip empty query parameters.
foreach ($query as $param => $value) {
if (! isset($value) || $value == '') {
unset($query[$param]);
}
}
// If there were empty query parameters, redirect to a new url with the
// non empty query parameters. Otherwise keep going with the current
// request.
if ($queryCount > count($query)) {
return redirect()->route($request->route()->getName(), $query);
}
return $next($request);
}
}
Note the middleware should only be applied to specific routes, not to all request. In my particular case I have a resource controller and to apply the middleware only to the index route I have used the next approach inside the resource controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Middleware\StripEmptyParamsFromQueryString;
class MyController extends Controller
{
/**
* Instantiate a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware(StripEmptyParamsFromQueryString::class)
->only('index');
}
...
}

Related

codeigniter, form validation false verse first time visit

In Codeigniter, the following code is typically used for a page that has a form. But the first time a user lands on the page and a form validation fails gets routed through the same path.
As this example shows, the flash data will trigger. even if the user just land on the page and have not submit any form yet.
I am trying to echo a new class name to some input field to highlight them if validation fails. but currently it highlights the field on first load as well.
I am aware I can echo a validation_error or form_error. is there a way to echo a generic message that is not tied to a field-name and only after submission fails
// rules and other stuff above
if ($this->form_validation->run() == FALSE){
$this->session->set_flashdata('errorClass',"is-invalid");
$this->load->view('defaultOrFalse');
}else{
$this->load->view('success');
}
//view file
<input class=" <?php $this->session->flashdata('errorClass') ; ?>">
Basically I am trying to get bootstrap 4's input validation to show up
https://getbootstrap.com/docs/4.0/components/forms/#server-side
I don't know your exact setup but you can do logic like the following:
<?php
class Some_controller extends CI_Controller {
// controller/search/{$term}
public function some_method($term = null) {
// where some_field is some field in your form
// that gets posted on submit
if ($this->input->post('some_field')) {
// or if (isset($_POST)) {
if ($this->form_validation->run() == FALSE) {
$this->session->set_flashdata('errorClass', "is-invalid");
$this->load->view('defaultOrFalse');
} else {
$this->load->view('success');
}
} else {
// default view
}
}
}
?>
For your second question:
<h5>Username</h5>
<?php echo form_error('username'); ?>
<input type="text" name="username" value="<?php echo set_value('username'); ?>" size="50" <?php if (!empty(form_error('username'))) { echo "class='error'"; } ?> />
Can also make a helper and use instead of form_error to check if field has error for your class (haven't verified this works but it should).
/**
* Checks if form validation field by name
* has error
*
* #param string $field Name of field
* #return boolean
*/
function field_has_error($field) {
$CI = &get_instance();
$CI->load->library('form_validation');
$arr = $CI->form_validation->error_array();
if (isset($arr[$field])) {
return true;
}
return false;
}
Usage:
<?php if (field_has_error('username')) { echo "class='error'"; } ?> />

How to use checkboxes with Phalcon forms?

I am creating a form using Phalcon that has a checkbox on it. I use this code to create the checkbox in my PagesForm.php file
$this->add(new Check('usesLayout'));
and then in my view I have
{{ form.render("usesLayout") }}
However, if the checkbox is unchecked then Phalcon complains about usesLayout is required.
The html code produced by the view is
<input type="checkbox" id="usesLayout" name="usesLayout" value="1" checked="checked" />
What is the correct way to create a Phalcon form with a checkbox so that it accepts it both checked and unchecked?
Desired outcome
After looking back at a form made when using CakePHP the html output is
<input type="hidden" name="usesLayout" id="usesLayout_" value="0" />
<input type="checkbox" name="usesLayout" id="usesLayout" value="1" checked="checked" />
This works fine, so I am looking for something similar to this.
Current Workaround
After modifying the code in the final response to this question I have this workaround currently (I use this instead of Phalcon\Forms\Element\Check)
namespace Armaware\InBrowserDev\Forms\Element;
use Phalcon\Forms\Element\Check as PhalconCheck;
class Check extends PhalconCheck
{
/**
* Renders the element widget returning html
*
* #param array|null $attributes Element attributes
*
* #return string
*/
public function render($attributes = null)
{
$attrs = array();
if (!is_null($attributes)) {
foreach ($attributes as $attrName => $attrVal) {
if (is_numeric($attrName) || in_array($attrName, array('id', 'name', 'placeholder'))) {
continue;
}
$attrs[] = $attrName .'="'. $attrVal .'"';
}
}
$attrs = ' '. implode(' ', $attrs);
$id = $this->getAttribute('id', $this->getName());
$name = $this->getName();
$checked = '';
if ($this->getValue()) {
$checked = ' checked';
}
return <<<HTML
<input type="hidden" id="{$id}_" name="{$name}" value="0" />
<input type="checkbox" id="{$id}" name="{$name}" value="1"{$attrs}{$checked} />
HTML;
}
}
public Phalcon\Forms\ElementInterface setDefault (unknown $value) inherited from Phalcon\Forms\Element
Sets a default value in case the form does not use an entity or there is no value available for the element in _POST
Source.
Looks like your declaration of form can look like this:
$controls[] = (new Check('usesLayout', ['value' => '1']))
->setLabel('Should I use layout?')
->setDefault('0') // or `false` in case it's not filtered
->addFilter('bool'); // filtering to boolean value
Not tested, but probably will do. You can always try to make this trick with handling this in beforeValidation() method of form, but have no space to test it right now and am not risking on failurable solution here.

Keep select value on change with laravel

I am having a paginated backend table with db-data. The admin person can filter that table for data status. This happens via ajax. Everything works fine but I do not get the selected filter value to remain selected when I click on the second pagination link.
E.g. I choose select option: '1' => 'Active' so that only db-rows show up that have a status of 1. But when I then click on the second pagination link to see the next 20 rows then again it also displays the inactive db-rows. How would I get the selected option to remain selected in this situation? I tried Input::old('status') and passing $selected to view as below but no success. Thank you for any hint!
View:
<form id="filter_form" onsubmit="" action="<?php echo URL::action('countries#anyIndex'); ?>">
<?php echo Form::select('filter_status', funcs::get_status_options(), $selected, array('id' => 'filter_status')); ?>
</form>
Ajax:
$(function(){
$("#filter_status").on('change', function(){
frm = $("#filter_form");
frm.serialize();
status = $('#filter_status').val();
$.ajax({
type: "POST",
url: $(frm).attr('action'),
data: {status: status},
success: function(data){
$("#list").html(data.list);
},
dataType: "json"
});
});
});
Controller:
class countries extends BaseController {
public $filter = array(0,1,2);
function anyIndex()
{
$data['title'] = "Countries list";
if(Input::has('status')){
$status = Input::get('status');
if($status != 2){
$this->filter = array($status);
}
}
$d['items'] = $this->_getItems(20);
if(Request::ajax()){
$data['list'] = View::make('admin/countries/countries_list', $d)->withInput($status)->render();
return Response::json($data);
}
$data['selected'] = $this->filter;
$data['list'] = View::make('admin/countries/countries_list', $d);
return View::make('admin/admin_layout')->nest('view', 'admin/countries/countries_view', $data);
}
private function _getItems($paginate)
{
$items = Country::whereIn('status', $this->filter)->paginate($paginate);
return $items;
}
}

Joomla 2.5 - component development - using form

I am trying to add some form to my component, but I am not shure what naming conventions must be applied to work it correctly.
Currently I have a working form - it displays fields stored in XML file and loads data from database to it. However, when i try to submit this form (edit or add new records), it doesn't work. After pressing submit (save() method) it just redirects me and displays that record was edited successfuly but it wasn't. When I try to edit existing record, after pressing submit nothing happens and when I try to add new record, it just adds empty/blank record.
So I was doing a little debug and discovered, that problem is in the JController::checkEditId() method. It always returns false which means that JControllerForm::save() returns false as well and that's why it doesn't save it correctly. HTML code of form is correct and I can access the data by using global array $_POST.
I suspect that this problem is because of naming conventions in methods loadFormData, getForm of JModelAdmin class. I am not sure how to name that form.
So here is my code related to this problem:
Subcontroller for displaying the form - controllers/slideshowform.php
class SlideshowModelSlideshowForm extends JModelAdmin{
public function getForm($data = array(), $loadData = true){
return $this->loadForm('com_slideshow.slideshowform', 'editform', array('load_data' => $loadData, 'control' => 'jform'));
}
protected function loadFormData(){
$data = JFactory::getApplication()->getUserState('com_slideshow.edit.slideshowform.data', array());
if (empty($data))
{
$data = $this->getItem();
}
return $data;
}
public function getTable($table = "biometricslideshow"){
return parent::getTable($table);
}
}
views/slideshowform/view.html.php
class SlideshowViewSlideshowForm extends JView{
public function display($tmpl = null){
if (count($errors = $this->get('Errors')))
{
JError::raiseError(500, implode('<br />', $errors));
return false;
}
$this->form = $this->get('form');
$this->item = $this->get('item');
JToolBarHelper::save('slideshowform.save');
parent::display();
}
}
views/slideshowform/tmpl/default.php
<?php
defined('_JEXEC') or die('Restricted access');
JHtml::_('behavior.tooltip');
?>
<form method="post" action="<?php echo JRoute::_("index.php?option=com_slideshow&id=".(int) $this->item->id)?>" name="adminForm" id="slideshow-form">
<fieldset class="adminform">
<legend>Edit slide</legend>
<table>
<input type="hidden" name="task" value="">
<?php echo JHtml::_('form.token'); ?>
<?php
foreach($this->form->getFieldset() as $field){
?>
<tr><td><?php echo $field->label ?></td><td><?php echo $field->input ?></td></tr>
<?php
}
?>
</table>
</fieldset>
</form>
Can someone take o look, please?
you have to add controller SlideshowControllerSlideshowForm and code save method. In there you have to validate the form data and call SlideshowModelSlideshowForm->save event, then redirect with success/failure message.

Codeigniter: getting select option from form

I'm trying to get the option item selected in a form select element using Codeigniter...
I have a controller named results with this code in it
//get form data
if($_SERVER['REQUEST_METHOD'] == "POST"){
$data['searchdata'] = array(
"ionum" => $this->input->post('ionum'),
"thisdb" => $this->input->post('thisdb')
);
}
which loads into a view, the 'ionum' is a text input which I can retrieve, the 'thisdb' is the select, I get no results for it...how do I pull that?
Ensure your html looks like:
<form action="<?= site_url('mycontroller/myfunction');?>" method='post'>
<input type='text' name='ionum'/>
<select name='thisdb'>
<option value='db1'>DB1</option>
<option value='db2'>DB2</option>
</select>
</form>
Then in your controller, you would write:
class Mycontroller extends CI_Controller{
function myfunction(){
$p = $this->input->post();
if($p){
//you can now access the ionum and thisdb... try echo
echo $p['ionum'];
echo $p['thisdb'];
}
}
}
It is unnecessary to run the if($_SERVER['REQUEST_METHOD'] == "POST") conditional. Just check if $p exists as above.