0

Update

I have integrated the Type into Member Registration using some hints in Igor's Answer and searching stackoverflow. It doesn't work as intended as except for the first members type select other members type select elements are not triggering the registrationTypeChange function. Hence the first member's type works fine where as others aren't being displayed as intended.

Note : The first member's select works as intended in Chrome and IE but doesn't work in Firefox

Screenshots

member type year

member type period

As you can see when the second member's type is changed to "period" the related elements are not being displayed and it should be similar to the first member as both are of type "period". I have checked the regular expression I have used to find the number in id it works fine (Fiddle). I guess the error might be with the function registrationTypeChange. Can someone help me in fixing the code to work as intended in all browsers?

Fiddle

HTML

<div class="row">
    <fieldset class="frame-border">
        <legend class="frame-border">Members Registration</legend>
        <div class="alert alert-warning alert-dismissible" role="alert" id="memberMinAlert">
            <button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span>

            </button>Minimum one member is required.</div>
        <div class="row">
            <div class="form-group-sm required">
                <label class="col-xs-2 col-md-2"></label>
                <label class="control-label col-xs-2 col-md-3">Name</label>
                <label class="control-label col-xs-2 col-md-2">Type</label>
            </div>
            <div class="form-group-sm">
                <label class="control-label col-xs-2 col-md-2">1st Parameter</label>
                <label class="control-label col-xs-2 col-md-2">2nd Parameter</label>
            </div>
            <div class="col-xs-2 col-md-1"> <span class="glyphicon glyphicon-plus-sign big" id="memberAdd" data-toggle="popover" data-placement="right" title="Click to add a member."></span>
 <span class="glyphicon glyphicon-minus-sign big" id="memberRemove" data-toggle="popover" data-placement="right" title="Click to remove a member."></span>

            </div>
        </div>
        <div class="member-template">
            <div class="row">
                <div class="form-group-sm required">
                    <label class="control-label col-xs-2 col-md-2" id="registrationMemberLabel">Member</label>
                    <div class="col-xs-2 col-md-3"> <span class="help glyphicon glyphicon-info-sign" data-toggle="popover" data-placement="right" title="Name of the member."></span> 
                        <input type="text" id="registrationMemberName" class="form-control" placeholder="Enter Name">
                    </div>
                    <div class="col-xs-2 col-md-2"> <span class="help glyphicon glyphicon-info-sign" data-toggle="popover" data-placement="right" title="Type of the membership."></span>

                        <select id="registrationMemberType" class="type-selector form-control">
                            <option value="yearly" selected="selected">Yearly</option>
                            <option value="period">Period</option>
                        </select>
                    </div>
                    <div class="col-xs-2 col-md-2"> <span class="help glyphicon glyphicon-info-sign" id="registrationMemberParam1Help" data-toggle="popover" data-placement="right" title="Help"></span>

                        <input type="number" id="registrationMemberParam1" name="registrationMemberParam1" class="form-control" min="2014" max="3000" step="1" placeholder="Name">
                    </div>
                    <div class="col-xs-2 col-md-2"> <span class="help glyphicon glyphicon-info-sign" id="registrationMemberParam2Help" data-toggle="popover" data-placement="right" title="Help"></span>

                        <input type="number" id="registrationMemberParam2" name="registrationMemberParam2" class="form-control" min="2015" max="3000" step="1 " placeholder="Name">
                    </div>
                </div>
            </div>
        </div>
        <div id="memberContainer"></div>
    </fieldset>
</div>

JavaScript

function registrationTypeChange(memberNum) {
    var theValue = $('#registrationMember' + memberNum + 'Type').find("option:selected").text();
    if (theValue === "Yearly") {
        $('#registrationMember' + memberNum + 'Param1Help').attr("title", "Please provide the year of membership");
        $('#registrationMember' + memberNum + 'Param1').attr("placeholder", "Year");
        $('#registrationMember' + memberNum + 'Param2').hide();
        $('#registrationMember' + memberNum + 'Param2Help').hide();
    } else if (theValue === "Period") {
        $('#registrationMember' + memberNum + 'Param1Help').attr("title", "Please provide the starting year of membership");
        $('#registrationMember' + memberNum + 'Param1').attr("placeholder", "From");
        $('#registrationMember' + memberNum + 'Param2Help').attr("title", "Please provide the ending year of membership");
        $('#registrationMember' + memberNum + 'Param2').attr("placeholder", "To");
        $('#registrationMember' + memberNum + 'Param2').show();
        $('#registrationMember' + memberNum + 'Param2Help').show();
    }
}

