How to split some html content by "page breaker"? - javascript

I use ckeditor in my website, which supports "page breaker". The sample content contains page breakers like:
<h1>
Little Red Riding Hood</h1>
<p>
"<b>Little Red Riding Hood</b>" is a famous fairy tale about a young girl's encounter with a wolf. The story has been changed considerably in its history and subject to numerous modern adaptations and readings.</p>
<div style="page-break-after: always;">
<span style="display: none;"> </span></div>
<p>
The version most widely known today is based on the Brothers Grimm variant. It is about a girl called Little Red Riding Hood, after the red hooded cape or cloak she wears. The girl walks through the woods to deliver food to her sick grandmother.</p>
This special div is page breaker:
<div style="page-break-after: always;">
<span style="display: none;"> </span></div>
I want to use javascript to split the content into multi pages by the page breaker, to tell the user how many pages the content will be, and can let user preview each page.
But how to check and split it? Is there a pure javascript or "Extjs" based solution?

You can use the String.prototype.split(); function for this: container.innerHTML.split('<div style="page-break-after: always;">');, assuming the container for your HTML code to be container.
You can use Regular Expressions for this:
var regexp = /<div\s+style=('")page-break-after:\s*always;?.*?$1[^>]*>.*?<\/div>/gm;
Which will find all the breaker DIVs for you. You can then split the string using that.

Use regex:
content.split(/<div style="page-break-after: always;">[\s\S]*?<\/div>/)
Is there a better way for [\s\S] part? I think it's a little strange.

HTML:
<form name="myform">
<input type="checkbox" name="mybox" onClick="breakeveryheader()">
</form>
JavaScript:
function breakeveryheader(){
var thestyle=(document.forms.myform.mybox.checked)? "always" : "auto"
for (i=0; i<document.getElementsByTagName("H2").length; i++)
document.getElementsByTagName("H2")[i].style.pageBreakBefore=thestyle
}

Related

How can I make a "read-more" button for mutiple text elements?

I have multiple images on my website with some text about each image.
<div>
<h2>I still get butterflies</h2>
<p>
A virtuoso display of personality. A sophisticated layered piece that depicts dynamism and vibrancy while also betraying the turmoil and tranquility of humanity. The artist’s ode to the enduring Metamorphosis of an individual and so
much more.
<span id="text">
<br />
The artist’s personality is on full display. A breathtakingly beautiful piece; full of energy, light, sorrow, and pain. The artist’s vision will shake you to the very core. This hauntingly post-modernist piece is an exercise in
raw emotion on canvas; that demands the full attention of the viewer. It is a raw un-tempered glimpse into the fabric of humanity. The vibrancy of colors harmoniously interact with the chaotic themes on display. This artwork
pulls you in, what message you see in it, what themes you feel the artwork depict are entirely up to you. It will touch everyone differently. You and your guest will see a part of you depicted on the painting, a facet of your
life laid bare.
<br />
"I still get butterflies" is a fascinating portrayal of humanity. The dance of colors, the vibrant display of personality and the chaotic themes on display perfectly gel together to depict the elegance and the reality
of existence.
</span>
</p>
<button id="toggle" class="astext">Read More</button>
</div>
<div>
<h2>To levitate</h2>
<p>
"To levitate" is a thoughtful, emotional piece that transcends the fabric of reality. This piece appeals directly to the senses, beneath the incessant and formidable dance of colors is a rapturous delight. Ecstasy, so
profound, so pure that it borders on angelic transformation.
<span id="text">
<br />
"To levitate" is at its heart a deeply disquieting and disturbing display of strange nature that is at once entirely realistic and yet almost supernatural. It conveys a message of self-realization and self-acceptance:
to break free from the chaos of life. The artist portrays a dazzling song that is beautifully pure. "To levitate" is a majestic creation of colors. It betrays the indefinable aroma of the artist&apos;s sincerity to
their vision and intercourse with reality. The message of the piece transcends reality, borders on the supernatural, yet within that artistic expression is perhaps the most human message of all.
<br />
"To levitate" is a deeply feverish piece. At first glance the piece conveys a sense of chaos; it blends the supernatural with reality, but beneath all that chaos lies the harmony of colors, the artist&apos;s intention,
and a beautifully sublime message.
</span>
</p>
<button id="toggle" class="astext">Read More</button>
</div>
<div>
<p>January 14<sup>th</sup>, 2021</p>
<img data-src="./images/portfolio/5524E4534A898F56064C481CD305C703.webp" class="lazyload" alt="my image" />
</div>
The access text is hidden with css #text {display: none;}
Alongside with the HTML & CSS goes JS/jquery code to show the rest on the buttonclick
$(document).ready(function() {
$("#toggle").click(function() {
var elem = $("#toggle").text();
if (elem == "Read More") {
//Stuff to do when btn is in the read more state
$("#toggle").text("Read Less");
$("#text").slideDown();
} else {
//Stuff to do when btn is in the read less state
$("#toggle").text("Read More");
$("#text").slideUp();
}
});
});
Is there a way to show the text according to what button was clicked, without having a seperate script for each?
First of all, use classes instead of IDs in this case. Having multiple elements with the same ID is a big no-no. Then, make the use of jQuery's $(this), along with the sibling and children selectors, to get what you want. $(this) selects only the element you just clicked, and siblings/children will only target the text elements that are directly related to that button within the same div. This Codepen has a live demo.
HTML:
<div>
<h2>I still get butterflies</h2>
<p>
A virtuoso display of personality. A sophisticated layered piece that depicts dynamism and vibrancy while also betraying the turmoil and tranquility of humanity. The artist’s ode to the enduring Metamorphosis of an individual and so
much more.
<span class="text">
<br />
The artist’s personality is on full display. A breathtakingly beautiful piece; full of energy, light, sorrow, and pain. The artist’s vision will shake you to the very core. This hauntingly post-modernist piece is an exercise in
raw emotion on canvas; that demands the full attention of the viewer. It is a raw un-tempered glimpse into the fabric of humanity. The vibrancy of colors harmoniously interact with the chaotic themes on display. This artwork
pulls you in, what message you see in it, what themes you feel the artwork depict are entirely up to you. It will touch everyone differently. You and your guest will see a part of you depicted on the painting, a facet of your
life laid bare.
<br />
"I still get butterflies" is a fascinating portrayal of humanity. The dance of colors, the vibrant display of personality and the chaotic themes on display perfectly gel together to depict the elegance and the reality
of existence.
</span>
</p>
<button class="toggle astext">Read More</button>
</div>
<div>
<h2>To levitate</h2>
<p>
"To levitate" is a thoughtful, emotional piece that transcends the fabric of reality. This piece appeals directly to the senses, beneath the incessant and formidable dance of colors is a rapturous delight. Ecstasy, so
profound, so pure that it borders on angelic transformation.
<span class="text">
<br />
"To levitate" is at its heart a deeply disquieting and disturbing display of strange nature that is at once entirely realistic and yet almost supernatural. It conveys a message of self-realization and self-acceptance:
to break free from the chaos of life. The artist portrays a dazzling song that is beautifully pure. "To levitate" is a majestic creation of colors. It betrays the indefinable aroma of the artist&apos;s sincerity to
their vision and intercourse with reality. The message of the piece transcends reality, borders on the supernatural, yet within that artistic expression is perhaps the most human message of all.
<br />
"To levitate" is a deeply feverish piece. At first glance the piece conveys a sense of chaos; it blends the supernatural with reality, but beneath all that chaos lies the harmony of colors, the artist&apos;s intention,
and a beautifully sublime message.
</span>
</p>
<button class="toggle astext">Read More</button>
</div>
<div>
<p>January 14<sup>th</sup>, 2021</p>
<img data-src="./images/portfolio/5524E4534A898F56064C481CD305C703.webp" class="lazyload" alt="my image" />
</div>
JS:
$(document).ready(function() {
$(".toggle").click(function() {
var elem = $(this).text();
if (elem == "Read More") {
//Stuff to do when btn is in the read more state
$(this).text("Read Less");
$(this).siblings().children('.text').slideDown();
} else {
//Stuff to do when btn is in the read less state
$(this).text("Read More");
$(this).siblings().children('.text').slideUp();
}
});
});
It looks like you are using jQuery already. You might want to consider using the toggle() function, which is just for this purpose:
https://www.w3schools.com/jquery/eff_toggle.asp
$("#toggle").click(function(){
$("#text").toggle();
});

Odoo-9, my widget doesn't work in QWeb view

I have made a widget in Odoo 9 for cutting product description in website view. Added widget="short_desc" to product form view and website product view. I mean something like that:
<span t-field="product.description"/> <!-- full description -->
<span t-field="product.description" t-field-options='{"widget": "short_desc"}'/> <!-- short description -->
<span t-field="product.description" widget="short_desc"/> <!-- also tried this syntax -->
I found helpful this answer: Odoo 9. How to override form widgets?, but it works only in product form and doesn't on website.
So, I have a widgets.js:
odoo.define('wsup.widgets', function (require) {
'use strict';
var core = require('web.core');
var FieldChar = core.form_widget_registry.get('char');
var ShortDescriptionView = FieldChar.extend({
render_value: function() {
console.log('hey, im working!');
this.$el.html('<span>Ok, widget really works</span>');
},
});
core.form_widget_registry.add('short_desc', ShortDescriptionView);
});
When I go to Sales -> Products and open any product, I can see "Ok, widget really works" instead of its description, but when I go to /shop page — product description still has no changes and nothing in JS console.
Here is part of my website product XML view (it works good at all, except short description part):
<div class="product-preview oe_website_sale">
<div class="product-preview__image">
<a t-attf-href="/shop/product/{{ item.id }}">
<span itemprop="image" t-field="item.image" t-field-options='{"widget": "image"}' t-att-alt="item.name"/>
</a>
</div>
<div class="product-preview__info text-center">
<div class="product-preview__info__title">
<h2><a t-attf-href="/shop/product/{{ item.id }}"><span t-field="item.name"/></a></h2>
</div>
<div class="product-preview__info__description">
<p><span t-field="item.description" t-field-options='{"widget": "short_desc"}'/></p>
</div>
</div>
</div>
Why it doesn't work on /shop page? What I forgot to do? Thank you.
As I understand your comment your requirement was to show small amount of description rather than showing a huge description. So, I think this requirement can be easily achieved without create a widget.
Suppose, you have this content as description:
Two is better than one.
Unlike many small headphones, each earpiece of the Apple In-Ear Headphones contains two separate high-performance drivers — a woofer to handle bass and mid-range sounds and a tweeter for high-frequency audio. These dedicated drivers help ensure accurate, detailed sound across the entire sonic spectrum. The result: you’re immersed in the music and hear details you never knew existed. Even when listening to an old favorite, you may feel like you’re hearing it for the first time.
And from this much description if you want to show small amount of description or number of words than you can simple use the below code.
<span t-if="product.website_description and len(product.website_description) > 500">
<t t-set="description" t-value="product.website_description[:500] and product.website_description[:500].replace('+', '\n')+'...'"/>
<p class="text-muted ">
<t t-raw="description"/>
</p>
</span>
In this above code, [:500] will be the number of words to be used.
Output will be:
Two is better than one.
Unlike many small headphones, each earpiece of the Apple In-Ear Headphones contains two separate high-performance drivers — a woofer to han...
Hope, this code will help you.
Thanks.

Convert HTML content to PNG or SVG

I am currently using dom-to-image to convert elements on a page to an image but i would like to convert the content in the textarea to an image.
For example:
JSFIDDLE EXAMPLE
<textarea>
<div class="w3-row">
<div class="w3-third w3-container w3-padding-24"><img src="http://www.w3schools.com/images/w3cert.gif" style="width:100%;" alt="W3Schools Certification"> </div>
<div class="w3-twothird w3-container"><h2>W3Schools' Online Certification</h2>
<p>The perfect solution for professionals who need to balance work, family, and career building.</p>
<p>More than 10 000 certificates already issued!</p>
</div>
</div>
</textarea>
Let me know details of the issue are clear. Would really appreciate the assistance
HTML2canvas allows you to take a snapshot of the a DOM segment. I am not sure sure about SVG though, these scripts will be very helpful though.

Is there a way to add an element to the same height as another selected element dynamically?

I am new to front-end development. I was trying to code an annotation tool. A sample screen is shown on the image below. After the user select a sentence, an annotation box appears on the right side bar at the same horizontal position as the highlighted sentence. Any ideas about how I can achieve that effect?
Here is my html structure. I used the framework of Zurb Foundation:
<section id="main">
<div class="row">
<div class="small-8 large-8 columns"id="rawdata">
<p> <span class="sentence">2:22 So, last time I was here, I don't know if I told you this, but, um, we kind of did a "I like, I wish" activity on paper, about things that you like about studio, and things that you wish would change.</span><span class="sentence"> Um, do you want to share any of those thoughts now, so maybe we can talk about them? [name], I have yours if you want to look at it again.</span></p>
<p><span class="sentence">2:47 I forgot to add something.</span></p>
<p><span class="sentence">2:54 Well, I don't know, in terms of what I dislike about studio.</span></p>
<p><span class="sentence">2:57 So, some people wrote in theirs that, um, they dislike how cluttered it gets.</span></p>
<p><span class="sentence">5:09 I don't get bothered.</span>< <span class="sentence">I like the draftiness, I'm a little...</span><span class="sentence"> I'm one of the ones that opens the windows, and like—</span></p>
</div>
<div class="small-4 large-4 columns" id="annotations"><p></p>
</div>
</div>
</section>
JS for selecting sentence and adding annotations:
<script>
$('.sentence').click(function() {
$(this).toggleClass('sentenceStyle');
var y = $(this).offset().top;
var para = document.createElement("p");
$("#annotations").append(para);
para.innerHTML="this is an annotation";
para.css("position",'absolute');
para.style.top = y;
});
</script>
And here it is the fiddle: http://jsfiddle.net/yujuns/HDe6v/3/
There are some things that you want to change in your code.
First what you want is to get the offset of the selection. That can only happen if you put an html tag around the selection and then get its offset. You can then place an absolute positioned message box by setting its left and top offset to the offset you got from html element.
In the following fiddle, I have shown a basic implementation to give you the basic idea. Hope it helps.
Fiddle
EDIT:
Try this fiddle update.(In response to author's question). I have added comments to lines of code that I added to js. I also added position: relative to css for annotations
Updated Fiddle

jQuery fade out fade in replaces text while jumping instead of overlaying

The below code is running on the following web page. If you click any of the three buttons on the left under the rotating banner you will see the behaviour I talk about. The text next to the buttons is meant to fade out and fade in a new section. But the new section fades in before the first is gone and jumps back up.
I thought as I was using a callback function for the fade in that this would not occur. Can anyone advise as to what I should be doing?
http://www.tacticalsalestraining.co.uk/
<span style="float:left;">
<a target="_blank" href="http://www.tacticalsalestraining.co.uk/sales-training-courses-listing" class="textbutton" data-conn="text1">
<img src="/images/OpenOver.png" alt="Open Courses" width="300" height="47">
</a><br />
<a target="_blank" href="http://www.tacticalsalestraining.co.uk/sales-training-courses-listing" class="textbutton" data-conn="text2">
<img src="/images/InHouseOver.png" alt="In House Training" width="300" height="47">
</a><br />
<a href="http://tacticalsalestraining.com/seminars/seminars_full.html" class="textbutton" data-conn="text3">
<img src="/images/FreetoAttendOver.png" alt="Free to Attend" width="300" height="47">
</a>
</span>
<span style="width:610px;height:200px;float:right; background-color:#bcbcbc;font-size:15px;line-height:15px;">
<div class="texts" id="text"><h1>UK's Fastest Growing Sales Training Company</h1>
Tactical Sales Training, providers of measurably effective sales courses for all industries. We offer training that's interactive, effective and straight out of our own playbook.<br />
We practice what we teach; the courses are filled with exactly what we do back in the office when prospecting for new clients or looking to close deals.
</div>
<span class="texts" id="text1" style="display:none;"><h2>Action Based Open Sales Courses, Nationwide</h2>
Trouble getting new business? Difficulty closing that deal? How's your qualification going? These are questions that can define the difference between a good or great sales person. We've helped 100s of businesses exponentially increase their sales with our open courses, what can we do for you?
</span>
<span class="texts" id="text2" style="display:none;"><h2>For the More Tricky Sales Processes</h2>
Getting to the root of the problem or finding the perfect solution can be a call for our bespoke option. Many national and international companies have opted for this because they wanted us to look deep into their sales processes.<br /><br />
They also wanted the perfect solution with instantly actionable solutions that prove the effectiveness with measurable results. We've provided just that, every single time we go out on a bespoke mission.
</span>
<span class="texts" id="text3" style="display:none;">Content Text</span>
</span>
<script>
$(".textbutton").click(function(){
var link = $(this).attr("data-conn");
$(".texts").fadeOut(1000, function() {
$("#"+link).fadeIn(1000);
});
return false;
});
</script>
One problem with your script is that you apply fadeOut on all items with texts class & try to fadeIn one of them back. The better approach would be to keep track of the current selected text, say by adding another class selected.
Here is the modified script you could work on. One of the items with texts class has to have the selected class all the time.
$(".textbutton").click(function(){
var link = $(this).attr("data-conn");
$(".texts.selected").removeClass("selected").fadeOut(1000, function() {
$("#"+link).addClass("selected").fadeIn(1000);
});
return false;
});
$(".texts:first()").addClass("selected");

Categories