Display label before input using formRow view helper in Zf2 - zend-framework2

In Zend Framework 2.1.4 I am using the standard form view helpers to render out my form elements.
When I try:
<?php echo $this->formRow($form->get('Title'));?>
The label text and input element are placed within the label:
<label>
<span>Title</span><input type="text" name="Title" placeholder="Inserisci titolo"
required="required" value="">
</label>
The same with:
<?php echo $this->formCollection($form, TRUE);
However, if I render out the label and input individually:
echo $this->formLabel($form->get('Title'));
echo $this->formInput($form->get('Title'));
It generates the html I want:
<label for="Title">Title</label>
<input type="text" name="Title" placeholder="Insert Title" required="required" value="">
How can I achieve the same with the formRow view helper?

If a form element does not have an "id" attribute, the label will wrap the input:
<label>Label<input /></label>
Otherwise:
<label for="test">Label</label><input id="test" />

Looking at (zf2 version 2.25 dev):
\Zend\Form\View\Helper\FormRow
It appears that if you don't provide an id for your form elements, the default general behaviour is to place the input element inside their corresponding label element.
The second argument for the formRow view helper, will place the label text before (prepend) or after (append) the input element in the document flow. (The default is to place it before.)
Check the render method for more details.

In first you must look source code to understand how formRow works : https://github.com/zendframework/zf2/blob/master/library/Zend/Form/View/Helper/FormRow.php
After you'll see in this code that __invoke has $labelPosition parameter that you can prepend or append with const LABEL_APPEND and LABEL_PREPEND.
In short, try to do something like this :
$this->formRorw($form->get('element'), 'prepend'); // Or append as you want

Related

Booststrap v5 textform class="form-label" prepopulate data in a way that can be copied to clipboard