function addMember() {
    var memberNum = $('.member').length + 1;
    var $html = $('.member-template').clone();
    $html.find('[id=registrationMemberLabel]').html("Member" + memberNum);
    $html.find('[id=registrationMemberLabel]').attr("id", "registrationMember" + memberNum + "Label");
    $html.find('[id=registrationMemberName]').attr("id", "registrationMember" + memberNum + "Name");
    $html.find('[id=registrationMemberType]').attr("id", "registrationMember" + memberNum + "Type");
    $html.find('[id=registrationMemberParam1]').attr("id", "registrationMember" + memberNum + "Param1");
    $html.find('[id=registrationMemberParam1Help]').attr("id", "registrationMember" + memberNum + "Param1Help");
    $html.find('[id=registrationMemberParam2]').attr("id", "registrationMember" + memberNum + "Param2");
    $html.find('[id=registrationMemberParam2Help]').attr("id", "registrationMember" + memberNum + "Param2Help");
    return $html.html();
}

function removeMember() {
    var memberNum = $('.member').length;
    if (memberNum > 1) {
        document.getElementById("registrationMember" + memberNum).remove();
    } else {
        $("#memberMinAlert").alert();
        $("#memberMinAlert").fadeTo(2000, 500).slideUp(500, function () {
            $("#memberMinAlert").alert('close');
        });
    }
}

function addMemberHTML() {
    $('<div/>', {
        'class': 'member',
            'id': 'registrationMember' + ($('.member').length + 1),
        html: addMember()
    }).appendTo('#memberContainer');
    registrationTypeChange($('.member').length);
}

$(function () {
    addMemberHTML();
    registrationTypeChange(1);
    $("#memberMinAlert").hide();
    $('#memberAdd').click(function () {
        addMemberHTML();
    });
    $('#memberRemove').click(function () {
        removeMember();
    });
    $(".type-selector").change(function () {
        var re = /(?:\d+)/;
        var num = event.target.id.match(re);
        registrationTypeChange(num);
    });
});

I need to manage form elements dynamically within a dynamic elements set. For example, I have a membership form which manages inputs (add, remove and change attributes) dynamically by clicking icons.(plus to add and minus to remove) which is designed based on this post.

member registration

The Type select in Member Registration is managing some elements (show, hide and change attributes) dynamically by changing options.

member type

member type

HTML

<div class="row">
    <fieldset class="frame-border">
        <legend class="frame-border">Type</legend>
        <div class="row">
          <div class="form-group-sm required">              
            <label class="control-label col-xs-4 col-md-4">Type</label>
            <label class="col-xs-4 col-md-4">1st Parameter</label>
            <label class="col-xs-4 col-md-4">2nd Parameter</label>
          </div>
        </div>
          <div class="row">
          <div class="form-group-sm required">
      <div class="col-xs-4 col-md-4">
      <span class="help glyphicon glyphicon-info-sign" data-toggle="popover" data-placement="right" title="Type of Membership."></span>  
        <select id="registrationMemberTypeSample" class="form-control" >
          <option value="yearly" selected="selected">Yearly</option>
          <option value="period">Period</option>
        </select>
      </div>
      <div class="col-xs-4 col-md-4">
            <span class="help glyphicon glyphicon-info-sign" id="registrationMemberParam1Help" data-toggle="popover" data-placement="right" title="Help"></span>
            <input type="number" id="registrationMemberParam1" name="registrationMemberParam1" class="form-control" min="2014" max="3000" step="1" placeholder="Name">
          </div>
      <div class="col-xs-4 col-md-4">
            <span class="help glyphicon glyphicon-info-sign" id="registrationMemberParam2Help" data-toggle="popover" data-placement="right" title="Help"></span>
            <input type="number" id="registrationMemberParam2" name="registrationMemberParam2" class="form-control" min="2015" max="3000" step="1 "placeholder="Name">
      </div>
      </div>
      </div>
      </fieldset>
    </div>
    <div class="row">
      <fieldset class="frame-border">
        <legend class="frame-border">Members Registration</legend>
        <div class="alert alert-warning alert-dismissible" role="alert" id="memberMinAlert">
          <button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
          Minimum one member is required.
        </div>
        <div class="row">
          <div class="form-group-sm required">
            <label class="col-xs-3 col-md-3"> </label>                
            <label class="control-label col-xs-4 col-md-4">Name</label>
            <label class="control-label col-xs-3 col-md-3">Type</label>
          </div>
          <div class="col-xs-2 col-md-2">
            <span class="glyphicon glyphicon-plus-sign big" id="memberAdd" data-toggle="popover" data-placement="right" title="Click to add a member."></span>
            <span class="glyphicon glyphicon-minus-sign big" id="memberRemove" data-toggle="popover" data-placement="right" title="Click to remove a member."></span>
          </div>
        </div>
        <div class="member-template">
          <div class="row">
            <div class="form-group-sm required">
              <label class="control-label col-xs-3 col-md-3" id="registrationMemberLabel">Member</label>
              <div class="col-xs-4 col-md-4">
                <span class="help glyphicon glyphicon-info-sign" data-toggle="popover" data-placement="right" title="Name of the member."></span>                      
                <input type="text" id="registrationMemberName" class="form-control" placeholder="Enter Name"> 
              </div>
              <div class="col-xs-3 col-md-3">
              <span class="help glyphicon glyphicon-info-sign" data-toggle="popover" data-placement="right" title="Type of the membership."></span>
                <select id="registrationMemberType" class="form-control" >
                  <option value="yearly" selected="selected">Yearly</option>
                  <option value="period">Period</option>
                </select>
              </div>
            </div>
          </div>
        </div>
        <div id="memberContainer"></div>
      </fieldset>
    </div> 

