TinyMCE render listbox items as html - listbox

I created a TinyMCE plugin and need the listbox items to display html. This is my plugin:
editor.addButton('icons', {
title: 'Foo',
text: 'Foo',
type: 'button',
onclick: function() {
editor.windowManager.open({
title: 'Foo',
width: 300,
height: 200,
body: [{
type: 'listbox',
label: 'Foo',
name: 'foo',
values: [{
title: '<em>Foo</em>', // <-- Mark save. Render as html.
value: 1
}],
}],
});
}
});
See also the fiddle: http://jsfiddle.net/allcaps/vqctac3d/
But the output looks like:
Expected:
How can I mark the list option title save so the contents is rendered as html?

Here is your updated snippet:
https://jsfiddle.net/mzvarik/1cwr07z6/55/
I was looking for same thing but listbox and it can be done like this:
(see fiddle for more)
editor.addButton('myshortcuts', {
type: 'listbox',
text: 'Vložit proměnnou',
values: self.shortcuts_data,
onselect: function() {
// do something
this.value(null); //reset selected value
},
onShow: function (event) {
var panel = $(event.control.getEl()),
button = event.control.parent().getEl();
var i=0;
panel.find('.mce-text').each(function(){
var item = $(this);
if (!item.next('.mce-menu-shortcut').length) {
// THIS WILL ADD HTML TO EXISTING MENU ITEM
item.after('<div class="mce-menu-shortcut">('+self.shortcuts_data[i].value+')</div>');
}
i++;
});
setTimeout(function(){
panel.css('width', 360);
panel.children().first().css('width', 360);
}, 5);
}
});
Here is screenshot:

Since noone else answered this question i will put the proposed solution/workaround from the comment into an answer.
Actually, it is not possible to insert html code using the tinymce way of listbox creation. But it is possible to style listboxes using css.
Due to the fact that listboxes and other tinymce UI elements get rendered dynamically it might be difficult to adress the correct html dom elements.
A workaround to this can be to exchange the listbox html after the listbox has been created. This is possible in case the ordering is known (and that is almost true).

Related

Jquery UI Autocomplete- How to format results AND add button at end?

