Why is my code to hide a parent div not working? - javascript

I tried following the information here, editing it to match my needs, but so far it's not working.
I'm trying to hide a parent div with two child elements. The parent div is part of a list, all with the same classes, and each div has two child elements: an input, and an image. Each input has a unique "data-wapf-label" that I'm trying to select so that I can hide the parent div. The HTML is as follows:
<div class="has-pricing wapf-swatch wapf-swatch--image">
<input type="radio" id="wapf-field-61b148f2fc8fe_lzhx7" name="wapf[field_61b148f2fc8fe]" class="wapf-input" data-field-id="61b148f2fc8fe" value="lzhx7" data-wapf-label="Peppermint Mocha" data-is-required data-wapf-pricetype-"fx">
<img src="...">
</div>
There are several pages where this product shows up, and rather than going in and deleting the product field (because I'll just have to add it again next season), I'm trying to create a piece of code that will hide all the divs for all the products that have the above code (since each has a unique "id", I'd have to do it several times for each id using "selectElementById", and I'd like to avoid doing that, obviously).
I installed Code Snippets, but I'm having a bit of trouble with the Javascript. I should add that Code Snippets inserts code to the website via php (so php tags are required with every snippet). I've tried several things, but this is my latest version. It throws a syntax error "unexpected 'hideFlavors' (T_STRING), expecting '('".
Here's my php/Javascript code:
<?php
add_action( 'wp_head', function hideFlavors() { ?>
<script>
if var peppermintMocha = document.querySelectorAll("[data-wapf-label='Peppermint Mocha']") {
peppermintMocha.parentNode.style.display = "none";
}
</script>
<?php } );
I've also tried it with "document.querySelector" (without the "All"), but with the same or similar problem. When I do get the code to actually go through without any errors, it still doesn't fix the problem.
At this point, I feel a little like the guy looking through the tank's periscope on "Independence Day". No matter what I do, "target remains".

<?php
add_action( 'wp_head', function() {
?>
<script>
window.onload = function() {
document.querySelectorAll("[data-wapf-label='Peppermint Mocha']").forEach(function(el) {
el.parentNode.style.display = "none";
});
};
</script>
<?php
});
?>
querySelectorAll returns an array of elements, so you need to loop through each element and hide their parent respectively.

Instead querySelectorAll use querySelector. Then it would be work. But make sure that exists only one input field with the selector [data-wapf-label='Peppermint Mocha'].

Related

Display more of a hidden text on button click, php, phalcon

I have a table that displays items from a database. One of the items is a description so it can be very long.The thing I'm having the most problem with is how can I use JS and HTML smoothly in my controller class.
I want to be able to display a little bit of it if its longer than 100 char, and a button that looks like '...' where if the user clicks on it, it displays the trimmed text. I want to do this using javascript and here is what I tried, this code is in my controller, so I'm just sending these to the view.
The problem is when I press the button it doesn't display anything so what is wrong here? Some suggested to use jquery but I don't want to write my js script elsewhere and call it again since I'm not sure how I will do that in Phalcon controller.
$this->view->tblColumns = [
'element one',
'element two',
function (tablename $instance) {
if (strlen($desc = $instance->getDescription()) > 100) {
return $shortDesc = substr($instance->getDescription(), 0, 100) . '
<button style="background: none;border: none" onclick="(function(){
var desc= <?php echo
$desc; ?>; document.write(desc) ;
})()" >...</button>';
} else {
return $instance->getDescription();
}
},
do NOT use document.write after load of the page. It will wipe the page
your desc needs to be in single quotes and have no carriage returns.
you cannot use an IIFE in an onclick unless it returns a function
if your button is in a form, you will submit the form - it should be type=button
You MAY mean
<button type="button" onclick="var desc='<?php echo $desc; ?>';
document.querySelector('#someContainer').innerHTML=desc;"...>
but a better way is to toggle the existing text inside tags (span for example)
I find a way to do what I wanted, using the code for read more,read less from this link https://codepen.io/maxds/pen/jgeoA
The thing I was having trouble with in phalcon MVC, was that I didn't know I could my java-script, and css in the view of the controller and that's what I did.
I just used the js from that link, into my view file, the same for the css using tag and tag.
And in the function on the controller I wrote the following `
$this->view->tblColumns = [
'one',
'two',
function(tablename $link){
$desc=$link->getDescription();
$html=<<<HTML
<span span class="more"> $desc</span>
HTML;
return $html;
}`

Want to print a particular section of a page using JavaScript

