Switching between partial forms using radio inputs - javascript

I have this template that depending on which radio input is clicked the form changes. The teacher-signup-form is checked by default.
<!-- when user clicks either teacher or student a different partial will render in view
each partial is wrapped in its own form element -->
<div class="container">
<div class="d-flex flex-row mt-5 mb-5">
<h2 style="font-family: 'champagne-limo';" class="">General Information:</h2>
</div> <!--teacher-student checkboxes -->
<div class="row">
<div class="col-4">
<h5>You are:</h5>
</div>
<div class="col-2">
<input checked name="teacher-student" type="radio" id="teacher-signup">
<label for="teacher-signup">Teacher</label>
</div>
<div class="col-2">
<input type="radio" name="teacher-student" id="student-signup">
<label for="student-signup">Student</label>
</div>
</div>
</div>
<!--this partial would have the id of 'teacher-signup-form' -->
<%-include("./partials/teacher-signup.ejs")%>
<!--this partial would have the id of 'student-signup-form' -->
<%-include("./partials/student-signup.ejs")%>
In my jQuery, I created a simple function that should switch the forms
$('#student-signup-form').hide();
$('#input[name="teacher-student"]:radio').on('change', function(){
$('#teacher-signup-form').hide();
$('#student-signup-form').show();
})
});
Unfortunately this does not work and shows both forms for a few seconds then hides the student-signup-form.
Is there a more cleaner efficient way to do this? My jQuery seems like it isn't the best solution.

I would suggest a few changes. First to hide the student-signup-form on page load you could add the css to do so.
#student-signup-form { display: none; }
Then in order to allow the toggle back and forth from student and teacher, what I would suggest is you give each form a class of signup-form in addition to the ids they have. Then your radio buttons could be changed to something like the following.
<input type="radio" name="teacher-student" class="signup-radio" id="teacher-signup" data-target="#teacher-signup-form" checked>
<input type="radio" name="teacher-student" class="signup-radio" id="student-signup" data-target="#student-signup-form">
Then you can generalize the change handler for the form class and the data element on the radios.
//cache the forms lookup
var $signupForms = $('.signup-form');
$('.signup-radio').on('change', function(e){
var $this = $(e.target);
//hide the forms that do not match the target selector
$signupForms.not($this.data('target')).hide();
//show the form that matches the target selector
$signupForms.filter($this.data('target')).show();
});

Set the initial state based on static CSS. Otherwise while the page is loading you will see both.
So set style display:none on the student partial.
Then your JS would just become
$('#input[name="teacher-student"]:radio').on('change', function(){
$('#teacher-signup-form').toggle();
$('#student-signup-form').toggle();
})
});

Related

how to toggle a specific div in javascript

i have dynamic data in my rails view, all divs have the same name; 'allData', which has alot of info, so i have it not displayed, i want to display that specific div and not all divs when i click show, but it shows all divs, i want to be able to show just that target div i clicked
$('.show'').on('click', (event) =>{
$('.allData').toggle();
$(event.currentTarget).closest('.allData').toggle();
})
<div class='eachData'>
<div class='header'>
<div class='show'> show</div>
<div class='numberOfdata'> 100</div>
</div>
<div class='allData; display:none'>
"foobar all data is here"
</div>
</div>
<div class='eachData'>
.......
</div>
<div class='eachData'>
.......
</div>
Your closest call is on the right track but you're not quite using it right. First you want to find the container (.eachData) that contains your <div class="show">, you use closest for that:
let container = $(event.currentTarget).closest('.eachData');
then you search within that container for the .allData you want to toggle by using find:
container.find('.allData').toggle();
So you use closest to go up the node tree and then find to come back down.
BTW, this:
<div class='allData; display:none'>
should be:
<div class="allData" style="display: none">
The class attribute contains CSS class names delimited by whitespace, raw CSS goes in the style attribute and is delimited by semicolons.
Your inline style on the div should be as follows:
<div class="allData" style="display: none">
Then try the following:
$('.show').on('click', function() {
$(document).find('.eachData .allData:visible').hide('fast');
$(this).parent().closest('.allData').show('fast');
});

Weird behavior using bootstrap toggle

