2

I am building a webpage with a customisable print settings.What happens is that whenever the print button is clicked, a dialog box is opened (I did with the onclick attribute and some js). The dialog box has some checkboxes, which are named as follows:

  • Remove Menu
  • Remove sidebars
  • Remove links and buttons
  • Remove comments

So, what I want is, whenever a user clicks the checkboxes, the linked items are removed from the @media print queries.

So, the ways I can think of is to use media queries in JavaScript or conditional statements in css.

Is it possible or some other language is required?

SK-the-Learner
  • 523
  • 5
  • 18

4 Answers4

3

What I would recommend instead is adding/removing classes to the items, and including them in your print CSS. Could be as simple as:

.hidden {
  display: none;
}

Then, in your JavaScript:

document.querySelector('.comments').classList.add('hidden');

See also: https://developer.mozilla.org/en-US/docs/Web/API/Element/classList

Brad
  • 159,648
  • 54
  • 349
  • 530
  • This would not be customisable then... The items would automatically be clipped while printing. I want it to be the users' choice to remove or keep the items – SK-the-Learner Feb 09 '21 at 06:04
  • @WebDevelopmentPro I don't follow what the issue is. Of course it's customizable. Are you asking how to handle `change` events on input checkboxes? You only add/remove the `hidden` class (or whatever you end up calling it) when the user indicates in the form that that's what they want. – Brad Feb 09 '21 at 06:05
  • What I want is, on clicking the checkbox, the linked item is set to `display: none;` from the print css, and as soon as it is unchecked, the items are set to `display: block;` in the print css @Brad – SK-the-Learner Feb 09 '21 at 06:10
  • 1
    @WebDevelopmentPro Right, exactly. I'm telling you, you can do this simply by adding/removing a class based on the checkbox state. That way, you can keep your CSS in your CSS. – Brad Feb 09 '21 at 06:17
  • You mean tht the JavaScript yove given should be used with an `onclick` attribute, added to the checkbox? @Brad – SK-the-Learner Feb 09 '21 at 06:23
  • 1
    @WebDevelopmentPro I would use `onchange`, but yes. – Brad Feb 09 '21 at 06:59
  • I have some doubts over your answer, so could you please provide me a working snippet... @Brad – SK-the-Learner Feb 10 '21 at 03:58
  • @WebDevNoob Show us the code you've tried so there is something to go off of... – Brad Feb 10 '21 at 04:25
  • Umm, after using your code in a document, I’ve understood it. Thank you! – SK-the-Learner Feb 10 '21 at 07:18
1

Working:

  • Click on Update Print Info button to update the print info and then click submit.

  • After closing of modal click on Print button to find out the changes.

I hope this code will help lots of users in future too.

Good Luck Everyone.

function update_print()
{
  var style = "<style>@media print {";
    if (document.getElementById('remove_menu').checked)
    {
        style += ".menu { display: none; }";
    }
    if (document.getElementById('remove_sidebars').checked)
    {
        style += ".sidebars { display: none; }";
    }
    if (document.getElementById('remove_links_buttons').checked)
    {
        style += ".links_buttons { display: none; }";
    }
    if (document.getElementById('remove_comments').checked)
    {
        style += ".comments { display: none; }";
    }
    style += "}</style>";
    document.getElementById("div_for_style").innerHTML = style;
  $('#myModal').modal('hide');
}
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>

<div id="print_box">
    <p class="menu">This is Menu</p>
    <p class="sidebars">This is Sidebar</p>
    <p class="links_buttons">This is Links & Buttons</p>
    <p class="comments">This is Comments</p>
</div>

<style>
@media print {
  .hide_while_print
  {
      display: none;
  }
}
</style>

<div class="container">
  <div class="hide_while_print">
  <button type="button" class="btn btn-info btn-md" data-toggle="modal" data-target="#myModal">Update Print Info</button>
  <button type="button" class="btn btn-info btn-md" onclick="window.print();">Print</button>
  </div>
</div>

<!-- Modal -->
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">

  <!-- Modal content-->
  <div class="modal-content">
    <div class="modal-header">
      <button type="button" class="close" data-dismiss="modal">&times;</button>
      <h4 class="modal-title">Print Information</h4>
    </div>
    <div class="modal-body">
        <input type="checkbox" id="remove_menu" /> <label for="remove_menu">Remove Menu</label>
        <br />
        <input type="checkbox" id="remove_sidebars" /> <label for="remove_sidebars">Remove sidebars</label>
        <br />
        <input type="checkbox" id="remove_links_buttons" /> <label for="remove_links_buttons">Remove Links & Buttons</label>
        <br />
        <input type="checkbox" id="remove_comments" /> <label for="remove_comments">Remove Comments</label>
    </div>
    <div class="modal-footer">
      <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <input type="button" class="btn btn-success btn-sm" onclick="update_print();" value="Submit" />
    </div>
  </div>
  