I'm basing my code off of this solution by Ben Nadel
Here is the code included in the page
<script type="text/javascript">
// When the document is ready, initialize the link so
// that when it is clicked, the printable area of the
// page will print.
$(function() {
// Hook up the print link.
$("a").attr("href", "javascript:void(0)").click(function() {
// Print the DIV.
$( ".printable" ).print();
// Cancel click event.
return(false);
});
});
</script>
Here is a codepen
The Buttons are not working in the pen but do work locally.
What i'm trying to do is have the user print the contents of each list item which as you can tell is a Q&A so essentially have the user be able to print each Q&A pair when they click the button.
I've only included two to provide the minimal example to help me figure out where my error is.
What's happening is that no matter which button I click it will always print the first "li" with the class of "printable" and i'm not sure how to distinguish each section so that the button understands to only print 'this' and not the first li that has that class which is what it's doing.
Obviously this is a problem since each Answer will have a "click to print" button and I don't want them to all print the same Q&A pair.
Does this make sense?
My instinct is to have some kind of loop in play or iterate through an array, but i'm very new to JavaScript so i'm looking for a moderately challenging solution.
Yes, it does make sens. You are selecting elements to print with $('.printable').print([1]); It means, print the first element that match my selection, that is .printable. The first element that has the class printable. What you should do is bind each button with the appropriate section and use IDs instead of classes to select elements. As IDs are unique !
function(){
$('.printBtn').attr('href', 'javascript:void( 0 )').click(function(){
//select the corresponding section, first parent li that have .printable class
var section = $(this).closest("li.printable");
// Print Div
$(section).print([1]);
// Cancel click event
return(false);
});
You can use simple java script to print specific div of a page
var prtContent = document.getElementById("your div id");
var WinPrint = window.open('','','letf=0,top=0,width=800,height=900,toolbar=0,scrollbars=0,status=0');
WinPrint.document.write(prtContent.innerHTML);
WinPrint.document.close();
WinPrint.focus();
WinPrint.print();
WinPrint.close();

independently working div in Jquery

I am trying to make an independently working div which has a form inside of it.
I use jquery to calculate the price of a product depending of the user's selections in the form. However the user is able to add multiple items in his 'cart' so the form is duplicated to another div. The problem is that the calculation pattern can't separate these two divs and the calculation will be incorrect. The form is also interactive so it will be generated by the user's input. This is really complex set and renaming every variable by the 'product number' doesn't sound really efficient to me.
I'm kind of stuck here and i don't really know how to solve this problem. I had an idea that what if I put an iframe inside of the div and load my form and its calculation script inside of it, and then use post command to transfer the price of the product to the 'main page' to calculate the total price of all of the products the user wanted.
However it seems that jQuery scripts doesn't work independently inside of these iframes, they still have connection so they broke each other.
i will appreciate any kind of suggestions and help to solve this matter, thank you!
here's the code so far
Heres the body
var productNumber = 1;
<div id="div_structure">
</div>
<button id="newProduct" >Add new product</button><br \>
add new item
<!-- language: lang-javascript -->
$('#newProduct').click(function ()
{
$('<div id="productNo'+productNumber+'">')
.appendTo('#div_structure')
.html('<label onclick="$(\'#div_productNo'+productNumber+'\').slideToggle()">Product '+productNumber +' </label>'+
'<button onclick="$(\'#product'+productNumber+'\').remove()">Remove</button>');
$('<div id="div_product'+productNumber+'" style="display: none;">').appendTo('#product'+productNumber+'');
$('<iframe src="productform.html" seamless frameborder="0" crolling="no" height="600" width="1000">').appendTo('#div_product'+productNumber+'');
productNumber++;
});
it also has a function that allows the user to remove the inserted div.
Here's just few lines from the productform
$(document).ready(function()
{
$('#productCalculation').change(function ()
{
shape = $('input[name=productShape]:checked', '#productCalculation').val();
alert(shape);
});
});
<form id="productCalculation">
<div id="div_productShape" class="product1">
<h1>Select the shape of the product</h1>
<input type="radio" name="productShape" value="r1">R1</input><br \>
<input type="radio" name="productShape" value="r2">R2</input><br \>
<input type="radio" name="productShape" value="r3">R3</input><br \>
</div>
.
.
.
</form>
I translated all of the variables so they may not function correctly since i didn't test the translated version. So the problem is, if i try to make selections in the second generated div it wont even alert() the selected variable
There are two problems with this code: You say somewhere "I translated all of the variables so they may not function correctly since i didn't test the translated version. So the problem is, if i try to make selections in the second generated div it wont even alert() the selected variable". This is because event handlers are attached to elements that are in the DOM at that specific moment. To get it to work for all elements, use event delegation:
$(document).ready(function()
{
$(document).on( 'change', '#productCalculation', function ()
{
shape = $('input[name=productShape]:checked', '#productCalculation').val();
alert(shape);
});
});
Your other question is "My question in a nutshell: Is there a way to restrict jquery to function only in certain div even though i use the same variable names in the second div ". You can use the this variable to access the element the click was invoked on. From this element you can traverse the DOM if needed, for example with .parent().
$('div').on( 'change', function( e ) {
console.log( $(this).val() );
} );

HTML document pagination without jQuery

I have a large page having a lot of divs and all these divs are enclosed in a single div. And I have number links on the top of the page equal to the total enclosed divs I have. Now what I want to do is, on click on a number, I want to show only div corresponding to that number and hide all other.
links--> 1 2 3 4 5 6 7 .....
<div id="all">
<div id="mail1">..........</div>
<div id="mail2">..........</div>
<div id="mail3">..........</div>
<div id="mail4">..........</div>
<div id="mail5">..........</div>
<div id="mail6">..........</div>
.....and so on
</div>
I have to do it inside an HTML and that HTML will be stored and may be viewed offline as well, so cannot use jQuery here. Have to do it using JavaScript itself.
Could anybody help me with the JavaScript code here?.
<script type="text/javascript">
var divIds = ["mail1", "mail2", ..., "mailn"];
function showDiv(showId) {
for(var i = divIds.length; i--; ) {
if(divIds[i] === showId)
document.getElementById(showId).style.display = "block";
else
document.getElementById(divIds[i]).style.display = "none";
}
}
</script>
Then your links at the top will look like this:
1
Haven't tested it, but that's the idea. Downsides are you have to maintain the div in 3 places in code
In the var divIds array.
In the html tag itself.
In the links across the top.
You could write some javascript to generate all 3, taking away the maitenance part of it entirely.
As for using jQuery in an offline doc, the best route would probably be to include the text of the jquery.min.js file in the doc itself inside of <script></script> tags. That way you don't have to worry about paths and what-not.
You may do something like that (don't judge me on js coding style, i'm not a js ninja):
window.onload = function() {
var outer = document.getElementById("all");
for (var i=0; i < outer.childNodes.length; i++) {
outer.childNodes[i].addEventListener("click", doSomething);
}
function doSomething() {
// here you can run loop for changing display style for you divs
console.log(this.id);
}
}
I made an unobtrusive example without knowing the div ids:
http://jsfiddle.net/8pQzx/2/
Its more code but this is what you get if you dont want to use a js lib. ;)

