More then one event in an onclick print event - javascript

I have an onclick print event, its working fine but now i have some div's i want to print out, so my question is, how can i make this script working with all id="PrintElement" Or id="PrintElement1" / id="PrintElement2" and so on, so i can add the ID to the div's i want to print out on one paper.
I have this Javascript, thats work with One div called id="PrintElement".
<script type="text/javascript">
//Simple wrapper to pass a jQuery object to your new window
function PrintElement(elem){
Popup($(elem).html());
}
//Creates a new window and populates it with your content
function Popup(data) {
//Create your new window
var w = window.open('', 'Print', 'height=400,width=600');
w.document.write('<html><head><title>Print</title>');
//Include your stylesheet (optional)
w.document.write('<link rel="stylesheet" href="add/css/layout.css" type="text/css" />');
w.document.write('<link rel="stylesheet" href="add/css/main.css" type="text/css" />');
w.document.write('</head><body>');
//Write your content
w.document.write(data);
w.document.write('</body></html>');
w.print();
w.close();
return true;
}
</script>
Then i have a div
<div id="PrintElement">
SOME CODE.....SHORT/LONG
</div>
And to activate the function i have
<a onclick="PrintElement('#PrintElement')">Print</a>
Working fine now i just want it to work with more then one div called id="PrintElement" or if easier i can call the divs ID PrintElement and a number... so it just print out the div's with the ID's
<div id="PrintElement">
SOME CODE.....SHORT/LONG
</div>
<div>
SOME CODE.....SHORT/LONG
</div>
<div id="PrintElement">
SOME CODE.....SHORT/LONG
</div>
<div>
SOME CODE.....SHORT/LONG
<div id="PrintElement">
SOME CODE.....SHORT/LONG
</div>
<div>
SOME CODE.....SHORT/LONG
</div>
</div>
Hope u understand..

You should replace id="PrintElement" with class="PrintElement" in your HTML
And then change your <a onclick="PrintElement('#PrintElement')">Print</a> with <a onclick="PrintElement('.PrintElement')">Print</a>
And then:
function PrintElement(elem){
$(elem).each(function() {
Popup($(this).html());
});
}
This will open a new window for every PrintElement though...
You can collect data with a var and then call Popup at the end of the loop.
EDIT: The code above is using jQuery... so you'll need the library.
EDIT2: If you want to collect data and open only one popup
function PrintElement(elem){
var data = '';
$(elem).each(function() {
data = data + $(this).html();
});
Popup(data);
}

Without jQuery, first move the code that enumerates target IDs to a function, don't embed it in the HTML:
<a onclick="PrintElements()">Print</a>
And in JS:
function PrintElements() {
printElement('#PrintElement1')
printElement('#PrintElement2')
}
There's a better approach, however. You can use classes (<div class="PrintElement">) in your HTML to mark print targets and then pick them up from PrintElements using document.getElementsByClassName.
function PrintElements() {
targets = document.getElementsByClassName('PritnElement')
[].forEach.call(targets, function(x) {
PrintElement(x)
})
}

Related

Toggle hide/show not working on childs div

