button_to creates non-clickable button - html

I've noticed an odd behavior with button_to. I have some stylized buttons. When button_to is generated the input submit field is placed inside the button element. What ends up happening is that the inner edges of the button when clicked do not redirect the user to the new page. The user is forced to directly click on the text to redirect.
My question is, how do I fix this? I don't think CSS is a possible solution. Ideally I would like to apply the classes I pass in the button_to method to the input field. That way the input field becomes the button and not the form.
Here is the button_to method.
button_to("Click me!",
"/new-course",
{class: 'start-course-button is-normal start-course'}
).html_safe
Here is the html that is generated.
<form class="start-course-button is-normal start-course" method="post" action="/new-course">
// This must be clicked below and not the form itself for there to be a redirect
<input type="submit" value="Click me!">
<input type="hidden" name="authenticity_token" value="secret_auth_token">
</form>

Currently, you are applying styles to the form rather than the submit input inside of it. You can use a child selector to select the submit input as the form's child for a pure CSS solution.
For clarity's sake, create a new class to apply to the form. This class will select the child input of type submit.
.start-course-form input[type="submit"] {
/* button styles */
}
Then, update your helper method with the correct class.
button_to("Click me!",
"/new-course",
{class: 'start-course-form is-normal start-course'}
).html_safe
Note that this will not make the button a member of the start-course-button class, it will just look the same.

button_to does not allow you to apply classes or customize the submit input.
Rather you would use form_tag to manually create the form if you need that kind of flexibility. Edited to show how it would work in a presenter.
class CoursePresenter
def initialize(helpers)
#h = helpers
end
def new_course_button
h.form_for("/new-course") do
h.submit_tag "/new-course",
class: 'start-course-button is-normal start-course'
end
end
private
attr_reader :h
end
You could also use a CSS rule that targets the input element instead of the form:
.start-course-button input[type="submit"] {
border: 2px solid black;
padding: 10px 15px;
background-color: pink;
}
<form class="start-course-button">
<input type="submit" value="Click me">
</form>

Related

HTML fieldset: form attribute not working

