Pretty Radio Buttons using rails form_for - ruby-on-rails

I am using Twitter's Bootstrap 3, the one that produces the pretty blue buttons. I would like to, using either rails form_for or simple_form, produce a radio_button group that looks the same as the following html one does:
<div class= "form-group">
<div class= "btn-group" data-toggle="buttons">
<label class="btn btn-primary">
<input type="radio" name="ptype", id="freelancer">
Freelancer
</label>
<label class="btn btn-primary">
<input type="radio" name= "ptype" id="agency">
Agency
</label>
</div>
</div>
That is, I would like the radio button group to look like the bottom option in the image below, rather than the top.

<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary active">
<input type="radio" name="options" id="option1" checked> Freelancer
</label>
<label class="btn btn-primary">
<input type="radio" name="options" id="option2"> Agency
</label>
</div>
You will need the specific javascript for this to work.
http://getbootstrap.com/javascript/#buttons

that's how I fixed it, the rails way:
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary">
<%= radio_button_tag :flight_id, flight.id %>select
</label>
</div>

Related

Angular Rails Not Resolving

We currently have some hardcoded code:
ng-form class="form-horizontal" name="genderForm">
<div data-fields="">
<div class="form-field-gender control-group form-field" data-field="">
<div class="controls" data-input="">
<label class="radio">
<input type="radio" ng-model="appuser.traits[6]" ng-value= "[42198]" name="field-input-gender" id="field-input-gender-0" required>
<i class="fa fa-male fa-fw"></i> {{genderQuestion.traits[0].value_text}}
</label>
<label class="radio">
<input type="radio" name="field-input-gender" ng-model="appuser.traits[6]" id="field-input-gender-1" ng-value="[42199]" required>
<i class="fa fa-female fa-fw"></i> {{genderQuestion.traits[1].value_text}}
</label>
</div>
<div class="controls">
<div class="text-error" data-error="">
</div>
</div>
</div>
</div>
</ng-form>
Ideally it will be dynamic so it should be something like this:
ng-form class="form-horizontal" name="genderForm">
<div data-fields="">
<div class="form-field-gender control-group form-field" data-field="">
<div class="controls" data-input="">
<label class="radio">
<input type="radio" ng-model="appuser.traits[{{genderQuestion.id}}]" ng-value= "[{{genderQuestion.traits[0].id}}]" name="field-input-gender" id="field-input-gender-0" required>
<i class="fa fa-male fa-fw"></i> {{genderQuestion.traits[0].value_text}}
</label>
<label class="radio">
<input type="radio" name="field-input-gender" ng-model="appuser.traits[6]" id="field-input-gender-1" ng-value="[{{genderQuestion.traits[1].id}}]" required>
<i class="fa fa-female fa-fw"></i> {{genderQuestion.traits[1].value_text}}
</label>
</div>
<div class="controls">
<div class="text-error" data-error="">
</div>
</div>
</div>
</div>
</ng-form>
But something about going from ng-model="appuser.traits[6]" to ng-model="appuser.traits[{{genderQuestion.id}}]" and ng-value="[42199]" to ng-value="[{{genderQuestion.traits[1].id}}]" seems to make it spazz out and not resolve any of the {{}} fields.
Any idea where I'm going wrong? Technically genderQuestion.id = 6 and genderQuestion.traits[1].id = 42199 but in this format it doesn't seem to like those.
Maybe I'm missing like a toString format or something?
2 way data binding with the ngModel directive doesn't need {{ }} again. You can directly refer to the scope object with genderQuestion.id
appuser.traits[genderQuestion.id].
Ta

Bootstrap button group and form_for

In my Rails app I'd like to use a Bootstrap button group. There is a single field, and each button represents a different state .. ie like radio buttons.
Even better if I can do it with simple_form but can't find a solution by Googling.
<%= simple_form_for #user_word, url: user_words_path, remote: true, wrapper: :inline_form, html: { class: 'form-inline' } do |f| %>
<div class="row">
<div class="col-sm-12">
<div id="selector" class="btn-group btn-group-sm" >
<button class="btn level-unknown" id='unknown' type="button">Unknown</button>
<button class="btn level-low" id='low' type="button">Low</button>
<button class="btn level-medium active" id='medium' type="button">Medium</button>
<button class="btn level-high" id='high' type="button">High</button>
<button class="btn level-known" id='known' type="button">Known</button>
</div>
</div>
</div>
<% end %>
Not sure exactly what you're asking. If your issue is that the active class is not switching to your clicked button, it's because you need javascript to do so.
$('#selector button').on('click',
function(e){
var $obj=$(e.target);
$('#selector .active').removeClass('active'); //remove active class from buttons
$obj.addClass('active'); //add active class to clicked button
});
See a working example here https://jsfiddle.net/DTcHh/14519/
Edit:
I just learned that this functionality is built in to the bootstrap javascript library. Your markup just needs to be modified to match this syntax
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary active">
<input type="radio" name="options" id="option1" autocomplete="off" checked> Radio 1 (preselected)
</label>
<label class="btn btn-primary">
<input type="radio" name="options" id="option2" autocomplete="off"> Radio 2
</label>
<label class="btn btn-primary">
<input type="radio" name="options" id="option3" autocomplete="off"> Radio 3
</label>
</div>
See example at http://getbootstrap.com/javascript/#buttons-checkbox-radio