I find my self having a really weird behaviour using jQuery steps and bootstrap toggle.
I really don't know if there's any connection between both but I know that there are at least many css problems if you're about to use jQuery plugins/extensions within jQuery steps.
I load content per ajax and use partial views using #Html.Render()
My problem:
If I don't load my html markup containing my toggles using ajax but place the code for toggle inputs directy in the (partial) view toggles won't work.
They are displayed correctly but simply don't react on any input.
If I do use ajax the toggles will not be displayed correctly without initializing per javaScript. If I do so they work but I don't want to always load my content using ajax.
Here is the code for the partial view:
<div class="form-horizontal">
<div class="form-group">
<div class="col-md-2">
</div>
<div class="col-md-6">
<div class="checkbox">
<label>
<input id="course" data-toggle="toggle" name="Rate.OfferingRates" type="checkbox" >
</label>
</div>
</div>
</div>
<div class="form-group">
<div id="offeringRateContainerSubscription">
<div class="col-md-2">
</div>
<div class="col-md-6">
<div class="checkbox disabled">
<label>
<input id="subscription" disabled data-toggle="toggle" name="Rate.OfferingRates" type="checkbox" value="#SlRateBaseTypes.Subscription">
</label>
</div>
</div>
</div>
</div>
</div>
<script>
$(function () {
// reached 2 times using #Html.Render()
debugger;
$('#course').bootstrapToggle({
on: 'Ja',
off: 'Nein'
});
$('#subscription').bootstrapToggle({
on: 'Ja',
off: 'Nein'
});
$('#course').change(function () {
debugger;
var isCourse = $('#course').filter(":checked");
if (isCourse.length) {
$('#subscription').bootstrapToggle('enable');
$('#subscription').parent().parent().parent().removeClass('disabled');
} else {
$('#subscription').bootstrapToggle('off');
$('#subscription').bootstrapToggle('disable');
$('#subscription').parent().parent().parent().addClass('disabled');
}
});
});
</script>
Moreover:
I placed a debugger mark in the javaScript in this partial view MyPartialView that initializes toggles
The debugger mark breaks two times when loading per ajax. I have no idea how this is possible.
I don't know if this is a problem either.
I just found the solution to the problem.
jQuery steps internally renders again.
Replacing the code in the .js file like suggested in
https://github.com/rstaib/jquery-steps/issues/42
worked for me!

Javascript modal that displays list that closes and returns to main html

