How can I make multipage intro by using Intro.js programmatic - javascript

Hello I just start learning with javascript and I would like to know how to make multipage intro by using intro.js
function beginer() {
var intro = introJs();
intro.setOptions({
steps: [
{
element: '#beginer1',
intro: "This is a <b>bold</b> tooltip."
},
{
element: '#beginer2',
intro: "Ok, <i>wasn't</i> that fun?",
position: 'bottom'
},
]
});
intro.setOptions({
'showStepNumbers': false
});
intro.start();
}

It is as simple as combining the options given in the multipage and programmatic examples in the repo. The multipage example is here
All you got to do is add an onComplete listener on the first page like so:
function beginer() {
var intro = introJs();
intro.setOptions({
showStepNumbers: false,
doneLabel: "Next page",
steps: [
{
element: '#beginer1',
intro: "This is a <b>bold</b> tooltip."
},
{
element: '#beginer2',
intro: "Ok, <i>wasn't</i> that fun?",
position: 'bottom'
},
]
});
intro.start().oncomplete(function() {
window.location.href = 'second.html?multipage=true';
});
}
I have sanitized the setOptions call in your function and combined all the options there. So that you don't have to do setOptions multiple doneLabel param. I guess, it triggers the oncomplete method which is defined after intro.start(). It redirects to the next page which in my case is second.html. Remember to pass the param multipage=true.
second.html is a regular HTML file but you need to start the introJs function to make the whole transition mulitpage. All you do is:
<script type="text/javascript">
if (RegExp('multipage', 'gi').test(window.location.search)) {
introJs().start();
}
</script>
This in essence triggers the introJs().start() function after it finds the word multipage in the url or href in your browser address bar. Remember we called second.html like second.html?multipage=true. This just starts another intro instance on the second page. Now you can define the options here in form of JSON if you want or just use the data-step attributes on DOM as defined in the docs.
Hope it gets you started in the right direction.

Related

Monaco Editor: only show part of document

Is there a way to only show part of a document, or in monacos case of a model, while still getting intellisense for the whole document?
I only want a user to edit a part of a document, but the user should be able to get the right contextual intellisense.
It would be best for my usecase to hide the uneditable sections, but deactivating them would also be ok.
In case this is not possible, is there any embedded editor that can do this, or can this be achived by modifying the language server?
Monaco editor loads every line as a container under a section with the class name "view-lines". Once the editor content has loaded, set "display: none" to the corresponding container for each line that you want to hide.
Implementation: https://jsfiddle.net/renatodc/s6fxedo2/
let value = `function capitalizeFirstLetter(string) {
\treturn string.charAt(0).toUpperCase() + string.slice(1);
}
$(function() {
\tlet word = "script";
\tlet result = capitalizeFirstLetter(word);
\tconsole.log(result);
});
`
let linesToDisable = [1,2,3];
let editor = monaco.editor.create(document.getElementById('container'), {
value,
language: 'javascript',
theme: 'vs-dark',
scrollbar: {
vertical: "hidden",
handleMouseWheel: false
},
scrollBeyondLastLine: false
});
// onLoad event for Monaco Editor: https://github.com/Microsoft/monaco-editor/issues/115
let didScrollChangeDisposable = editor.onDidScrollChange(function() {
didScrollChangeDisposable.dispose();
setTimeout(function() {
$(".monaco-editor .view-lines > div").each(function(i) {
if(linesToDisable.includes(i+1)) {
$(this).css("display","none");
$(this).css("pointer-events","none");
}
});
},1000);
});
Scrolling from Monaco will render the lines again and break the implementation. To prevent this, disable the scrolling feature in Monaco, set a fixed height for the editor container, and use the browser or a parent container to scroll instead.
If you use the arrow keys 'up' or 'down' to navigate to the hidden content, the cursor will still work, and typing will break the implementation. You might be able to use the editor's onKeyDown event to prevent this.
If you're looking for a break-proof implementation, I would suggest loading Monaco editor only with the portion of the document that you wish to edit. Then extend the completion provider (Intellisense) as shown in this example: https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-completion-provider-example
monaco.languages.registerCompletionItemProvider('javascript', {
provideCompletionItems: function(model, position) {
return {
suggestions: [
{
label: "capitalizeFirstLetter",
kind: monaco.languages.CompletionItemKind.Method,
documentation: "Capitalize the first letter of a word",
insertText: "capitalizeFirstLetter("
}
]
};
}
});
monaco.editor.create(document.getElementById("container"), {
value: `$(function() {
\tlet word = "script";
\tlet result = capitalizeFirstLetter(word);
\tconsole.log(result);
});
`,
language: "javascript"
});
Use an AST parser like Esprima to get the identifiers from your source document, and plug these into the suggestions array.

