jQuery - cannot select third child element - javascript

As mentioned in the title, jQuery does not select 3rd child for some reason. This problem is not occurring when I target first and second child element. I want to hide a paragraph which starts with "Gift Aid legislation..."
Is there any way to sort it?
HTML
<div class="pmpro_checkout-fields custom">
<p>
You have selected the <strong>Non-Member</strong> membership level.
</p>
<p>Need Text</p>
<div id="pmpro_level_cost">
<p>The price for membership is <strong>£0.00</strong> now.</p>
</div>
<br>
<span style="margin-top: -25px; display: block">
Details required on this form will also appear in the Directory Listing. Please read below. *Information required
</span>
<hr>
<h3>Gift Aid</h3>
<p>Gift Aid legislation allows us to reclaim 25p of tax on every £1 that you give on your subscription and additional donations. It won't cost you any extra.</p>
<input type="checkbox" id="gift_aid" name="gift_aid" value="1">
<label class="pmpro_normal pmpro_clickable" for="gift_aid">
Allow Gift Aid to be collected?
</label>
<hr>
</div>
Jquery
$( ".pmpro_checkout-fields h3" ).hide();
$(".pmpro_checkout-fields p:nth-child(3").hide();

$(".pmpro_checkout-fields p:nth-child(3").hide();
I guess there is syntax problem
$(".pmpro_checkout-fields p:nth-child(3)".hide();

First, the method Cbroe mentioned in the comments will get you working:
$(".pmpro_checkout-fields p:nth-of-type(3)").hide();
However, long term, I do not recommend this approach (manual indexes of element positions in a form), as it is fragile. As soon as you add another <p> element before the target, things break. If you refactor it, things could break silently. A more standard way would be to surround the elements that should disappear in a div or span with an ID, then target that ID in the jQuery, so that it will always work as long as you don't change the ID:
HTML snippet:
<div class="pmpro_checkout-fields custom">
...
<hr>
<div id="giftAid">
<h3>Gift Aid</h3>
<p>Gift Aid legislation allows us to reclaim 25p of tax on every £1 that you give on your subscription and additional donations. It won't cost you any extra.</p>
<input type="checkbox" id="gift_aid" name="gift_aid" value="1">
<label class="pmpro_normal pmpro_clickable" for="gift_aid">
Allow Gift Aid to be collected?
</label>
<hr>
</div>
</div>
jQuery snippet to replace the two you have:
$("#giftAid").hide();
This is also a far more readable and maintainable approach. I am, of course, assuming your ultimate goal is to hide the gift-aid section entirely based on some logic. but if you really only want the header and P element hidden, just move the others outside the div tag with the "giftAid" id.

Related

Find any keyword entered into Search input on lengthy HTML page?

I looked online for a few references to my question, but having a hard time understanding what it is I truly need to do to make this work.
For example, if I want to search for the keyword "necessary" or any keyword I need to find, how would I go about finding that keyword using a Input search field throughout all the text in the page and go down to that keyword?
Would this require some JavaScript?
For reference, I provided some basic HTML code i'm trying to filter through and the word necessary is toward the bottom...
Any ideas would help!
<div class="course-title">
<h4>Difficult Conversations: Situation, Behavior, Impact</h4>
</div>
<div class="course-info">
<p><span>Course Description:</span> The Situation/Behavior/Impact model is perfect to prepare feedback statements when it’s critical to give clear, actionable feedback. Learn more about the model, how to use, and how to manage through complicated conversations.
</p>
<p><span>Subject:</span> Personal Growth</p>
<p><span>Provider:</span>L&D</p>
<p><span>Timing:</span> 1.5 Hours</p>
<p><span>Formats Offered:</span> Virtual</p>
<p><span>Link:</span> </p>
</div>
<br><br>
<div class="course-title">
<h4>Leading Change</h4>
</div>
<div class="course-info">
<p><span>Course Description:</span> Change is a constant in innovative organizations, so it’s imperative to handle it well and adapt. In this workshop, discover what happens neurologically when change is experienced, and learn easy techniques to reduce resistance and increase inspiration, commitment, and decisive action.
</p>
<p><span>Course Type:</span> Leadership Development</p>
<p><span>Provider:</span> LL</p>
<p><span>Timing:</span> 2 Hours</p>
<p><span>Formats Offered:</span> Virtual</p>
<p><span>Accessing:</span> </p>
</div>
<br><br>
<div class="course-title">
<h4>Managing Difficult Conversations: Issue Clearing</h4>
</div>
<div class="course-info">
<p><span>Course Description:</span> Difficult conversations are a common and necessary aspect in growing a strong, connected team with a high trust climate. In this session, we'll explore Issue Clearing, a tool to help guide conversations towards open, clear, vulnerable communication.
</p>
<p><span>Course Type:</span> Leadership Development</p>
<p><span>Provider:</span> L&D</p>
<p><span>Timing:</span> 2 Hours</p>
<p><span>Formats Offered:</span> Virtual</p>
<p><span>Accessing:</span> </p>
</div>
You could give each section its' own anchor. for example by changing each h4 (such as this one):
<div class="course-title">
<h4>Managing Difficult Conversations: Issue Clearing</h4>
</div>
to:
<a name="courseid123456">
<div class="course-title">
<h4>Managing Difficult Conversations: Issue Clearing</h4>
</div>
</a>
then you can jump to that location either with hyperlinks () or with javascript code such as window.location = '#courseid123456';

Changing display from block to none for multiple textareas

I'm currently trying to figure out how to make a text area disappear while another one will appear instead.
I have no knowledge of javascript and I have just started learning the basics of HTML and CSS, is there a chance anyone from the forum can help me out or maybe guide me to the correct path.
I'm attaching the part of the code, to make it more clear.
When you click on "2.svg" it should change the "textarea.one's and three's" "display: block;" into "display: none;"
When you click on "3.svg" it should change the "textarea.two's and one's" "display: block;" into "display: none;"
When you click on "1.svg" it should change the "textarea.two's and three's" "display: block;" into "display: none;"
I hope this explanation is clear enough, I'm also not sure if I'm allowed to ask to provide full code on this forum without preparing anything on my own.
Thank you in advance to whoever will read this!
<div>
<img id="header1" src="/1.svg" alt="Open Menu" class="menu">
<img id="header1" src="/2.svg" alt="Open Menu" class="menu">
<img id="header1" src="/3.svg" alt="Open Menu" class="menu">
</div>
<div class="textniz">
<textarea class="one" id="myInput" name="myInput" readonly>
Line one
Line two
Line three</textarea>
</div>
<div class="textniz">
<textarea class="two" id="myInput" name="myInput" readonly>
Line four
Line five
Line six</textarea>
</div>
<div class="textniz">
<textarea class="three" id="myInput" name="myInput" readonly>
Line seven
Line eight
Line nine</textarea>
</div>
Read this: https://www.w3schools.com/jsref/prop_style_display.asp
In order to change an element's display property, you can access it like this:
document.querySelector("myelement").style.display = "theValueIWant";
Mind the different selectors
Now, what you want is when we click 2.svg to change textarea one and three's diplay property from block to none. First select these using document.querySelector("textarea.one") and then change the value: document.querySelector("textarea.one").style.display = "none";
Now, to call this javascript you need an event. You can use the onClick one. Simply
<img id="header1" onClick="document.querySelector('textarea.one').style.display = 'none';" src="/1.svg" alt="Open Menu" class="menu">
would change the display property of the textarea.one element on click.
Method I In order to call multiple elements, what I suggest is adding one more class to the two elements that you are going to hide, and the simply use the above code with changing the class. E.g., to textarea one and three add class hideOne and then hide the element with document.querySelector("hideOne").style.display = "none";
Method II Another way you can accomplish this, is by creating a function that would hide the two components. Create a script tag and then use the above selector to hide the two elements:
<script>
function hide1(){
document.querySelector('textarea.one').style.display = "none"
document.querySelector('textarea.three').style.display = "none"
}
</script>
Then call the function by inserting into the element to be clicked(your svg): onClick="hide1()"
That's it!
The following is a very short way of achieving the same without jQuery.
It is not as easy to read as the jQuery based solution but contains certain elements that might be interesting to you too:
I used a "delegated event attachment" which means I attached the click event handler to the parent element (the first div in the document) of the three <img> elements. Doing it this way keeps the document "fast" and makes it easily extendable by further elements.
I identify the clicked image by its id attribute: only if the clicked element has the tagName==="DIV" and its id starts with "header", I will take the remaining (id-string - 1) as the index to look-up the class name c in the cls array.
In the txtas.forEach() loop I will then make the <textarea> containing c in its classList visible, while all others will be hidden.
const cls=["one","two","three"],
txtas=document.getElementsByName("myInput");
document.querySelector("div").onclick=ev=>{ let el=ev.target;
if(el.tagName==="IMG"&&el.id.substr(0,6)==="header"){
let c=cls[el.id.substr(6)-1];
txtas.forEach(t=>t.style.display=t.classList.contains(c)?"":"none");
}
}
<div>
<img id="header1" src="/1.svg" alt="first" class="menu">
<img id="header2" src="/2.svg" alt="second" class="menu">
<img id="header3" src="/3.svg" alt="third" class="menu">
</div>
<div class="textniz">
<textarea class="one" name="myInput" readonly>
Line one
Line two
Line three</textarea>
</div>
<div class="textniz">
<textarea class="two" name="myInput" readonly>
Line four
Line five
Line six</textarea>
</div>
<div class="textniz">
<textarea class="three" name="myInput" readonly>
Line seven
Line eight
Line nine</textarea>
</div>
I removed the id attributes from your <textarea> elements as they would have been dupes. The script works very well without them.
Impossible with just CSS but so easy with JQuery (which I think would be easier fo you to start as the semantic is much more read friendly for begginers than pure javascript)
like this:
$("#header1").click(function(){
$(".two").hide();
$(".three").hide();
$(".one").show();
});
$("#header2").click(function(){
$(".one").hide();
$(".three").hide();
$(".two").show();
});
$("#header3").click(function(){
$(".one").hide();
$(".two").hide();
$(".three").show();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div>
<img id="header1" src="/1.svg" alt="Open Menu" class="menu">
<img id="header2" src="/2.svg" alt="Open Menu" class="menu">
<img id="header3" src="/3.svg" alt="Open Menu" class="menu">
</div>
<div class="textniz">
<textarea class="one" id="myInput" name="myInput" readonly>
Line one
Line two
Line three</textarea>
</div>
<div class="textniz">
<textarea class="two" id="myInput" name="myInput" readonly>
Line four
Line five
Line six</textarea>
</div>
<div class="textniz">
<textarea class="three" id="myInput" name="myInput" readonly>
Line seven
Line eight
Line nine</textarea>
</div>
So as per your question, if it is just a quick switch and you want only one view to be active, it's better and easy to use jQuery because it is very direct, #Alvaro has already shared the quick code snippet. It's very easy to play around with jQuery.
Disclaimer: It makes your life so easy that if in case you try to learn a full seasoned framework, then there will be a long workaround. But get started with jQuery. You'll find it very interactive.
Happy Coding :)

How can I adjust the z-index of a tooltip for a Bootstrap form field?

I'm trying to add field validation to a "Contact Us" form using Bootstrap and a validation library (a jQuery Plugin) called Validetta (http://lab.hasanaydogdu.com/validetta/).
After implementing the form and the validation, though, I am noticing a problem with the z-index of the tooltip that causes it to show up beneath the next form field.
If I were dealing with normal HTML and CSS, I think the answer would be a little more clear to me, but with Bootstrap, I do not know what sort of mysticism is afoot and am having trouble finding answers on how to solve this problem in the best-practices way.
I know that Validetta is adding a <SPAN> after the form field and is applying a custom CSS class to it, which I can easily modify, override, or append. I've also read, in other contexts, that this problem can be solved using a combination of z-index and position on the tooltip SPAN and one or more of its parent elements... but all of my quick tests and trials have not had the desired affect.
Here's the rendered HTML for the form field shown above:
<div class="form-group has-feedback has-error">
<label class="control-label" for="inputFromName">Your Name</label>
<input type="text" class="form-control" id="inputFromName" name="fromName" placeholder="Your Name Here" data-validetta="required" data-vd-message-required="This field is required!">
<span class="validetta-bubble validetta-bubble--bottom">This field is required!<br></span>
</div>
Any help would be much appreciated!
you may check the z-index attribute on parent elements of "validetta-bubble" ;
because z-index judge from parent to child, if a parent has a lower z-index while child elemtn has a higher this element's z-index finally work base on the parenet's
you may try to set form-group's z-index
.form-group {
z-index: 10000;
position: relative;
}
and set a higher on target like answer 1
.crazy-zindex {
z-index: 10001;
}
Ultimately, I found the answer to this question here: z-index of hover tooltip with CSS
The answer from Панайот Толев provided this example:
<div class="level1">
<span class="level2"> 1 </span>
<span class="level2"> 2 </span>
<span class="level2"> 3 </span>
</div>
So, to solve the problem, I wrapped each row of form elements in a div that specified a z-index in the style attribute. As I went down the rows, I decreased the z-index value, like so:
<div style="z-index: 23;"> .. </div>
<div style="z-index: 22;"> .. </div>
<div style="z-index: 21;"> .. </div>
This ensured that each row fell "behind" the one above, which allowed tool-tips to appear on top of the fields (and labels), rather than beneath them.
I had same issue.
When no other script solved my problem. Then I had used parent class as data-container.
For exp.
<ul id="responsivator">
<li data-placement="bottom" data-toggle="tooltip" data-container="#responsivator" title="iPhone landscape Preview" >
</ul>
I would add a custom class like crazy-zindex (I'm sure you can come up with a better name) and a rule in the css for it.
HTML
<span class="validetta-bubble validetta-bubble--bottom crazy-zindex">This field is required!<br></span>
^^^^^^^^^^^^
CSS
.crazy-zindex {
z-index: 10000;
}
Its important to remember that CSS is cascading, so the last rule will overwrite anything above it, with this said, any overwrites you want to do to bootstrap you'll have to link that stylesheet after bootstrap. Or you can use !important but that's not good practice.

Refactoring overuse of jQuery show/hide methods for simple buttons

I have implemented some buttons on a web page that show and hide some text based on which button the user clicks:
Please bear in mind that the .reveal-1 fragment is set to display:none in the CSS by default.
http://bestclownintown.co.uk/ct/bootstrap-3.3.7/docs/examples/CT_task/index.html
HTML:
<div class="media">
<div class="media-left"> <img alt="New delivery options" class="media-object" src="images/thumbnail-new-delivery-options.jpg"> </div>
<div class="media-body">
<h4 class="media-heading">Cotton Traders Introduces New Delivery Options</h4>
<p class="text-muted">14th January 2016</p>
<p>Cheshire based retailer, Cotton Traders, has added three new delivery options to its e-commerce offering, in order to improve the customer shopping experience.</p>
<a class="btn btn-default reveal-button-1" href="#" role="button">Read More <i class="fa fa-caret-down" aria-hidden="true"></i></a>
<div class="reveal-1">
<p>The casual clothing retailer now offers its UK customers a choice of standard, next day, Sunday and nominated delivery options.</p>
<p>With more delivery options to choose from, customers will benefit from this added convenience, allowing them to get their items quicker and at a time that suits them, for as little as £3.99.</p>
<p>Talking about the introduction, Supply Chain Director, Caroline Allerton, said: "As a company we are constantly striving to improve the offering for our customers and this includes the delivery options.</p>
<p>"We know that our customers all have busy lives, so the introduction of these options will fit into their schedule and allow them to get their orders when they need them."</p>
<p>The introduction comes after Cotton Traders launched its dedicated Australian e-commerce website earlier this year.</p>
<a class="btn btn-default hide-button-1" href="#" role="button">Read Less <i class="fa fa-caret-up" aria-hidden="true"></i></a>
</div>
</div>
</div>
JS:
$(".reveal-button-1").click(function(){
$(".reveal-1").show();
});
$(".reveal-button-1").click(function(){
$(".reveal-button-1").hide();
});
$(".reveal-button-1").click(function(){
$(".hide-button-1").show();
});
$(".hide-button-1").click(function(){
$(".reveal-1").hide();
});
$(".hide-button-1").click(function(){
$(".hide-button-1").hide();
});
$(".hide-button-1").click(function(){
$(".reveal-button-1").show();
});
1) So in the first call to the jQuery object we show the <div> with a class of .reveal-1 when .reveal-button-1 is clicked
2) Then we hide .reveal-button-1
3) We then show .hide-button-1 when .reveal-button-1 is clicked
Now the hide button is present in the DOM.
4) We hide the <div> with a class of .reveal-1 when .hide-button-1 is clicked
5) We hide .hide-button-1
6) Finally we show .reveal-button-1 again.
Are there any solutions I can apply to refactor my JavaScript, so that I am not calling to the jQuery object as often and repeating myself so many times. I am aware of the .toggle method but I am not sure that it can be applied in this case. Please give a thorough explanation with your answer as I need to understand the jQuery logic. I have tried to keep the jQuery logic as simple as possible as I am only of a junior level.
I currently have 24 lines of jQuery code for 4 HTML fragements which seems quite excessive, but I don't know if there is a better way to implement/optimise.
here it is,
On any button click all element toggles visibility. its exactly what you need.
$(".reveal-button-1, .hide-button-1").click(function(){ //on click of either button.
$(".reveal-1, .reveal-button-1, .hide-button-1").toggle(); //toggle visibilty on all the corresponding elements
});
Make sure your initial values (display:none) are correct.
reveal button click will hide itself, show the hide button and toggle the reveal field (to show).
since the hidden button is now visible and the reveal button is no longer. once we click on this button the field will toggle (to be hidden again). the reveal button will be visible again.
side note: You probably want to use better css classes in your html though. (to make a more generic javascript code so that you can re-use its functionality).
re-usable solution
here is a re-usable version, with better classes.
$('.toggle-btn').click(function(){
$(this).closest('.container').find('.toggle').toggle();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="toggle-btn toggle" style="display:none;">show</div>
<div class="toggle-btn toggle">hide</div>
<div class="toggle">bla bla</div>
</div>
<div class="container">
<div class="toggle-btn toggle" style="display:none;">show</div>
<div class="toggle-btn toggle">hide</div>
<div class="toggle">bla bla</div>
</div>
Explanation: when a toggle-button is clicked. it goes and finds the first parent that has a class .container. then from this parent, it checks all the html elements with the .toggle class inside this container and toggles their visibility.
Side note on this solution: it is not a very prerformant solution because every time it tries to find the container class in its parents and then tries to find all the childs with class toggle. (better is to cache these classes). but for this simple solution it doesn't really matter.
out of the box libraries
bootstrap collapse
jquery accordion
You only need one event handler for each element. Repeating like that causes a lot of extra functions to be called on each event, which will slow your site down. (Probably not noticeably, but if your site grows it could become problematic.)
If your HTML is structured similarly for each of your sections, you could eliminate the specific classes, and go on a more general approach. (Shortened for brevity.)
<a class="... reveal-button"...>
<div class="reveal">
...
<a class="... hide-button"...>
</div>
Then down inside your JavaScript, instead of 4 sets of all your calls, you can do just a single. I'll explain how this works as we go. The function .on() is the preferred method to wire events since jQuery 1.7.
$('.reveal-button').on('click', function () {
var $self = $(this); // 'this' will be the element that was clicked.
$self.next('div.reveal')
.show();
$self.hide();
});
$('.hide-button').on('click', function () {
var $parent = $(this).parent(); // refers to div.reveal
$parent.hide(); // hide the div
$parent.prev('a.reveal-button').show(); // show the reveal button.
});

Overlay conflict with input field

Had a question. I'm trying to include a widget (which is contained in a div) for my landing page. Now, essentially what I am trying to do is when i hit the button is to fire the OverLayTwo BUT have it fall to the background, instead of the foreground. I tried the z-index method and it doesn't seem to help.
<div class="OverLay">
<div class="widgetContainer">
<li>This is a Div</li>
First Name: <input type="text" name="fname"></input>
</div>
<div class="OverLayTwo">
</div>
<button class="randomButton">Hello</button>
</div>
So essentially what I want is when User hits button, to have 'OverLayTwo' drop however have it fall to the BACKGROUND/backdrop behind the "widgetContainer" div. --
The reason is I want the user to be able to type into the input field(s), however, lately everything I have looked at or referenced is not solving the problem. Essentially just drops the overlay ontop/into the front of the widget - Not allowing the user to enter text into the appropriate input field.
Hope that made sense. The land of CSS is a true maze o.o ...Also, it should be noted I am using javascript and jQuery functionality.
Any tips and/or suggestions would be truly appreciated!
Thank you!
would be hard to make it fall in the background when it lives inside the first overlay.. try something like this..
<div class="OverLay" style="z-index:100">
<div class="widgetContainer">
<li>This is a Div</li>
First Name: <input type="text" name="fname"></input>
</div>
<button class="randomButton">Hello</button>
</div>
<div class="OverLayTwo" style="z-index:90">
</div>

Categories

Resources