I have an autocomplete combobox using both knockout and jquery ui libraries.
When you type something in that is not in the autocomplete list, the combobox gets blank and that is exactly what I want it to do, but it does not update my selectedOption value too (I would like to set it to null when the combobox is left blank)
I have tried adding a subscribe event to the selectedOption but knockout does not fire it in this case. I also tried with the valueAllowUnset property but it did not work either.
Thank you very much for your help!
Here is my snippet (it looks a bit ugly because I did not add CSS but it shows the problem):
function viewModel() {
var self = this;
self.myOptions = ko.observableArray([{
Name: "First option",
Id: 1
},
{
Name: "Second option",
Id: 2
},
{
Name: "Third option",
Id: 3
}
]);
self.selectedOption = ko.observable(3);
}
var myViewModel = new viewModel();
ko.applyBindings(myViewModel);
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.1.0/knockout-min.js"></script>
<html>
<body>
<p> Combobox: </p>
<select id="myCombo" data-bind="options: myOptions, optionsText: 'Name', optionsValue: 'Id', value: selectedOption, valueAllowUnset: true, combo: selectedOption"></select>
<p> Option selected Id: </p>
<texarea data-bind="text: selectedOption()"> </texarea>
</body>
</html>
<script>
// ko-combo.js
(function() {
//combobox
ko.bindingHandlers.combo = {
init: function(element, valueAccessor, allBindingsAccessor) {
//initialize combobox with some optional options
var options = {};
$(element).combobox({
select: function() {
var observable = valueAccessor();
observable($(element).combobox('value'));
}
});
//handle the field changing
ko.utils.registerEventHandler(element, "change", function() {
var observable = valueAccessor();
observable($(element).val());
});
//handle disposal (if KO removes by the template binding)
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$(element).combobox("destroy");
});
},
//update the control when the view model changes
update: function(element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
$(element).combobox('value', value);
}
};
})();
</script>
<script>
// jquery.ui.combobox.js
/*!
* Copyright Ben Olson (https://github.com/bseth99/jquery-ui-extensions)
* jQuery UI ComboBox #VERSION
*
* Adapted from Jörn Zaefferer original implementation at
* http://www.learningjquery.com/2010/06/a-jquery-ui-combobox-under-the-hood
*
* And the demo at
* http://jqueryui.com/autocomplete/#combobox
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
(function( $, undefined ) {
$.widget( "ui.combobox", {
options: {
editable: false
},
version: "#VERSION",
widgetEventPrefix: "combobox",
uiCombo: null,
uiInput: null,
_wasOpen: false,
_create: function() {
var self = this,
select = this.element.hide(),
input, wrapper;
input = this.uiInput =
$( "<input />" )
.insertAfter(select)
.addClass("ui-widget ui-widget-content ui-corner-left ui-combobox-input")
.val( select.children(':selected').text() );
wrapper = this.uiCombo =
input.wrap( '<span>' )
.parent()
.addClass( 'ui-combobox' )
.insertAfter( select );
input
.autocomplete({
delay: 0,
minLength: 0,
appendTo: wrapper,
source: $.proxy( this, "_linkSelectList" )
});
$( "<button>" )
.attr( "tabIndex", -1 )
.attr( "type", "button" )
.insertAfter( input )
.button({
icons: {
primary: "ui-icon-triangle-1-s"
},
text: false
})
.removeClass( "ui-corner-all" )
.addClass( "ui-corner-right ui-button-icon ui-combobox-button" );
// Our items have HTML tags. The default rendering uses text()
// to set the content of the <a> tag. We need html().
input.data( "ui-autocomplete" )._renderItem = function( ul, item ) {
return $( "<li>" )
.append( $( "<a>" ).html( item.label ) )
.appendTo( ul );
};
this._on( this._events );
},
_linkSelectList: function( request, response ) {
var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), 'i' );
response( this.element.children('option').map(function() {
var text = $( this ).text();
if ( this.value && ( !request.term || matcher.test(text) ) ) {
return {
label: text.replace(
new RegExp(
"(?![^&;]+;)(?!<[^<>]*)(" +
$.ui.autocomplete.escapeRegex(request.term) +
")(?![^<>]*>)(?![^&;]+;)", "gi"),
"<strong>$1</strong>"),
value: text,
option: this
};
}
})
);
},
_events: {
"autocompletechange input" : function(event, ui) {
var $el = $(event.currentTarget);
if ( !ui.item ) {
var matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( $el.val() ) + "$", "i" ),
valid = false;
this.element.children( "option" ).each(function() {
if ( $( this ).text().match( matcher ) ) {
this.selected = valid = true;
return false;
}
});
if (!this.options.editable) {
if (!valid) {
// remove invalid value, as it didn't match anything
$el.val("");
this.element.prop('selectedIndex', -1);
//return false;
}
}
}
this._trigger( "change", event, {
item: ui.item ? ui.item.option : null
});
},
"autocompleteselect input": function( event, ui ) {
ui.item.option.selected = true;
this._trigger( "select", event, {
item: ui.item.option
});
},
"autocompleteopen input": function ( event, ui ) {
this.uiCombo.children('.ui-autocomplete')
.outerWidth(this.uiCombo.outerWidth(true));
},
"mousedown .ui-combobox-button" : function ( event ) {
this._wasOpen = this.uiInput.autocomplete("widget").is(":visible");
},
"click .ui-combobox-button" : function( event ) {
this.uiInput.focus();
// close if already visible
if (this._wasOpen)
return;
// pass empty string as value to search for, displaying all results
this.uiInput.autocomplete("search", "");
}
},
value: function ( newVal ) {
var select = this.element,
valid = false,
selected;
if (!arguments.length) {
selected = select.children(":selected");
return selected.length > 0 ? selected.val() : null;
}
select.prop('selectedIndex', -1);
select.children('option').each(function() {
if ( this.value == newVal ) {
this.selected = valid = true;
return false;
}
});
if ( valid ) {
this.uiInput.val(select.children(':selected').text());
} else {
this.uiInput.val( "" );
this.element.prop('selectedIndex', -1);
}
},
_destroy: function () {
this.element.show();
this.uiCombo.replaceWith( this.element );
},
widget: function () {
return this.uiCombo;
},
_getCreateEventData: function() {
return {
select: this.element,
combo: this.uiCombo,
input: this.uiInput
};
}
});
}(jQuery));
</script>
Change the select event by change event in your binding handler :
function viewModel() {
var self = this;
self.myOptions = ko.observableArray([{
Name: "First option",
Id: 1
},
{
Name: "Second option",
Id: 2
},
{
Name: "Third option",
Id: 3
}
]);
self.selectedOption = ko.observable(3);
}
var myViewModel = new viewModel();
ko.applyBindings(myViewModel);
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.1.0/knockout-min.js"></script>
<html>
<body>
<p> Combobox: </p>
<select id="myCombo" data-bind="options: myOptions, optionsText: 'Name', optionsValue: 'Id', value: selectedOption, valueAllowUnset: true, combo: selectedOption"></select>
<p> Option selected Id: </p>
<texarea data-bind="text: selectedOption()"> </texarea>
</body>
</html>
<script>
// ko-combo.js
(function() {
//combobox
ko.bindingHandlers.combo = {
init: function(element, valueAccessor, allBindingsAccessor) {
//initialize combobox with some optional options
var options = {};
$(element).combobox({
change: function() {
var observable = valueAccessor();
observable($(element).combobox('value'));
}
});
//handle the field changing
ko.utils.registerEventHandler(element, "change", function() {
var observable = valueAccessor();
observable($(element).val());
});
//handle disposal (if KO removes by the template binding)
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$(element).combobox("destroy");
});
},
//update the control when the view model changes
update: function(element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
$(element).combobox('value', value);
}
};
})();
</script>
<script>
// jquery.ui.combobox.js
/*!
* Copyright Ben Olson (https://github.com/bseth99/jquery-ui-extensions)
* jQuery UI ComboBox #VERSION
*
* Adapted from Jörn Zaefferer original implementation at
* http://www.learningjquery.com/2010/06/a-jquery-ui-combobox-under-the-hood
*
* And the demo at
* http://jqueryui.com/autocomplete/#combobox
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
(function( $, undefined ) {
$.widget( "ui.combobox", {
options: {
editable: false
},
version: "#VERSION",
widgetEventPrefix: "combobox",
uiCombo: null,
uiInput: null,
_wasOpen: false,
_create: function() {
var self = this,
select = this.element.hide(),
input, wrapper;
input = this.uiInput =
$( "<input />" )
.insertAfter(select)
.addClass("ui-widget ui-widget-content ui-corner-left ui-combobox-input")
.val( select.children(':selected').text() );
wrapper = this.uiCombo =
input.wrap( '<span>' )
.parent()
.addClass( 'ui-combobox' )
.insertAfter( select );
input
.autocomplete({
delay: 0,
minLength: 0,
appendTo: wrapper,
source: $.proxy( this, "_linkSelectList" )
});
$( "<button>" )
.attr( "tabIndex", -1 )
.attr( "type", "button" )
.insertAfter( input )
.button({
icons: {
primary: "ui-icon-triangle-1-s"
},
text: false
})
.removeClass( "ui-corner-all" )
.addClass( "ui-corner-right ui-button-icon ui-combobox-button" );
// Our items have HTML tags. The default rendering uses text()
// to set the content of the <a> tag. We need html().
input.data( "ui-autocomplete" )._renderItem = function( ul, item ) {
return $( "<li>" )
.append( $( "<a>" ).html( item.label ) )
.appendTo( ul );
};
this._on( this._events );
},
_linkSelectList: function( request, response ) {
var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), 'i' );
response( this.element.children('option').map(function() {
var text = $( this ).text();
if ( this.value && ( !request.term || matcher.test(text) ) ) {
return {
label: text.replace(
new RegExp(
"(?![^&;]+;)(?!<[^<>]*)(" +
$.ui.autocomplete.escapeRegex(request.term) +
")(?![^<>]*>)(?![^&;]+;)", "gi"),
"<strong>$1</strong>"),
value: text,
option: this
};
}
})
);
},
_events: {
"autocompletechange input" : function(event, ui) {
var $el = $(event.currentTarget);
if ( !ui.item ) {
var matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( $el.val() ) + "$", "i" ),
valid = false;
this.element.children( "option" ).each(function() {
if ( $( this ).text().match( matcher ) ) {
this.selected = valid = true;
return false;
}
});
if (!this.options.editable) {
if (!valid) {
// remove invalid value, as it didn't match anything
$el.val("");
this.element.prop('selectedIndex', -1);
//return false;
}
}
}
this._trigger( "change", event, {
item: ui.item ? ui.item.option : null
});
},
"autocompleteselect input": function( event, ui ) {
ui.item.option.selected = true;
this._trigger( "select", event, {
item: ui.item.option
});
},
"autocompleteopen input": function ( event, ui ) {
this.uiCombo.children('.ui-autocomplete')
.outerWidth(this.uiCombo.outerWidth(true));
},
"mousedown .ui-combobox-button" : function ( event ) {
this._wasOpen = this.uiInput.autocomplete("widget").is(":visible");
},
"click .ui-combobox-button" : function( event ) {
this.uiInput.focus();
// close if already visible
if (this._wasOpen)
return;
// pass empty string as value to search for, displaying all results
this.uiInput.autocomplete("search", "");
}
},
value: function ( newVal ) {
var select = this.element,
valid = false,
selected;
if (!arguments.length) {
selected = select.children(":selected");
return selected.length > 0 ? selected.val() : null;
}
select.prop('selectedIndex', -1);
select.children('option').each(function() {
if ( this.value == newVal ) {
this.selected = valid = true;
return false;
}
});
if ( valid ) {
this.uiInput.val(select.children(':selected').text());
} else {
this.uiInput.val( "" );
this.element.prop('selectedIndex', -1);
}
},
_destroy: function () {
this.element.show();
this.uiCombo.replaceWith( this.element );
},
widget: function () {
return this.uiCombo;
},
_getCreateEventData: function() {
return {
select: this.element,
combo: this.uiCombo,
input: this.uiInput
};
}
});
}(jQuery));
</script>
Related
I am working on a plugin that will allow us to add block options to the ACF block system and save the fields in meta. The issue is I am really rusty with js and I am unable to figure out how to merge my loop into the wp.element.create system. I have included my javascript below with comments of what I am trying to accomplish. Any help on this is greatly appreciated.
jQuery(function(){
var el = wp.element.createElement,
Fragment = wp.element.Fragment
registerBlockType = wp.blocks.registerBlockType,
RichText = wp.editor.RichText,
BlockControls = wp.editor.BlockControls,
AlignmentToolbar = wp.editor.AlignmentToolbar,
InspectorControls = wp.editor.InspectorControls;
var withInspectorControls = wp.compose.createHigherOrderComponent( function( BlockEdit ) {
return function( props ) {
// Set data if it does not exist - needed when new page is created
if(props.attributes.data === undefined){ props.attributes.data={}; }
// begin creating the return element
var elm = el(
Fragment,
{},
el( BlockEdit, props ),
el( InspectorControls, {},
el( PanelBody, { title: 'Accordion Options' },
// THIS IS WHERE THE ADDED ELEMENTS WILL GO
)
);
$.each(fields, function( key, field ) {
switch(field.type){
case 'text':
var optionField = el( TextControl, {
label: field.label,
help: field.instructions,
onChange: function(value){
textField=value;
props.setAttributes( { textField: value } );
}
});
// ADD optionField TO elm ABOVE CORRECTLY
break;
default: continue;
}
});
return elm;
};
}, 'withInspectorControls' );
wp.hooks.addFilter( 'editor.BlockEdit', 'acf/accordion', withInspectorControls );
}
I have a dropdown/combo box, this is how its made
#Html.DropDownList("combobox", Model.Sizes, "--select--")
It uses a jquery ui widget which is,
<script>
(function ($) {
$.widget("custom.combobox", {
_create: function () {
this.wrapper = $("<span>")
.addClass("custom-combobox")
.insertAfter(this.element);
this.element.hide();
this._createAutocomplete();
this._createShowAllButton();
},
_createAutocomplete: function () {
var selected = this.element.children(":selected"),
value = selected.val() ? selected.text() : "";
this.input = $("<input>")
.appendTo(this.wrapper)
.val(value)
.attr("title", "")
.addClass("custom-combobox-input ui-widget ui-widget-content ui-state-default ui-corner-left")
.autocomplete({
delay: 0,
minLength: 0,
source: $.proxy(this, "_source"),
//ADDED HERE
select: function(event, ui) {
sizeID=ui.item.id;
}
})
.tooltip({
tooltipClass: "ui-state-highlight"
});
this._on(this.input, {
autocompleteselect: function (event, ui) {
ui.item.option.selected = true;
this._trigger("select", event, {
item: ui.item.option
});
},
autocompletechange: "_removeIfInvalid"
});
},
_createShowAllButton: function () {
var input = this.input,
wasOpen = false;
$("<a>")
.attr("tabIndex", -1)
.attr("title", "Show All Items")
.tooltip()
.appendTo(this.wrapper)
.button({
icons: {
primary: "ui-icon-triangle-1-s"
},
text: false
})
.removeClass("ui-corner-all")
.addClass("custom-combobox-toggle ui-corner-right")
.mousedown(function () {
wasOpen = input.autocomplete("widget").is(":visible");
})
.click(function () {
input.focus();
// Close if already visible
if (wasOpen) {
return;
}
// Pass empty string as value to search for, displaying all results
input.autocomplete("search", "");
});
},
_source: function (request, response) {
var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
response(this.element.children("option").map(function () {
var text = $(this).text();
if (this.value && (!request.term || matcher.test(text)))
return {
label: text,
value: text,
option: this
};
}));
},
_removeIfInvalid: function (event, ui) {
// Selected an item, nothing to do
if (ui.item) {
return;
}
// Search for a match (case-insensitive)
var value = this.input.val(),
valueLowerCase = value.toLowerCase(),
valid = false;
this.element.children("option").each(function () {
if ($(this).text().toLowerCase() === valueLowerCase) {
this.selected = valid = true;
return false;
}
});
// Found a match, nothing to do
if (valid) {
return;
}
// Remove invalid value
this.input
.val("")
.attr("title", value + " didn't match any item")
.tooltip("open");
this.element.val("");
this._delay(function () {
this.input.tooltip("close").attr("title", "");
}, 2500);
this.input.autocomplete("instance").term = "";
},
_destroy: function () {
this.wrapper.remove();
this.element.show();
}
});
})(jQuery);
$(function () {
$("#combobox").combobox();
$("#toggle").click(function () {
$("#combobox").toggle();
});
});
</script>
I then am trying to pass the value of this dropdown using Json likeeee
<script type="text/javascript">
$(function () {
$("[name='combobox']").change(function () {
$.getJSON('#Url.Action("GetSize")', { sizeID: $("[name='combobox']").val() }, function (Size) {
// Fill the fields according to the Jsondata we requested
$("#KID").val(Size["KammID"]);
This uses the get size action in my controller which is,
public JsonResult GetSize(int sizeID)
{
var Size = db.AllSizes.Find(sizeID);
return Json(Size, JsonRequestBehavior.AllowGet);
}
Andddddd this worked perfectly with my normal dropdown, but once i changed it to a combo box it seems its not getting the sizeID,
HELP BENJI
you could add in a select function as outlined here:
Get value in jquery autocomplete
so when an option is selected you store the value in a variable.
eg:
var sizeID;
.autocomplete({
delay: 0,
minLength: 0,
source: $.proxy(this, "_source"),
select: function(event, ui) {
sizeID=ui.item.id;
}
})
With the project I am on, I have been asked to move from CKEditor 3 to 4. Everything works fine except for a custom plugin someone wrote.
Argument 1 of Node.appendChild is not an object.
The code is all over the place, and a bit of a mess. Here is the plugin, which I think is causing the error.
/*
Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/
/**
* #fileOverview The "limereplacementfields" plugin.
*
*/
(function()
{
var limereplacementfieldsReplaceRegex = /(\{[A-Z]+[^\{\}]+[A-Z0-9]+\})/g;
CKEDITOR.plugins.add( 'limereplacementfields',
{
requires : [ 'dialog' ],
lang : [ 'en' ],
init : function( editor )
{
var lang = editor.lang.limereplacementfields;
editor.addCommand( 'createlimereplacementfields', new CKEDITOR.dialogCommand( 'createlimereplacementfields' ) );
editor.addCommand( 'editlimereplacementfields', new CKEDITOR.dialogCommand( 'editlimereplacementfields' ) );
editor.ui.addButton( 'Createlimereplacementfields',
{
label : lang.title,
command :'createlimereplacementfields',
icon : this.path + 'limereplacementfields.gif'
});
if ( editor.addMenuItems )
{
editor.addMenuGroup( 'limereplacementfields', 20 );
editor.addMenuItems(
{
editlimereplacementfields :
{
label : lang.title,
command : 'editlimereplacementfields',
group : 'limereplacementfields',
order : 1,
icon : this.path + 'limereplacementfields.gif'
}
} );
if ( editor.contextMenu )
{
editor.contextMenu.addListener( function( element, selection )
{
if ( !element || !element.data( 'cke-limereplacementfields' ) )
return null;
return { editlimereplacementfields : CKEDITOR.TRISTATE_OFF };
} );
}
}
editor.on( 'doubleclick', function( evt )
{
if ( CKEDITOR.plugins.limereplacementfields.getSelectedPlaceHoder( editor ) )
evt.data.dialog = 'editlimereplacementfields';
});
editor.on( 'contentDom', function()
{
editor.document.getBody().on( 'resizestart', function( evt )
{
if ( editor.getSelection().getSelectedElement().data( 'cke-limereplacementfields' ) )
evt.data.preventDefault();
});
});
CKEDITOR.dialog.add( 'createlimereplacementfields', this.path + 'dialogs/limereplacementfields.js' );
CKEDITOR.dialog.add( 'editlimereplacementfields', this.path + 'dialogs/limereplacementfields.js' );
},
afterInit : function( editor )
{
var dataProcessor = editor.dataProcessor,
dataFilter = dataProcessor && dataProcessor.dataFilter,
htmlFilter = dataProcessor && dataProcessor.htmlFilter;
if ( dataFilter )
{
dataFilter.addRules(
{
text : function( text )
{
return text.replace( limereplacementfieldsReplaceRegex, function( match )
{
return CKEDITOR.plugins.limereplacementfields.createlimereplacementfields( editor, null, match, 1 );
});
}
});
}
if ( htmlFilter )
{
htmlFilter.addRules(
{
elements :
{
'span' : function( element )
{
if ( element.attributes && element.attributes[ 'data-cke-limereplacementfields' ] )
delete element.name;
}
}
});
}
},
onLoad: function(editor) {
CKEDITOR.addCss(
'.cke_limereplacementfields' +
'{' +
'background-color: #ffff00;' +
( CKEDITOR.env.gecko ? 'cursor: default;' : '' ) +
'}'
);
}
});
})();
CKEDITOR.plugins.setLang('limereplacementfields','en', {
limereplacementfields: {
title:sReplacementFieldTitle,
button:sReplacementFieldButton
}
}
);
CKEDITOR.plugins.limereplacementfields =
{
createlimereplacementfields : function( editor, oldElement, text, isGet )
{
var element = new CKEDITOR.dom.element( 'span', editor.document );
element.setAttributes(
{
contentEditable : 'false',
'data-cke-limereplacementfields' : 1,
'class' : 'cke_limereplacementfields'
}
);
text && element.setText( text );
if ( isGet )
return element.getOuterHtml();
if ( oldElement )
{
if ( CKEDITOR.env.ie )
{
element.insertAfter( oldElement );
// Some time is required for IE before the element is removed.
setTimeout( function()
{
oldElement.remove();
element.focus();
}, 10 );
}
else
element.replace( oldElement );
}
else
editor.insertElement( element );
return null;
},
getSelectedPlaceHoder : function( editor )
{
var range = editor.getSelection().getRanges()[0];
range.shrink( CKEDITOR.SHRINK_TEXT );
var node = range.startContainer;
while( node && !( node.type == CKEDITOR.NODE_ELEMENT && node.data( 'cke-limereplacementfields' ) ) )
node = node.getParent();
return node;
}
};
Turns out it was another file altogether, which I had to rewrite.
Hello I'm parsing some data from my database into a table using aui-datatable plugin however I would like to add some basic sorting in my columns. Bellow you may see the function "renderProducts" which renders the data-table. Furthermore bellow is a sample column object that is being passed into the table renderer.
var API= (function(Y){
var settings = {
serviceURL : null
};
var getServiceAttribute = function( attribute ) {
return '_openpimadmin_WAR_OpenTest_' + attribute;
}
var getServiceURL = function( service ) {
return settings.serviceURL + '&p_p_resource_id=' + service;
};
var service = function( service, dataSet, handlers ){
var serviceData = {};
var serviceHandlers = {
start : function(){},
success : function(){},
failure : function(){},
end : function(){}
};
for (prop in dataSet) {
serviceData[getServiceAttribute(prop)] = dataSet[prop];
}
for (prop in handlers) {
if ( serviceHandlers.hasOwnProperty(prop) && typeof handlers[prop] === 'function') {
serviceHandlers[prop] = handlers[prop];
}
}
Y.io(
getServiceURL( service ),
{
method : 'POST',
data : serviceData,
on : {
start : function( transactionID ) {
serviceHandlers.start(transactionID);
},
success : function( transactionID, response ) {
var parsed = Y.JSON.parse(response.responseText);
if (parsed.success === true){
serviceHandlers.success( transactionID, parsed );
} else {
console.log('Service [' + service + '] error: ' + parsed.error);
}
},
failure : function( transactionID, response ) {
serviceHandlers.failure( transactionID, response );
},
end : function( transactionID ) {
serviceHandlers.end( transactionID );
}
}
}
);
}
return {
services : {
getProducts : function( dataSet, handlers ){
dataSet = dataSet || {};
handlers = handlers || {};
service( 'getProducts', dataSet, handlers );
},
getProductsTableAttributeHeaders : function( dataSet, handlers) {
dataSet = dataSet || {};
handlers = handlers || {};
service( 'getProductsTableAttributeHeaders', dataSet, handlers );
},
},
views : {
renderProducts : function( el, columns, dataSet ) {
Y.one(el).get('childNodes').remove();
new Y.DataTable.Base({
columnset : columns,
recordset : dataSet,
width: '100%'
}).render(el);
}
},
get : function( prop ) {
return settings[prop];
},
set : function( options ) {
settings = Y.merge( settings, options );
}
};
})( YUI().use('node', 'io', 'aui-datatable', 'datatable-sort', function(Y){return Y;}) );
Column object:
Object {key: "name", label: "Όνομα", allowHTML: true, emptyCellValue: "<em>(not set)</em>", sortable: true}
The issue I'm facing is that sorting is nowhere to be seen, columns dont seem interactive and the user is not able to sort them, although the table is being rendered fine.
Thank you in advance.
PS: I'm new to YUI().
You need to make sure that sortable: true set for column that need sorting.
Here is a real world example with sorting feature
It seems this was the problem:
new Y.DataTable.Base({
columnset : columns,
recordset : dataSet,
width: '100%'
}).render(el);
Should have been like this:
new Y.DataTable({
columnset : columns,
recordset : dataSet,
width: '100%'
}).render(el);
My full code is here: http://jsfiddle.net/HfNk9/13/
I am looking to this example jqueryUi autocomplete - custom data and display.
Let's suppose the object projects is different and it looks like this:
project = [
{
name: 'bar',
value: 'foo',
imgage: 'img.png'
}
]
If I set source = project the autocomplete refers to project.value and not project.name.
How should I change this behaviour?
var autocomplete = function(element, data) {
var fixtures = [
{
avatar: "http://www.placekitten.com/20/20",
name: 'aaaaaaaaa',
value: 'bbbbbbbbb'}
];
element.autocomplete({
minLength: 3,
source: function(request, response) {
var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
response($.grep(fixtures, function(value) {
return matcher.test(value.name);
}));
},
create: function() {
console.log(fixtures)
element.val(fixtures.name);
},
focus: function(event, ui) {
element.val(ui.item.name);
return false;
},
select: function(event, ui) {
element.val(ui.item.name);
return false;
}
}).data('autocomplete')._renderItem = function(ul, item) {
return $('<li></li>')
.data('item.autocomplete', item)
.append('<a><img src="' + item.avatar + '" />' + item.name + '<br></a>')
.appendTo(ul);
};
};
autocomplete($('#auto'));
My full code: http://jsfiddle.net/HfNk9/13/
You need to filter on a different property than the autocomplete widget searches on by default (as you've noticed it's name or value when using a source array with objects).
You can use a function instead of an array as the source and perform your own filtering that way:
element.autocomplete({
minLength: 3,
source: function(request, response) {
var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
response($.grep(fixtures, function(value) {
return matcher.test(value.name);
}));
},
create: function() {
console.log(fixtures)
element.val(fixtures.name);
},
focus: function(event, ui) {
element.val(ui.item.name);
return false;
},
select: function(event, ui) {
element.val(ui.item.name);
return false;
}
}).data('autocomplete')._renderItem = function(ul, item) {
return $('<li></li>')
.data('item.autocomplete', item)
.append('<a><img src="' + item.avatar + '" />' + item.name + '<br></a>')
.appendTo(ul);
};
Example: http://jsfiddle.net/QzJzW/
You should use the select property:
$("...").autocomplete({
source: ...,
select: function( event, ui ) { //when an item is selected
//use the ui.item object
alert(ui.item.name)
return false;
}
});
The answer is in the source code to the page you've linked to. If you want to use the value of name instead of value then you would do something like this:
$( "#input" ).autocomplete({
minLength: 0,
source: projects,
focus: function( event, ui ) {
$( "#input" ).val( ui.item.value );
return false;
},
select: function( event, ui ) {
$( "#input" ).val( ui.item.value );
return false;
}
})
.data( "autocomplete" )._renderItem = function( ul, item ) {
return $( "<li></li>" )
.data( "item.autocomplete", item )
.append( "<a>" + item.name + "</a>" )
.appendTo( ul );
};