Polymer back button doesn't work with hash routing

Sup! Back button sometimes doesn't work with my polymer project. When i hit back button the page variable is steel the current page and i need to hit the button twice or three times to get it working for example i go to the /#/rules page from /#/home but it doesn't go back to /#/home once i press the back button the second or third time by the way it does go back to the main page. Here is my observer and router:
properties: {
page: {
type: String,
reflectToAttribute: true,
observer: '_pageChanged',
},
},
observers: [
'_routePageChanged(routeData.page)',
],
_routePageChanged: function (page) {
this.page = page || 'home';
this.set('route.path', `/${this.page}`);
},
_pageChanged: function (page) {
// Load page import on demand. Show 404 page if fails
var resolvedPageUrl = this.resolveUrl(page + '.html');
this.importHref(resolvedPageUrl, null, this._showPage404, true);
window.history.pushState({}, null, `#/${this.page}`);
},
And this is my app-route element:
<app-route route="{{route}}" pattern="/:page" data="{{routeData}}" tail="{{subroute}}"></app-route>
Just can't figure out why it does not work the first time. Any help is appreciated and i have already searched a lot with no results.
Can you try this, assuming you have <app-route route="{{route}}"></app-route>?
observers: [
'_routePageChanged(route.path)',
],
_routePageChanged: function(path) {
if (path) {
this.page = this.routeData.page;
} else {
/*
* It's unnecessary to have the following line.
*/
// this.page = 'home';
this.set('route.path', '/home');
}
},
Why it works after all?
I learned my lesson by debugging the source code of <app-route>. If the path is empty, the code for updating data will be skipped - and your observer, _routePageChanged(routeData.page), won't be triggered. See
https://github.com/PolymerElements/app-route/blob/master/app-route.html#L254-L257
https://github.com/PolymerElements/app-route/blob/master/app-route.html#L320-L328
You may consider it to be a flaw in <app-route>. Whatsoever, it's open source, and you can always find your way.

Tinymce 3 - insert new content in new block after custom button click

I want to ask if it's possible to add new content "outside" of content that has beed added recently.
So, i have custom button which adds some simple HTML.
And what i want to archive is to add the same html but outside of existing one, so in place marked green on my screenshot. I'm looking for a way how to escape from this div, and add new html after existing one.
below screenshot, and code - how javascript button in generated - very simple.
Thanks for advice.
var oferta = '<div class="col-sm-3"><h1>test</h1></div>'
setup: function (ed) {
ed.addButton('example', {
title: 'example.desc',
image: './/',
text: 'Oferta',
icon: true,
onclick: function () {
tinyMCE.execCommand('mceInsertContent', false, oferta);
}
});
},
EDIT: Below how this looks now when i hit button 3 times in row.(every next content is added to existing one.)
Is very easy to do it try to change you code with this example.
setup: function (editor) {
ed.addButton('example', {
title: 'example.desc',
image: './/',
text: 'Oferta',
icon: true,
onclick: function () {
var h1 = editor.dom.create('h1');
h1.innerText = 'test';
var oferta = editor.dom.create('div' ,{'class': 'col-sm-3'});
oferta.appendChild(h1);
var divs = editor.dom.select('div');
if(divs && divs.length > 0){
editor.dom.insertAfter(oferta,divs[divs.length-1])
}else{
tinyMCE.execCommand('mceInsertContent', false,oferta.outerHTML);
}
editor.selection.select(oferta);
editor.selection.collapse(true);
}
});
},

intro.js show and hide data-hint