I am trying to create an HTML form is separate parts for layout reasons. As far as I understand, you can use a fieldset with a form attribute to associate the fieldset with the form, even if it’s not inside the form (https://developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset).
However, if I have a separate fieldset with a submit button or another input in it, it doesn’t seem to work.
<form id="test">
<input name="inside-stuff" value="Inside">
<button type="submit">Doit Inside</button>
</form>
<fieldset form="test">
<input name="outside-stuff" value="Outside">
<button type="submit">Doit Outside</button>
</fieldset>
In the above snippet I have two submit buttons and two inputs. The one in the actual form works, while the one in the attached fieldset doesn’t. When I use the inside submit button, it only submits what’s in side the main form, not what is in the associated fieldset.
This may not be obvious when running the snippet, but is certainly the case when tried in real life.
What is missing to make this work?
Update 1
The problem appears to be more generic than that. I find that input elements inside an associated fieldset don’t get submitted either.
Update 2
This is not a duplicate of Submit form using a button outside the <form> tag. This question specifically refers to a fieldset element. The other doesn’t even mention it.
I wrote the following javascript
function control() {
function view(i) {
var frm = items[i].getAttribute("form");
var fBase = document.querySelector("form[id=" + frm + "]");
fBase.addEventListener("submit", function(){
var fld = document.querySelector("fieldset[form='" + this.id + "']");
var cln = fld.cloneNode(true);
cln.style.display = "none";
document.getElementById(frm).appendChild(cln);
},true);
}
var items = document.querySelectorAll("FIELDSET[form]");
var getter = function () {
return this.getAttribute("form");
};
for(var i = 0; i < items.length; i++) {
view(i);
Object.defineProperty(items[i], 'form', {
get: getter
});
}
}
window.addEventListener("load",control,true);
It's happening because the Form you have placed inside the fieldset is wrong. The form should be the parent of the fieldset in order to get it to work!
The form tag should always be the parent of the fieldset.
If you place <form> and <fieldset> then it will work. The code below should do.
<form id="test">
<input name="stuff">
<button type="submit">Doit</button>
</form>
<form>
<fieldset>
<input type="text" name="stuff2">
<button type="submit">Doit</button>
</fieldset>
</form>
I hope this will help!

angular ngModel style

Is it possible to style the value in the attribute ngModel of an input tag?
Example:
<input class="input" type="text" [(ngModel)] = "myService.text">
Let's say the value of text is '28 packages', can I put 28 in bold?
So if i understand correctly you want to have it bold whenever the value is 28 ?
yes its possible you can use a ng-class with a ternary expression like this
.bold{
font-weight:600;
}
<input type="text" ng-class="myService.text == '28 ? 'bold' : '''" class="input" ng-model="myService.text" />
This is not angular-related rather a CSS related question.
You cannot style only a part of an input in HTML/CSS so you won't be able to do it in angular.
Instead, you can use an input that is hidden behind a div. The idea is that when the user clicks the div, you actually focus the input. When the user types text, you capture the content of the input and fill the div with it, eventually adding <span class"highlight"> around the number of packages.
I prepared you a stackblitz in pure CSS/JS. You can adapt it in angular if you want.
Relevant pieces of code :
HTML :
<span id="hiddenSpan">This is the hidden div. Click it and start typing</span>
<div>
<label for="in">The real input</label>
<input id="in" type="text">
</div>
JS :
const input = document.getElementById('in')
const hiddenSpan = document.getElementById('hiddenSpan')
function onInputChanged() {
let text = input.value
const regex = new RegExp('(\\d+) packages')
let result = regex.exec(text)
if(result) {
hiddenSpan.innerHTML = '<span class="highlight">'+result[1]+'</span> packages'
} else {
hiddenSpan.innerHTML = text
}
}
// Capture keystrokes.
input.addEventListener('keyup', onInputChanged)
// Focus the input when the user clicks the pink div.
hiddenSpan.addEventListener('click', function() {
input.focus()
})
CSS :
#hiddenSpan {
background-color: pink;
}
.highlight {
font-weight: bold;
background-color: greenyellow;
}
Note : the downside is that the blinking caret is not visible anymore. You can take a look at this resource if you want to simulate one.
It is not possible to style certain parts of a text <input> field in bold. However, you can use a contenteditable div instead of a text <input> field. Inside the contenteditable div you can have other HTML tags like <strong> to style certain parts of the text however you like.
I created an Angular directive called contenteditableModel (check out the StackBlitz demo here) and you can use it to perform 2-way binding on a contenteditable element like this:
<div class="input" contenteditable [(contenteditableModel)]="myService.text"></div>
The directive uses regular expressions to automatically check for numbers in the inputted text, and surrounds them in a <strong> tag to make them bold. For example, if you input "28 packages", the innerHTML of the div will be formatted like this (to make "28" bolded):
<strong>28</strong> packages
This is the code used in the directive to perform the formatting:
var inputElement = this.elementRef.nativeElement;
inputElement.innerHTML = inputElement.textContent.replace(/(\d+)/g, "<strong>$1</strong>");
this.change.emit(inputElement.textContent);
You can change the <strong> tag to something else (e.g. <span style="text-decoration: underline"> if you want the text to be underlined instead of bolded).
When performing the formatting, there is an issue where the user's text cursor position will be unexpectedly reset back to the beginning of the contenteditable div. To fix this, I used 2 functions (getOriginalCaretPosition and restoreCaretPosition) to store the user's original cursor position and then restore the position back after the text formatting is performed. These 2 functions are kind of complex and they're not entirely relevant to the OP's question so I will not go into much detail about them here. You can PM me if you want to learn more about them.

Default styling classes for a password/username input form on bootstrap 3?

So i am making a php login page. I have the login application finished but all i need are a list of classes that will style my login form the way i want it.
Picture of the login form now - http://i.imgur.com/mrfvXXq.png
I need to style it so it is centered on the screen and will also not take the whole width.
I want it to look like this - http://i.imgur.com/C6G0FGK.png
Now i need it centered on the screen. Note im not adding in the Email input and text box. Only my Username and Password input. All i need is styles.
For a live version please visit gippixservers.com/zAdmin/admindashboard
Code -
">
<div class = "form-group">
<label for="txtUsername" class = "col-lg-2 control-label">Username:</label>
<div class = "col-lg-10">
<input class = "form-control input-block-level" type="text" title="Enter your Username" name="txtUsername" placeholder = "Username" />
</div>
</div>
<div class = "form-group">
<label for="txtPassword" class = "col-lg-2 control-label">Password:</label>
<div class = "col-lg-10">
<input class = "form-control input-block-level" type="password" title="Enter your password" name="txtPassword" placeholder = "Password" />
</div>
</div>
<div class = "form-control">
<input class = "btn btn-primary" type="submit" name="Submit" value = "Login"></input>
</div>
</form>
Bootstrap uses a grid system to place elements:
There are 12 grids you can have on one row. I have used col-*-offset in the code, this will leave space in the beginning. So what I'm basically doing is:
form class="form-horizontal col-md-offset-4 col-md-4" name="form"
method="post" action="/zAdmin/admindashboard.php"
This means, leave grid of 4 length before the form, and set the form to be of grid 4 length thus your form gets centered. [the leftover space on right is 4, all together in total making it 12]
Few changes made near your login button too. Use the class pull-right to position elements to the right side.
Also, remove this:
#gippix-adminControl {
width: 50%;
margin: 0 auto;
}
This is already done with the classes I mentioned above.
Fiddle Demo
I think your asking to make the live version smaller and centered ?
You need to add the following to your form tag. OR wrap your form in a div.
width: 50%; /* or whatever width you see fit */
margin: 0 auto;
Alternatively, You can view all bootstraps predefined form display options - getbootstrap.com/css/#forms
Or on your div <div id="gippix-adminControl" ... inputs... </div>
Just adjust your css to
#gippix-adminControl input{
width: blah;
max-width: blah;
min-width: blah;
}
To move your login button to the right simply set your
<input class="btn btn-primary" type="submit" name="Submit" value="Login">
to float: right; either in your css sheet or inline.
You can put a max-width to your .gippix-adminControl css class and go from there.
.container{max-width: 500px;}
You can also remove the div around your button , that will get rid of the unintended border. Then put a float: right on the button and you'll have yourself a good looking login form !
you can also make a .loginbutton-right css class like this :
.loginbutton-right{float: right;}
and add that class to your button !
It results in this :

