elclanrs / jq-idealforms-old

The ultimate framework for building and validating responsive HTML5 forms.
665 stars 95 forks source link

Add fields after intialization? #49

Closed dcampbell85 closed 12 years ago

dcampbell85 commented 12 years ago

Is it possible to add fields after idealforms initailization?

I am adding some checkboxes through ajax. And if they click the checkbox i wanted to add a file input.

elclanrs commented 12 years ago

Yes, you can do this already. Check out the documentation on addFields. There's also Youtube video showing this feature in action. Here's an example:

$myform = $('form').idealforms(options);

$('#mycheckbox').click(function(){
  var newFields = [{
    name: 'myfile',
    label: 'My File',
    type: 'file',
    addAfter: 'mycheckbox'
  }];
  if ($(this).is(':checked')) { 
    $myform.addFields(newFields); 
  } else {
    $myform.removeFields(['myfile']);
  }
});

The above will add or remove the fields that you want accordingly. Keep in mind that this method will have to refresh the form everytime the field is added or removed so it works but it's not perfect for performance but you can optimize it by adding multiple fields all in one call, that way it'll only refresh once.

There's another way of doing this with the setFieldOptions method that will be better for performance. Basically you just create a file field, hide it and remove it's filters. Then when the checkbox is checked you show the field and add the filters again. Check out this little demo (it only works in Chrome due to a weird bug in JSBin). Now try submitting the form with the input visible and hidden and it will alert how many invalid fields are there.

var $myform = $('#my-form').idealforms();
var $file = $('#file').hide(); // hide the file input

// remove the filters when it's hidden so the field
// doesn't count for the validation process
$myform.setFieldOptions('file', { filters: '' });

$('#toggle').change(function(){
  var isChecked = $(this).is(':checked');
  var filters = 'required file';
  $myform.setFieldOptions(
    'file', 
    { filters: isChecked && filters } // add filters if checked
  );
  $file.toggle();
});

Shouldn't be too hard to implement a utility function to do this on multiple items. Hope this helps.

dcampbell85 commented 12 years ago

The file input is not being required. Any ideas?

elclanrs commented 12 years ago

No idea, if you can post your code I can maybe take a look...

elclanrs commented 12 years ago

I took the snippet I posted above and added a new feature toggleFields. Together with addFields you get all you need to add/remove fields dynamically based on the situation.

cuongvo commented 12 years ago

Is there a reason textarea isn't a field type under addFields?

dcampbell85 commented 12 years ago

This is where I add the file inputs. @foreach (CarrierStateInfo state in ViewBag.States) { string divid = @state.State + "licensediv"; string inputid = @state.State + "license";

        }

And this is where I hide/show. For some reason toggle didn't want to work for me.

$(".state").button().click(function () {
    var options;
    var state = $(this).attr('name');
    var filters = 'required file';
    var inputname = state + 'license';
    var divname = state + 'licensediv';
    var isChecked = $(this).is(':checked');
    $idealform.setFieldOptions(
      inputname,
      { filters: isChecked && filters } // add filters if checked
    );
    //$('#' + divname).toggle();
    if ($(this).is(':checked')) {
        $('#' + divname).show();
        options = {
            icons: {
                primary: "ui-icon-check"
            }
        };
    } else {
        $('#' + divname).hide();
        options = {
            icons: {
                primary: null
            }
        };
    }
    $(this).button("option", options);
});

If you want this is the site so far http://12.230.140.205/Test/MVC/Contracting

dcampbell85 commented 12 years ago

Nevermind I figured it out. I added required as a class on the file input as they are created then I set all of them to no filters and hide the surrounding div. And the show the div when they select each state.

By the way when I tried the toggleFields('inputname') it hid everything in the body of my page, not just one control.

Also great project and great support!

elclanrs commented 12 years ago

I uploaded a couple fixes for toggleFields maybe that solves your issue. Keep in mind that for toogleField to work the field has to exist previously. You can of course create that field with addFields if you want.

Did you try debuggin' it? Did you get any errors in console?

elclanrs commented 12 years ago

I also added textarea to addFields.

dcampbell85 commented 12 years ago

I have another question. Is there a way to use a wild character for an input name or use a class for the setFieldOptions method?

ie - $myform.setFieldOptions( '.myclass', // or '*fileinputs' { filters: 'required extension', data: { extension: ['pdf'] } });

elclanrs commented 12 years ago

I don't quite understand. What are you trying to do?

dcampbell85 commented 12 years ago

It might be a bug. When I add fields and do not set any filters on them before initialization, it will not let me change them. So what I was doing was putting required as a class on the the controls and then I do

$('.statelicense').each(function () { //var inputname = $(this).attr('name'); $idealform.setFieldOptions( $(this).attr('name'), { filters: '' } ); });

this removes the required setting for all the file inputs. Then I have this to toggle them on or off.

$(".state").button().click(function () {
    var options;
    var state = $(this).attr('name');
    var inputname = state + 'license';
    var divname = state + 'licensediv';
    var isChecked = $(this).is(':checked');
    //var inputfilter =$.idealforms.forms.$0.options.inputs[inputname].filters;
    //$('#' + divname).toggle();
    //$idealform.toggleFields([inputname]); //this hides the entire page not just the control

    if (isChecked) {
        $('#' + divname).show();
         //inputfilter = inputfilter.append('required');
        //$('#' + inputname).addClass('required');
        $idealform.setFieldOptions(
          inputname,
          { filters: 'required extension', data: { extension: ['pdf'] } } // add filters if checked
        );
        //$idealform.setOptions({
        //    inputs: {
        //        inputname: {
        //            filters: 'required extension',
        //            data: {
        //                extension: ['pdf']
        //            }
        //        }
        //    }
        //});
        options = {
            icons: {
                primary: "ui-icon-check"
            }
        };
    } else {
        $('#' + divname).hide();
        //inputfilter = inputfilter.replace('required', '');
        //$('#' + inputname).removeClass('required');
        $idealform.setFieldOptions(
          inputname,
          { filters: '' } // add filters if checked
        );
        //$idealform.setOptions({
        //    inputs: {
        //        inputname: {
        //            filters: ''
        //        }
        //    }
        //});
        options = {
            icons: {
                primary: null
            }
        };
    }
    //$idealform.reload().fresh();
    $(this).button("option", options);
});
elclanrs commented 12 years ago

Oh I see... setFieldOptions only works with inputs that have been initialized with validation rules, if you want to add filters to an input that has no filters then use setOptions.

$myform.setOptions({ inputs: { 'myinput': { filters: 'required' } } })
dcampbell85 commented 12 years ago

Thanks that worked great.