How to do nice GET URLs in Laravel - php

If I have a form:
<form method="get" action="<?=action( "SomethingController#DoSomething" ) )?>">
<select name="SomethingID">
<?php foreach( $somethings as $something ) : ?>
<option value="<?=$something->id?>"><?=$something->title?></option>
<?php endforeach; ?>
</select>
</form>
How do I do a route for this so that my DoSomething function gets an id given to it rather than generating an ugly as hell URL like www.example.com/project/3/something?SomethingID=7
Route::get( "project/3/something/{SomethingID}", "SomethingController#DoSomething", function( $somethingID ) {
return App::make( "SomethingController" )->DoSomething( $somethingID );
} );
I want the URL to be www.example.com/project/3/something/7
The problem is it can't be a post... because then people can never just simply go to that URL... they'd always have to post to it.
Do I need to make the dropdown box change the anchor href of a button with javascript that then generates the correct url from that?
Can't seem to find anything in here:
http://laravel.com/docs/4.2/routing

I feel like you're doing everything right... I am a little confused on what you're trying to do though, and subsequently doing "wrong" (since everything seems right), so apologies in advance for the shot in the dark. Instead of the select, can you use simple a tags?
#foreach($somethings AS $something)
{{ $something->title }}
#endforeach
That way, clicking the link takes them to www.example.com/project/3/something/7 -> or whatever ID is generated by the link. As for routing, you could do:
Route::get("project/3/something/{SomethingID}", "SomethingController#getSomething");
Route::post("project/3/something/{SomethingID}", "SomethingController#postSomething");
And your controller:
public function getSomething($somethingID){
// Handle returning the view and whatever else you need
}
public function postSomething($somethingID){
// Handle the post function (i.e. do stuff.)
}
Those are a couple things to try when routing dependent on variable ID's, but if there's something else you're trying to accomplish, leave a comment and I'll look into that as well.
Cheers!

Related

Yii2, Form and field names