How to style button inside of file upload input

Not sure how to style or change the text of the "Choose File" button inside of my file upload input field.
http://codepen.io/leongaban/pen/wrCLu
<input id="choose_file" type="file" name="datafile" size="40">
input {
padding: 10px 15px;
border: 0;
background: orange;
}
^ Here the background gets styled instead of the button.
As I told you in my comment you can simply create whatever layout and visuals you like to a button and create a file button then simply hide that file button and bind the event on the styled button to trigger the file button.
I've made this example for that purpose:
Codepen with custom file button
There are no native options for styling an input[type="file"] element. However, this article describes a cool (but hacky) trick you can use to accomplish this. Basically:
Create a button and style the layout as you would like it to appear.
Position your <input type="file" /> absolutely over the top of your new button element.
Add a z-index to the element to make it one level above the styled button.
Set the input to have an opacity: 0;
Wire up the proper events described in the article to make the input function accordingly.
CSS only solution
You can use the file-selector-button CSS pseudo-element
::-webkit-file-upload-button{
..
}
more information
Here is my straight-forward HTML 5 solution shown using an MVC Razor Form, but you could use a plain html form just as well. This solves the problem with the Input type=file not rendering the same in all browsers. You could style the browseBtn however you like by setting a background image for it. I tested this in IE 11, Firefox, and Chrome. IMO, the look of the default Chrome native control (shown in the question) is unacceptable.
Index.cshtml
<h2>Index</h2>
#using (Html.BeginForm("postFile", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div style="display:inline-block; margin-bottom:10px">
<input type="text" name="uploadControl" id="uploadControl"
style="width: 400px; height: 1.1em;" readonly="true" >
<button type="button" id="browseBtn" >Browse...</button>
</div>
<input type="file" name="upfile" id="upfile" style="display:none;" >
<button type="submit" id="uploadbtn" style="display:block">Click to upload</button>
<br><br>
#ViewBag.Message
}
<script src="~/Scripts/jquery-1.8.2.js"></script>
<script src="~/Scripts/UploadFile.js"></script>
UploadFile.js
$('#browseBtn').click(function () {
$('#upfile').first().trigger("click"); //cause the browse menu to pop up
});
$('#upfile').first().change(function (event) {
event.preventDefault();
var fileName = $('#upfile').val();
if (fileName && fileName.length > 0) {
$('#uploadControl').val(fileName);
}
});
HomeController.cs
public ActionResult postFile(HttpPostedFileBase upfile)
{
if (upfile != null && upfile.ContentLength > 0)
{
try
{
string path = Path.Combine(Server.MapPath("~/Images"),
Path.GetFileName(upfile.FileName));
//upfile.SaveAs(path);
ViewBag.Message = Path.GetFileName(upfile.FileName) + " uploaded successfully";
}
catch (Exception ex)
{
ViewBag.Message = "ERROR:" + ex.Message.ToString();
}
}
else
{
ViewBag.Message = "You have not specified a upfile.";
}
return View("Index");
}

How do I select property inside multiple divs

I have this:
<div id="sidebar-a">
<form id="form">
<input class="button" type="submit">
</input>
</form>
</div>
And I need to select only the input (my page has same <form> in #footer, the only way to change property of this one is, like I tried to do, with #sidebar-a, but it doesn't work)
Given that you made no mention of JQuery, I'm assuming you're trying to select the input element via CSS.
#sidebar-a > form > input.button:first-child {
font-size: 2em;
}
An example is available at this JSFiddle
You should not have 2 form elements with same ID. However this will do it:
#sidebar-a > form > input.button:first-of-type { }