IF returns false but should return true - javascript

HTML:
<div class="container" id="1" onclick="test()"> </div>
<div class="container" id="2" onclick="test()"> </div>
<div class="container" id="3" onclick="test()"> </div>
<div class="container" id="4" onclick="test()"> </div>
JS:
{
document.getElementById(e.target.id).appendChild(document.NewDiv("div", {id:"element1"}));
if (document.getElementById("1").contains(document.getElementById("element1")) &&
document.getElementById("2").contains(document.getElementById("element1")))
{
console.log("yes")
}
else
{
console.log("no")
}
};
This code returns "no" when element1 is in containers with id 1 and 2 but in my meaning it should be "yes"
But this code returns "yes" as should it be - if element1 is present in at least one of the two containers
{
document.getElementById(e.target.id).appendChild(document.NewDiv("div", {id:"element1"}));
if (document.getElementById("1").contains(document.getElementById("element1")) || //<-- changed
document.getElementById("2").contains(document.getElementById("element1")))
{
console.log("yes")
}
else
{
console.log("no")
}
};
I want this code to return "yes" if element1 is in container 1 and 2
{
document.getElementById(e.target.id).appendChild(document.NewDiv("div", {id:"element1"}));
if (document.getElementById("1").contains(document.getElementById("element1")) &&
document.getElementById("2").contains(document.getElementById("element1")))
{
console.log("yes");
}
else
{
console.log("no");
}
};

You can't have the same element in two different containers. Therefore the && condition can't be true, while || can.
id attribute must be unique, you should not have more than one element with the same id in the same document.
If you happened to have multiple elements with the same id, only the first element can be selected with document.getElementById().
However, theoretically you could use myelement.querySelector('[id="element1"]') to get element with id in the myelement container, but you should fix the code by not using the same ids.
if (document.getElementById("1").contains(document.getElementById("1").querySelector("[id='element1']")) &&
document.getElementById("2").contains(document.getElementById("2").querySelector("[id='element1']"))))
{
console.log("yes")
}
else
{
console.log("no")
}

Related

jQuery - Detect when two html `<span>` contain same value

