JS - Style Change Issue - javascript

Having an issue with my script, Its meant to show a button if it gets into the ELSE meaning if the Season Episode name isnt found then show the button, But for some reason it always shows it once I change my tag's value. It's meant to only show if its not a value that can be found.
JS:
function season1episodesChange() {
var s1_episodes = JSON.parse(document.getElementById('s1_episodes').value);
var selectseason1episode = document.getElementById('selectseason1episode');
for (var i = 1; i <= s1_episodes.length; i++){
if (selectseason1episode.value == s1_episodes[i - 1]){
document.getElementById('season1episode' + i).style.display = 'inline-block';
} else {
document.getElementById(['season1episode' + i].join('')).style.display = 'none';
document.getElementById('notuploadedyet').style.display = 'inline-block';
}
}
}
Update:
Tried adding:
document.getElementById('notuploadedyet').style.display = 'none';
In the if {} bit but now it seems to only hide when im on the last value or first value it will open and stay open in all other values.

By the discussion, the logic is:
Loop through the possible options value, then:
Hide all not matched elements.
If no element match, show notuploaded button.
If an element match, show the episode if it exist, otherwise, show notupload button, so the code can be:
function season3episodesChange() {
var s1_episodes = JSON.parse(document.getElementById('s1_episodes').value);
var selectseason3episode = document.getElementById('selectseason3episode');
//Setup the Flag.
var notuploaded = true;
var targetEle;
for (var i = 1; i <= s1_episodes.length; i++){
// Get the element to show first.
targetEle = document.getElementById('season3episode' + i);
// Only check match if the element to match exist
// So even if it match, it won't see notuploaded to false.
if (targetEle !== null) {
if (selectseason3episode.value == s1_episodes[i - 1]){
document.getElementById('season3episode' + i).style.display = 'inline-block';
// Hide the button when : there's exist an element which match the select.
notuploaded = false;
} else {
// Hide the not matched but exist elements.
document.getElementById(['season3episode' + i].join('')).style.display = 'none';
}
}
}
//Using the flag decide to show the notuploaded button or not;
document.getElementById('notuploadedyet').style.display = notuploaded ? 'inline-block' : 'none';
}

Related

js, get element from text-offset/text-position?

I am trying to parse and reformat some web page.
The text is well formatted but the DOM structure is not (generated from WYSIWYG editor).
Thus I would like to parse the text content, then find back corresponding element(s) of each portions of the text.
example problem:
//example.html
<div id="a">
ABC
<span id="b">
DEF
<span id="c">
GHI
</span>
<span id="d">
JKR
</span>
</span>
</div>
//script.js
let a = document.getElementById('a');
let text_pos=a.textContent.indexOf('J');
// good way to get element #d from text_pos?
I know one way is to loop through all child elements of #a, then subtract each text length until 0.
But are there better way?
From what I understood from you is that you want to find parent element of the text that you search for. So instead of looping through all the text we will use indexOf search term and then backtrack to get first tag after that we will forward search to get closing tag and return this part of string between first tag and last tag
Another way is to backtrack to find first id= instead of first html tag but Im not sure if all you elements have id attribute
var data = "<div>Data<div id='d'><br/>AB</div></div>";
console.log(getparentElementOf("AB", data))
function getparentElementOf(searchTerm, data){
var indexOfTerm = data.indexOf(searchTerm);
var indexOfFirstTag = getStartIndexOfParentTag(indexOfTerm);
var indexOfEndTag = getEndIndexOfParentTag(indexOfTerm + searchTerm.length, data.length);
var element = data.substr(0, indexOfEndTag +1);
element = data.substring(indexOfFirstTag, element.length);
return element;
}
function getStartIndexOfParentTag(startFromIndex){
var indexOfFirstTag = -1;
var flagClosingBracket = false, flagOpeningBracket = false;
// back track from that found position until you find the first tag
for(var i = startFromIndex; i >= 0; i--){
// If we have detected closing bracket
if(flagClosingBracket == true){
// If we have / then cancel detected closing bracket
if(data[i] == "/"){
flagClosingBracket = false;
}else if(data[i] == "<"){
// otherwise we have found index of our first tage
flagOpeningBracket = true;
indexOfFirstTag = i;
i = -1; // to exit loop
}
}else{
// Otherwise detect closing bracket
if(data[i] == ">"){
flagClosingBracket = true;
}
}
}
return indexOfFirstTag;
}
function getEndIndexOfParentTag(startFromIndex, to){
var indexOfFirstTag = -1;
var flagClosingBracket = false, flagOpeningBracket = false, flagSlash = false;;
// back track from that found position until you find the first tag
for(var i = startFromIndex; i < to; i++){
// If we have detected closing bracket
if(flagOpeningBracket == true){
// If we have / then cancel detected closing bracket
if(data[i] == ">"){
flagOpeningBracket = false;
}else if(data[i] == "/"){
// otherwise we have found index of our first tage
flagSlash = true;
}
}else{
// Otherwise detect closing bracket
if(data[i] == "<"){
flagOpeningBracket = true;
}
}
if(flagSlash == true)
{
if(data[i] == ">"){
flagClosingBracket = true;
indexOfFirstTag = i;
i = to; // to exit loop
}
}
}
return indexOfFirstTag;
}
Well I think the question is alittle confusing but as I undestoood you you want the text of the elements as they are nested you should loop them. As you comment at the question text. I leave you a fragment of a loop with no lenght evaluation:
var strResult = "";
let a = document.getElementById('a');
for(content_word in a.textContent.trim().split("\n")) {
var isaWord = /[aA-zZ]/.test(a.textContent.trim().split("\n")[content_word])
if (isaWord) {
strResult = strResult + a.textContent.trim().split("\n")[content_word].trim()
}
};
console.log(strResult)
I hope this could help.
Regards