Simple question but no solution yet. As we know
<?php $form = ActiveForm::begin(['method'=>'get']); ?>
<?= $form->field($formFilter, 'keyword')
->textInput(['placeholder' => \Yii::t('', 'keyword')]); ?>
...
will create simple form and input fields. Of course we will load $_POST data in action like
if ($this->isPost() && $formFilter->load($this->post())) {
if ($formFilter->validate()) {
...
If we will look in $_POST we will see something like FormFilter[keyword] as name of field. So question is, how can I change it? I need (i think) somehow change in in form\model not in view, because we need proper loading in action.
Where it will be used? Any GET form will show ugly url with class names, for example using simple action and models we will get FormFilter[keyword] but I want change it to keyword, so url will be more understandable than 'long field names'.
Anyone know how to deal with this?
Sorry, later I found solution, I think it will help not just me...
Simple one is to redefine formName() method in our form/model. Using formName() we can even change it what ever we need or disable at all if will set such one
public function formName()
{
return '';
}
So, if forName() returns empty string we will get url :
http://site/items?keyword=&locationID=&employmentType=&educationLevel=&salaryMin=
Default one will be:
http://site/items?FormVacanciesFilter[keyword]=&FormVacanciesFilter[locationID]=6&FormVacanciesFilter[employmentType]=&FormVacanciesFilter[educationLevel]=&FormVacanciesFilter[salaryMin]=
You can change it per field in the view, e.g. I have a form based on yii\base\DynamicModel where I need to control the field names, and, for example:
echo $form->field($model, 'test')->hiddenInput(['name' => 'test'])->label(false);
will output:
<div class="form-group field-dynamicmodel-test">
<input type="hidden" id="dynamicmodel-test" class="form-control" name="test" value="{value of $model->test}">
<p class="help-block help-block-error"></p>
</div>

joomla - How to show search query in link on addressbar

My question is:
How can I make my search/filter/ordering fields can be shown in the link after the search button is clicked. I have my model-controller-view-layout files. In model file requred fields are set as state variable in populateState function and are retrieved by the buildWhereQuery function to make it useable in querystring. Everything is going correct up to this point. But from now my problem arrises as what if a user want to send the listing link to his/her frind to show same listing. I need to set the link for this porpose but I don't know how to do this.
I just wrote a function for this in view file as following but I couldn^t figure out how can I use this created link to work. (the variable query is $query = $this->get('state'); in the format of JObject.
protected function preQuery($query){
$params = array();
foreach ($query as $key => $value) {
if(!isset($query->$key) || empty($value) || $value == ''){
unset($query->$key);
}else{
if(strpos($key,'filter') || in_array($key, array('limit','limitstart','order','order_Dir'))){
$params[$key] = $value;
}else{
unset($query->$key);
}
}
}
$que = JURI::buildQuery($params);
$cur = JURI::current();
return (strpos($cur,'?') ? ($cur.'&'. $que) : ($cur.'?'.$que));
}
EDIT:
Layout file contains the form which contains the all inputs some for redirection like view task layout component as joomla requred. Some for filterineg or searching. So I couldn't use the GET method for form :/
The search is starting from a form. Now you have two cases.
If you are invoking your view directly from the form, simply change the form method to GET (instead of the default POST) so your form will look like
<form method="GET" ....
If you however are invoking a controller, and in turn the controller redirects to the form, you might need to change some logic. In this latter case, it doesn't matter if you use POST or GET invoking the controller; but the controller must not set the user state variables, instead add the parameters to the URL you are redirecting to
setRedirect(JRoute::_("index.php?option=com_something&view=results&param1=SOMETHING etc.
A final alternative after your comment: to only include some fields in the URL, assuming you are pointing directly to the view:
<form method="POST" action="<?php echo JRoute::_("index.php?option=com_yourcomponent&view=yourview&explicit_param_1=something&explicit_param_2=somethingelse
<input type="hidden" ...
but this poses more problems as the page should be able to function both with and without the extra params, which won't be present if the user shares the url. You might be better off handling this in a (sub)controller without a redirect (just instantiate the view and its display method in the controller function being invoked).
Remember you can have the syntax task=subcontroller.task to shorten your url.

Php and forms problem

This is my super-simplified index.php:
<?php
require_once 'DeleteOrAdd.php'; // handles adding/deleting a db record
doAddDeleteRecord();
// other functions are called here, left out though for brevity
?>
Here's DeleteOrAdd.php (much simplified)
<?php
function doAddDeleteRecord()
{
echo <<<_END
<form action="index.php" method="post">
// the other form html not shown here
<input type="submit" value="ADD RECORD" />
</form>
_END;
// NOT SHOWN -- code to handle the form when it is POST'd
}
?>
So it's late 10:30pm, I'm new to PHP, okay /excuses.
Can't figure out how to do this.
I want to change my form action="index.php" above to form action="DeleteOrAdd.php"
(ie. I want to re-post to the same file that this form is in,
not to index.php, so the code is cleaner).
but it won't work because I have all the form-handling logic for the POST --
inside the doAddDeleteRecord() function, so if I set my form action="DeleteOrAdd.php"
it won't work.
Is it possible to do something like form action="DeleteOrAdd.php:doAddDeleteRecord()?
I don't want to put this in classes.
I also want to keep my index.php just as it is above -- calling functions and no major
inline code beyond that.
Any ideas?
Originally, all the code was inline inside index.php (got it from a PHP book's sample)
and I then divided the code into logically-named PHP files in the Netbeans project
to clean it up, and to put stuff in functions that get called from index.php.
remove the action value completly from the form, default it will post always back to the url on which it is displayed.
<form action="" method="POST">
Your application is not well structured. I would recommend to follow MVC pattern.
But for your current problem you can do something like this
just set the action to your <form action="DeleteOrAdd.php" or you can leave the action completely blank which post your data on the same file in which the form is created.
When the form is posted your could do below in your DeleteOrAdd.php file.
if (isset($_POST['submit']))
{
doAddDeleteRecord();// this will call your
}
but in this case you may have to change the code of your index.php
I think the problem you have here is being able to make your PHP page discern between whether or not its a fresh load or whether or not its submission of the form, and that is why your incorporating the index page in your action parameter. However, this is not necessary.
Set the id and name (for valid markup) attribute of your submit element to a unique name. Such as "form_submit" so here is an example.
<form action="" method="post">
<input type="submit" id="form_submit" name="form_submit" value="ADD RECORD" />
</form>
So what you put in your PHP script (doAddorDelete.php) is this ...
if (array_key_exists('form_submit', $_POST)) {
//this is the code to execute on form submit
//use print_r($_POST) to view variables you can use here
//make sure you validate all data passed here especially if using a database
//ie if MySQL
//$validated_userinput = mysql_real_escape_string(strip_tags(htmlentities(trim($_POST['userinput']))), $link_resource); for text
//(int) $_POST['userinput']; for numbers
} else {
echo <<<_END
<form action="" method="post">
// the other form html not shown here
<input type="submit" id="form_submit" name="form_submit" value="ADD RECORD" />
</form>
_END;
}
Hope this helps! :)
Foreword: Since you say this as a learning exercise, I'll skip past the sanctimonious manifesto on best practice and the many and sundry virtues of OOP. ;) Your book probably details every dire warning / stern lecture I'd normally prepend to a solution like this anyway.
Is it possible to do something like
form
action="DeleteOrAdd.php:doAddDeleteRecord()
?
In short, yes. The easiest way to accomplish your goal is to just reference your file in your form action, as you've done:
<!-- form.php -->
<form action="DeleteOrAdd.php" method="POST">
And then in DeleteOrAdd.php, trigger your function by testing the $_POST data your form submit will send in, like so:
<?php
// DeleteOrAdd.php
if(isset($_POST['some_form_variable']) && $_POST['some_form_variable'] != null) {
$data = array();
foreach($_POST as $post) {
array_push($data, $post);
}
doAddDeleteRecord($data);
}
function doAddDeleteRecord($data) {
// ...your processing code, etc.
The upshot to a purely procedural approach like you've specified is quite frankly, you can do stuff like this. You wouldn't want to develop like this in real life (skipping this deep-dive too, I guarantee your book explains why not in exhaustive detail.)
Important note!! Since I didn't see a return value in the code snippet you posted, and you say you're just getting started, I'm going to take a minute and point out a hidden pitfall here just in case:
--> Your code might work perfectly with those six lines I added above your function, and you'd never know it if you're not
returning a value (which proves the code ran, if nothing else) and
capturing said value so you can act on it / display it / otherwise show yourself that
a. something happened -- and ideally,
b. what that something was.
Otherwise, all you've got is ambiguity: no indication it's either working or breaking (not throwing errors, warnings, etc). Frustrating to debug, to say the least.
So, that stated -- presuming you've got your function returning something (true on success, string with a message, whatever) it probably goes something like this:
function doAddDeleteRecord($data) {
// ... your function code, etc.
$sql = "INSERT INTO mytable VALUES(".implode(',',$data).")";
if (mysql_query($sql) == true) {
$message = "Record saved";
} else {
$message = false;
}
return $message;
}
Any value your function returns needs a variable to capture it or it won't be set. Capture it with a variable assignment when you call your doAddDeleteRecord() function:
... // same 6 little lines of conditional code ...
}
$result = doAddDeleteRecord($data);
}
// maybe just echo it out or something...
echo $result;
-- or --
... // still the same 6 lines ...
}
$result = doAddDeleteRecord($data);
}
// maybe have a new test based on the outcome of the last one...
if ($result == false) {
// do something about the fail...
} elseif (is_string($result)) {
// do something about the success...
}
Good luck, HTH. :)

What is the best way to get jQuery/Ajax to work with CodeIgniter in this example?

I have a problem trying to get CodeIgniter and jQuery to produce ajax functionality. I have been coding all day, learning jQuery, and generally getting my butt kicked. Let me break down the situation, and hopefully, someone will have the courage to help me.
I have a trouble ticket system that displays many tickets on a page... each ticket is nested inside of a multitude of divs like so:
<div class="eachticketwrapper" id="ticket-362">
<div class="actionlog">
<form action="<?= base_url();?>admin/updateticket/362" method="post" id="362" name="362">
<ul class="displayinline">
<p>Action Log:
<span class="actionlog-362">
<?php echo $actionlog; ?>
</span>
</p>
</div> <!--actionlog-->
<p>
<textarea name="actionlogbox362" cols="100" rows="2" id="actionlogbox362" style="" ></textarea>
</p>
<div class="finalbuttons">
<?php echo form_open('admin/updateticket/'.'362'); ?>
<li><?php
$attrib = "class='updatebutton-362' id='updatebutton-362'";
echo form_submit("RapidTask",'Update',$attrib); //setup the button, and set permissions. ?></li>
<?php echo form_close(); // close the form. ?>
</div> <!--finalbuttons-->
</div> <!--eachticketwrapper-->
When run, the $actionlog should resemble something like the following:
worker - 2009-06-25 18:15:23 - Received and Acknowledges Ticket.
worker - 2009-06-25 18:15:23 - Changed Status to In Progress
worker - 2009-06-25 18:15:46 - Changed Priority to High
worker - 2009-06-25 18:15:46 - Changed Category to Network Connection Problem
worker - 2009-06-25 18:17:16 - did something
And then there is a textarea and an update button following it.
Here is the contents of my supplementary jQuery file:
$(document).ready(function() {
$('.updatebutton-362').click(function()
{
var id = $(this).attr("id").split("-"); // Split the id value at the hyphen, and grab the ticketnum.
$('.actionlog-'+id[1]).load('http://localhost/ci/index.php/ajaxtestc/'); // do something...
return false; // return false so default click behavior is not followed.
});
});
the ajaxtestc controller looks like this:
function index()
{
$data['actionlog'] = $this->m_tickets->actionLogPull(362);
$this->load->vars($data);
$this->load->view('content/ajaxtestform');
}
And the m_tickets model looks like this:
function actionLogPull($requestedNum=NULL)
{
$this->db->where('ticketnum', $requestedNum); // Grab only the status for the ticket requested $requestednum=NULL
$requestedTicket = $this->db->get('tickets'); // set the initial ticket info to a variable
$returnvalue = $requestedTicket->row('actionlog');
return $returnvalue;
}
Now... here is what I WANT. I want to click the update button, have it take whatever the worker has typed into the text area, add it to the end of the existing log in the database, and refresh the action log on the screen.
I can't come up with a clear way to do this. Can anyone shed some light on how I could start this process?
Any help is greatly appreciated, and thanks in advance.
Inside $('.updatebutton-362').click, change the .load() line to (replace name, id with whatever parameters you want to send):
$.post('http://localhost/ci/index.php/ajaxtestc/',
{name: "John Doe", id: "anything"},
function(data) {
$('.actionlog-'+id[1]).html(data);
}
});
Then above everything in index() in the ajaxtestc controller, parse the _POST variables and call whatever function you have in your model to update the action log.
Whatever is displayed by the index() action will be loaded into the actionlog span.
First, your code look mess. The first tag seems unclosed, and the form_open is nested inside it.
My rule of thumb to developing a web is, make it work without any javascript first. Then add javascript as better experience.
In your case above, try build the form with old way, after submit, redirect to page you want. After that working well, add jquery one at a time. Use jquery form plugins to submit form. Add a simple checking in the controller to handle ajax request.
I usually use json for form submit, so in controller, I will return a json_encode array to a ajax submitted form request.
Hope this help you.

