How to extend image or link dialogs to get values for other attributes of "img" and "a" tags from the user?
How to create a dialog for any tag just like image or link dialogs?

There is the eDefTagDialog(tag, fields, dtitle, stitle, func) function in default buttons library to create a dialog for any tag.

  • tag - tag name
  • fields - an array of attributes that are either strings or objects.
  • dtitle - dialog title. if not specified, "(tag) Tag Dialog" is used.
  • stitle - label for submit button. if not specified, browser's default is used.
  • func - name of the function that will be executed after submission instead of the default one. (for advanced use)

The simplest form, for example:

eDefTagDialog('div', ['id', 'class', 'style']);
//In 6.x a special attribute name 'html' was introduced which represents the inner HTML of the tag.
eDefTagDialog('div', ['id', 'class', 'style', 'html']);

will create a DIV Tag Dialog requesting values of attributes id, class and style. It will also detect if the selection is a proper DIV tag, and if so, will put the values of attributes to the corresponding fields. After submission, it will enclose/replace the selection in textarea.

You might have noticed that fields in image/link dialogs are declared as objects not as strings. That's a customized form of declaring attributes. It is ideal to define a field as an object if you want

  • a field type other than textfield (type: 'select', options: {'left': 'Left', 'right': 'Right'}) - only select is supported.
    In 6.x 'textarea' was introduced as an additional field type.
  • a custom label (title: 'Image URL')
  • a default value (value: ' ')
  • some prefix or suffix text or html (prefix: '[ ', suffix: ' ]')
  • to join two fields in a single line like in image width & height fields (getnext: true)
  • to set custom attributes for the field (attributes: {size: 10, style: 'width: 200px'})

The field object must have a name property that specifies the attribute name. {name: 'href'}