I have a script that gets data from a Google Sheet and displays it as a webpage - using JS and Tabletop.js.
There are multiple entries in the Sheet thus multiple entries in the webpage. To organise the Data I have a hide/show button. When the button is clicked on the first entry it works. However when the any of the other buttons are clicked it hides or shows the first entries data, not its own!
How do I hide/show each individual entries data? Below is the code I am working with!
I am new to JavaScript - Thanks in advance!
P.S - I struggled writing the Title to the questions!
<link href="../common/cats-copy.css" media="screen" rel="stylesheet" type="text/css" />
</head>
<style>
#add-info {
display: none
}
</style>
<body>
<div class="container">
<h1>Resturants</h1>
<div id="content"></div>
<script id="cat-template" type="text/x-handlebars-template">
<div class="entry">
<h5>{{establishment_name}}</h5>
<h6>Area: {{area}}</h6>
<h6>Cuisine: {{cuisine}}</h6>
<button id="btn" class="button-primary" onclick="myFunction()">Hide</button>
<div id="add-info">
<h6>Address: {{address}}</h6>
<h6>Google Maps: {{google_maps_location}}</h6>
<h6>Opening Times: {{opening_times}}</h6>
<h6>Rating: {{rating}}</h6>
<h6>Added By: {{added_by}}</h6>
<h6>Date Added: {{date_added}}</h6>
</div>
</div>
</script>
</div>
<!-- Don't need jQuery for Tabletop, but using it for this example -->
<script type="text/javascript" src="handlebars.js"></script>
<script type="text/javascript" src="../../src/tabletop.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script type="text/javascript">
var public_spreadsheet_url = 'https://docs.google.com/spreadsheets/d/1h5zYzEcBIA5zUDc9j4BTs8AcJj-21-ykzq6238CnkWc/edit?usp=sharing';
$(document).ready( function() {
Tabletop.init( { key: public_spreadsheet_url,
callback: showInfo,
parseNumbers: true } );
});
function showInfo(data, tabletop) {
var source = $("#cat-template").html();
var template = Handlebars.compile(source);
$.each( tabletop.sheets("food").all(), function(i, food) {
var html = template(food);
$("#content").append(html);
});
}
</script>
<script>
function myFunction() {
var x = document.getElementById("add-info");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
</script>
</body>
</html>
Are all the entries on your page filled from the given template, meaning they are divs with the class entry? If so, I think your issue is the following: Your entry div has a child div with the id="add-info". And when you click the button, your handler function (myFunction()) tries to get a reference to that div via document.getElementById("add-info"); Now, if you have multiple such entries on a page, you will have multiple divs with id="add-info". But the id attribute of an element must be unique in your whole document. See the description of id or that of getElementById().
So the root cause of your problem is that the same id is used multiple times in the document when it shouldn't be. You get the behavior you're seeing because getElementById() just happens to be returning a reference to the first element it finds on the page, regardless of which button you click. But I believe you're in undefined behavior territory at that point.
One way to solve the problem is to somehow give myFunction() information about which button was clicked, while making each div you'd like to manipulate unique so they can be found easier. For instance, you can use the order of the restaurant on your page as its "index", and use that as the id of the div you'd like to hide/show. And you can also pass this index as an argument when you call your click handler:
...
<button id="btn" class="button-primary" onclick="myFunction('{{index}}')">Hide</button>
<div id="{{index}}">
<!-- The rest of the code here... -->
...
... add the index into your template context, so Handlebars can fill in the {{index}} placeholder:
...
$.each( tabletop.sheets("food").all(), function(i, food) {
food.index = i // Give your context its 'index'
var html = template(food);
$("#content").append(html);
});
...
... and then alter your function slightly to use the given argument instead of always looking for the div with id="add-info":
function myFunction(indexToToggle) {
var x = document.getElementById(indexToToggle);
// rest of the code is same
With this approach, I expect your DOM to end up with divs that have ids that are just numbers ("3", "4", etc.) and your click handler should get called with those as arguments as well.
Also note that your <button> element has id="btn". If you repeat that template on your page, you will have multiple <button>s with the same id. If you start trying to get references to your buttons via id you will have similar issues with them too since the ids won't be unique.

How can I add a class on Click event

Here is my markup :
<div class="section-dots active-section"></div>
<div class="section-dots"></div>
<div class="section-dots"></div>
<div class="section-dots"></div>
Here is my JavaScript code:
Note, I am building my markup with the following Jquery code, dynamically:
<script>
var count = 1;
var next;
var url;
var elementId;
// First remove all of the dots
$('.section-dots-container').empty();
$('H2').each(function () {
elementId = 'section-' + count;
url = '#section-' + count;
$(this).attr('id', elementId);
$('.section-dots-container').append('<DIV Class="section-dots"></DIV>');
count++;
});
</script>
This is my script for the click event:
<script>
function setActive() {
next = $(this).find('.section-dots');
next.addClass("active-section");
}
</script>
thus it is setActive that should add "active-section" to the Div inside the anchor tag which I am building dynamically. but I not certain if I am doing this correctly.
It seems like it would be easier to just bind the click event to your element in your js code based on its class rather than adding it into your html.
So maybe change markup to include a common class name like:
<div class="section-dots active-section"></div>
<div class="section-dots"></div>
<div class="section-dots"></div>
<div class="section-dots"></div>
And then just bind a click event to all elements with that class:
$('.section').click(function(){
$(this).find('.section-dots').addClass("active-section");
});
I would un-capitalize the DIV and some other things in your code, but this should work if I'm understanding what you want to do.
$('.section-dots').click(function(){
$(this).addClass('active-section');
});
you are using $(this) without passing any parameter to the function.
<script>
function setActive() {
next = $(this).find('.section-dots');
next.addClass("active-section");
}
</script>
useing jquery, select the element you want to add the class to it and use the addClass("class_to_add") function.

slide hidden div on an onclick event

I have the following php while loop code:
while (...($...)){
$convid = $row['ID'];
echo"
<button onclick='getconvo($convid)'>open</button>
<div class="convowrap"></div>
";
}
and the javascript code
<script type='text/javascript'>
$(document).ready(function(){
$(".convowrap").hide(0)
})
</script>
script type='text/javascript'>
function getconvo(id){
$(".convowrap").hide(0).delay(200).slideDown(500)
var convid = id;
$('.convowrap').load('fetch_info.php', {id : convid}, function () {
// do something when success
});
}
</script>
When i click on the button above that says 'open,' all of the div that says convowrap slides, but i only want the current div to slide based on the button that was clicked that was generated from the php while loop.
If the php loop executed three times, when i click on the first button generated by the first loop, the convowrap div slides on all three entries generated by the loop.
What do I do? Please help?
Thanks in advance.
The problem is that all the divs have the same class so its functioning as you it is supposed to ...
As you have the div after the button you can replace
$(".convowrap")
With
$(this).next()
Inside the function for both .load and .hide
(Whichever you want)
more generic
It may be more usefull to assign another class to each div like
<div class='convowrap dummyclass$convid'></div>
And on button click change the selector to match that class like
$('dummyclass'+id)
Hope this helps
As you are using inline onlclick function inside HTML, you have to pass this explicitly like onclick='getconvo(this)'.
Anyway, see the following fiddle and hope you wanted this workaround -
https://jsfiddle.net/nuhil/4scas2gh/
Code:
<button onclick='getconvo(this)' id="1">Button 1</button>
<div class="convowrap">Content First</div>
<br/>
<button onclick='getconvo(this)' id="2">Button 2</button>
<div class="convowrap">Content Second</div>
<!-- More pairs of (button and div) go here -->
<script>
$(document).ready(function(){
$(".convowrap").hide();
})
function getconvo(button){
$(button).next().delay(200).slideDown(500);
// You could use toggle here like following for better UX
// $(button).next().toggle("slow");
// Anyway,
// Get the id from button attribute but make sure you already set it by PHP
var convid = $(button).attr("id");
console.log(convid);
// $(button).next().load('fetch_info.php', {id : convid}, function () {
// do something when success
// });
}
</script>

detect element where the function was called from

I need to know where my jQ function was called from...
In head:
function call_pl2(){
$(this).text('some text');
}
in Body:
<p> <script> call_pl2(); </script> </p>
<!-- OR -->
<div> <script> call_pl2(); </script> </div>
I got your point, I'm afraid you cannot get from the function the element that your js function is there, but each time that your function is called you can use another function and search your html content to see where this function is inside. I assume that this function is called ones from the html code when this is loaded.
Instead of trying to determine which element contains the the script tag (and, by extension, a particular call to call_pl2()) you could explicitly pass the containing element to call_pl2() as a parameter:
$(function() {
var call_p12 = function(element) {
if ($(element).is('p')) {
$(element).text('here is some text added to a paragraph');
}
if ($(element).is('div')) {
$(element).text('here is some text added to a div');
}
}
$('div, p').each(function() {
call_p12($(this));
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<p></p>
<div></div>
It would be relatively easy to modify the call_p12() function to swap in a more specific selector in the jQuery is(). For example is('.someclass') to check for a class value instead of a tag name.

how to recode my jquery/javascript function to be more generic and not require unique identifiers?

I've created a function that works great but it causes me to have a lot more messy html code where I have to initialize it. I would like to see if I can make it more generic where when an object is clicked, the javascript/jquery grabs the href and executes the rest of the function without the need for a unique ID on each object that's clicked.
code that works currently:
<script type="text/javascript">
function linkPrepend(element){
var divelement = document.getElementById(element);
var href=$(divelement).attr('href');
$.get(href,function (hdisplayed) {
$("#content").empty()
.prepend(hdisplayed);
});
}
</script>
html:
<button id="test1" href="page1.html" onclick="linkPrepend('test1')">testButton1</button>
<button id="test2" href="page2.html" onclick="linkPrepend('test2')">testButton1</button>
<!-- when clicking the button, it fills the div 'content' with the URL's html -->
<div id="content"></div>
I'd like to end up having html that looks something like this:
<button href="page1.html" onclick="linkPrepend()">testButton1</button>
<button href="page2.html" onclick="linkPrepend()">testButton1</button>
<!-- when clicking the button, it fills the div 'content' with the URL's html -->
<div id="content"></div>
If there is even a simpler way of doing it please do tell. Maybe there could be a more generic way where the javascript/jquery is using an event handler and listening for a click request? Then I wouldn't even need a onclick html markup?
I would prefer if we could use pure jquery if possible.
I would suggest setting up the click event in JavaScript (during onload or onready) instead of in your markup. Put a common class on the buttons you want to apply this click event to. For example:
<button class="prepend-btn" href="page2.html">testButton1</button>
<script>
$(document).ready(function() {
//Specify click event handler for every element containing the ".prepend-btn" class
$(".prepend-btn").click(function() {
var href = $(this).attr('href'); //this references the element that was clicked
$.get(href, function (hdisplayed) {
$("#content").empty().prepend(hdisplayed);
});
});
});
</script>
You can pass this instead of an ID.
<button data-href="page2.html" onclick="linkPrepend(this)">testButton1</button>
and then use
function linkPrepend(element) {
var href = $(this).data('href');
$.get(href, function (hdisplayed) {
$("#content").empty().prepend(hdisplayed);
});
}
NOTE: You might have noticed that I changed href to data-href. This is because href is an invalid attribute for button so you should be using the HTML 5 data-* attributes.
But if you are using jQuery you should leave aside inline click handlers and use the jQuery handlers
<button data-href="page2.html">testButton1</button>
$(function () {
$('#someparent button').click(function () {
var href = $(this).data('href');
$.get(href, function (hdisplayed) {
$("#content").empty().prepend(hdisplayed);
});
});
});
$('#someparent button') here you can use CSS selectors to find the right buttons, or you can append an extra class to them.
href is not a valid attribute for the button element. You can instead use the data attribute to store custom properties. Your markup could then look like this
<button data-href="page1.html">Test Button 1</button>
<button data-href="page2.html">Test Button 1</button>
<div id="content">
</div>
From there you can use the Has Attribute selector to get all the buttons that have the data-href attribute. jQuery has a function called .load() that will get content and load it into a target for you. So your script will look like
$('button[data-href]').on('click',function(){
$('#content').load($(this).data('href'));
});
looking over the other responses this kinda combines them.
<button data-href="page2.html" class="show">testButton1</button>
<li data-href="page1.html" class="show"></li>
class gives you ability to put this specific javascript function on whatever you choose.
$(".show").click( function(){
var href = $(this).attr("data-href");
$.get(href,function (hdisplayed) {
$("#content").html( hdisplayed );
});
});
This is easily accomplished with some jQuery:
$("button.prepend").click( function(){
var href = $(this).attr("href");
$.get(href,function (hdisplayed) {
$("#content").html( hdisplayed );
});
});
And small HTML modifications (adding prepend class):
<button href="page1.html" class="prepend">testButton1</button>
<button href="page2.html" class="prepend">testButton2</button>
<div id="content"></div>
HTML code
<button href="page1.html" class="showContent">testButton1</button>
<button href="page2.html"class="showContent">testButton1</button>
<!-- when clicking the button, it fills the div 'content' with the URL's html -->
<div id="content"></div>
JS code
<script type="text/javascript">
$('.showContent').click(function(){
var $this = $(this),
$href = $this.attr('href');
$.get($href,function (hdisplayed) {
$("#content").empty().prepend(hdisplayed);
});
}
});
</script>
Hope it helps.

Categories

Resources