Using bootstrap 5, specifically going over this: https://getbootstrap.com/docs/5.3/forms/form-control/
I am trying to create a simple example text area with some text in it pre-populated, so that I can add a button that will copy the propulated text into clipboard.
Method 1-
Sample code from Bootstrap looks like this:
<div class="mb-3">
<label for="exampleFormControlTextarea1" class="form-label">Example textarea</label>
<textarea class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea>
</div>
If I use something like 'placeholder' the text box gets prepopulated but I can't "grab" that text neither manually or via a js script. The placeholder my understaning is just a hint of what is to be filled out in the box.
Method 2-
If I used for example a regular HTML textarea element I can do this, no problem, with something like this:
<textarea id="textbox" rows="3" cols="80">{{prepopulated_date_variable}}</textarea><br />
<button type="button" class="btn btn-primary"onclick="copyTextBoxData()">Copy Copy Data</button>
So if I use a regular "textbox" like in Method 2, it does not leverage the cool look and resizing capabilities of bootstrap, hence why I am trying to get Method 1- or similar to work.
Any queues? tips? maybe another element?
I am new to this all, but the concept is that I am passing from a another piece of code the prepopulated data for user to see (leveraging Jinja template with Python if that makes any difference) and then idea is that button allows my user to copy to mem clipboard what is in the text box, so that they can past in something else.
Appreciate any support or ideas.
I am using Method 2- described in problem statement. What I am expecting is that I can use Method 1 or alternative with bootstrap component to leverabe the styling and features of bootstrap.
You can use JavaScript to set the value of the form inputs when the page loads.
This code creates a form with two inputs (email and password) and a button that, when clicked, copies the values of the inputs to the clipboard. The copyToClipboard function uses the document.getElementById method to get the values of the inputs, concatenates them into a string, creates a temporary input element, sets its value to the string, selects it, and then executes the document.execCommand("copy") command to copy the value to the clipboard. Finally, it removes the temporary input element and alerts the user that the data has been copied.
function copyToClipboard() {
var email = document.getElementById("exampleInputEmail1").value;
var password = document.getElementById("exampleInputPassword1").value;
var data = "Email: " + email + "\nPassword: " + password;
var tempInput = document.createElement("input");
tempInput.style = "position: absolute; left: -1000px; top: -1000px";
tempInput.value = data;
document.body.appendChild(tempInput);
tempInput.select();
document.execCommand("copy");
document.body.removeChild(tempInput);
alert("Copied to clipboard: " + data);
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/css/bootstrap.min.css" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<form>
<div class="form-group">
<label class="form-label" for="exampleInputEmail1">Email address</label>
<input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" value="example#email.com">
</div>
<div class="form-group">
<label class="form-label" for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" id="exampleInputPassword1" value="password123">
</div>
<button type="button" class="btn btn-primary" onclick="copyToClipboard()">Copy to Clipboard</button>
</form>

Styling single jQuery UI controlgroup-item

I am using jQuery UI controlgroup to style checkboxes in an HTML form. After the input values are processed by a PHP script, the results are displayed on the the same page along with the form itself, so that the user can adjust the filters. What I am trying to do, is to have the boxes that were checked previously remain checked after the form has been processed, so that the user sees what selection criteria were used. To achieve that I store all the PHP $_POST data in a JS variable using json_encode, which I'd like to use to iterate through the labels and mark those that were checked previously. The problem is that the only option of the controlgroup widget that I can use is classes with ui-controlgroup-item which shows every single label within the group as active, and for the life of me I cannot figure out how to make it conditional, e.g. so that I can use if(label[for=' + var.value +'])', var being <?php echo json_encode($_POST) ?> or something similar. Will appreciate any suggestions.
Here is the HTML:
<div id="currencyList">
<label for="gbp">GBP</label>
<input type="checkbox" value="gbp" name="currency[]" id="gbp" >
<label for="usd">USD</label>
<input type="checkbox" value="usd" name="currency[]" id="usd">
<label for="eur">EUR</label>
<input type="checkbox" value="eur" name="currency[]" id="eur">
</div>
And this is the JavaScript bit:
$( "#currencyList" ).controlgroup({
classes: {
"ui-controlgroup-item": "ui-checkboxradio-checked ui-state-active"
}
});
After trying to find a solution for several days I decided to skip trying via the classes option and instead to move outside the controlgroup widget. So here is my not-so-pretty-but-working solution:
var postData = <?php echo json_encode($_POST) ?>;
$( "#currencyList" ).controlgroup();
$('#currencyList').children('label').each(function () {
if(postData.currency.indexOf($(this).attr("for")) >= 0){
$(this).addClass( "ui-checkboxradio-checked ui-state-active");
}
});

Go vs. return button in iOS keyboard for HTML input forms

Managing the iOS keyboard for HTML <input> forms (used in UIWebView) is well known, i.e. <input type="tel"></input> for telephone numbers.
https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html
But I was wondering about the keyboard's blue 'Go' button.
Sometimes the keyboard has a blue 'Go' button, sometimes the keyboard has a gray return button.
Is there any opportunity to control this behavior programmatically?
Update 2020/2021
As Cameron Cobb pointed out,
Safari Mobile supports the new HTML attribute enterkeyhint since version 13.7 ~ Sept. 2020 (https://caniuse.com/mdn-html_global_attributes_enterkeyhint).
The following values are possible (https://mixable.blog/ux-improvements-enterkeyhint-to-define-action-label-for-the-keyboard-of-mobile-devices/):
<input enterkeyhint="enter">
<input enterkeyhint="done">
<input enterkeyhint="go">
<input enterkeyhint="next">
<input enterkeyhint="previous">
<input enterkeyhint="search">
<input enterkeyhint="send">
Original Answer
Aha...
The 'Go' button is only shown, if the <input> tag is inside a <form> tag (and the form tag has an action attribute).
So, if you access your form elements afterwards with i.e. JavaScript, you can omit <form> tags.
'Go' button:
<form action="..." method="...">
<input type="text"></input>
</form>
'return' button:
<input type="text"></input>
The important part is that the form tag has an action property. (action="#" is a noop.)
<form>
<input type="text" />
</form>
<form action="#">
<input type="text" />
</form>
There is a better and more "straight forward" way of changing the enter button text. Use the attribute enterkeyhint in the input tag like in the example shown below.
<input enterkeyhint="go">
You can find more documentation on the Mozilla site here.

Using Angular to set style to display: none broken in IE 10, works elsewhere

I have the following mvc code:
#Html.DropDownListFor(model => model.State, Model.States, new { #class = "form-control",
// Displays if the country is United States
style="display:{{State_Display()}}",
Name="State"})
#Html.TextBoxFor(model => model.State, new { #class = "form-control",
// Displays if the country is not United States
style="display:{{Province_Display()}}",
Name="Province"})
EDIT: I guess I should mention that Province_Display() is a method in my angular controller that either returns the string "none" or "block" depending on the country chosen.
In the latest versions of Chrome and Firefox, this does what you'd expect: if the user picks united states from a different control, the State field is shown and the Province field hidden.
In IE 10 however, both controls display all the time. Inspecting the elements with f12 in IE, neither of them have any style property at all.
The way I'm thinking of solving this would be to use angular to apply an additional CSS class to the elements instead of using angular to dynamically update the inline style, but my question remains:
Why does this work in Chrome and Firefox but not IE? What's being handled differently? Why doesn't anything appear for Style when I inspect in IE? If you know, will my CSS class idea actually fix the issue (before I bother reworking things)? I'd like to understand the cause so I can avoid similar situations in the future. Thanks!
Additional info:
Right-click, view page source (same in both chrome/IE):
<select Name="State" class="form-control" data-val="true" data-val-required="The State field is required." id="State" name="State" style="display:{{State_Display()}}">
<input Name="Province" class="form-control" id="State" name="State" style="display:{{Province_Display()}}" type="text" value="" />
Inspect (Chrome):
<select name="State" class="form-control" data-val="true" data-val-required="The State field is required." id="State" style="display:block">...omitted...</select>
<input name="Province" class="form-control" id="State" style="display:none" type="text" value="">
Inspect (IE):
<select name="State" class="form-control" id="State" data-val-required="The State field is required." data-val="true">
<input name="Province" class="form-control" id="State" type="text" value=""/>
There's still really not enough of your code to go by, but there are a few approaches you can take. The class thing you recommend should work, but there's something in your code we can't see that's causing it to not execute in IE properly. (any errors in your console?) My best guess... you're missing your DTD, or it's set improperly. Try adding this at the top of your html template:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
A better approach (still need to ensure your DTD is set correctly) would be to use ng-show/ng-hide: http://docs.angularjs.org/api/ng.directive:ngHide
<!-- when $scope.myValue is truthy (element is hidden) -->
<div ng-hide="myValue"></div>
<!-- when $scope.myValue is falsy (element is visible) -->
<div ng-hide="myValue" class="ng-hide"></div>
However, if you wish, you can define a css class like so:
.hide {
display:none;
}
and just apply that class to whichever input you wish to hide within you application logic.

All radioButtons are false at the view

#Html.RadioButton("smth",true)
This row at the page looks like UNCHECKED radioButton. Why?
You should use
HtmlHelper.RadioButton(string name, object value, bool isChecked)
extension method.
First argument is the name of the form field which is input field generated by html helper.
Second argument is the value of input element. If this radio is selected when the postback to server happens, this value is used.
Third argument is what you are looking for. If it is true it makes radio button selected.
For instance,
#Html.RadioButton("Name", "Value" ,true)
would generate an input element which looks like following,
<input checked="checked" id="Name" name="Name" type="radio" value="Value" />
You need to use something of the form
#Html.RadioButton(id,value,checked (bool true/false))
So
#Html.RadioButton("A","B",true)
For example would produce:
<input checked="checked" id="A" name="A" type="radio" value="B" />
The documentation for this is here
In your previous query, you got this answer.
You asked the same query in it's comment section. The problem was that the second line of code was missing one parameter.
Please check below details....
Parameter Details
Razor Syntax
#Html.RadioButton("smth", "smth", true)
#Html.RadioButtonFor( m => m.Prop, true, new { id = "rdBtn" } )

Resources