I have created an abstract form class that adds a submit element to the form. When my other form classes extend this form class I am having to call parent::__construct() at the bottom of the class so that the submit element is added last.
How do I set the submit button to always be the last element in the form, event if I call parent::__construct() first?
The form add function accepts two parameters - either an array or element instance, and an array of flags. One of the flag options is priority. The smaller the number, the lower in the list of elements it will appear. Therefore, setting it to -1000 (unless you have greater than 1000 elements) will set the submit button to appear at the bottom of the form:
$this->add([
'name' => 'submit',
'type' => 'submit',
'attributes' => [
'value' => 'Submit',
'class' => 'btn btn-sm',
],
'options' => []
],
[ 'priority' => -1000 ]);
RichardParanby-King's answer is good but careful for the view :
In the view we have a lot of options to show the form :
<?= $this->form($form)?>
<?= $form->get('{element}') ?>
loop over $form->getIterator()
loop over $form->getElements()
etc...
I have to say I used a lot this structure in all of my projects :
<?php foreach ($form->get('fieldset')->getElements() as $elementName => $element): ?>
<?= $this->partial('partial/formElement', ['element' => $element])?>
<?php endforeach ?>
The problem is : getElements does not use priority, so its just give the element in order of when it was instanciated.
In the view we have to use the iteration method ($form->getIterator()) to get back this priority.
Related
I would like to know how to disable escaping on Form Checkbox Element label ?
I would like to have my label html, this is my current code :
$score = new \Zend\Form\Element\MultiCheckbox('score');
$score->setLabel('Score');
$score->setOptions(array('value_options' => array(1 => '<b>Test 1</b>', 2 => '<b>Test 2</b>')));
$score->setAttributes(array('escape' => false));
$this->add($score);
$score->setLabelOptions(array('disable_html_escape' => true));
You don't have a way to short-circuit the HTML escaper. The code on the Multicheckbox view helper does not allow for a conditional escape. You would need to create your own view Helper in order to render the HTML.
If all you're looking to do is set the labels to bold, however, you can accomplish that with CSS. The 'value_options' option can be an array of arrays where the second level contains options for each individual input in the Multicheckbox. For example:
'value_coptions' => array(
'test_1' => array(
'value' => '1',
'label' => 'Test 1',
'label_attributes' => array( 'style' => 'font-weight: bold' ),
'selected' => true,
),
),
I have folowing schema:
Template
UserTemplate
template_id
Costs
template_id
amount
value
What I'm trying to do, is to create a sfWidgetFormDoctrineChoice that displays the shipping costs based on a UserTemplate id.
$this->widgetSchema['cost'] = new sfWidgetFormDoctrineChoice(array(
'model' => 'Costs',
'key_method' => 'getValue',
'method' => 'getAmount',
'add_empty' => 'Please Select Amount',
'expanded' => false,
'multiple' => false
));
This displays all of the Costs.
Ideally, I'd like it to limit it to the UserTemplate.
I have looked at creating a custom query and passing that into the widget, but I'm not sure if this would be the correct way of doing this
So If I have a bunch of costs assigned to the template id of 12 and the user template references 12, when I'm on example.com/user-template/12 - I'd expect to see the costs for this in my form widget.
Creating a custom query and passing it to the widget is exaclty what you're looking for. You will have to build the query depending on the template_id you use in the URL.
What is 'the rails way' to have a form with submit_tags for each row, where the submit_tag 'tells' the controller which row's submit was clicked?
Inside a form_tag, my form displays a list of users, and next to each user are several actions such as 'foo' and 'bar'.
Currently I use link_to for those actions, which adds a query param :row => this_row.guid so my controller knows which row to take action on. It works, but I don't like having the query params exposed on the url, and I don't like how they persist on the URL so if the user clicks refresh it performs the action again.
Since the rows are displayed are inside a form already, I'd like to have each action be a submit_tag. But I do not see from the API docs that there is any way to add a different query param to each instance of a submit_tag.
When I try this:
= submit_tag "foo", {:row => this_row.guid}
= submit_tag "bar", {:row => this_row.guid}
The html DOES look like <input .... row='SOMEGUID' ...>
However the POSTed params do not include the :row query params
I also tried
= submit_tag "foo", params.merge(:row => this_row.guid)
= submit_tag "bar", params.merge(:row => this_row.guid)
with the same result ( includes the row=GUID, but that param is not POSted to the controller when the user clicks the submit button).
I'd appreciate any help on how to have many rows of submit buttons (with the same name visible to the user) also pass a row identfier to the controller.
the value of the submit button also gets sent as a parameter. check your logs.
UPDATE
Add the row id as a data attribute of the submit button:
= submit_tag "bar", {:data => {:row => this_row.guid}}
Then when the submit button is clicked it should add the row id as a hidden field in the form before it gets submitted.
$('input[type="submit"]').click(function(){
$('form').append('<input type="hidden" name="row" value="' + $(this).data('row') + '" />');
});
I want to create a form for making a reservation for borrowed items. A reservation consists of pick up time, return time and items the reserver wants to borrow and their amounts. For example, I might want to reserve three plates, three knives and three forks for the rest of the week.
In the form, I want to do an AJAX validation that checks whether there is enough items available. Next to each item I have a text box with which the reserver inputs the item amount. After the input, I want to do an onchange call that checks if the amount of items is available for the given dates. Thus, I need to pass the remote function called in the onchange following parameters: item id, item amount (value of the current textfield) and pick up time and return time which are both given in datetime_select fields above. This is my code:
<% with = "'amount='+value+'&item=#{item.id.to_s}&pick_up_time=#{#reservation.pick_up_time.to_s}&return_time=#{#reservation.return_time.to_s}'" %>
<%= text_field_tag "reservation[#{prefix}reserved_items][#{item.id}]", get_amount_value(item, #reservation), :size => 3, :onchange => "#{remote_function(:url => { :controller => :items, :action => :availability }, :with => with, :update => availability_url) }" %>
Obviously, this does not work since #reservation.return_time and #reservation.pick_up_time are not yet set because the form is not yet sent. My question is: how do I get those values? I believe that it should be done via a javascript call, but I didn't manage to insert a javascript call in the "with" variable or at least didn't get it to work. Does anybody have any idea on what I should do?
use prototype selectors $(#reservations_pick_up_time).value
the :with attribute is just a place for you to write JS code that it will display inline
I have a partial that renders a select box using the following method:
<%= collection_select 'type', 'id', #types, "id", "name",
{:prompt => true},
{:onchange =>
remote_function(
:loading => "Form.Element.disable('go_button')",
:url => '/sfc/criteria/services',
:with => "'type_id=' + encodeURIComponent(value) + '&use_wizard=#{use_wizard}'"),
:class => "hosp_select_buttons"
} %>
This partial gets used 2 times on every page, but at one point I need to get the value of the first select box. Using:
$('type_id')
returns the second select box. Is there a way to find the first one easily? Should I fix this using javascript or by redoing my partial?
Note: the dropdowns do get rendered in separate forms.
Yes, each element does need a unique ID, the page probably also fails HTML validation. Also, unless these are in 2 different forms you'll have a conflict with the CGI parameter name.
If they are in 2 different forms you can probably get away with just setting the :id as you posted, if they are the same form you need to abstract the parameter name too:
collection_select 'type', "id_wizard_#{use_wizard}"...
I figured out one way to do this by assigning an ID in the html_options block. I already am passing in a value for use_wizard, so I can append that value on to the ID to differentiate between the two dropdowns.
:id => "type_id_wizard_#{use_wizard}"