Check_box problems to retrieve the one checked

I tried to use this form to put checkboxes on a form:
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary active">
<input type="checkbox" autocomplete="off" checked> Checkbox 1 (pre-checked)
</label>
<label class="btn btn-primary">
<input type="checkbox" autocomplete="off"> Checkbox 2
</label>
<label class="btn btn-primary">
<input type="checkbox" autocomplete="off"> Checkbox 3
</label>
</div>
My problem is that when I try to get the checkboxes checked with my parameters, I always can get only one (the last one checked, example: if I check 1 and 2, I will get 2 only).
How can I do to get them in my controller?
Thanks in advance
Try giving your inputs a name attribute with unique value attributes and unique id attributes.
Example:
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary active">
<input type="checkbox" autocomplete="off" id="first" value="1" name="box-selections[]" checked> Checkbox 1 (pre-checked)
</label>
<label class="btn btn-primary">
<input type="checkbox" autocomplete="off" id="second" value="2" name="box-selections[]"> Checkbox 2
</label>
<label class="btn btn-primary">
<input type="checkbox" autocomplete="off" id="third" value="3" name="box-selections[]"> Checkbox 3
</label>
</div>

File upload formatting in Bootstrap MVC

I have this in an MVC view
<form id="fileupload" action="#Url.Action("Save")" method="POST" enctype="multipart/form-data">
<div class="container">
<div class="row">
<div class="form-group">
<label for="datepicker1">Invoice Date</label>
<div class='bfh-datepicker' id='datepickerDiv'>
<input type='text' id="datepicker1" class="form-control" />
</div>
</div>
<div class="form-group">
<label for="InvoiceNumberTB">Invoice Number</label>
<input type="text" class="form-control" id="InvoiceNumberTB" />
</div>
<div class="form-group">
<label for="NetAmountTB">Net Amount</label>
<input type="text" id="NetAmountTB" class="form-control text-right" placeholder="0.00" />
</div>
<div class="form-group">
<label for="TaxAmountTB">Sales Tax</label>
<input type="text" id="TaxAmountTB" class="form-control text-right" placeholder="0.00" />
</div>
<div class="form-group">
<label for="InvoiceTotalTB">Invoice Total</label>
<input type="text" id="InvoiceTotalTB" class="form-control text-right" placeholder="0.00" />
</div>
<div class="form-group">
<label for="InvoiceDescriptionTB">Description</label>
<input type="text" id="InvoiceDescriptionTB" class="form-control" />
</div>
<div class="form-group">
<label for="DocumentUploadTB">Optional - Upload Invoice (PDF)</label>
<span class="btn btn-success fileinput-button">
<span>Add File...</span>
<input type="file" id="DocumentUploadTB" class="form-control" />
</span>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary"><span class="glyphicon glyphicon-plus-sign"></span> Save</button>
</div>
</div>
</div>
But the label for the file upload is not formatting as I would have hoped (at the top of the field as the others) but looks like this
Could someone point me in the correct direction?
Thanks
Wrap the content after the label in a form-control-static div and lose the form-control class on the input:
<div class="form-group">
<label for="DocumentUploadTB">Optional - Upload Invoice (PDF)</label>
<div class="form-control-static">
<span class="btn btn-success fileinput-button">
<span>Add File...</span>
<input type="file" id="DocumentUploadTB" />
</span>
</div>
</div>
You want your btn span to display as a block element. Try adding a display: block; style to it, or use a simple bootstrap utility class like .show:
<div class="form-group">
<label for="DocumentUploadTB">Optional - Upload Invoice (PDF)</label>
<span class="btn btn-success fileinput-button show">
<span>Add File...</span>
<input type="file" id="DocumentUploadTB" class="form-control" />
</span>
</div>
Example: http://codepen.io/kspearrin/pen/PqpgYq

angularjs ng-required not working on ios

