So I have a form in my view:
{{Form::file('projectPicture', ['class' => 'uploadedImage', 'data-some-attribute' => ''])}}
with the attribute data-some-attribute.
And in my route I retrieve it like so:
$request->file('projectPicture');
How do I get a data-some-attribute in the route? Is it even possible?
I know I can use ajax to pass any data, but can it be avoided in this case?
Thank you!
It is not possible how you intend it to work, only because it's not how form data is working under the hood. The second argument in your sample Form::file is just decorating the rendered form element. It has no correlation with the form data that is transferred between the server and client.
For all intents and purposes form data is just a glorified set of key value pairs. If you wanted to pass some-data-attribute to your route controller, you have two options -
Add another form field, and make it empty using Form::hidden. In this case, you would just name the field some-data-attribute.
If your form is submitted through a POST method, you can tack on some-data-attribute onto the form's route and retrieve it from the request.
ie - your/route becomes your/route?some-data-attribute=whatever, and you can retrieve it later with something like $request->input('some-data-attribute').
Related
Updating existing items in DB in my application is solved by this way:
I have url like this:
http://localhost/project/public//structure/edit/about-us
In router I have set
Route::get('/structure/edit/{url}', 'StructureController#update'); //for displaying the prefilled form
Route::post('/structure/edit/{url}', 'StructureController#update'); // for saving new values
So it means, I'm building update query where url = $url . This is the main part of my view file:
{!! Form::open(['url' => URL::current()]) !!}
I don't know where to point "form action". So I¨m using the same url as current url, so router recognizes, that this is post request and I can process the update inside the same controller and select new (updated) data to my update form.
The problem is, when I update the url via form, new value will set to database. So it means, from this moment old url doesn't exists, but and my form action point to url, which doesn't exists anymore.
What can I do with that? If you know, what I mean...
To update use patch method instead of post. Write this in web.php
Route::get('/structure/edit/{id}', 'StructureController#edit');
Route::patch('/structure/{id}/update', 'StructureController#update');
You can use either action or url as a form action. Pass the structure id in the second parameter of the action
{!! Form::model($structure,['action' => ['StructionController#update',$structure->id],'method'=>'patch']) !!}
If you do what #smartrahat suggests and still got the error you posted, then can you run php artisan route:list command and show us the structure of your routes?
In my form, I am populating state and city dropdowns using ajax.
Also, on the same form the user can add multiple employees by clicking on the "Add more button".
In both above scenarios the HTML DOM elements are generated using jquery.
I need re-build the dynamically generated elements in case the validation fails on form submit.
Can anyone please tell me a right approach for achieving the above mentioned issue.
Thanks.
Say you've generated a list of inputs dynamically by calling a js function, maybe something like
//JS
function generate(){
$("#container-abc").append("<input name=name[]>");
}
<!--HTML -->
<input name=name[] />
<input name=name[] />
Submit them and if there's validation error you will get back the values using:
//in your blade
$name = Request::old('name');
#if(count($name) > 0)
for (var i = 1; i <= {{count($name)}}; i++) {
generate();
}
#endif
you can use
return Redirect::back()->withInput();
or for more info visit https://laravel.com/docs/5.2/requests#old-input
Old Input
Laravel allows you to keep input from one request during the next
request. This feature is particularly useful for re-populating forms
after detecting validation errors. However, if you are using Laravel's
included validation services, it is unlikely you will need to manually
use these methods, as some of Laravel's built-in validation facilities
will call them automatically. Flashing Input To The Session
The flash method on the Illuminate\Http\Request instance will flash
the current input to the session so that it is available during the
user's next request to the application:
$request->flash();
You may also use the flashOnly and flashExcept methods to flash a
sub-set of the request data into the session:
$request->flashOnly(['username', 'email']);
$request->flashExcept('password');
Flash Input Into Session Then Redirect
Since you often will want to flash input in association with a
redirect to the previous page, you may easily chain input flashing
onto a redirect using the withInput method:
return redirect('form')->withInput();
return redirect('form')->withInput($request->except('password'));
Retrieving Old Data
To retrieve flashed input from the previous request, use the old
method on the Request instance. The old method provides a convenient
helper for pulling the flashed input data out of the session:
$username = $request->old('username');
Laravel also provides a global old helper function. If you are
displaying old input within a Blade template, it is more convenient to
use the old helper. If no old input exists for the given string, null
will be returned:
I currently have a view, manage, that lists data items. Instead of running "edit" and "add" actions with separate views, I'm having the appropriate form display inline in the page when it is needed. On the form is a "cancel" button that will hide it.
Right now I decide what, if any, form to display inline through a GET parameter called mode. So /controller/manage will display the items, while /controller/manage?mode=edit will display the items and show the edit form for the correct data item.
The action accepts various other GET parameters such as a date interval.
In order to activate the form, I'm generating a link to the current action with the mode parameter spliced in with existing parameters in $_GET. I'm using the following one-liner:
<?php echo CHtml::link('Edit', array_merge(array('/session/manage', 'mode' => 'edit', 'id' => 6), $_GET)); ?>
To implement the "cancel" link, I'm using:
<?php echo CHtml::link('Cancel', array_diff(array_merge(array('/session/manage'), $_GET), array('edit'))); ?>
My question is: is there a cleaner way to do this? While this works, it feels like a hack. I haven't found any documentation on generating URLs that include existing GET parameters. Does Yii provide a built-in method to do what I want to do? Should I re-evaluate my general approach to conditional views, which might in turn yield a cleaner solution?
One way would be to hold all of the most recent _GET variables in session state. Your controller would then act on that stored data and use new _GET variables to override it. Using that method, you wouldn't need to merge the existing _GET variables back into the new request. The tradeoff is that you end up having to manage that session data and handle possible special cases (like starting over with fresh state).
Another way would be to use Ajax to call an action that returns a partial view with your rendered edit form. Then your links would just need to call some javascript that does the Ajax call with the current ID and displays the returned form on the page. Your links would end up looking something like this:
<a href="#" onclick="showEdit(6)">
Since using Ajax wouldn't cause the page to reload, you don't need to worry about any of the _GET parameters required to show your list. And your Cancel link would become a javascript call to simply remove the edit form from the DOM. Using jQuery:
$('#editform').remove();
Another way to make it a little cleaner would be to encapsulate all of the array_merge() stuff up there into a method of a custom component or helper. Then your code could look something like:
echo CHtml::link('Edit', URLHelper::mergeGet(array('/session/manage', 'mode' => 'edit', 'id' => 6));
or even ecapsulate that in your own CHtml class:
echo MyCHtml::link('Edit', array('/session/manage', 'mode' => 'edit', 'id' => 6));
where MyCHtml::link() does everything that CHtml::link() does in addition to the array_merge stuff. MyCHtml could even extend CHtml so that it has all of CHtml's methods.
If I build a form:
$search_words = new Zend_Form_Element_Text('text');
$search_words->setRequired(true)->setDecorators(array(array('ViewHelper')));
$form->addElement($search_words);
$go = new Zend_Form_Element_Submit('gogogo');
$go->setDecorators(array(array('ViewHelper')))
->setIgnore(true);
$form->addElement($go);
With method GET.
I will see in the URL gogogo=gogogo. If I was writing the markup myself, I simply wouldn't give the submit any [name] attribute and that would have solved that. Trying to set the name of a submit to '' won't work (either throws an exception or is being ignored, depends on the way you do it).
Any (built in) ideas?
Another possibility would be to disable the submit button before the form is submitted:
$go->setDecorators(array(array('ViewHelper')))
->setIgnore(true)
->setAttrib('onclick', 'this.disabled = true');
This way, the value of the submit button will be ignored upon submitting the form.
There are a few possible options:
Use a custom decorator to build the markup, so a name attribute is not specified
Use a string replacement function on the markup returned by Zend_Form's render methods, to remove the attribute
What I often do, as follows
I usually add a custom route so that either of the following is valid:
domain.tld/search/keyword
domain.tld/search?q=keyword
Then you can use javascript to redirect to the cleaner form of the URL, taking care to urlencode the keyword field
Most of your users will see the cleaner URL this way.
I have got a form which a user can use to create a new store and to edit an existing one. When this form is being used to edit a store there are certain fields that I want the user to see but not edit eg. store_id. I have explored the different Zend_Form_Elements hoping to find some kind of static element but with no luck.
So my question is, how do I display information using Zend_Form that a user can't edit?
Thanks.
readonly alone is not enough, because users will still be able to edit it if they really want. You should use $element->setIgnore(true) that will ensure that Zend_Form_Element won't try to populate the element from POST/GET, and I'd double check that also. You have to make sure the values you are getting into the databases can never contain this element.
Finally, if you would like your element to be displayed in a different way than just with readonly, you can do that by changing the element decorators.
I just managed to work this one out myself. The solution was to change the view helper on the elements to the formNote helper eg. $element->helper = 'formNote'. The result of this was that the value gets displayed as straight text instead of being inside a form element.
Thanks for your answers.
That's very good solution when you don't need to populate the element value when the form is submitted.
It's equivalent solution is to use the Form Element method setAttrib() and disable the form element
$formElement->setAttrib('disable','disable')
which will only freeze the element.
But if you need to populate the field, using the previous solutions you will probably need additional hidden field added, which will pass the value. Developing custom form element will be good style but that's not welcomed by each developer so you can use some tricky way to set a form element as a text only but populate its value. That way is when you create the element as a hidden field, set its value and use the Form Element method setDescription() to set and display the element text value.
$formElement = new Zend_Form_Element_Hidden( 'elName',
array( 'label' => 'elLabel', 'value' => 'elValue' ) );
$formElement->setDescription( 'elValue' );
Then you can render that hidden element and display the value with the
$formElement->getDescription().
$element->setAttrib('readonly', 'true');
http://www.w3.org/TR/html401/interact/forms.html#adef-readonly
According to Amr Mostafa, if you use:
$element->setAttrib('readonly', 'true');
OR
$element->setAttribs(array('disabled' => 'disabled'));
User still send values by POST/GET and they are stored in DB.
The only way for me to don't taking into account the values from POST/GES is:
$element->setIgnore(true)
Example:
$element = new Zend_Form_Element_Text('element');
$element->setIgnore(true);