can't uncheck the check box (hide content while checkbox is unchecked)

I'd like to hide div content while checkbox is unchecked.
Here's my code
I've made almost the same function for the div with id "focus" (big grey frame):
document.getElementById("checkFocus").onchange = function() {
var one = document.getElementById("focus");
if (document.getElementById("checkFocus").checked === true) {
one.style.display = "block";
}
else one.style.display = "none";
}
And it works!
So, I don't understand why the next function doesn't works at all:
document.getElementById("checkMass").onchange = function() {
var elem = document.querySelector("PeriodicTable")
var mass = elem.querySelectorAll("div.element > div.mass");
if (document.getElementById("checkMass").checked === true) {
mass.style.display = "block";
}
else mass.style.display = "none";
}
What am I doing wrong?
elem.querySelectorAll("div.element > div.mass"); doesn't return a single element, it returns a collection of all matches.
That said you can't do mass.style.display on a array, only on a single element so you need to do
if (document.getElementById("checkMass").checked === true) {
for (var i = 0; i < mass.length; i++) {
mass[i].style.display = "block";
}
else {
for (var i = 0; i < mass.length; i++) {
mass[i].style.display = "none";
}
}
instead.
The querySelector("Any CSS rule") needs a rule, . signify class, # signify id, but you have querySelector("PeriodicTable"). Therefor you are looking for elements with tagname of PeriodicTable. Either use document.getElementById('PeriodicTable') or querySelector("#PeriodicTable")
https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector

Adding a new row to html table on click event

I have a list with names, each name has a sublist with subitems.
I need to pass those subitems to the table when I click on the name.
Here is an example, try to expand the first name.
But if I click on it again, it will keep adding that value to different cells of the table. How may I add this only once ? Or always at the same place?
Also, I have some attributes of the disciplines:
data-time = The time the discipline start;
data-id = The ID of that discipline (all brought from database);
My Code:
/*JQuery*/
$(document).ready(function(){
$(".prof-list h3").click(function(event){
var obj = event.target;
var disciplina_id = $(this).next().find('li').data('id');
var disciplina_hora = $(this).next().find('li').data('time');
if(disciplina_hora == "14:30:00"){
var myRow = document.getElementById("prof-table").rows[3];
myRow.insertCell(1).innerHTML = $(this).next().find('li').text();
}
else if(disciplina_hora == "08:30:00"){
var myRow = document.getElementById("prof-table").rows[1];
myRow.insertCell(1).innerHTML = $(this).next().find('li').text();
}
if(obj.nodeName == "H3")
$(this).next().slideToggle();//Aplica efeito slide
//$("#list_prof").html("clicked: " + event.target.nodeName ); //Teste
})
})
use .cells[] to update cell content
if(disciplina_hora == "14:30:00"){
var myRow = document.getElementById("prof-table").rows[3];
// insert if `myRow` only has 1 cell
if(myRow.cells.length <= 1)
myRow.insertCell(1);
// use `cells[1]` to update the 2nd cell content
myRow.cells[1].innerHTML = $(this).next().find('li').text();
}
Edit Update
if(myRow.cells.length <= 1){
$(this).next().find('li').each(function(idx, elm) {
myRow.insertCell(idx + 1);
myRow.cells[idx + 1].innerHTML = $(elm).text();
});
} else {
while(myRow.cells.length > 1)
myRow.deleteCell(1);
}

Using labels like HTML5 placeholder

I am trying to use <label> elements in my html contact form like the HTML5 placeholder attribute for inputs. I have written the following JavaScript to to act as a reusable function witch will provide the following functionality.
Find the input by name.
Get the value of the input.
Find the label belonging to the input.
Change the label style depending on the state of the input.
Change the label style depending on the value of the input.
However it is not working and I don't know why as no errors appear in the console. What am I doing wrong? here is a JS Fiddle with code
function placeholder(field_name) {
// Get the input box with field_name
// Then get input value
var box = document.getElementsByName(field_name);
var i;
for (i = 0; i < box.length; i++) {
var value = document.getElementById(box[i].value);
}
// Get the labels belonging to each box using the HTML for attribute
var labels = document.getElementsByTagName('LABEL');
for (i = 0; i < labels.length; i++) {
if (labels[i].htmlFor !== '') {
var elem = document.getElementById(labels[i].htmlFor);
if (elem) {
box.label = labels[i];
}
}
}
// Colors
var focusColor = "#D5D5D5";
var blurColor = "#B3B3B3";
// If no text is in the box then show the label grey color
box.onblur = function () {
box.label.style.color = blurColor;
};
// If input focuses change label color to light grey
box.onfocus = function () {
box.label.style.color = focusColor;
};
// If there is text in the box then hide the label
if (box.value !== "") {
// Quick do something, hide!
box.label.style.color = "transparent";
}
}
// Call the function passing field names as parameters
placeholder(document.getElementsByName("email"));
placeholder(document.getElementsByName("firstName"));
placeholder(document.getElementsByName("lastName"));
This might be considered a little overkill on the number of listeners I've used, feel free to remove any you think unnecessary, but I've tried to employ your HTML structure as you have it and give you all desired effects. It should work for either the <label>s for matching the <input>s id OR matching it's <name> (given no id matches). I'll always say prefer using an id over name. I believe this JavaScript should also work in all browsers too, except the addEventListener for which you'd need a shim for old IE versions (let me know if it doesn't in one/the error message).
Demo
var focusColor = "#D5D5D5", blurColor = "#B3B3B3";
function placeholder(fieldName) {
var named = document.getElementsByName(fieldName), i;
for (i = 0; i < named.length; ++i) { // loop over all elements with this name
(function (n) { // catch in scope
var labels = [], tmp, j, fn, focus, blur;
if ('labels' in n && n.labels.length > 0) labels = n.labels; // if labels provided by browser use it
else { // get labels from form, filter to ones we want
tmp = n.form.getElementsByTagName('label');
for (j = 0;j < tmp.length; ++j) {
if (tmp[j].htmlFor === fieldName) {
labels.push(tmp[j]);
}
}
}
for (j = 0; j < labels.length; ++j) { // loop over each label
(function (label) { // catch label in scope
fn = function () {
if (this.value === '') {
label.style.visibility = 'visible';
} else {
label.style.visibility = 'hidden';
}
};
focus = function () {
label.style.color = focusColor;
};
blur = function () {
label.style.color = blurColor;
};
}(labels[j]));
n.addEventListener('click', fn); // add to relevant listeners
n.addEventListener('keydown', fn);
n.addEventListener('keypress', fn);
n.addEventListener('keyup', fn);
n.addEventListener('focus', fn);
n.addEventListener('focus', focus);
n.addEventListener('blur', fn);
n.addEventListener('blur', blur);
}
}(named[i]));
}
};
placeholder("email"); // just pass the name attribute
placeholder("firstName");
placeholder("lastName");
http://jsfiddle.net/cCxjk/5/
var inputs = document.getElementsByTagName('input');
var old_ele = '';
var old_label ='';
function hide_label(ele){
var id_of_input = ele.target.id;
var label = document.getElementById(id_of_input + '-placeholder');
if(ele.target == document.activeElement){
label.style.display = 'none';
}
if (old_ele.value == '' && old_ele != document.activeElement){
old_label.style.display = 'inline';
}
old_ele = ele.target;
old_label = label;
}
for(var i = 0; i < inputs.length; i++){
inputs[i].addEventListener('click', hide_label);
}
I will point out a couple things, you will have to find away around the fact that the label is inside the input so users now can't click on half of the input and actually have the input gain focus.
Also I guess you want to do this in IE (otherwise I would strongly advise using the html5 placeholder!) which means you would need to change the ele.target to ele.srcElement.

