Using Rails and Formtastic to make a dynamic form - javascript

I am trying to make a very simple dynamic form. I am using Rails 3.1 and formtastic. Basically, I want to change a couple of fields based on a radio button.
It would look something like..
What kind of a shape are you making?
(Radio Button with a choice of square or rectangle)
If square is selected one new field for size is displayed. If rectangle is selected two fields are displayed for size.
The table will actually have only one size column, so the model will munge the potentially two fields into one before the ultimately hit the database (i think, still working on this issue as well)
Anyway, it is my understanding that I would need to use javascript in order to change the form. I am pretty javascript illiterate and really don't understand how to use it with formtastic. Any pointers would help.
Thanks!

Yes, you should use js to do that. If you're new to js don't hesitate and learn jQuery, it's becoming sort of js standard for rails now.
To do what you want you should display both size fields in your view and show/hide second field depending on radio values. It can be something like that:
$(function() {
var $radios = $("input[name=radioName]");
var $size2 = $("#size_field_2");
function toggleSizeField() {
$size2.toggle($radios.filter(":checked").val() == 0);
}
$radios.click(toggleSizeField);
toggleSizeField();
});

Related

Django Dynamic formset: correct usage with inline formsets?

I am using Django Formsets to make invoices (need to add items, people, materials etc.). To be able to add and delete formsets, I am using Django Dynamic Formset. However, this plugin seems to be no longer maintained and while it seems to work fine for modelformsets, the problem arises with inline formsets.
I am using this logic to select the number of extra forms I need for the view(where you can modify your invoice)
costi_offerta_inline = forms.inlineformset_factory(offerta_impianti,
offerta_impianti_costi,
form=offerta_impianti_costi_form, extra=0)\
if (offerta_impianti_costi.objects.filter(offerta_ref=instance).count() > 0) \
else forms.inlineformset_factory(offerta_impianti, offerta_impianti_costi,
form=offerta_impianti_costi_form, extra=1)
Problem is that doing this(it's probably not the reason, but you never know) the formsets act weird. If I add a new form, it works fine. Total Forms updates adding plus one and form is displayed correctly. But when I try to remove one, Total Forms doesn't decrement and I'm left with an extra form that blocks all validation from happening.
Can someone help me?

Multy-filter page with transitions - Isotope & Quicksand JS problems

(note: edited since I've just realized the question are somehow correlated, at least in my mind!)
I want to create a multi-filter page in which the result will be animated...
I'm trying with 2 different plugin (quicksand and Isotope) and with both solution I'm having problems...
---ISOTOPE--- (original)
With Isotope I need to filter data based on active class, or based on IDs of filters, which I've already stored in JS, does anyone know how can I do that?
I set up a page with 2 different filter like 'color' (red, blue, orange...) and 'type' (square, round...)
I already have a Javascript that assign class active to the 2 filtering lu based on selection, if all color are selected shift the 'active' class to 'all', and more than one sub-filter can be activated. And this also save the list of the id of the active li items in a string for color filter and another string for shape filter
I also already set up the page like the combination filter Isotope demo at this link: http://isotope.metafizzy.co/demos/combination-filters.html and it is working fine but doesn't allow to select more than one sub-filter at the same time.
I saw the demo at this link http://fiddle.jshell.net/desandro/JB45z/ with filtering combination, but it is based on radio button that I'd like to avoid.
I'm not sure if what I'm trying to do is easy or not... is like, how to tell to Isotope to filter based on the sub-filter that have active class or based on the sum of the li with the ID saved in my two string?
Thanks for any help, as you can easily understand I'm not skilled in js at all and english is not my first language!
--- QUICKSAND --- (edited)
I've just realized that I didn't explain why I stored the IDs of the selected items in the js string. And this is also about the different js question.
I was trying to set up the same system with Quicksand instead of Isotope.
But since quicksand need to have a starting li and a destination li to display the animation I set up the js to pass an array to a different temporary php page that use the array to display a destination li.
All until here is working fine but I'm not able to get back the li data in the original page to let Quicksand perform the animation. The last part of my js appear to have problems that I'm not able to fix (too many days trying with no success), the last part of the js is:
$.post( 'destination_li_filtered.php', {
colorString,
shapeString,
$('#ids').attr('val')
},
function(data) { // should contains the resulting data from the request (?)
$('.list').quicksand( $(data).find('li'),
{ adjustHeight: 'auto' },
function() {
callbackCode();
}
);
e.preventDefault();
});
the external page destination-li-filtered is displaying the results but the original page is not able to take back the data...
Obviously I need to set op the page with isotope or quicksand, not both.
but I'm also wondering witch is the best plugin to display 100's of results with about 20 filters (without considering the combinations). And of course, which is the easiest to use!
You should see the radio button and the change in view as separate things.
It's a common misconception that you should store all your state in the DOM (ie. which checkbox is checked). The DOM is a view, you don't keep state in a view.
You should have a state that lives in your JavaScript.
Like:
var state = "all_selected"; // green, red, blue
Then, when you check the radio button, it will set the appropriate state and update the list (show/hide elements based on state).
This allows you to make any control you want, be it a radio button, a checkbox or something completely custom.

jQuery searchable checkbox list and tristate checkbox

I'm building a simple asp page on which I have list of peoples with checkbox on left of every name.
I've managed to create a simple jQuery script that allows hiding and showing rows of table based on input:
http://jsfiddle.net/Tq97v/ (first part)
As You can see I can enter part of name and then specific row are hidden.
Using red "x" I can uncheck all checkboxes.
What I'm trying to do now is to change that static red "x" into tristate checkbox.
Don't have idea how to even start.
Do I must add change listener to every checkbox in my list?
Second thing - how to create multiple instances of the same "plugin" on site.
Right now I'm identifying input by it, but it would be nice to call function with that input as param, and it would fine table after that input and create necessary logic.
This way I could call function multiple times on page to have more than one list.
I'm not asking for whole solution (of course it is always welcome :) ) but what I need is idea how to accomplish this in efficient way and as optimized as possible, because sometimes my list has 500+ elements.
P.S. don't look at HTML code, it is ASP generated.
I found this plugin: https://github.com/bcollins/jquery.tristate, but I have no idea how to use it with my list.
UPDATE:
I've managed to turn my code into functions, but right now I must call 3 functions for every list.
Here is my updated code: http://jsfiddle.net/65MEV/4/
How can I change it to one function? Will it be better?
This is my updated code. Still thinking about way of doing that Indeterminate Checkbox instead of my remove image.
UPDATE2
I build working code :)
http://jsfiddle.net/65MEV/9/
But I would like to improve it as much as possible.
Any suggestions are welcome!
A tristate checkbox is like the Three-Portal Device: an illusion.
What you actually want is to make the checkbox indeterminate (by setting the property of the same name to true). To implement this, you will need a change (or click) handler on each checkbox, then you'll need to check if all of them are in the same state, and if not then you set the indeterminate property. It's a hassle, really, because you rarely see indeterminate checkboxes and so most users don't know what to do with them. To be avoided, if possible.
To create multiple instances of the same plugin access elements relatively to an other element.
For example: in your case instead of keeping the item in a jQuery object var $tableRows = $('table.myList tr'); access them in the event.
$('#user_name').keyup(function () {
var sValue = $.trim($('input#user_name').val());
if(lastInput==sValue) return;
var $tableRows = $(this).next().next().find("table.myList tr");
if (sValue == '') {
$tableRows.show();
} else {
$tableRows.each(function () {
var oLabel = $(this).find('label');
if (oLabel.length > 0) {
if (oLabel.text().toLowerCase().indexOf(sValue.toLowerCase()) >= 0) {
$(this).show();
} else {
$(this).hide();
}
}
});
lastInput=sValue;
}
});
and you only have your actual list.
And for the tree state checkbox you don t need a plugin just add a button or link and every click check it status you can keep the status by jQuery data and change the element image according to this data.

How to design dynamic form?

I want to design form with many fields. Some fields are dependent on the first drop-down list.
How to design to show only those that are needed?
You should hide those that you might not be needed in CSS.
Then, you should create some javascript to show/hide fields depending on the value of the select. Example with jQuery:
$('select[name=yourselect]').change(function() {
switch($(this).val()) {
case 'someval':
$('input[name=somefield]').show();
$('input[name=someotherfield]').hide();
break;
// add as many cases as you want, one for each value
}
})
// this is useful when your select has an initial value,
// to show/hide the fields depending on the initially selected option
$('select[name=yourselect]').trigger('change');
You can also make server side checks with your form clean() method.
If you want to make a dynamic form in multiple steps in which second form depends on first forms values then you can use Django Form Wizard. This is good if you don't want to use jquery. In this way you can also apply customized clean function for individual forms.
Check the form wizard documentation. I hope this will be useful for you.

MVC3 - jQuery datepicker when multiple elements have the same ID

I have a weird situation (don't we all?) with datepickers and want to get some advice.
I have a screen with a list of Locations, and for each Location, they can click Edit and edit that location. The Edit displays below the Edit link, and they can edit multiple locations at one time. This means the same View is rendered on the screen multiple times, and therefore multiple fields will exist with the same id (editing 4 locations will result in 4 "DateOpened" fields).
So, when I load my View, javascript adds datepickers to any fields that need it like so:
$(document).ready(function () {
var elements = $(".NeedsDatePicker > td > input");
$(".NeedsDatePicker > td > input").datepicker();
$(".NeedsDatePicker").removeClass("NeedsDatePicker");
});
Works fine, but, as you've probably already figured out, when I click a date on the calender, it populates the first "DateOpened" field when multiple Edit windows are open.
Is there a way to tell the datepicker to use the field WITHIN a certain parent, like you can for general jQuery selects?
$("#DateOpened", "Location-134").doWhatever...
...or is there a way to give the fields different id's without breaking MVC's UpdateModel() function? Or any other advice?
You should definitely keep IDs unique within an HTML DOM. Most, if not all, DOM manipulation libraries/frameworks, including jQuery, have this assumption built-in.
There are a few questions on SO WRT to avoid the same IDs in the form:
two forms with same input id in asp.net mvc
how to prevent html input id duplication on asp.net mvc 3 when a model contains multiple elements

Categories