I've figured out how to change the formatting on my results:
https://github.com/salmanarshad2000/demos/blob/v1.0.4/jquery-ui-autocomplete/custom-html-in-dropdown.html
And I've figured out how I can add a link to the bottom of the results:
Jquery Auto complete append link at the bottom
What I can't figure out is how to do both at the same time.
The closest that I've come is the following:
$( "#search1" ).autocomplete({
source: products,
minLength: 3,
select: function( event, ui ) {
event.preventDefault();
},
focus: function(event, ui) {
event.preventDefault();
}
}).data("ui-autocomplete")._renderItem = function(ul, item) {
console.log(ul.content)
var $div = $("<div></div>");
$("<img style='height:76px;'>").attr("src", item.image).appendTo($div);
$("<span></span>").text(item.label).appendTo($div);
($div).append( "<a href='https://google.com'>Click Me</a>" )
return $("<li></li>").append($div).appendTo(ul);
};
The problem is that adds the link to each individual returned result, rather than slamming it onto the end of the list.
I've tried various incarnations of wrapping the link (li, div, etc) but nothing's working.
What do I need to do to get a link as the last thing on the list?
JS Fiddle: http://jsfiddle.net/spgbq6w7/13/
Consider the following code.
Working Example: http://jsfiddle.net/Twisty/wur8vok9/23/
HTML
Search: <input id="search1">
JavaScript
var products = [{
value: "MS-Word",
label: "Microsoft Word 2013",
image: "https://upload.wikimedia.org/wikipedia/commons/4/4f/Microsoft_Word_2013_logo.svg"
},
{
value: "MS-Excel",
label: "Microsoft Excel 2013",
image: "https://upload.wikimedia.org/wikipedia/commons/8/86/Microsoft_Excel_2013_logo.svg"
},
{
value: "MS-Outlook",
label: "Microsoft Outlook 2013",
image: "https://upload.wikimedia.org/wikipedia/commons/0/0b/Microsoft_Outlook_2013_logo.svg"
},
{
value: "MS-PowerPoint",
label: "Microsoft Word 2013",
image: "https://upload.wikimedia.org/wikipedia/commons/b/b0/Microsoft_PowerPoint_2013_logo.svg"
},
{
value: "MS-Access",
label: "Microsoft Access2013",
image: "https://upload.wikimedia.org/wikipedia/commons/3/37/Microsoft_Access_2013_logo.svg"
},
{
value: "Adobe-PSP",
label: "Adobe Photoshop CC",
image: "https://upload.wikimedia.org/wikipedia/commons/a/af/Adobe_Photoshop_CC_icon.svg"
},
{
value: "Adobe-LR",
label: "Adobe Lightroom CC",
image: "https://upload.wikimedia.org/wikipedia/commons/5/56/Adobe_Photoshop_Lightroom_Classic_CC_icon.svg"
},
{
value: "Adobe-PRM",
label: "Adobe Premiere Pro CC",
image: "https://upload.wikimedia.org/wikipedia/commons/5/58/Adobe_Premiere_Pro_CS6_Icon.png"
},
{
value: "Adobe-ACR",
label: "Adobe Acrobat",
image: "https://upload.wikimedia.org/wikipedia/commons/0/0b/Adobe_Acrobat_v8.0_icon.svg"
},
{
value: "Adobe-ILS",
label: "Adobe Illustrator CS6",
image: "https://upload.wikimedia.org/wikipedia/commons/d/d8/Adobe_Illustrator_Icon_CS6.png"
}
];
$(function() {
$("#search1").autocomplete({
source: products,
minLength: 3,
open: function() {
var $li = $("<li>");
var $link = $("<a>", {
href: "#",
class: "see-all"
}).html("See All Results").click(function(e) {
e.preventDefault();
$("#search1").autocomplete("option", "minLength", 0);
$("#search1").autocomplete("search", "");
}).appendTo($li);
$li.appendTo($('.ui-autocomplete'));
},
select: function(event, ui) {
event.preventDefault();
$("#search1").autocomplete("option", "minLength", 3);
},
focus: function(event, ui) {
event.preventDefault();
}
}).data("ui-autocomplete")._renderItem = function(ul, item) {
console.log(ul.content)
var $div = $("<div>").css("position", " relative");
$("<img>", {
src: item.image
}).css("height", "38px").appendTo($div);
$("<span>").css({
position: "absolute",
top: 0,
display: "inline-block",
"margin-left": "3px"
}).text(item.label).appendTo($div);
return $("<li>").append($div).appendTo(ul);
};
});
So you're using _renderItem() properly. I removed the Link from here based on the example you linked to. I moved this to the open callback as is shown in the example. I also switched some of your code. It wasn't wrong, I just prefer this method.
So the items get rendered so that the image and label show as desired. The the open call back adds a final link item that causes the a search for all items. See more: http://api.jqueryui.com/autocomplete/#method-search
Can be called with an empty string and minLength: 0 to display all items.
When an item is selected, the preferred minLength is returned to ensure that if the user starts a new search, it operates the same way it did the first time.
Update
http://jsfiddle.net/Twisty/wur8vok9/40/
Minor cleanup and better separation of code and style.
Hope this helps.

Position a image next a textfield in a form