</div>
</div>

<div id="div_for_style"></div>
John Doe
  • 1,401
  • 1
  • 3
  • 14
  • Ok, your snippet works actually fine, but maybe there is some problem. When the "update print settings" is clicked, the dialog box opens, but does not close on clicking "submit". Well that's not a serious problem, but after the "close" button is clicked and we print the snippet, there is some css-like-text which comes in the print preview... – SK-the-Learner Feb 09 '21 at 06:45
  • Ok, thank you! But is it possible without linking external stylesheets or scripts? Also, I didn't understand why you used the`innerHTML`... – SK-the-Learner Feb 09 '21 at 06:56
  • This is because the overall document is already huge. – SK-the-Learner Feb 09 '21 at 06:57
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/228452/discussion-between-john-doe-and-web-development-pro). – John Doe Feb 09 '21 at 06:57
1

As a complementary answer to this one: the snippet provided can benefit from refactoring to avoid common pitfalls:

  1. Do not use inline event attributes, the modern way is to use addEventListener instead (if you absolutely must support old browsers, utilize polyfills and bundlers, but do not write your source code like that).
  2. Make the code maintainable by avoiding string concatenation and sets of if statements. There is a native way to modify Element classes - via the classList property exposing DOMTokenList methods like add or remove.
  3. Avoid using innerHTML to update nodes (see, for example, here for details) and element styles (you can use style property to update specific values programmatically).

Below is a reworked snippet dealing with the issues above (note the HTML markup changes as well):

(() => {
  const $ = (selector) => document.querySelector(selector);
  const $$ = (selector) => document.querySelectorAll(selector);

  const submitBtn = $("#submit");
  const modal = $("#myModal");
  const inputs = $$("input[type=checkbox]");
  const hideClass = "hide_while_print";

  submitBtn.addEventListener("click", (event) => {
    inputs.forEach(({
      id,
      checked
    }) => {
      const {
        classList
      } = $(`.${id.replace("remove_", "")}`);
      checked ? classList.add(hideClass) : classList.remove(hideClass);
    });

  });

  $("#print").addEventListener("click", () => window.print());
})();
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>

<div id="print_box">
  <p class="menu">This is Menu</p>
  <p class="sidebars">This is Sidebar</p>
  <p class="links_buttons">This is Links & Buttons</p>
  <p class="comments">This is Comments</p>
</div>

<style>
  @media print {
    .hide_while_print {
      display: none;
    }
  }
</style>

<div class="container">
  <div class="hide_while_print">
    <button type="button" class="btn btn-info btn-md" data-toggle="modal" data-target="#myModal">Update Print Info</button>
    <button id="print" type="button" class="btn btn-info btn-md">Print</button>
  </div>
</div>

<!-- Modal -->
<div class="modal fade" id="myModal" role="dialog">
  <div class="modal-dialog">

    <!-- Modal content-->
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal">&times;</button>
        <h4 class="modal-title">Print Information</h4>
      </div>
      <div class="modal-body">
        <input type="checkbox" id="remove_menu" /> <label for="remove_menu">Remove Menu</label>
        <br />
        <input type="checkbox" id="remove_sidebars" /> <label for="remove_sidebars">Remove sidebars</label>
        <br />
        <input type="checkbox" id="remove_links_buttons" /> <label for="remove_links_buttons">Remove Links & Buttons</label>
        <br />
        <input type="checkbox" id="remove_comments" /> <label for="remove_comments">Remove Comments</label>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-success" data-dismiss="modal" id="submit">Submit</button>
      </div>
    </div>

  </div>
</div>

In the snippet, I shadowed $ to define a lightweight utility using DOM API. If you do not use Bootstrap (which has JQuery as a hard dependency), the $ and $$ utilities can allow you to avoid loading JQuery just to select elements.

0

You can use :checked:

@media print {
  .checkbox-class:checked + .remove-me {
    display: none;
  }
}

Remember the element with the class .remove-me should be adjacent siblings. Like this:

<label for="checkbox-id">Click Me</label>
<input type="checkbox" id="checkbox-id" class="checkbox-class">

<div class="remove-me">
  Lorem ipsum dolor sit amet consectetur adipisicing elit.
</div>

Check it in action on Codepen: Editor View Debug Mode

Manas Khandelwal
  • 3,790
  • 2
  • 11
  • 24