Get the value from only selected checkbox

I am trying to get the value from a checkbox using javascript.
I want only one checkbox value to be passed to the javascript function, and if multiple are selected, an alert box informing that only one box can be checked for the function.
I've tried this:
var publish_trigger = document.querySelector("#publish_trigger");
publish_trigger.onclick = function() {
var _posts = document.getElementsByName('post_id[]');
var check = _posts.checked;
var boxes = _posts.length;
var txt = "";
if(check.length > 1) {
alert("Only one at a time");
} else {
for (i = 0; i < boxes; i++) {
if (_posts[i].checked) {
txt = txt + _posts[i].value + " "
}
}
}
alert(txt);
return false;
}
This code is wrong:
var _posts = document.getElementsByName('post_id[]');
var check = _posts.checked;
getElementsByName() returns a NodeList (effectively an array) of elements, so your variable _posts doesn't have a checked property. You need to loop through _posts to count the checked property on the individual elements within _posts.
You already have a for loop so add the validation in there:
var count = 0;
for (var i = 0; i < boxes; i++) {
if (_posts[i].checked) {
if (++count > 1) {
alert("Only one checkbox may be checked at a time.");
return false;
}
// I don't know what you're trying to do with the following line
// but I've left it in.
txt = txt + _posts[i].value + " "
}
}
(Note: unrelated to your question, you should declare the loop counter i within your function otherwise it will be global and might lead to hard to debug problems if you are using it in other places too.)

Categories