I have a form with some text fields. One of them is a image upload button.
I need to put the image preview box (a div) to the right side of the field (after the field button).
I already do the hard work by creating the div in the afterrender event:
listeners: {
afterrender: function ( cmp ) {
var container = this.body.dom.id;
$("#" + container ).append('<div style="position:absolute;
left:DONTKNOW;top:DONTKNOW" id="myPictureDiv"></div>');
}
}
how can I position elements in a ExtJS form? Can I use position:absolute ? But how to find the button position? What about form resizing?
EDIT: Image to illustrate scebotari's solution alignment problem:
One solution for this is to create the additional div as a component and to place it in a "fieldcontainer" with the main field.
{
xtype: 'fieldcontainer',
layout: 'hbox',
items: [{
xtype: 'textfield',
fieldLabel: 'Picture'
},{
xtype: 'component',
autoEl: 'div',
width: 32,
height: 32,
margin: '0 0 0 5',
style: 'border: 1px solid #d0d0d0; border-radius: 50%'
}]
}
Here is a fiddle illustrating this concept
This is the Form field
fieldLabel: 'My Field',
width: 330,
id: 'displayColumn',
name: 'displayColumn',
allowBlank : false,
value : '#CACACA',
This is the form listener:
listeners: {
afterrender: function ( cmp ) {
// Get the Window Container
var container = this.body.dom.id;
// Get the Component (ExtJS way)
var comp = Ext.getCmp("displayColumn");
// The ExtJS field ID is not the same you gave
var el = comp.getEl();
// Get the real Field ID
var displayColumnId = el.id;
// If you need its value...
var initialColor = comp.getValue();
// If you need to hide the field to make room to your div...
// I mean if you want to replace the field and keep the label...
// <YOUR_FIELD_ID>-triggerWrap
$("#displayColumn-triggerWrap").css("display","none");
// Append your div to the field container
// <YOUR_FIELD_ID>-bodyEl
$("#displayColumn-bodyEl").append(YOUR_DIV);
}
}
Do some style to the div as you wish

Choosing Option In Ajax-based Select2 From JS

I am using select2 4.0.0 for this project. A lot of the other comments and thoughts on this issue seem be for previous versions of select2, so I decided to post a new question.
I have a select2 on a page that can both create entries in the database and edit entries in the database. The select2 is populated dynamically by ajax after the user types a few letters and they can select a value. This works fine for creating entries when they need to select one.
On the same page, they can click existing entries to display further information and edit the entry in the same form. This also needs to update the select2 element with the correct selection text and update the select element that is backing the select2. Since this is normally done through ajax, the markup doesn't exist normally.
I've tried reading the documentation for select2, but I find it a bit disorganized. Does select2 provide any feature for accomplishing this? Do I need to create and update all the markup manually? I had looked at a dataAdapter, but I'm not sure if that is what I need or not.
HTML:
<select class="form-control" name="entry" id="select_field" data-url="/entry/search"></select>
Code for the select2 element:
$("#select_field").select2({
placeholder: "Search",
minimumInputLength: 2,
allowClear: true,
ajax: {
cache: true,
delay: 250,
method: 'POST',
url: $("#select_field").data('url'),
processResults: function (data, page) {
return {
results: data,
};
},
},
escapeMarkup: function (markup) { return markup; },
templateSelection: function (record) {
if (!record.id) { return record.text; }
return record.title;
},
templateResult: function (record) {
if (record.loading) { return record.text; }
var markup = $("<div>").text(record.title);
return markup.html();
},
});

Ember.js + JQuery-UI Tooltip - Tooltip does not reflect the model / controller changes

Context
I have a small Ember app, which, amongst other things, displays a number of connected users and, when hovering an element of the page, their names as a list.
All in all, it works quite well. The applications pulls data from a REST endpoint every two minutes, as the backend didn't allow for pushing data.
The contents of the tooltip are computed in the Controller, with a function that basically concatenate strings in various ways according to the context. Then it's bound to a data attribute of the <img> the tooltip is created on. When the View is ready and didInsertElement is fired, the tooltip is generated (if needs be) based on this data-bindattr value.
Question
When new data is pulled from the backend, everything is updated accordingly, except the tooltip content. (When browsing the page's DOM, the data-bindattr value is updated too.)
What could cause the tooltip to not refresh? Is it a case of JQuery-UI not calculating it again?
Some code
Refreshing code in the app's controller:
Monitor.ApplicationController = Ember.ArrayController.extend({
itemController: 'process',
sortProperties: ['name'],
sortAscending: true,
intervalId: undefined,
startRefreshing: function() {
var self = this;
if (self.get('intervalId')) {
return;
}
self.set( 'intervalId', setInterval(function() {
self.store.find('process');
}, 120000 ));
}
});
View: Process.hbs
<div {{bind-attr class=":inline inactive:inactive"}}>
<img {{bind-attr src=icon}} {{bind-attr data-caption=contentText}} class="caption" />
<div class="counter">{{nbUsers}}</div>
</div>
View: ProcessView
Monitor.ProcessView = Ember.View.extend({
// (...) Various stuff.
didInsertElement: function() {
this.updateTooltip();
},
updateTooltip: function() {
console.log('Inside updateTooltip!');
if (!this.$()) {return;}
if (this.get('controller').get('inactive')) {
this.$().tooltip({items: '.caption', disabled: true});
return;
}
this.$().tooltip({
items: '.caption',
tooltipClass: 'tooltip',
content: function() {
return $(this).data('caption');
},
position: {
my: 'left+15px center',
at: 'right center',
collision: 'flip'
},
show: false,
hide: false
});
}.observes('controller.inactive', 'controller.contentText')
});
Controller: ProcessController
Monitor.ProcessController = Ember.ObjectController.extend({
contentText: function() {
var tooltipContent = '';
this.get('containers').forEach(function(container) {
// Do a lot of things to tooltipContent involving:
// container.get('name')
// container.get('text')
// container.get('size')
// container.get('nbUsers')
// The data-bindattr value refreshes correctly so I cut this out for readability.
return tooltipContent;
}.property('name', 'containers.#each')
});
Edit 1:
Replaced 'containers.#each' by 'contentText' in the observer and added logging.
Here's what I think is happening:
Your tooltip library isn't observing the data-caption attribute. Meaning, when you update the attribute, you have to explicitly tell the library to update the tooltip as well. So although your attribute is updating just fine, the tooltip library isn't actually watching for those updates.
This can be remedied by calling updateTooltip, which you do, in didInsertElement. However, didInsertElement only fires once, when the element is first inserted. It's not called when the content changes.
Those two things combined are, I think, causing your problem. I think that all you need to do is have updateTooltip also observe the controller.contextText property. Then it should be called when the text updates.
So it turns out my codes declares and initialize a tooltip, but once it's done, you can't change the content the same way. Plus it adds unneeded computing anyway.
Thanks to #GJK's answer and that question, I found out what was happening. Turns out you need to set the content of the tooltip to refresh it, not recreate it.
Here is the working code for Ember integration:
Monitor.ProcessView = Ember.View.extend({
// Other stuff
didInsertElement: function() {
this.initTooltip();
},
initTooltip: function() {
if (!this.$()) {return;}
if (this.get('controller').get('inactive')) {
this.$().tooltip({items: '.caption', disabled: true});
return;
}
this.$().tooltip({
items: '.caption',
tooltipClass: 'tooltip',
content: function() {
return $(this).data('caption');
},
position: {
my: 'left+15px center',
at: 'right center',
collision: 'flip'
},
show: false,
hide: false
});
},
updateTooltip: function() {
if (!this.$()) {return;}
if (this.get('controller').get('inactive')) {
this.$().tooltip({items: '.caption', disabled: true});
return;
}
content = this.get('controller').get('contentText');
this.$().tooltip("option", "content", content);
}.observes('controller.contentText')
});
As an added bonus, you can avoid using the data attribute as a buffer now, although I'm not sure why.

Pass variable by Post method from JQuery UI Autocomplete to PHP page

I have two JQuery UI autocomplete input fields.
When an option is selected in the first one, the value of the selection will be used as condition for a database query that will send the source data for the second autocomplete field.
My problem is how do I send the value of the first selection to the PHP page via Post method?
The code so far is shown below (this code is from a tutorial which used the GET method; but I want to use Post):
<script>
$("input#divisions").autocomplete ({
//this is the first input
source : [
{ value: "81", label: "City1" },
{ value: "82", label: "City2" },
{ value: "83", label: "City3" } ],
minLength : 0,
select: function(event, ui) {
$('#divisions').val(ui.item.label);
return false;
},
focus: function(event, ui){
$('#divisions').val(ui.item.label);
return false;
},
change: function(event, ui){
//the tutorial has this value sent by variables in the URL; I want the selection value sent by POST. How can I change this?
c_t_v_choices = "c_t_v_choices.php?filter=" + ui.item.value;
$("#c_t_v").autocomplete("option", "source", c_t_v_choices);
}
}).focus (function (event)
{
$(this).autocomplete ("search", "");
});
$("#c_t_v").autocomplete({
source: "",
minLength: 2,
select: function(event,ui){
//$('#city').val(ui.item.city);
}
});
</script>
Can anyone please help?
Dont hesitate to let me know if you have any questions.
The solution I found for this is to use AJAX to create the source when a selection is made in the first autocomplete.
Sample code can be found here: https://stackoverflow.com/questions/12715204/assigning-source-for-jquery-autocomplete

Resources