I am trying to use the ng-required in a form.
All I did was add ng-required="true" on my input.
In Chrome, when clicking submit it prevents submission and asks the user to fill the field, as expected. On an iPhone, it doesn't show any error and it executes the submit function.
<form name="addGuest" ng-submit="GLCtrl.addGuest()">
<div class="form-group">
<label for="newGuestFirstName">First Name</label>
<input type="text" id="newGuestFirstName" ng-model="GLCtrl.newGuest.firstName" class="form-control" required="true"/>
</div>
<div class="form-group">
<label for="newGuestLastName">Last Name</label>
<input type="text" id="newGuestLastName" ng-model="GLCtrl.newGuest.lastName" class="form-control" required="true"/>
</div>
<div class="form-group">
<label for="arrivalDate">Arrival Date</label>
<div class="input-group">
<input type="text" id="arrivalDate" class="form-control" datepicker-popup="yyyy-MM-dd" ng-model="GLCtrl.newGuest.arrivalDate" is-open="opened" required="true" close-text="Close"
/>
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open($event)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</div>
</div>
<button type="button" class="btn btn-default" ng-click="GLCtrl.cancelAdd()"><i class="glyphicon glyphicon-remove"></i></button>
<button type="submit" class="btn btn-default"><i class="glyphicon glyphicon-ok"></i></button>
</form>
You need to check if the form is valid before proceeding to your form submission process. In regards to your problem, you are probably relying on HTML5's required attribute which is added when ng-required is true. This might work on chrome but it partially works in IOS.
See the note on this link
Partial support in Safari refers to lack of notice when form with required fields is attempted to be submitted. Partial support in IE10 mobile refers to lack of warning when blocking submission.
Solution:
Add novalidate in your form, don't use the HTML5 required attribute messaging which is only useful for some browsers. Show required error message explicitly.
Sample HTML implementation:
<form name="form" ng-submit="submit(form, user)">
<input type="email" required name="email" ng-model="user.email">
<div ng-show="form.email.$error.required>This field is required</div>
<input type="password" required name="password" ng-model="user.password">
<div ng-show="form.password.$error.required>This field is required</div>
<button type="submit">Login</button>
</form>
Sample Controller implementation:
$scope.submit = function(form, user) {
if(form.$valid) { // guard against any errors
// do you login process here..
}
};
Additionally, you can also use the ng-disabled approach to disable the submit button when when form is invalid.
<button type="submit" ng-disabled="form.$invalid">Login</button>
UPDATE:
This update takes into consideration that you are using twitter bootstrap3. By using the following classes: 'has-error' for form-groups and 'help-block' for showing the error messages. By using the ng-class and ng-show directives in showing the errors with angular form validation indicators mentioned in each angular input directives and the FormController and NgModelController documentation and also the guides shown in the developer's guide.
DEMO
HTML
<form name="form" ng-submit="submit(form, guest)" novalidate>
<div class="form-group" ng-class="{'has-error': form.firstName.$invalid && form.firstName.$dirty}">
<label class="control-label" for="newGuestFirstName">First Name</label>
<input type="text" id="newGuestFirstName" ng-model="guest.firstName" name="firstName" class="form-control" required="" />
<div ng-if="form.firstName.$invalid && form.firstName.$dirty">
<span class="help-block" ng-show="form.firstName.$error.required">This field is required</span>
</div>
</div>
<div class="form-group" ng-class="{'has-error': form.lastName.$invalid && form.lastName.$dirty}">
<label class="control-label" for="newGuestLastName">Last Name</label>
<input type="text" id="newGuestLastName" ng-model="GLCtrl.newGuest.lastName" name="lastName" class="form-control" required="" />
<div ng-if="form.lastName.$invalid && form.lastName.$dirty">
<span class="help-block" ng-show="form.lastName.$error.required">This field is required</span>
</div>
</div>
<div class="form-group" ng-class="{'has-error': form.arrivalDate.$invalid && form.arrivalDate.$dirty}">
<label class="control-label" for="arrivalDate">Arrival Date</label>
<div class="input-group">
<input type="text" id="arrivalDate" class="form-control" datepicker-popup="yyyy-MM-dd" ng-model="arrivalDate" is-open="opened" name="arrivalDate" required close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open($event)">
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
</div>
<div ng-if="form.arrivalDate.$invalid && form.arrivalDate.$dirty">
<span class="help-block" ng-show="form.arrivalDate.$error.required">This field is required</span>
</div>
</div>
<button type="button" class="btn btn-default">
<i class="glyphicon glyphicon-remove"></i>
</button>
<button type="submit" class="btn btn-default">
<i class="glyphicon glyphicon-ok"></i>
</button>
</form>
JAVSCRIPT
Controller Logic submit()
var fields = ['firstName', 'lastName', 'arrivalDate'];
$scope.submit = function(form, guest) {
if(form.$valid) {
// form is valid, do you form submission processhere..
} else {
angular.forEach(fields, function(field) {
form[field].$dirty = true;
});
}
};

Resources