dygraphs setVisibility() with muiltiple plots on page - javascript

I've been working with dygraphs and have gotten a webpage working well with check boxes to toggle on and off visibility for a potentially infinite number of dygraphs on a page.
I am however now stuck when I've added buttons to set the values all on or all off.
I've found a basic example I've followed: http://dygraphs.com/tests/color-visibility.html which has the ID names of the check boxes 0-3. This works well with one plot, or even with multiple plots as long as I don't have to call the ID of the check boxes. I had the whole system working with repeating the ID numbers.
However when I add a button to automatically check the box I need uniquely identified check boxes or else it only checks and unchecks the first set of boxes. Then once I rename the check box ID the original visibility function doesn't work.
HTML:
<input type=checkbox id=0 onClick="change(this,plotname)" checked=true > A
<input type=checkbox id=1 onClick="change(this,plotname)" checked=true > B
<input type=checkbox id=2 onClick="change(this,plotname)" checked=true > C
<input type=checkbox id=3 onClick="change(this,plotname)" checked=true > D
<input id="all_On" type="button" value="All On" onclick="checkTheBoxes([true, true, true, true],<%= chartnumber %>)">
JS code:
function change(element,name) {
name.setVisibility(element.id, element.checked);
}
function checkTheBoxes(tfarray,section) {
for (var j = 0;tfarray.length;j++){
document.getElementById(j).checked = tfarray[j]
document.getElementById(j).onclick()
//I have been using the section input to identify plots with the renamed IDs
}
}
I believe the problem lies in the "this" call when passing through the change function. When I probe with Firebug the element is input#3 if I click check box number 3 and this works. However if I have renamed the ID something like plot2box3 the firebug element is input#plot2box3 which I believe the setVisibilty function doesn't know what to do with.
The question is then, how do I keep the "this" reference outputting the correct element while being able to uniquely call the check box.
Thanks!

Related

How can I hide this table row based on the value of an input field 4 levels down

