Javascript UWA button style - javascript

I would like put a button on the left using css style and a UWA button.
This would be the code:
var btn = new UWA.Controls.Input.Button({value: 'Add new',style: {'position:absolute;right:20px;'}}).inject(widget.body);
I am not sure how to write the styles to take them into account.
I have tried:
style: {'position:absolute;right:20px;'} -> syntax error '}'
style:'position:absolute;right:20px;' -> nothing happens, doesn't appear in styles in console
style: {'position':'absolute';'right':'20px;'} -> nothing happens
Proposed syntaxes from answers that didn't work:
style: {'position': 'absolute', 'right': '20px'}
Here is the full code snippet (couldn't make a fiddle work with the references):
<head>
<!-- Application Metas Start -->
<title>TEST</title>
<!-- Application Metas End -->
<!-- UWA -->
<link rel="stylesheet" type="text/css" href="http://uwa.netvibes.com/lib/c/UWA/assets/css/standalone.css" />
<script type="text/javascript" src="http://uwa.netvibes.com/lib/c/UWA/js/UWA_Standalone_Alone.js"></script>
<!-- Application JS Start -->
<script type="text/javascript">
/* global widget */
( function () {
require({
baseUrl: '../'
}, ['UWA/Core', 'UWA/Element', 'UWA/Class', 'UWA/Controls/Input'], function(Core, Element, Class, Button) {
'use strict';
UWA.debug = true;
var myWidget = {
onLoad: function() {
try {
var btn = new UWA.Controls.Input.Button({value: 'Add new',styles: {position:'absolute',right:'20px'}}).inject(widget.body);
//btn.setAttributes({color: 'red'});
}
catch (err){
alert(err);
}
}
};
if (widget.launched)
myWidget.onLoad();
else
widget.onLoad = myWidget.onLoad;
}); // -- End of require
}() ) ;
</script>
<!-- Application JS End -->
</head>
<body>
</body>
</html>

It's probably in the docs. From my cursory glance at it, it looks you should set it through the attributes since style is an attribute:
var btn = new UWA.Controls.Input.Button({
value: 'Add new',
attributes: {
style: 'position:absolute;right:20px;'
}
}).inject(widget.body);
See https://uwa.netvibes.com/docs/Uwa/html/Input.UWA.Controls.Input.html
or possibly:
var btn = new UWA.Controls.Input.Button({
value: 'Add new',
styles: {
'position':'absolute',
'right':'20px'
}
}).inject(widget.body);
See https://uwa.netvibes.com/docs/Uwa/html/Element.html
EDIT - Since the above doesn't seem to work, perhaps creating your own Element instead of using the built in Button. In this example, I just reused the classes from the Button so they look the same:
var btn = new UWA.createElement('button', {
text: 'Add new',
styles: {
'position':'absolute',
'left':'20px'
},
class: 'dark-grey uwa-button uwa-button-root uwa-input uwa-input-root active'
}).inject(widget.body);
Fiddle: https://jsfiddle.net/nmde8m75/
see docs for createElement: https://uwa.netvibes.com/docs/Uwa/html/Element.html
NOTE: That once you make this button absolute positioned, you will need to make sure that the surrounding panel has a height.

Have you tried passing correct object? {'position':'absolute';'right':'20px;'} is not valid, because properties must be separated , and not ;.
Try style: {'position': 'absolute', 'right': '20px'}

var btn = new UWA.createElement('button', {
// you can also use var btn=new UWA.Element('button', {
text: 'Add New', //you can add value: 'Add New'
styles: {
position:'relative',
left:'20px'
},
class: 'uwa-button uwa-button-root uwa-input'
}).inject(widget.body);

Related

Quill insertText producing TypeError: n.appendChild is not a function

I'm planning on implementing Quill into my website but unfortunately the insertText function is producing the following:
TypeError: n.appendChild is not a function shadow.ts:150
wrap shadow.ts:150
formatAt shadow.ts:70
format embed.ts:26
value cursor.js:25
formatAt embed.ts:30
formatAt container.ts:98
forEachAt linked-list.ts:114
formatAt container.ts:97
formatAt block.ts:42
value block.js:78
value cursor.js:35
value selection.js:110
value quill.js:157
a quill.js:437
value quill.js:149
value toolbar.js:101
I'm extending the text blot and attempting to use the documentation notes from here (copying the divider code) but the output ends up just printing true to the editor.
JS
const Text = Quill.import("blots/text");
class SchoolNameBlot extends Text {}
SchoolNameBlot.blotName = "tagName";
SchoolNameBlot.tagName = "NAME";
const toolbarOptions = [['bold', 'italic'], ['link', 'image', 'tagName']];
Quill.register(SchoolNameBlot);
const options = {
debug: 'info',
theme: 'snow',
modules: {
toolbar: toolbarOptions
}
}
const editor = new Quill("#msgText", options);
$("#tagName-Button").click(function() {
let range = editor.getSelection(true);
editor.insertText(range.index, "insertText");
});
HTML Element:
<div class="col-md-11">
<div id="msgText"></div>
</div>
Output
From what I can tell, I am using Quill correctly so I'm not to sure why this error is being produced. I'm using the CDN's provided on their page.
I'm extending the text blot and attempting to use the documentation
notes from here (copying the divider code) but the output ends up just
printing true to the editor.
In the link presented talking about how to clone Medium, there is no blot being created that extends blots/text. Divider is created using blots/block/embed. Basically, there are 3 types of blots that can be created:
Block Blot
Inline Blot
Embed Blot
To help you better understand what I'm talking about, I suggest you to read a little about Parchment and Blots.
Now, about your problem itself... As you can see from your example, you just created a blot, but didn't add any behavior to it, and you have set your created blot tag name to NAME. Of all existing tags in HTML, there is not one with the name <NAME>. Look:
https://www.w3schools.com/TAGs/
https://techspirited.com/all-html-tags-list-of-all-html-tags
The name you give to tagName will be the HTML tag used for the result, ie what your blot will represent. If you want to add an image, for example, you need to give tagName the value IMG. For a header title, you could use h1, h2, h3, and so on.
Looking at your code, and seeing the name "tag" written on it, it seems to me that you just want to add some stylized text. Would it be? If this is your case, look at the following example:
let Inline = Quill.import('blots/inline');
class SchoolNameBlot extends Inline {
// Overriding this method, in this particular case, is what
// causes the Delta returned as content by Quill to have
// the desired information.
static formats(domNode) {
if(domNode.classList.contains('my-style')){
return true;
}
else{
return super.formats(domNode);
}
}
formats() {
// Returns the formats list this class (this format).
let formats = super.formats();
// Inline has the domNode reference, which in this
// case represents the SPAN, result defined in tagName.
formats['tag-name'] = SchoolNameBlot.formats(this.domNode);
// In the code above, it is as if we are adding this new format.
return formats;
}
}
SchoolNameBlot.blotName = 'tag-name';
SchoolNameBlot.tagName = 'span';
SchoolNameBlot.className = 'my-style';
Quill.register(SchoolNameBlot);
$(document).ready(function () {
var toolbarOptions = {
container: [['bold', 'italic'], ['link', 'image', 'tag-name']],
handlers: {
'tag-name': function(){
this.quill.insertText(0, 'Hello', 'tag-name', true);
}
}
};
var quill = new Quill('#editor', {
theme: 'snow',
modules: {
'toolbar': toolbarOptions
}
});
});
.my-style{
background: rgb(254, 255, 171);
border-radius: 2px;
padding: 2px 2px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="//cdn.quilljs.com/1.3.6/quill.min.js"></script>
<link href="//cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
<p>Instructions:</p>
<ol>
<li>Press the invisible button (with no icon) next to the add image button.</li>
</ol>
<div id="editor">
</div>
To just style text, I do not advise creating a new Blot, as there is no need for something so complex. You could use Attributors. The previous code would look as:
const Parchment = Quill.import('parchment')
var config = {
scope: Parchment.Scope.INLINE,
whitelist: ['yellow', 'red', 'blue' , 'green']
};
var SchoolName = new Parchment.Attributor.Class('my-attributor', 'style' , config);
Quill.register(SchoolName);
$(document).ready(function () {
var toolbarOptions = {
container: [['bold', 'italic'], ['link', 'image', 'my-button'] , ['clean']] ,
handlers: {
'my-button': function () {
let range = this.quill.getSelection();
this.quill.insertText(range.index, 'Hello', 'my-attributor' , 'yellow');
}
}
};
var quill = new Quill('#editor', {
theme: 'snow',
modules: {
'toolbar': toolbarOptions
}
});
});
.style-yellow{
background: rgb(254, 255, 171);
border-radius: 2px;
padding: 2px 2px;
}
.style-red{
background: rgb(255, 171, 171);
border-radius: 2px;
padding: 2px 2px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="//cdn.quilljs.com/1.3.6/quill.min.js"></script>
<link href="//cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
<p>Instructions:</p>
<ol>
<li>Press the invisible button (with no icon) next to the add image button.</li>
</ol>
<div id="editor">
</div>
As a final tip, you can always get more information from Quill official website, as well as from its repositories. For even more information, examples and frequently asked questions (Quill FAQ), take a look here.

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.

Issue using Buttons instead of default navigation with Glide.js

I am working with the glide.js library to make an image slider on my website. I would like to have three pre made buttons to act as the slider buttons instead of the default navigation. The default nav seems to be using <a> tags.
Looking through the js file It seems the default navigation is created here:
Glide.prototype.navigation = function() {
this.navigation.items = {};
//CLASS
// Navigation wrapper
this.navigation.wrapper = $('<div />', {
'class': this.options.navigationClass
}).appendTo(
/**
* Setting append target
* If option is true set default target, that is slider wrapper
* Else get target set in options
* #type {Bool or String}
*/
(this.options.navigation === true) ? this.parent : this.options.navigation
);
//Navigation controls
for (var i = 0; i < this.slides.length; i++) {
this.navigation.items[i] = $('<li />', {
'href': '#',
'class': this.options.navigationItemClass,
// Direction and distance -> Item index forward
'data-distance': i
}).appendTo(this.navigation.wrapper);
}
// Add navCurrentItemClass to the first navigation item
this.navigation.items[0].addClass(this.options.navigationCurrentItemClass);
// If centered option is true
if (this.options.navigationCenter) {
// Center bullet navigation
this.navigation.wrapper.css({
'left': '50%',
'width': this.navigation.wrapper.children().outerWidth(true) * this.navigation.wrapper.children().length,
'margin-left': -(this.navigation.wrapper.outerWidth(true)/2)
});
}
};
I adjusted the code, I replaced the loop with the code below to use 3 buttons I placed on my html page but it has no effect. I'm just wondering if I am doing something wrong, or if it is even possible? This is the changes I made to the code:
this.navigation.items[0] = $('.b1', {
'href': '#',
'class': this.options.navigationItemClass,
'data-distance': 0
}).appendTo(this.navigation.wrapper);
this.navigation.items[1] = $('.b2', {
'href': '#',
'class': this.options.navigationItemClass,
'data-distance': 1
}).appendTo(this.navigation.wrapper);
this.navigation.items[2] = $('.b3', {
'href': '#',
'class': this.options.navigationItemClass,
'data-distance': 2
}).appendTo(this.navigation.wrapper);
Does anyone have any idea how I might implement this?
I just solved the issue. Might be helpful to anyone trying to do the same thing. It was very easy, I don't know how I didn't figure it out initially.
Basically initialize the slider as follows:
$('.slider').glide({
autoplay: 5000,
arrows: 'none',
navigation: 'none'
});
Get an instance of the API:
var glide = $('.slider').glide().data('api_glide');
Then get references to each button and code the required action you want to execute when the button is clicked:
$('.b1').click(function(){
console.log("Button 1 Clicked");
glide.jump(1, console.log('1'));
});
$('.b2').click(function(){
console.log("Button 2 Clicked");
glide.jump(2, console.log('2'));
});
$('.b3').click(function(){
console.log("Button 3 Clicked");
glide.jump(3, console.log('3'));
});
All of this assumes you've got three buttons on your page like so:
<button class="b1" id="b1" name="b1" >Button 1</button>
<button class="b2" id="b2" name="b2">Button 2</button>
<button class="b3" id="b3" name="b3">Button 3</button>

Mootools class - storing reference to document body in a class property

Greetings all! I'm trying to learn Mootools classes. I've made this class to add a div to the page.
var F = new Class({
Implements: [Options, Events],
options: {
container: document.body,
width: '250px',
background: '#ccc'
},
initialize: function(options) {
this.setOptions(options);
this.addDemoDiv();
},
addDemoDiv: function() {
var dDiv = new Element('div', {
'class': 'myClass',
html: 'Click me!',
styles: {
padding: '20px',
border: '1px solid #999',
width: this.options.width,
background: this.options.background
},
events: {
click: this.animate
}
});
dDiv.inject(this.options.container);
},
animate: function() {
alert('Hello world');
}
});
window.addEvent('domready', function() {
var item = new F();
});
It's supposed to allow the user to specify the container to inject the div into, with the document body being the default. When I do it like above, the code validates OK, but the script fails to add the div - Firebug and Chrome complain about the container being null or undefined.
I have to change dDiv.inject(this.options.container); to this
if (!this.container) {
dDiv.inject(document.body);
} else {
dDiv.inject(this.container);
}
to make it work.
Can any wise Mootools ninja tell me why inject works when I pass document.body in directly, but breaks when I try to pass it a reference to document.body supposedly stored in the class's container option? I've tried variations on document.body, like 'document.body' and $$('document.body') and $$(document.body).
My guess is that document.body is not available when your class code gets interpreted, this usually occurs when your script is placed in the <head> tags. Moving your script(s) to the bottom of the document (just before </body>) solves a lot and is good practise since your script(s) won't block HTML rendering anymore either.
It's also better to avoid putting a static default DOM references in your class as their availability is always questionable. You can keep options.container null and change your method to:
... code ...
dDiv.inject( this.options.container || document.body );
... code ...
So if this.options.container is not set (falsy) it will default to document.body, this way you can also keep your script(s) in the <head> if you really want to.

Categories