JavaScript

function registrationTypeChange() {
     var theValue = $("#registrationMemberTypeSample").find("option:selected").text();
     if(theValue === "Yearly" )
         {
         $('#registrationMemberParam1Help').attr("title","Please provide the year of membership");
         $('#registrationMemberParam1').attr("placeholder","Year");
         $('#registrationMemberParam2').hide();
         $('#registrationMemberParam2Label').hide();
         $('#registrationMemberParam2Help').hide();
         }
     else if(theValue === "Period" )
     {
     $('#registrationMemberParam1Help').attr("title","Please provide the starting year of membership");
     $('#registrationMemberParam1').attr("placeholder","From");
     $('#registrationMemberParam2Help').attr("title","Please provide the ending year of membership");
     $('#registrationMemberParam2').attr("placeholder","To");
     $('#registrationMemberParam2').show();
     $('#registrationMemberParam2Help').show();
     $('#registrationMemberParam2Label').show();
     }
}
function addMember() {
  var memberNum = $('.member').length+1;
  var $html = $('.member-template').clone();
  $html.find('[id=registrationMemberLabel]').html("Member" + memberNum);
  $html.find('[id=registrationMemberLabel]').attr("id", "registrationMember" + memberNum + "Label");
  $html.find('[id=registrationMemberName]').attr("id", "registrationMember" + memberNum + "Name");
  $html.find('[id=registrationMemberType]').attr("id", "registrationMember" + memberNum + "Type");
  return $html.html();
}

function removeMember() {
  var memberNum = $('.member').length;
   if(memberNum > 1 ) {
  document.getElementById("registrationMember" + memberNum).remove();
   }
   else {
       $("#memberMinAlert").alert();
       $("#memberMinAlert").fadeTo(2000, 500).slideUp(500, function(){
       $("#memberMinAlert").alert('close');
       });   
   }
}

function addMemberHTML(){
     $('<div/>', {
         'class' : 'member', 'id' :'registrationMember'+($('.member').length+1), html: addMember()
     }).appendTo('#memberContainer'); 
}

 $(function () {
     registrationTypeChange();
     addMemberHTML();
     $("#memberMinAlert").hide();
     $('#memberAdd').click(function () {
         addMemberHTML();   
    });
     $('#memberRemove').click(function () {
         removeMember();   
    });
     $("#registrationMemberTypeSample").change(function() {
            registrationTypeChange();
        });
     });

JS Fiddle

Now I need help to integrate the Type into Member Registration for all the member rows. I don't know to go about to achieve this. Can anyone guide me how to do this?

Community
  • 1
  • 1
Ram
  • 3,092
  • 10
  • 40
  • 56
  • 1
    You don't seem to have a problem in your code. You actually is asking us to code it for you. Maybe that's why you got a closing (and down) vote. – emerson.marini Dec 18 '14 at 16:46
  • I know that.I am just asking for adding comments to improve my post. I try to do the same when I downvote. I am not asking for the code I asking to guide me about how to do it as I can't wrap my head around how to code it. – Ram Dec 18 '14 at 16:48

1 Answers1

1

The guidelines:

  1. registrationTypeChange() works well to manage some fields.
  2. In the members registration you create selector assign special class to it, ex. <select class="type-selector" >
  3. Upon that class you hinge on() method, ex:

    ('.type_selector').on('change', function{... do stuff to change other inputs}).

  4. Inside of this function function{... do stuff to change other parameters }) the this(or $(this)) should refer to the particular type selector changed now by user (see docs for more clearance). So you trace its siblings/parents with jquery, ex: $(this).siblings(<selector optional>) thus being able to change/add other parameters settings only in this given row.

Feel free to ask if smth. is not clear.

Update

For point 4:

Your template:

 <div class="member-template">
      <div class="row">
        <div class="form-group-sm required">
          <label class="control-label col-xs-3 col-md-3" id="registrationMemberLabel">Member</label>
          <div class="col-xs-4 col-md-4">
            <span class="help glyphicon glyphicon-info-sign" data-toggle="popover" data-placement="right" title="Name of the member."></span>                      
            <input type="text" id="registrationMemberName" class="form-control" placeholder="Enter Name"> 
          </div>
          <div class="col-xs-3 col-md-3">
          <span class="help glyphicon glyphicon-info-sign" data-toggle="popover" data-placement="right" title="Type of the membership."></span>
            <select id="registrationMemberType" class="form-control" >
              <option value="yearly" selected="selected">Yearly</option>
              <option value="period">Period</option>
            </select>
          </div>
        </div>
      </div>
    </div>
  • $(this).parent('span') will hold the parent span of the select element (<span class="help glyphicon glyphicon-info-sign" data-toggle="popover" data-placement="right" title="Type of the membership."></span>)
  • $(this).parents('.row') will hold all the parents with class row , in our case it is the top parent in this row; see parents() of jquery
  • $(this).parents('.row').children('input') will hold the input element. See children() of jquery. By the way input's id should be unique since there going to be multiple of these rows.
  • Having this input you might handle it however you want (change type, clone etc.)

I did not test it, so you do tiny steps and console.log() or console.dir() the selected elements.

Update 2

Here is where you call registrationTypeChange() on type-selector change:

$(".type-selector").change(function () {
    var re = /(?:\d+)/;
    var num = event.target.id.match(re);
    registrationTypeChange(num);
});

because these type selectors are dynamical:

it doesn't work because it wasn't originally included in the page initialization.

So you need to hinge their functionality thru jquery on() method that:

Attach an event handler for all elements which match the current selector, now and in the future.

See my answer's update section to this kind of case.

Try this:

$(".type-selector").on('change', function () {
    var re = /(?:\d+)/;
    var num = event.target.id.match(re);
    registrationTypeChange(num);
});

Update 3

From this answer it states that this on method needs a selector parameter

otherwise the event is directly bound instead of delegated, which only works if the element already exists (so it doesn't work for dynamically loaded content)

So the code for binding should be

JQuery(document).on('change', ".type-selector" ,function () {
    ...
});
Community
  • 1
  • 1
Igor Savinkin
  • 5,669
  • 8
  • 37
  • 69
  • Thanks for the answer. I have understood the first 3 steps. In step 4, I didn't understand how to refer to the particular selector changed by the user and how to trace its [siblings](http://api.jquery.com/siblings/) as they are not select elements but input and span elements. – Ram Dec 18 '14 at 18:08
  • Thanks for the edit. I will try it and update you whether it is working or not. – Ram Dec 18 '14 at 18:30
  • @Sri, yes, do it. You might update your question with a new code and make known what works and what does not. – Igor Savinkin Dec 18 '14 at 18:32
  • @Sri, is the `num` value passed into the funciton? I'd suggest you to rewrite this function simplifying it. – Igor Savinkin Dec 21 '14 at 06:23
  • http://jsfiddle.net/ycvvj6u3/ a fiddle checking the num vale passed to a function. – Ram Dec 22 '14 at 14:59
  • @Sri, you use cloning method; but after you clone, can you check if created form elements (some are hidden) do exist? use web dev tools/firebug. – Igor Savinkin Dec 22 '14 at 15:03
  • I did check them they do exist and some are hidden – Ram Dec 22 '14 at 15:20
  • Can you please suggest a better title for my post? I think the title is not clear? – Ram Dec 22 '14 at 15:34
  • @Sri, if they exist, try to toggle their visibility by script apart from type field. You need to do tiny steps to find out where the process breaks. – Igor Savinkin Dec 23 '14 at 07:42
  • @Sri, I think since you create dynamic elements, they are not in original DOM, thus it's not easy to handle them. You need to do tiny steps to find out where the process breaks. Like inside of the function you `console.dir($(this).siblings())` to see all the elements the jquery sees inside a single row. Compare 1st row result with 2nd (where toggling doesn't work) row result. For better title you might add words: 'toggle', 'DOM elements', 'handle' – Igor Savinkin Dec 23 '14 at 07:48
  • @Sri, i seems to find the solution. See the last update. – Igor Savinkin Dec 24 '14 at 13:21
  • Sorry I couldn't test what you mentioned yesterday. Thanks I will try to check if it works – Ram Dec 24 '14 at 14:22
  • @Sri, you are welcome, i'm myself in the learning process. Want to share with you a gospel [video](https://www.youtube.com/watch?v=nlvOrTq4Bes) on man's third part. – Igor Savinkin Dec 24 '14 at 14:43