I have a table with lots of rows
I have a filter to hide these rows based on the content of a child element (an input field) several levels down within the row
The input field within the row is wrapped several times. I can't manage to hide the row based on that inputs value.
Here's how a row looks:
<tr class="acf-row" data-id="row-13">
<td class="acf-field acf-field-date-picker acf-field-5de02ec006a2e" data-name="datum" data-type="date_picker" data-key="field_5de02ec006a2e">
<div class="acf-input">
<div class="acf-date-picker acf-input-wrap" data-date_format="dd.mm.yy" data-first_day="1">
<input type="text" class="input hasDatepicker" value="24.03.2020" id="dp1582735317447">
</div>
</div>
</td>
</tr>
Please note that there are more siblings on each level than I've put in here for readability. But the hierarchy is as displayed here.
Then I've got this input field to define what we want to filter:
<input placeholder="Datum filtern" type="text" id="datefilter" style="padding:5px; width:150px;">
And last but not least the jquery:
$( "#datefilter" ).change(function() {
var filterdate = $("#datefilter").val();
jQuery('.input.hasDatepicker').each(function() {
var currentElement = $(this);
var dateinfield = currentElement.val();
if( dateinfield !== filterdate){
$(this).closest('.acf-row').hide();
}
});
});
Currently it hides all the rows, not just those with a different value. What should happen is that only the rows get hidden where the value of #datefilter is different from the value of .input.hasDatepicker
I tried a few things like trying to use .parent().parent()... but didn't get it to work. Help would be greatly appreciated.
Here's a jsfiddle with the whole table including all siblings:
https://jsfiddle.net/59by3w7o/
UPDATE:
I think I can now say for sure the issue is 2 instances of the input element in each row. Here's a jsfiddle with only that and no noise:
https://jsfiddle.net/8k41xy6u/
How could I solve that? I tried playing with :first but couldn't get it to take the first within each .acf-row and not the very first in the whole document.
From the updated JSFiddle, a table row looks something like:
<tr class="acf-row">
<td>
<div class="acf-input">
<div>
<input class="input hasDatepicker" type="text" value="26.03.2020">
<input class="input hasDatepicker" type="text" value="10:00">
</div>
</div>
</td>
</tr>
And now the problem becomes clear. In the JS, .each() iterates over everything with the classes .input and .hasDatepicker. Both your inputs match that, so it will test both of them. If the value of the either one does not match your filterdate that row will be hidden. But the 2nd input value is a time, and that will never match a date, no matter what the date is - so every row will always be hidden.
There are 2 obvious ways to tackle this - 1) make the inputs distinguishable, so you can target just the date input in your filter comparison, OR 2) somehow target just the first input in the set of 2.
The first option (make them distinguishable) is by far the best, as the second relies on the layout of the HTML. It could happen in future that you'll do a redesign and the inputs won't be in the same order, or even in the same <div>, and then your JS will break. That might even happen without you doing it or even knowing about it if the HTML is autogenerated by some 3rd-party library (eg ACF/Wordpress), and a plugin update changes things. But if you can distinguish the inputs then you can target the right ones no matter where they are on the page.
To make them distinguishable, you could add a class, eg:
<input class="input hasDatepicker date" type="text" value="26.03.2020">
Then update your JS to target only those:
$('.input.hasDatepicker.date').each(function(i) {
If changing the HTML isn't an option, then you'll have to rely on and make use of position. Iterate instead over all div.acf-inputs, and find the first input in each:
$('div.acf-input').each(function(i) {
var dateinfield = $(this).find('input.input.hasDatepicker').first().val();
// ...
Working JSFiddle (of option 2).

How to get value from selected input field (not using id)

I try to do simple code for guessing notes by ear. I have tabs with several empty input fields and you need to put right numbers in these fields according to certain melody (for guitar fretboard) . One button shows first note, another button checks whether you put right or wrong number and depend on it approves or erase your number.
I know how to check every input field using its id's but can i do it such way that when i push 2nd button it get value from selected input and compare it to its placeholder or value attribute?
It is my codepen
https://codepen.io/fukenist/pen/BxJRwW
Script part
function showfirst() {
document.getElementById("fst").value = "12"
}
function show1other() {
var snote = document.getElementById("scnd").value;
if (snote == 9 ){
document.getElementById("scnd").value = "9";
}
else {
document.getElementById("scnd").value = "";
}
}
You can use document.querySelectorAll() to get all your inputs and loop over them.
Sample:
// Get all inputs as an array (actually NodeList, to be precise; but it behaves similar to an array for this use case)
var inputs = document.querySelectorAll('input');
// Function to reveal the first input's value
function showFirst(){
inputs[0].value = inputs[0].dataset.v;
}
// Function to check all values and clear input if wrong
function checkAll(){
inputs.forEach(function(input){
if(input.dataset.v !== input.value){
// Wrong answer, clear input
input.value = '';
}
});
}
<input data-v="12" size="2" value=""/>
<input data-v="9" size="2" value=""/>
<input data-v="8" size="2" value=""/>
<br/>
<button onclick="showFirst()">Show First</button>
<button onclick="checkAll()">Check All</button>
Notes:
I have used data-v to store the correct answer instead of placeholder as that attribute has a semantically different meaning
It may be out of turn but my two cents: Writing out entire songs like this by hand may become tedious. Consider using a JSON string or something similar to map out the tabs and use a templating framework to align them.. Some things you may need to look out for while designing something like this : Alignment of notes (successive notes, simultaneous notes), timing of the song, special moves like slide, hammer on etc.
It may be a better idea to make the Guitar Strings be a background element (either as a background-image or as absolutely positioned overlapping divs) (so You don't have to worry about the lines going out of alignment)
Reference:
HTMLElement.dataset
document.querySelectorAll

clear selected checkbox scope value

My HTML:
<div class="check" ng-repeat="point in dbs">
<input
name="db"
id="{{point.id}}"
ng-model="point.select"
ng-click="update($index, dbs)"
ng-checked="false"
type="checkbox"
ng-required="point.select" />
</div>
Whilst my update() function looks like:
$scope.update = function(position, dbs) {
angular.forEach(dbs, function(point, index) {
if (position != index)
point.select = false;
});
}
This works as with regards to tracking what the selected checkbox is, and sending into another controller that expects the value, all is working good.
However, when I go back from the resulting page, back to this search form again, somehow the checkbox I selected before, is preselected, and I don't want anything to appear, rather just have everything blank.
Would it be as easy as simply stating:
$scope.point.select = null;
as I can't seem to find a good solution for this, so that the checkbox is always blank / not pre selected when you arrive on this form.
Let me see if I get what you are doing. It looks like you are trying to make your list of checkboxes mutually exclusive. I might look at using a radio button list (a set of radio buttons with the same name attribute, HTML interprets this as a mutually exclusive list). If you create a variable which will hold the value of the selected option and pass that value around, you probably can achieve the same result with less code. Take a look here: https://jsbin.com/sunusihuse/edit?html,js,output
As for clearing the list of controls when you revisit the page, what I have described will do that too because the value of the variable which will hold the selected value is initialized to an empty string. Hope this helps.

Jquery get Checkbox in span

I have some jquery code where I am trying to select a checkbox when the user clicks on a div. My fiddle is below:
http://jsfiddle.net/5PpsJ/
What i have come up with is this, but it is not selecting the checkbox inside of the span:
$('span[name="' + current + '"]').closest('input:checkbox[id="CB_Selected"]').prop('checked', true);
The full code is in the link
My question is how can i get the select box inside of the span based on its unique name and select it?
n.b I have commented out the hide functio0n in jquery to visually see whether the checkbox is selected or not
EDIT
My ID's are the same because I am working inside of ASP.NET and using a repeater to create the HTML shown in the fiddle. Inside of Repeaters I can not set the ID of item as the Repeater control does not allow me to set the ID with Eval(datasource)
IDs are unique. All you need is this:
$("#CB_Selected").prop('checked', true);
Actually, you don't even need jQuery:
document.getElementByID('CB_Selected').checked = true;
As others have pointed out, it would be preferred to use a class rather than an ID if there are multiple checkboxes. In addition, an input cannot have children, so the closest function won't work; did you mean find (for children) or siblings?
Instead of giving several checkboxes the same ID -- which invalidates your html -- use a class on the checkboxes. Change:
<input id="CB_Selected" type="checkbox" name="ctl00$ContentPlaceHolder_Content_Wraper$ctl01$Repeater_Selected$ctl00$CB_Selected" />
To:
<input class="CB_Selected" type="checkbox" name="ctl00$ContentPlaceHolder_Content_Wraper$ctl01$Repeater_Selected$ctl00$CB_Selected" />
Then you can use the code:
$('#s_' + this.id).find(':checkbox.CB_Selected').prop('checked', true);

Show Input Box on Check

You can see in the paper form attached what I need to convert into a web form. I want it to show the check boxes and disable the input fields unless the user checks the box next to it. I've seen ways of doing this with one or two elements, but I want to do it with about 20-30 check/input pairs, and don't want to repeat the same code that many times. I'm just not experienced enough to figure this out on my own. Anyone know anywhere that explains how to do this? Thanks!
P.S. Eventually this data is all going to be sent through an email with PHP.
I don't think this is a good idea at all.
Think of the users. First they have to click to enter a value. So they always need to change their hand from mouse to keyboard. This is not very usable.
Why not just give the text-fields? When sending with email you could just leave out the empty values.
in your HTML :
//this will be the structure of each checkbox and input element.
<input type="checkbox" value="Public Relations" name="skills" /><input type="text" class="hidden"/> Public Relations <br/>
in your CSS:
.hidden{
display:none;
}
.shown{
display:block;
}
in your jQuery:
$('input[type=checkbox]').on('click', function () {
// our variable is defined as, "this.checked" - our value to test, first param "shown" returns if true, second param "hidden" returns if false
var inputDisplay = this.checked ? 'shown' : 'hidden';
//from here, we just need to find our next input in the DOM.
// it will always be the next element based on our HTML structure
//change the 'display' by using our inputDisplay variable as defined above
$(this).next('input').attr('class', inputDisplay );
});
Have fun.
Since your stated goal is to reduce typing repetitive code, the real answer to this thread is to get an IDE and the zen-coding plug in:
http://coding.smashingmagazine.com/2009/11/21/zen-coding-a-new-way-to-write-html-code/
http://vimeo.com/7405114

Categories