Rather new to javascript, jquery and bootstrap, etc., so bear with me. I have a situation where I want to present a list of errors in a model dialog after the user hits a "validate" button. Got all the working - I am generating a list of objects that indicate to the user they need more work to the exact spot that needs additional data entry. I have the the DIV "id" that represents the field that needs more data (and each item will jump someplace different).I do not want a drop down list since there are be lots and lots of these items.
A few questions:
How do I go about jumping from the modal to the main html. I believe I have seen scrollIntoView mentioned in a few other posts as I was looking but will that hop to the DIV and also close the modal?
What construct should I use for the list? A list of scrolling button? The size of this can be quite large (hundreds) so it will need a scroll capability.
Finally, the app is "paged" with a next and prev buttons. I assume that will not be a problem from the aspect of jumping to a page not already displayed?
Here is the current modal code:
<script id="template-validation-error" type="text/x-handlebars-template">
<div id="validationErrorModal" class="modal">
<div class="message-container">
<div class="header">
Validation Errors
</div>
<div class="message">
The following fields are required:
</div>
<div class="center">
<input type="button" class="btn btn-solid-green btn-sm" onclick="fffdevice.validationErrorOk();" value="Done" />
</div>
</div>
</div>
</script>
and
showValidationError: function (fieldlist) {
settings.focusedField = $(':focus');
$("#validationErrorModal").detach();
$(".device-container").append(templates.validationerror({ fieldlist }));
$(".message-container input").focus();
},
validationErrorOk: function () {
$("#validationErrorModal").detach();
if (settings.focusedField) {
settings.focusedField.focus();
}
},
The field list is a list of objects that contain the id (field.id) of the DIV and also a description (field.fieldName) that I want to display.
Here is something I mocked up in paint...I am not sold on it but it show in a general sense what I am looking for:
I don't need a full solution rather, just want mechanisms I can use.
UPDATE
Just to help out anyone else in the future, using the info provided in the correct answer below I have a new code as follows:
<script id="template-validation-error" type="text/x-handlebars-template">
<div id="validationErrorModal" class="modal">
<div class="validation-container">
<div class="header" align="center">
Validation Errors
</div>
<div class="message">
<div class="scrolling-container" style="background-color: rgb(238, 238, 238); height:660px">
<div class="grid grid-pad">
{{#each fieldlist}}
<div class="row click-row" onclick="fffdevice.validationErrorFix('{{id}}');">
<div class="col-7-8 field-name">{{fieldName}}</div>
<div class="col-1-8">
<img class="pull-right" src="/mysite/Content/device/images/fix.png" style="width: 40px; position:relative; top: -5px;">
</div>
</div>
{{/each}}
</div>
</div>
</div>
<div><br/></div>
<div class="center">
<input type="button" class="btn btn-solid-green btn-sm" onclick="fffdevice.validationErrorOk();" value="Done" />
</div>
</div>
</div>
Then the Javascript for the onClick is:
validationErrorFix: function (id) {
$("#validationErrorModal").detach();
var x = document.getElementById(id);
x.scrollIntoView({
behavior: "smooth", // or "auto" or "instant"
block: "start" // or "end"
});
},
Which closes the dialog and jumps to the field. It looks like (I know this is ugly and I will clean it up later):
Bind the modal event to the validation code and show the modal if error(s) are found.
Display the modal with the list of errors using an html unordered list, inside the li element an anchor tag where the href attribute will have a value with the id that corresponds to the input field, all this done dynamically from your validation code.
Once an error in the list is clicked hide the modal using bootstrap $('#your-error-modal').modal('hide'); so the code would be something like this:
$('#your-error-modal').on('click', 'a.error-item', function(){
$('#your-error-modal').modal('hide');
});
I haven't tested this code, but if you're having issues with scrolling to the section of the input and closing the modal you can probably do something like this too:
$('#your-error-modal').on('click', 'a.error-item', function(e){ // use this method of onclick because your list will be created dynamically
e.preventDefault(); // prevent the default anchor tag action
var href = $(this).attr('href'); // grab the href value
$('#your-error-modal').modal('hide'); // close the modal first
scrollToDiv(href); // then take the user to the div with error with a nice smooth scroll animation
});
function scrollToDiv(location) {
$('html, body').animate({
scrollTop: $(location).offset().top
}, 2000);
}
Again this is untested code, but the idea is there.
For UX reasons you might also want to create a floating div or something where users can click on it and go back to the modal to continue reading your list of errors.

Handling button mdl-js styling with dynamic innerHTML change

Changing <button> innerHTML seems to deactivate mdl-js-ripple-effect.
Use the method mentioned here to dynamically build a new element as the workaround or report this as a bug?
<body>
<button id="myButton" class="mdl-button mdl-js-button mdl-js-ripple-effect">OLD VALUE
</button>
</body>
JS:
window.addEventListener("load", () => {
document.getElementById("myButton").innerHTML = "new value";
});
http://codepen.io/anon/pen/KVvMOE
Tried the componentHandler.upgradeElement(button) on the existing element after setting new html, but as mentioned in the docs it's only good for new ones. Trying to reuse existing elements.
I when the component is parsed and upgraded by the MDL script, a lot of extra attributes are added to the outer node, and extra HTML added inside. That means both that setting the innerHTML will remove some of the necessary markup inside and that the upgradeElement will fail because of the markup that was added to the outer node.
You should try de-upgrading the button with componentHandler.downgradeElements first, then set the innerHTML, then call componentHandler.upgradeElement.
Some untested sample code:
function setText(element,newtext){
componentHandler.downgradeElements(element);
element.innerHTML=newtext;
componentHandler.upgradeElement(element);
}
setText(document.getElementById('myButton'),'new value');
I'm having a similar issue. I'm trying to add some card via innerHtml into the page. The card contains a radio button using the class mdl-radio.
Everything seems to work fine, but the radio button doesn't load the style. I'm seeing a simple radio button not the styled one. If I add the card to the page from the beggining the radio button looks OK, as expected.
Any comment is welcome, I'm not sure how to fix this.
main.innerHTML = '<!-- CARD PREGUNTA-->\
<div class="demo-cards mdl-cell mdl-cell--4-col mdl-cell--8-col-tablet" style="margin: 0 auto; display: none;" id="pregunta_card">\
<div class="demo-updates mdl-card mdl-shadow--2dp mdl-cell mdl-cell--4-col mdl-cell--4-col-tablet mdl-cell--12-col-desktop">\
<!-- Contenido -->\
<div class="mdl-card__supporting-text mdl-color-text--grey-600">\
<h2 class="mdl-card__title-text" id="pregunta_card_title"></h2>\
<br>\
<br>\
<!-- Radio Button 1 -->\
<label id="opt1" class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="option1">\
<input type="radio" id="option1" class="mdl-radio__button" name="options"/>\
<!-- intitial state checked using attribute checked -->\
<span class="mdl-radio__label" id="option1_value"></span>\
</label>\
</div>\
</div>'

Jquery class is not responding to .click() despite being listed within selectors

I have some several labels on a webpage, that can be clicked, and all share the class 'btn'. In the console, if I use the selector $('.btn'); among others the following elements DO appear:
<label id=​"skillstable_Certification" class=​"row btn">​Certification​</label>​,
<label id=​"skillstable_Compliance" class=​"row btn">​Compliance​</label>​,
<label id=​"skillstable_Technology" class=​"row btn">​Technology​</label>​,
<label id=​"skillstable_version(s)​" class=​"column btn">​Version(s)​</label>,​
<label id=​"skillstable_startdate" class=​"column btn">​StartDate​</label>​,
<label id=​"skillstable_enddate" class=​"column btn">​EndDate​</label>​,
<label id=​"skillstable_elapsedtime" class=​"column btn">​ElapsedTime​</label>,​
<label id=​"skillstable_expertiserating" class=​"column btn">​ExpertiseRating​</label>,​
which matches the HTML:
</fieldset>
<label id="fs_skillstable_heading" class="fs btn heading skillstable">Skills Table</label><br class="">
<label id="skillstable_Certification" class="row btn">Certification</label>
<label id="skillstable_Compliance" class="row btn">Compliance</label>
<label id="skillstable_Technology" class="row btn">Technology</label><br class="">
<label id="skillstable_version(s)" class="column btn">Version(s)</label><br class="">
<label id="skillstable_startdate" class="column btn">StartDate</label><br class="">
<label id="skillstable_enddate" class="column btn">EndDate</label><br class="">
<label id="skillstable_elapsedtime" class="column btn">ElapsedTime</label><br class="">
<label id="skillstable_expertiserating" class="column btn">ExpertiseRating</label><br class="">
</fieldset>
however, these elements only are not registering with the $('.btn').on('click', function() {...}) function, which has a console.log() section to show that it has been clicked. They all have the .btn class, so I am totally lost here. I am trying to make an array to use for persistence, and made a quick variable with .push() to show all the elements I have clicked on so i can use that string to make a persistent URL, but noticed that these sections only are not registering.
The generation for the elements are scoped within a self calling function (function TCC() {...})();, so I tried pulling them out of that function and calling them individually, but that did not work either. I also switched the functions from .click() to .on('click', function(){}) to no avail.
Here is the webpage.
Try this; on() usage :
Edit: #David Thomas mentioned this.id; will be better than $(this).attr('id'); :
$(document).on('click','.btn',function() {
var whichPart = this.id;
console.log(whichPart);
});
Here is jsFiddle.
The issue occurs because you bind the click event, before the "column button generator" loop. Easiest fix would be to use a "live" event
$('.btn').live('click',function(){...})
Or alternatively, create a callback for the loop and bind the click event then.
You can test the sample code on following link:
http://jsfiddle.net/shivkant/ueHNg/4/
your page works in chrome for me, i clicked on Expertise/skills/tools etc in the left section and it shows the links i clicked in the orange section on the right if that is what you wanted.
It works in IE if console/developer tools is opened already, it might be because you used console.log statements in your code
Refer to this
What happened to console.log in IE8?

Categories

Resources