Binding lots of objects visibility in javascript. Managing the current state - javascript

I'm writing a website where the user would hit a button to start.
Depending on which button they push, a new section on the page will appear.
More buttons in this section - hit one of those buttons and one of a few sections will appear.
I have code which is starting to get really long and messy.
So I was looking for a cleaner/better way of managing what needs to be visible at any one time.
I want to avoid installing something like angular/react/knockout - because it seems like a lot of overhead for just 1 page on a large(ish) website. So ideally just naked javascript or jquery.
But i'd also like to avoid pages and pages of javascript full of $('div1').show(); $('div2').hide();
etc
And it is becoming difficult to manage them all.
I've created a fiddle so hopefully you can see what I am trying to accomplish (it's only about 1/5 complete but already looking a mess):
https://jsfiddle.net/6w4mfndf/
But basically it's looking like this at the moment:
<div name="Group1">
<input name="group1" type="radio" id="btn1" />
<span>1</span>
<input name="group1" type="radio" id="btn2" />
<span>2</span>
<div>
<div name="group2">
<div id="div_btn1" style="display:none">
<input name="group2" type="radio" id="btn1_1" />
<span>1_1</span>
<input name="group2" type="radio" id="btn1_2" />
<span>1_1</span>
</div>
</div>
<script>
$(function () {
$('#btn1').change(function() {
if ($('#btn1').is(':checked')) {
$('#div_btn1').show();
$('#div_btn1_1').hide();
}
});
</script>
I am working with MVC if there is any kind of way that can be used to help model the data out. (Unlikely I'd guess, but just throwing it out there).
Any solutions I am missing?

Why not try to have a class that is shared by all the buttons which triggers the js and a data attribute that informs the js as to which div of content to show?
Something along these lines for example:
<div class="content-block" id="content1">
Content 1
</div>
<div class="content-block" id="content2">
Content 2
</div>
<button class="content-button" data-content-block="content1" value="content 1"></button>
<button class="content-button" data-content-block="content2" value="content 2"></button>
<script>
$(function () {
$(".content-block").hide();
$(".content-button").click(function() {
$(".content-block").hide();
var contentBlock = $(this).attr("data-content-block");
$("#" + contentBlock).show();
});
});
</script>

Related

How to separate the content of a button into another HTML file?

I'm working on an HTML file that acts as its own page in an Electron App. In this file, I have a button, which shows a pop-up form upon clicking.
Here's the relevant code for the button and the content that pops up:
<button class="open-button" id="openConfig">Change Configuration</button>
<div class="modal-content" id="networkConfig">
<div class="modal-header">
<h2>Configuration Settings</h2>
</div>
<div class="modal-body">
<p>To get started, enter some initial information about the network you want to configure.</p>
<p>Leave the number of nodes as zero if you would like to start from scratch.</p>
<br />
<p>Number of nodes:</p>
<input type="number" id="nodeNumber" value="0" min="0" max="30">
<br /><br />
<p>Preference:</p>
<div>
<input type="radio" id="prefsecure" name="option" value="Secure" checked>
<label for="prefsecure">Secure (Recommended)</label>
</div>
<div>
<input type="radio" id="prefefficient" name="option" value="Efficient">
<label for="prefefficient">Efficient</label>
</div>
<br />
</div>
<div class="modal-footer">
<button type="submit" class="btn">Start Configuration</button>
<button type="button" class="btn cancel" id="closeConfig">Cancel</button>
<br /><br />
</div>
</div>
Also, here are the relevant javascript functions that allow me to open/close this pop-up:
function openForm() {
document.getElementById("networkConfig").style.display = "block";
}
function closeForm() {
document.getElementById("networkConfig").style.display = "none";
}
document.addEventListener('DOMContentLoaded', function () {
document.getElementById('openConfig')
.addEventListener('click', openForm);
});
document.addEventListener('DOMContentLoaded', function () {
document.getElementById('closeConfig')
.addEventListener('click', closeForm);
});
What I would like to do is take that content that pops up when the button is clicked (the button's id="openConfig") and put that into a separate HTML file (the id of the content I want in a separate file is "networkConfig"). This is to help compartmentalize my code. How can I make the button refer to this other file? Anyone has any leads? I would greatly appreciate any help at all!
Also, I apologize if I've made any mistake while posting this. It's my first post to stackoverflow, and I haven't been able to find what I'm looking for these past few days. Thank you for reading!
If i got it right, the way for you to do that is to either POST the content you want to reuse somewhere, initializing an empty variable, adding the markdown and thus being able to prompt it elsewhere, or save a temporary file containing the markup (insecure).

How can I check a radio button with no id using a single line of javascript (no jQuery)?

All right, this is a pretty specific question from a beginner, so bear with me.
I'm a newbie just learning the ropes. Here's the background (skip to next para if you don't care): I'm updating my first android app and I'm using MIT App Inventor 2 to do it. It's a free tool online that uses a WYSIWYG screen editor and Blockly to create behaviors, interactions, etc. The app I'm making loads a specific web page with a form and fills out most of the form for you (specifically, it's to help people enter the online ticket lottery for a theater show). The page is not my own so I can't edit the HTML. But I can run javascript on top of it by plugging single lines of javascript code into the Blockly side of App Inventor. Here's a relevant example of how it looks.
I've figured out how to fill in most of the form using getElementByID(). But there's a set of radio buttons that have no id. Here's a lightly modified version of the HTML (which I cannot edit):
<div id="cont_id_tickets">
<div>
<input type="radio" name="tickets" value="1" />
<span style="font-family:Times New Roman; font-size:15px;">1</span>
</div>
<div>
<input type="radio" name="tickets" value="2" />
<span style="font-family:Times New Roman; font-size:15px;">2</span>
</div>
<div id="required_info_tickets" class="requiredInfo floatLeft">
</div>
<input type="hidden" name="reqField" value="tickets" alt="Radio" req="true" errorMsg="Please enter a valid value." requredErrorMsg="This field is required. Please enter a value."
patternID="0" customRegex="" />
</div>
I've made some progress by using the following:
document.querySelector('input[name=tickets]').checked = true;
But that of course only selects the first radio button. I'd like to able to get a value (1 or 2) and have it select the right button accordingly. The Blockly backend I'm using allows me to define a variable to plug into the line of javascript, but the line of javascript itself has to be essentially a single line. I was hoping one of the following would work if I wanted the value to be 2 for example:
document.querySelector('input[name=tickets][value=2]').checked = true;
document.querySelector('input[name=tickets]').2.checked = true;
But neither does. Any ideas on the correct syntax?
Thank you!
You need to place the value that you are trying to select using in quotes:
document.querySelector('input[name=tickets][value="2"]').checked = true;
Example
document.querySelector('input[name=tickets][value="2"]').checked = true;
<div id="cont_id_tickets">
<div>
<input type="radio" name="tickets" value="1" />
<span style="font-family:Times New Roman; font-size:15px;">1</span>
</div>
<div>
<input type="radio" name="tickets" value="2" />
<span style="font-family:Times New Roman; font-size:15px;">2</span>
</div>
<div id="required_info_tickets" class="requiredInfo floatLeft">
</div>
<input type="hidden" name="reqField" value="tickets" alt="Radio" req="true" errorMsg="Please enter a valid value." requredErrorMsg="This field is required. Please enter a value." patternID="0" customRegex="" />
</div>

Uncheck other checkboxs when one is checked

Ok I have been building this nutrition plugin for wordpress, trying to find a solution for this simple task that a couple of lines of js should work.... just to uncheck the other check boxes when one is checked.
I have 4 input's nested in div's as per this:
<div class="nutrition-mc-group nutrition-mc-group-activity-level">
<div class="nutrition-mc-selection-box">
<div class="nutrition-mc-checkbox-outter">
<input type="checkbox" id="squared-checkbox1">
<label class="nutrition-mc-checkbox" id="mc-sedentary-select" for="squared-checkbox1"></label>
</div>
<p class="nutrition-mc-notes nutrition-mc-notes-switch">Sedentary</p>
<p class="nutrition-mc-description">Typical desk job / Sitting most of the day</p>
</div>
<div class="nutrition-mc-selection-box">
<div class="nutrition-mc-checkbox-outter">
<input type="checkbox" id="squared-checkbox2">
<label class="nutrition-mc-checkbox" id="mc-lightly-active-select" for="squared-checkbox2"></label>
</div>
<p class="nutrition-mc-notes nutrition-mc-notes-switch">Lightly Active </p>
<p class="nutrition-mc-description">Walking around a good amount, retail jobs</p>
</div>
<div class="nutrition-mc-selection-box">
<div class="nutrition-mc-checkbox-outter">
<input type="checkbox" id="squared-checkbox3">
<label class="nutrition-mc-checkbox" id="mc-moderately-active-select" for="squared-checkbox3"></label>
</div>
<p class="nutrition-mc-notes nutrition-mc-notes-switch">Moderately Active</p>
<p class="nutrition-mc-description">Walking constantly in a fast paced environment, waiting tables</p>
</div>
<div class="nutrition-mc-selection-box">
<div class="nutrition-mc-checkbox-outter">
<input type="checkbox" id="squared-checkbox4">
<label class="nutrition-mc-checkbox" id="mc-vigorously-active-select" for="squared-checkbox4"></label>
</div>
<p class="nutrition-mc-notes nutrition-mc-notes-switch">Vigorously Active</p>
<p class="nutrition-mc-description">Very labor intensive, construction workers</p>
</div>
</div>
Now the js is a little different, I have tried to simplify it as much as possible:
this.allActive = this.mod.find( '.nutrition-mc-group-activity-level input');
_init: function(){
this.allActive.on('change', $.proxy( this._uncheckActivityBtn, this ) );
},
_uncheckActivityBtn: function(){
$(this.allActive).not(this).prop('checked', false);
},
It runs fine, but its like it is not recognizing the not(this) part argument.
if I change the .prop to true it changes the argument and all the inputs become checked when checking one. I cant figure out why it is not understanding the this part of the argument and not excluding the currently selected box.
I tried to just move everything in the one function but when doing a debug the output gave an error for the not(this) operator, saying something about it being unspecified.
We had similar requirement in our project and we turned up using radio button. Just change the styling as per your style guide.
Note: all radio button inputs must have the same name.

Parsing html code with jQuery

I'm using the new material-design-lite (mdl) on my website. I'm also loading in dynamic content using mustache.js.
Now, the newly created elements need to be registered with using the upgradeElement function for mdl to know of them and apply the javascript to them. On their website they have some sample code to do this:
<div id="container"/>
<script>
var button = document.createElement('button');
var textNode = document.createTextNode('Click Me!');
button.appendChild(textNode);
button.className = 'mdl-button mdl-js-button mdl-js-ripple-effect';
componentHandler.upgradeElement(button);
document.getElementById('container').appendChild(button);
</script>
However, I am using jQuery and I'm not entirely sure how I should parse the whole template I get from mustache.js and register each component correctly. This is what I've tried:
var filledTemplate = '
<div class="mdl-card mdl-shadow--2dp">
<div class="mdl-card__title">
<h2 class="mdl-card__title-text">Title</h2>
</div>
<div class="mdl-card__supporting-text">
<p>A simple paragraph with below some radio buttons</p>
<p>
<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="input_0">
<input type="radio" id="input_0" class="mdl-radio__button" name="options" value="radio1" />
<span class="mdl-radio__label">Radio button 1</span>
</label>
</p>
<p>
<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="input_1">
<input type="radio" id="input_1" class="mdl-radio__button" name="options" value="radio2" />
<span class="mdl-radio__label">Radio button 2</span>
</label>
</p>
</div>
<div class="mdl-card__actions mdl-card--border">
<a class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">
Send
</a>
</div>
</div>';
var html = $.parseHTML(filledTemplate);
$(html).find(".mdl-js-button").each(function(){
componentHandler.upgradeElement($(this));
});
The filledTemplate is just to give a clear idea of the stuff it can contain. I need to bind all input's, textareas, sliders, radios, checkboxes and a button. In the example above you can see a simple card-layout from mdl, with two radio boxes and a button.
I tried to get the componentHandler to upgrade the button-element first, but mdl returns element.getAttribute is not a function, so I guess I'm just giving the wrong value to .upgradeElement().
What am I doing wrong here?
Here is a codepen as an example: http://codepen.io/anon/pen/JdByGZ
Try componentHandler.upgradeElement(this, 'MaterialButton'); if you want just to update the button or componentHandler.upgradeAllRegistered(); to update all elements.
http://jsbin.com/tuluda/4/edit?js,output
I have structured my app as a general container and a set of views, loaded with jQuery and rendered with Hogan. I am invoking componentHandler.upgradeDom() after inserting templates and is seems to work fine.
I guess this might be optimized further, upgrading on a smaller granularity, but this simple minded approach works fine in my Phonegap application.
The variables tmpl and content are there to ease debugging, otherwise the code might be made more compact.
app.render = function(template, data, destination) {
$.get(template, function(html) {
var tmpl = Hogan.compile(html);
var content = tmpl.render(data);
$(destination).html(content);
componentHandler.upgradeDom();
});
};

Making certain questions appear on an html form through jQuery?

I'd like to say thanks to the community. You've been a tremendous help so far.
Here's my latest question: I'm designing an online submission form, and one of the questions is a yes/no question with radio buttons. If the lead answers yes, I want a certain question to display. If they answer no, a different question will be displayed instead.
I looked at a few other answers and was able to scrape together some jQuerym but it doesn't seem to be working for me. Here is my javascript and a jsfiddle with the rest of my code.
$(function() {
$('input[type="radio"]').click(function() {
if($(this).attr('id') == 'yes') {
$('#ifyes').show();
} else {
$('#ifno').show();
}
});
});
http://jsfiddle.net/yrktj4kz/
Any help would be appreciated!
Looking at the fiddle, you should use
$('.ifyes').show();
and
$('.ifno').show();
instead.
You were using the id's of the input fields to show the element instead of the class of the wrapping div to which the display: hidden; style was applied.
I have updated your code
HTML:
<li>
<label for="coverage">K. Do you have current coverage?</label>
<input type="radio" name="choice" class="radio-toggle" data-target=".ifyes" data-target-group=".ifdiv" /> Yes
<input type="radio" name="choice" class="radio-toggle" data-target=".ifno" data-target-group=".ifdiv" /> No
</li>
<li>
<div class="ifyes ifdiv">
<label for="ifyes">When does the policy expire?</label>
<input type="text" id="ifyes" name="ifyes" value="" />
</div>
<div class="ifno ifdiv">
<label for="ifno">When do you need the policy to take effect?</label>
<input type="text" id="ifno" name="ifno" value="" />
</div>
</li>
and JS:
$(document).ready(function(){
$('.radio-toggle').click(function() {
$($(this).data('targetGroup')).hide();
$($(this).data('target')).show();
});
});
Obviously you need to call the jQuery library.
This is the complete and updated fiddle: http://jsfiddle.net/yrktj4kz/1/
Note that i'm using html data attribute to optimize the js code.

Categories