I want to have a button that can turn on and off the 'hints' function in intro.js.
I have a working version to show and then hide but the show only works once. How can I get it to work repeatedly? This functionality works for the standard data-intro but not for data-hint.
<div class="jumbotron">
<h1 id='step1'>Hints</h1>
<p class="lead">Adding hints using JSON + callbacks</p>
<a id='step2' class="btn btn-large btn-success" href="javascript:void(0);">Add hints</a>
</div>
function addHints(){
intro = introJs();
intro.setOptions({
hints: [
{
element: document.querySelector('#step1'),
hint: "This is a tooltip.",
hintPosition: 'top-middle'
},
{
element: '#step2',
hint: 'More features, more fun.',
position: 'left'
},
{
element: '#step4',
hint: "<b>Another</b> step.",
hintPosition: 'top-middle'
}
]
});
intro.onhintsadded(function() {
console.log('all hints added');
});
intro.onhintclick(function(hintElement, item, stepId) {
console.log('hint clicked', hintElement, item, stepId);
});
intro.onhintclose(function (stepId) {
console.log('hint closed', stepId);
});
intro.addHints();
}
$(function() {
$('#step2').click(function(){
if ( $('#step2').hasClass('clicked') ) {
introJs().hideHints();
$('#step2').removeClass('clicked');
} else {
addHints();
$('#step2').addClass('clicked');
}
});
});
Instead of using hideHints intro.js API method just remove the div block of intro.js from DOM:
var introDiv = document.getElementsByClassName("introjs-hints")[0];
introDiv.parentNode.removeChild(introDiv);
(You can do the same thing with jQuery if you want to).
When the div is removed from DOM, just initialize hints once again as you do with your addHints method when you want to show hints and it'll work.
Instead of deleting the div block with javascript. You can use .removeHints()
This function is part of intro.js, but is not included in the documentation.
Perhaps a bit hacky, but this works for me...
First, put your hints into their own variable:
hints = [{...}, ...]
then, reset your hints in the intro options
intro.onhintclose(function(stepId) {
if (document.querySelectorAll('.introjs-hidehint').length === hints.length) {
intro.setOptions({hints: hints})
}
})
The hidden hints are given a class of introjs-hidehint, and document.querySelectorAll will return all of them in an array. Once that array is the same size as your hints array, reset your hints in your intro options and that will reset all your hints so you can show them all again.
Here's a more complete example that also allows:
(a) toggling hints on/off by clicking a button (located on a nav bar so used across multiple pages).
(b) once all hints have been clicked, the hints div gets removed so that clicking show hints button will again actually...show hints...
(c) allow you to store hints for multiple pages in a single json object array (re: nav bar).
var jquery = require('jquery');
var introJs = require('intro.js');
* ===========================================================================
* define onclick of hints button
* =========================================================================*/
jquery('#hints_button').on('click', function() {
if (document.getElementsByClassName('introjs-hints').length == 0){
addSomeHints();
}
else {
destroyHints();
};
});
/* ===========================================================================
* Add hints using the IntroJS library
* =========================================================================*/
/* define hints */
var theHints = [
{
element: document.querySelector('#step1'),
hint: "This is a tooltip.",
hintPosition: 'top-middle'
},
{
element: '#step2',
hint: 'More features, more fun.',
hintPosition: 'left'
},
{
element: '#step4',
hint: "<b>Another</b> step.",
hintPosition: 'top-middle'
}
];
/* generate hints with introjs */
function addSomeHints() {
intro = introJs();
intro.setOptions({
hints: theHints
});
intro.onhintclose(function (stepId) {
var remaining_hints = all_hints - document.getElementsByClassName("introjs-hidehint").length;
if (remaining_hints == 0) {
destroyHints();
};
});
/* add hints */
intro.addHints();
/* store number of hints created */
var all_hints = document.getElementsByClassName('introjs-hint').length;
};
/* remove hints div */
function destroyHints() {
var hintsDiv = document.getElementsByClassName("introjs-hints")[0]
hintsDiv.parentNode.removeChild(hintsDiv);
};
... hopefully this saves someone the 20 minutes it took me to piece together the answers and adapt it for what seems like a super common use case.

Can not change text when using Localization Sencha ExtJs

I has question about Localization,
I create key in Labels.js file, code :
Ext.define('Portal.Labels', {
singleton: true,
title: ''
});
And in event click of button, I using:
var main = Ext.getCmp('main'); // Get main (container) and destroy it.
main.destroy();
// Sure main is destroyed.
// Get url of local.
var url = Ext.util.Format.format('ext/packages/ext-locale/overrides/vn/ext-locale-vn.js');
// Sure url is loaded.
// Load script local file.
Ext.Loader.loadScript({
url: url,
scope: this
}
);
// Create main and show it.
main = Ext.create('main');
main.show();
In ext-locale-vn.js, I add :
Ext.define("Portal.locale.vn.Labels", {
override: "Portal.Labels",
title: "DASHBOARD"
});
In main container, I create lable:
xtype: 'label',
text:Portal.Labels.title
But when I click button, text of label still not change to "DASHBOARD", I don't know where I was wrong, please help me.

Categories