Wrapping a jquery validate span.error with nested divs

Heyo. This is my first stack overflow post because I am stumped and not finding many people who are trying to accomplish the same thing. I've tried using jquery .before(), .after(), and .wrap() to resolve this. I was initially using css :before and :after pseudo-elements, but as that won't work for legacy browsers, I've decided to use jquery.
I already have several forms on several pages with validation working. The error messages vary in length. We were using a static, one size background image on the default span element, so content was bleeding out on longer error messages. I built a flexible rounded corner series of nested divs to allow the error box to grow or shrink dynamically. The html I want to output is:
<div class="errorWrap">
<div class="errorTop"><span></span></div>
<div class="errorContent">
<span class="error">This is an error</span>
</div>
<div class="errorBottom"><span></span></div>
</div>
Here's an example of a solution I tried, but I'm still pretty new to javascript.
$('.error').before('<div class="errorWrap"><div class="errorTop"><span></span></div><div class="errorContent">');
$('.error').after('</div><div class="errorBottom"><span></span></div></div>');
Correct me if I'm wrong, but I think that I have the right idea with the jquery. But it's just kind of sitting there, not in any function being called. So I imagine that since the code isn't re-executing, it just doesn't show up. Is there an appropriate function to wrap this in? I'm certain I'm just not attacking this from the right direction. Any help is super appreciated.
the plugins "before" and "after" dont take html as string. you cannot start a div in one and close it in an other.
Either you take your current html and generate a new html string which you append where you want to or you use the "wrap" plugin http://api.jquery.com/wrap/
Using pure HTML
$(".error").html("<div class='beforeContent'>" + $(".error").html() + "</div>");
Using wrap (http://api.jquery.com/wrap/)
$(".error").wrap("<div class='beforeAndAfter'></div>");
If you want to show an error div after focus out of an input then you have to create it using html/wrap as Luke said and then you have to append it in ot the dom useing
$('.errorWrap').insertAfter('.focusedElement');
But there are other methods available to insert a new element like append/appendTo e.t.c,
I ended up fixing this problem on my own using jquery to create the div and it's nesting on pageload, the divs are generated with an error class that gives display:none. A custom errorPlacement function nests the error in the correct div. Then I used a custom validator highlight function to remove the class that hides the element. Then I used the unhighlight function to re-add the class to re-hide the div.
$(function() {
//Generate the elements and assign attributes
var errorWrap = document.createElement('div');
$(errorWrap).addClass('errorWrap hideError');
var errorTop = document.createElement('div');
$(errorTop).addClass('errorTop');
var topSpan = document.createElement('span');
var errorContent = document.createElement('div');
$(errorContent).addClass('errorContent');
var errorBottom = document.createElement('div');
$(errorBottom).addClass('errorBottom');
var bottomSpan = document.createElement('span');
//Place the elements directly after each dd element
$("dl > dd").append(errorWrap);
$("div.errorWrap").append(errorTop)
.append(errorContent)
.append(errorBottom);
$("div.errorTop").append(topSpan);
$("div.errorBottom").append(bottomSpan);
//Add custom validator defaults
$.validator.setDefaults({
errorPlacement: function(error, element) {
$(element).nextAll('.errorWrap').children('.errorContent').append(error);
},
highlight: function(element) {
$(element).nextAll('.errorWrap').removeClass('hideError');
},
unhighlight: function(element) {
$(element).nextAll('.errorWrap').addClass('hideError');
}
});
}
Although I'm sure this could have been done more shorthand, I really like this technique because I didn't have to update any of my pages that contained forms to get it to work. All of the nested divs are dynamically created by javascript, so I can include a global file to any page with forms and it will just work. Thanks for all who offered suggestions.

Categories

Resources