Simple Search: Passing Form Variable to URI Using CodeIgniter

I have a search form on each of my pages. If I use form helper, it defaults to $_POST. I'd like the search term to show up in the URI:
http://example.com/search/KEYWORD
I've been on Google for about an hour, but to no avail. I've only found articles on how $_GET is basically disabled, because of the native URI convention. I can't be the first person to want this kind of functionality, am I? Thanks in advance!
There's a better fix if you're dealing with people without JS enabled.
View:
<?php echo form_open('ad/pre_search');?>
<input type="text" name="keyword" />
</form>
Controller
<?php
function pre_search()
{
redirect('ad/search/.'$this->input->post('keyword'));
}
function search()
{
// do stuff;
}
?>
I have used this a lot of times before.
As far as I know, there is no method of accomplishing this with a simple POST. However, you can access the form via Javascript and update the destination. For example:
<form id="myform" onsubmit="return changeurl();" method="POST">
<input id="keyword">
</form>
<script>
function changeurl()
{
var form = document.getElementById("myform");
var keyword = document.getElementById("keyword");
form.action = "http://mysite.com/search/"+escape(keyword.value);
return true;
}
</script>
Check out this post on how to enable GET query strings together with segmented urls.
http://codeigniter.com/forums/viewthread/56389/#277621
After enabling that you can use the following method to retrieve the additional variables.
// url = http://example.com/search/?q=text
$this->input->get('q');
This is better because you don't need to change the permitted_uri_chars config setting. You may get "The URI you submitted has disallowed characters" error if you simply put anything the user enters in the URI.
Here is the best solution:
$uri = $_SERVER['REQUEST_URI'];
$pieces = explode("/", $uri);
$uri_3 = $pieces[3];
Thanks erunways!
I don't know much about CodeIgniter, but it's PHP, so shouldn't $_GET still be available to you? You could format your URL the same way Google does: mysite.com/search?q=KEYWORD and pull the data out with $_GET['q'].
Besides, a search form seems like a bad place to use POST; GET is bookmarkable and doesn't imply that something is changing server-side.

Categories