Now, lets add an "align" attribute field to the image dialog(note that it's not XHTML compliant):

The field object to pass to eDefTagDialog is;

{
 
name: 'align',//required
 
title: 'Image align', // if we dont set it, it will be set as 'Align' automatically.
 
type: 'select', // we use a selectbox instead of a plain textfield.
 
options: {'': '', left: 'Left', right: 'Right', center: 'Center'} // set options in the form-> {attribute-value: 'Visible value'}
}

Lets add it to the form in the image button's content:

var form = [
{
name: 'src', title: 'Image URL'},
{
name: 'width', title: 'Width x Height', suffix: ' x ', getnext: true, attributes: {size: 3}},
{
name: 'height', attributes: {size: 3}},
{
name: 'alt', title: 'Alternative text'},
{
name: 'align', title: 'Image align', type: 'select', options: {'': '', left: 'Left', right: 'Right', center: 'Center'}}
];
eDefTagDialog('img', form, 'Insert/edit image', 'OK');

That's it. We now have an image dialog which can also get/set the align attribute of an image tag.

Other than tag dialog, how to create a button that gets user input and adds it to the textarea?
Button content should be like this:

js:

// function that inserts the user input from the form into the textarea. this might be defined outside as well.
myUserInput = function(form) {
 
E.replaceSelection('User input is: '+ form.elements["user_input"].value);
 
editor.dialog.close();//close the dialog when done.
}

//form html. we define an input field named as "user_input".
var html = 'Input : '+ eDefInputText('user_input');
html += eDefInputSubmit('sbmt', 'Submit');
html = eDefHTML('form', html, {onsubmit: 'myUserInput(this); return false;'});//run getUserInput on submission

//open editor dialog with a title and the user form.
editor.dialog.open('User Input', html);

The above example uses a form which is more suitable for complex user input. If you want to get just a single input you may consider using javascript prompt(). Here is an example that gets image URL as a user input

js:
var
url = prompt('URL', '');//prompt for URL
var code = '<img src="'+ url +'" />';//put the url into the code.
E.replaceSelection(code);//replace the selection with the code.

How to create a button to insert XHTML compliant Underlined text?
Since <u> is not XHTML compliant, you should use CSS. First of all, you need to define a class in your theme's
CSS file, for instance;
.underlined-text {text-decoration: underline;}
As the above class exists, you can use it in your button content:

<span class="underlined-text">%TEXT%</span>

Where %TEXT% will be replaced by the selected text in the textarea.

6.x specific

How to extend the functionality of Headers button to create a specialized tag chooser?
How to create an image chooser(ie. smiley chooser) using eDefTagChooser?

Firstly, we should understand what eDefTagChooser does.
eDefTagChooser(tags, applyTag, wrapEach, wrapAll, effect)
It accepts 5 parameters among which only the first one is required and the rest is optional.

Parameter "tags": is an array of tag infos, each having the format:
[tag, title, attributes]
tag: the tag that will enclose the selected text in the textarea
title: the text or html to help the user choose this tag
attributes: attriutes that will be inserted inside the tag. ex:{'id': 'site-name', 'class': 'dark'}

ex tags: [ ['span', 'Red', {'style': 'color: red'}], ['span', 'Blue', {'class': 'blue-text'}] ]
this will create two options:
Red (inserting <span style="color: red"></span>)
Blue (inserting <span class="blue-text"></span>)

Parameter "applyTag": if set to true, the title of the tag-info will be enclosed by the tag itself. This will allow
the user to preview the effect of the tag.
Ex: ['span', 'Red', {'style': 'color: red'}] will genarate an option
- with applyTag=false : Red (text only)
- with applyTag=true : <span style="color: red">Red</span>

Parameter "wrapEach": the tag that will enclose each option.
This can be set to 'div' to make sure that each option is in a new line.

Parameter "wrapAll": the tag that will enclose the whole block of options.
Having set the parameter wrapEach to 'li' this can be set to 'ul' in order to create a proper list of options.

Parameter "effect": one of the jQuery effects for opening the dialog ('slideDown' or 'fadeIn')

Knowing the details we can create our customized tag chooser.
Let's, for example, add styled headers to the default header chooser.

js: eDefTagChooser([
[
'h1', 'Header1'],
[
'h1', 'Header1-title', {'class': 'title'}],// this will insert <h1 class="title"></h1>
['h2', 'Header2'],
[
'h1', 'Header2-title', {'class': 'title'}],
[
'h3', 'Header3'],
[
'h4', 'Header4']
],
true, 'li', 'ul', 'slideDown');

Now, let's create an image chooser
There will be no title for our tags since we will use applyTag to preview the image that will be inserted. However we
will be using a line break for every N(=4 in our example) image in order to create rows of options. Otherwise,
all of them will be placed in a single row.

js: eDefTagChooser([
[
'img', '', {'src': '/path-to-images/img1.png'}],//better to set also the width & height & alt attributes
['img', '', {'src': '/path-to-images/img2.png'}],
[
'img', '', {'src': '/path-to-images/img3.png'}],
[
'img', '<br />', {'src': '/path-to-images/img4.png'}],//line break added after 4th
['img', '', {'src': '/path-to-images/img5.png'}],
[
'img', '', {'src': '/path-to-images/img6.png'}],
[
'img', '', {'src': '/path-to-images/img7.png'}],
[
'img', '<br />', {'src': '/path-to-images/img8.png'}],//br after 8th
['img', '', {'src': '/path-to-images/img9.png'}],
[
'img', '', {'src': '/path-to-images/img10.png'}]
],
true, '', '', 'slideDown');

While inserting a single tag should we use the classic <tag>%TEXT%</tag> pattern or the new eDefTagger('tag') ?
What is the difference between <tag>%TEXT%</tag> and js:eDefTagger('tag') ?

  • First of all, the classic tag insertion method does not require the default buttons library, whereas eDefTagger is a part of the default buttons library.
  • Classic method preserves the selected text after tag insertion, whereas eDefTagger selects the whole insertion.
    Classic method: converts the selection "foo" to "<tag>foo</tag>", ("foo" still being selected)
    eDefTagger('tag'): converts the selection "foo" to "<tag>foo</tag>" (<tag>foo</tag> is selected)
  • Classic method doesnt parse the selection to check if it is an instance of the tag, whereas eDefTagger does and toggles it.
    Classic method: converts the selection "<tag>foo</tag>" to "<tag><tag>foo</tag></tag>"
    eDefTagger('tag'): converts the selection "<tag>foo</tag>" to "foo"
  • In classic method you define the attributes of the tag in the usual way, whereas in eDefTagger you pass them as an object
    <tag class="foo" id="bar">%TEXT%</tag> <=> eDefTagger('tag', {'class': 'foo', 'id': 'bar'})
  • In classic method It's possible to use the selected text for any purpose, whereas in eDefTagger the only goal is to html.
    Classic method can use the selection multiple times and do anything with it: [bbcode]%TEXT%[/bbcode]: (%TEXT%)

It's up to you which method to use. Select the one that fits best to your needs.

hi! thanks for

hi! thanks for bueditor!

please, help me: how i can add blockqoute button to qoute any selected text on a page?

thanks!

i try to add

i try to add this:
<blockqoute>%TEXT%</blockqoute>
but it's can work with text only typed in textarea, but i need to qoute text on a full page (qoute node content in comments)

What you request requires

What you request requires javascript. And it's not an esy one regarding browser compatibility, since browsers have different methods for handling the selected text in a page.

if i have JS function that

if i have JS function that return selected text (and its work fine on my browser) how i can add it to BUeditor ??????

you can create javascript

you can create javascript buttons by prefixing the content with the text js:. The remaining part should be the code inside your functon. You can use editor instance methods to change the selected text inside the textarea.

Under supervision of Drupal :)