I have the following html structure in my web application.
This is a group of <div>s which contain information about items. Specifically there are two <span> tags with pending and done quantities (integer values).
Clicking on other page elements will modify pending and done values.
Is it possible to track those changes and apply a class to the whole <div> when those values are the same?
So the whole <div id="{{ item.id }}"> will have a green background when pending and done match and no color background when values do not match. The actual action to be done is not relevant, what I miss is understanding the right approach in jQuery to monitor values in two html fields.
<div id="{{ item.id }}" href="#" state="{{ item.state }}" class="item">
<div class="row">
<div class="col-xs-4">
<span name="pending">{{ item.pending }}</span>
</div>
<div class="col-xs-4">
<span name="done">{{ item.done }}</span>
</div>
</div>
</div>
Use find and text functions along with these selectors '[name="pending"]' '[name="done"]'.
To listen to javascript modifications (jQuery), an alternative is to override the .val function.
var originalValFn = jQuery.fn.val;
jQuery.fn.val = function(value) {
originalValFn.apply(this, arguments);
if (value !== undefined) {
$('#done').trigger('input');
$('#pending').trigger('input');
}
};
Look at this code snippet.
The function updateSection must be called when the user changes the values.
var target = $('#myId');
var originalValFn = jQuery.fn.val;
jQuery.fn.val = function(value) {
originalValFn.apply(this, arguments);
if (value !== undefined) {
$('#done').trigger('input');
$('#pending').trigger('input');
}
};
var updateSection = function() {
var pending = target.find('[name="pending"]').text();
var done = target.find('[name="done"]').text();
if (pending === done) {
target.addClass('green-class');
target.removeClass('red-class');
} else {
target.addClass('red-class');
target.removeClass('green-class');
}
}
$('#pending').on('input', function(e) {
target.find('[name="pending"]').text(e.target.value);
updateSection();
});
$('#done').on('input', function(e) {
target.find('[name="done"]').text(e.target.value);
updateSection();
});
$('#done').val('3');
$('#pending').val('4');
//updateSection();
.green-class {
background-color: green;
}
.red-class {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="myId" href="#" state="{{ item.state }}" class="item">
<div class="row">
<div class="col-xs-4">
<span name="pending">222</span>
</div>
<div class="col-xs-4">
<span name="done">222</span>
</div>
</div>
</div>
<hr>
<p>Enter values to test:</p>
<input id='pending' placeholder='pending'>
<input id='done' placeholder='done'>
Resources
.find()
.text()
.on()
Sure. Place an input element inside each span and have the values actually be stored in the input. Then, set up input event handlers for those input elements that simply compare the values of the inputs. If they are the same. Apply a class.
// Get inputs
var $pending = $(".pending");
var $done = $(".done");
// Set up event handler
$pending.on("input", test);
$done.on("input", test);
function test(){
if($pending.val() === $done.val()){
$("div#parent").addClass("match");
} else {
$("div#parent").removeClass("match");
}
}
input { outline:none; border:none; }
.pending { background-color:rgba(255, 100, 100, .5); }
.done { background-color:rgba(255, 255, 100, .5); }
.match { background-color:rgba(100, 255, 100, .5); }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>For testing, type different (and then the same) values into the two fields</h1>
<div id="parent" href="#" state="{{ item.state }}" class="item">
<div class="row">
<div class="col-xs-4">
<span name="pending"><input class="pending"></span>
</div>
<div class="col-xs-4">
<span name="done"><input class="done"></span>
</div>
</div>
</div>
First: the "name" attribute only applies to input elements, you probably want to use the "id" attribute.
I would also suggest creating a function to check for equality, something like this:
var pendingDone = function(){
if($("#pending").text() === $("#done").text()) {
$("#pending").addClass("green");
$("#done").addClass("green");
} else {
$("#pending").removeClass("green");
$("#done").removeClass("green");
}
}
I would suggest just calling this function in all instances that modify the values, since the change and input listener suggested in another answer will not fire if the value is modified by javascript instead of user interaction.

Toggle display of an an element when you click on another element

I have a p element and a hidden pre element. I want to make it so that when you click on a p element with (for example) id/class = "p1", it changes the display of the pre element with (for example) id/class = "pre1".
This is my javascript code :
var p = 1;
setInterval(function() {
if(p <= document.querySelectorAll(".show").length) {
document.getElementById("display-pre"+p).onclick = function() {
console.log(p);
if(document.getElementById("display-pre-a"+p).style.display == '') {
document.getElementById("display-pre-a"+p).style.display = 'block';
} else if(document.getElementById("display-pre-a"+p).style.display == 'block') {
document.getElementById("display-pre-a"+p).style.display = 'none';
}
};
p++;
if(p > document.querySelectorAll(".show").length) {p = 1;}
}
}, 100);
This code kind of works but not really. It sometimes changes other elements and sometimes does nothing.
This is my full javascript code : https://pastebin.com/wEwdKKLy
This is my html :
<div id="test-div">
<input type="text" id="search"/>
<button type="submit" onclick="query()">Submit</button>
<button type="submit" onclick="newInput()">New</button>
<button type="submit" onclick="remove()">Delete</button>
<button type="submit" onclick="deleteAll()">Delete All</button>
<div class="query-div"><p class="query-p">Test-a</p></div>
<div class="query-div"><p class="query-p">Test-b</p></div>
<div class="query-div"><p class="query-p">Test-ba</p></div>
<p id="query-show0">TEST-SHOW</p>
<p id="child"></p>
</div>
Note : elements with class "show" have display none
I tried doing this with jquery but I'm just began learning jquery yesterday and it didn't work (I had the same problem as this).
Jquery code I tried : https://pastebin.com/cBisCmEZ
Thank you for your help.
Here is the solution for you
$("p[data-id]").on("click", function() {
var idFound = $(this).data("id");
$("[data-pre='"+ idFound +"']").toggleClass("show");
});
pre {
display:none;
}
.show {
display:block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p data-id="p1">This is the paragraph</p>
<pre data-pre="p1">This is the pre<pre>
I recommend using a button element for anything you click so that it stays accessible.

Show/hide div on select

I am trying to show div's depending on which value a select box is on. With my current script it is working, however, when I change the value of the select it shows the next div without hiding the previously selected one. I only want this JS script to show the currently selected div, not every div that is selected by the select box (ie. switching from one option to another).
js and html
<script>
$(function() {
$('#contract_bid').hide();
$('#equipment_purchase').hide();
$('#hiring_employees').hide();
$('#marketing').hide();
$('#expansion').hide();
$('#working_capital').hide();
$('#inventory_purchase').hide();
$('#refinancing').hide();
$('#other').hide();
$('#loan_application_requested_purpose').change(function(){
if($('#loan_application_requested_purpose').val() == 'Contract Bid') {
$('#contract_bid').show();
} else if($('#loan_application_requested_purpose').val() == 'Equipment Purchase') {
$('#equipment_purchase').show();
} else if($('#loan_application_requested_purpose').val() == 'Hiring Employees') {
$('#hiring_employees').show();
} else if($('#loan_application_requested_purpose').val() == 'Marketing') {
$('#marketing').show();
} else if($('#loan_application_requested_purpose').val() == 'Expansion/Renovation') {
$('#expansion').show();
} else if($('#loan_application_requested_purpose').val() == 'Working Capital') {
$('#working_capital').show();
} else if($('#loan_application_requested_purpose').val() == 'Inventory Purchase') {
$('#inventory_purchase').show();
} else if($('#loan_application_requested_purpose').val() == 'Refinancing') {
$('#refinancing').show();
} else {
$('#other').show();
}
});
});
</script>
# HTML
<div id="contract_bid"></div>
<div id="equipment_purchase"></div>
<div id="hiring_employees"></div>
<div id="marketing"></div>
<div id="expansion"></div>
<div id="working_capital"></div>
<div id="inventory_purchase"></div>
<div id="refinancing"></div>
<div id="other"></div>
Like this
Give all the divs a class, for example "loan_purpose"
change your script to this:
$(function() {
$('#loan_application_requested_purpose').on("change",function(){
$(".loan_purpose").hide();
// change all spaces to underscore and grab the first part of Expansion/
var $div = $("#"+$(this).val().toLowerCase().replace(/ /g,"_").split("/")[0]);
if ($div.length>0) $div.show();
else $("#other").show();
}).change(); // run change on load to show relevant already selected
});
Alternative to giving a class: if your divs have a common parent, you can do
$("#parentID > div").hide();
instead of
$(".loan_purpose").hide();
Alternative solution:
If you can change the values to reflect the IDs of the divs to show then the script will be much shorter:
<select id="loan_application_requested_purpose">
<option value="other">Please select</option>
<option value="equipment_purchase">Equipment Purchase</option>
.
.
<option value="expansion">Expansion/Renovation</option>
</select>
Then my script needs only
$(function() {
$('#loan_application_requested_purpose').on("change",function(){
$(".loan_purpose").hide();
$("#"+$(this).val()).show();
}).change(); // run change on load to show relevant already selected
});
First of all add common class to all your divs:
<div id="other" class="section"></div>
<div id="contract_bid" class="section"></div>
<!-- and so on ... -->
Then it will allow you to reduce your code:
$(function () {
$('.section').hide();
$('#loan_application_requested_purpose').change(function () {
$('.section').hide();
var val = $(this).val();
if (val == 'Contract Bid') {
$('#contract_bid').show();
} else if (val == 'Equipment Purchase') {
$('#equipment_purchase').show();
}
// other checks ....
else {
$('#other').show();
}
});
});
Note that it's cleaner to calculate value only once with var val = $(this).val(); and use it later.
And finally even better would be to use CSS to initially hide sections (and get rid of the first $('.section').hide();):
.section {
display: none;
}
<div id="#myDivs">
<div id="contract_bid"></div>
<div id="equipment_purchase"></div>
<div id="hiring_employees"></div>
<div id="marketing"></div>
<div id="expansion"></div>
<div id="working_capital"></div>
<div id="inventory_purchase"></div>
<div id="refinancing"></div>
<div id="other"></div>
</div>
if($('#loan_application_requested_purpose').val() == 'Contract Bid') {
$("#myDivs div").hide()
$('#contract_bid').show();
}else
{
...
you can hide the visible div before you display the hidden div:
$(function() {
$('#contract_bid').hide();
$('#equipment_purchase').hide();
$('#hiring_employees').hide();
$('#marketing').hide();
$('#expansion').hide();
$('#working_capital').hide();
$('#inventory_purchase').hide();
$('#refinancing').hide();
$('#other').hide();
$('#loan_application_requested_purpose').change(function(){
// here comes the change:
$('.loan_application_purpose:visible').hide();
if($('#loan_application_requested_purpose').val() == 'Contract Bid') {
$('#contract_bid').show();
} else if($('#loan_application_requested_purpose').val() == 'Equipment Purchase') {
$('#equipment_purchase').show();
} else if($('#loan_application_requested_purpose').val() == 'Hiring Employees') {
$('#hiring_employees').show();
} else if($('#loan_application_requested_purpose').val() == 'Marketing') {
$('#marketing').show();
} else if($('#loan_application_requested_purpose').val() == 'Expansion/Renovation') {
$('#expansion').show();
} else if($('#loan_application_requested_purpose').val() == 'Working Capital') {
$('#working_capital').show();
} else if($('#loan_application_requested_purpose').val() == 'Inventory Purchase') {
$('#inventory_purchase').show();
} else if($('#loan_application_requested_purpose').val() == 'Refinancing') {
$('#refinancing').show();
} else {
$('#other').show();
}
});
});
HTML:
<div id="contract_bid" class="loan_application_purpose"></div>
<div id="equipment_purchase" class="loan_application_purpose"></div>
<div id="hiring_employees" class="loan_application_purpose"></div>
<div id="marketing" class="loan_application_purpose"></div>
<div id="expansion" class="loan_application_purpose"></div>
<div id="working_capital" class="loan_application_purpose"></div>
<div id="inventory_purchase" class="loan_application_purpose"></div>
<div id="refinancing" class="loan_application_purpose"></div>
<div id="other" class="loan_application_purpose"></div>
Always hide all then show selected:
$( '#trigger' ).change( function() {
var selected_id = '#' + $('#trigger').val(); // Grab the ID to show
$( '.foo' ).hide(); // Hide all
$( selected_id ).show(); // Show selected
} ).change(); // Run at least once
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="trigger">
<option>d1</option>
<option>d2</option>
</select>
<div id="d1" class="foo">D1</div>
<div id="d2" class="foo">D2</div>
Here, you have to hide other div in if or elseif condition like in if
if($('#loan_application_requested_purpose').val() == 'Contract Bid') {
$('#contract_bid').show();
$('#equipment_purchase').hide();
$('#hiring_employees').hide();
$('#marketing').hide();
$('#expansion').hide();
$('#working_capital').hide();
$('#inventory_purchase').hide();
$('#refinancing').hide();
}

Complicated Conditional

I have a set of instruction at the top of my page:
<div class="instructions">
<div id="step1" class="step"><span class="step_active">1</span><span class="step_title_active">General Info</span></div>
<div id="step2" class="step"><span class="step_next">2</span><span class="step_title">Select Contact</span></div>
<div id="step3" class="step"><span class="step_next">3</span><span class="step_title">Log Details</span></div>
</div>
I have a form that reveals itself as conditions are met.
The first condition being that both select boxes must have options selected, before the next part appears.
<script>
$(document).ajaxSuccess(function () {
$("#test").hide();
$("#comType, #comDirection").bind('change', function () {
// show the button if they both have a value
if ($("#comType").val().length > 1 && $("#comDirection").val().length > 1) {
$("#test").fadeIn();
}
});
});
</script>
How can I change the classes in #step1 #step2 so that when the above conditions are met, they appear as:
<div id="step1" class="step"><span class="step_complete">1</span><span class="step_title">General Info</span></div>
<div id="step2" class="step"><span class="step_active">2</span><span class="step_title_active">Select Contact</span></div>
Thoughts?
You can use addClass & removeClass property of jQuery.
Try this:
if ($("#comType").val().length > 1 && $("#comDirection").val().length > 1) {
$("#test").fadeIn();
$("#step1").children("span").removeClass("step_active").addClass("step_complete");
$("#step2").children("span").removeClass("step_next").addClass("step_active");
$("#step1").children("span").next("span").removeClass("step_title_active").addClass("step_title");
$("#step2").children("span").next("span").removeClass("step_title").addClass("step_title_active");
}

JQuery get a contiguous sequence of elements

I'm trying to get a contiguous array of elements using JQuery. For example for the this html:
<div class="parent">
<div class="childType2">1</div>
<div class="childType2">2</div>
<div class="childType2">3</div>
<div class="childType1">4</div>
<div class="childType1">5</div>
<div class="childType1">6</div>
<div class="childType1">7</div>
<div class="childType2">8</div>
<div class="childType1">9</div>
<div class="childType1">10</div>
<div class="childType1">11</div>
<div class="childType1">12</div>
</div>
I want it to return the div's containing 4,5,6,7 (The first sequnce of the divs with the class="childType1").
I tried to do
$("<div>test</div>")($('.parent .childType2').siblings('.childType1').addBack());
But this of course will add the div with the text test after the last childType1 (12).
I'm not so good with JQuery.
Edit:
Since the div's are dynamically generated, I ended up adding for each "group" a special class post-fix of the id related to his group, and used the method described in suspectus's answer. Not exactly what i had in mind, but it works :D.
You can use either .each (docs) or .filter (docs). If you use .filter() you can chain another jQuery method after it.
var state = 0;
var elements = [];
$('.parent div').each( function( i, elem ) {
if( state != 2 && elem.className === "childType1" ) {
state = 1;
elements.push( elem );
} else if ( state == 1 ) {
state = 2;
}
} );
console.log( elements );
Or more jQuery approach:
var state = 0;
$('.parent div').filter( function() {
if( state != 2 && $(this).hasClass( "childType1" ) ) {
state = 1;
return true;
} else if ( state == 1 ) {
state = 2;
}
return false;
} ).css( 'background-color', 'red' );
<div class="parent">
<div class="childType2">1</div>
<div class="childType2">2</div>
<div class="childType2">3</div>
<div class="childType1 inner">4</div>
<div class="childType1 inner">5</div>
<div class="childType1 inner">6</div>
<div class="childType1 inner">7</div>
<div class="childType2">8</div>
<div class="childType1">9</div>
<div class="childType1">10</div>
<div class="childType1">11</div>
<div class="childType1">12</div>
</div>
$(".inner") // gives the elements required
You could use filter for this :
var $elements = $(".childType1").filter(function() {
var no = parseInt($(this).text(), 10)
return (( no > 3) && ( no < 8))
});
now $elements will contain only those matched elements between 3 and 8 ie., 4 to 7.
You can use .each() method for looping all the divs having class="childType1"
Following is the complete code. Modify it according to your need.
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
$(".childType1").each(function (i) {
if ( $(this).html() == "4" ||$(this).html() == "5" || $(this).html() == "6" ||$(this).html() == "7") {
alert($(this).html());
}
});
});
</script>
</head>
<body>
<div class="parent">
<div class="childType2">1</div>
<div class="childType2">2</div>
<div class="childType2">3</div>
<div class="childType1">4</div>
<div class="childType1">5</div>
<div class="childType1">6</div>
<div class="childType1">7</div>
<div class="childType2">8</div>
<div class="childType1">9</div>
<div class="childType1">10</div>
<div class="childType1">11</div>
<div class="childType1">12</div>
</div>
</body>
</html>

Categories

Resources