jquery addon function not adding element to DOM in nw.js inside w2ui panel - nw.js

I created this in fiddle to show what I'm trying to do in nw.js. This works just fine. 2 tabs get created dynamically at run-time just fine.
http://jsfiddle.net/fnbqupf4/
I port this over to my nw.js and I get an error when ace.edit() is called saying it can't find the element ID. When I look at the DOM in nw.js I see the tab and the editor is NOT created there. So the issue is the tab and editor div get created in the jsFiddle but not in the nw.js site.
Is there something with not being able to dynamically add elements to the DOM in nw.js?
$.fn.addEditorTab = function(name, tabName, contents) {
console.log("1");
$('ul', this).append('<li title="' + name + '">' + tabName + '<span class="ui-icon ui-icon-close" role="presentation"></li>');
$(this).append("<div id='tab-" + name + "'><div id='editor-" + name + "' class='editor'></div></div>");
$(this).tabs("refresh");
console.log("2");
var editor = ace.edit("editor-" + name);
console.log("3");
editor.setTheme("ace/theme/monokai");
editor.getSession().setMode("ace/mode/lua");
editor.setOptions({
maxLines: Infinity
});
editor.getSession().setValue(contents);
return editor;
};
[EDIT]
After some more messing around it seems it's only an issue when I have the tabs div inside a panel in w2ui.
$('#layout').w2layout({
name: 'layout',
panels: [
{ type: 'top', size: 50, style: pstyle, content: 'top', resizable: true },
{ type: 'left', size: 300, style: pstyle, content: '<div id="sidebar" style="height: 100%; width: 100%;"></div>', resizable: true }
//{ type: 'main', style: pstyle, content: '<div id="editor"></div>' }
{ type: 'main', style: pstyle, content: '<div id="tabs"><ul></ul></div>' }
]
});

Related

ckeditor dialog and widget not working properly

In the ckeditor (plugin.js) I have this code below.
CKEDITOR.plugins.add( 'beforeafter', {
requires: 'widget',
icons: 'beforeafter',
init: function( editor ) {
editor.widgets.add( 'beforeafter', {
button: 'beforeafter',
template:
'<div class="ba-slider-element">' +
'<div class="ba-slider">' +
'<div class="resize">' +
'<div class="handle">' +
'</div>',
dialog: 'beforeafterDialog',
upcast: function( element ) {
return element.name == 'div' && element.hasClass( 'ba-slider' );
}
} );
// Define an editor command that opens our dialog window.
editor.addCommand( 'beforeafter', new CKEDITOR.dialogCommand( 'beforeafterDialog' ) );
// Create a toolbar button that executes the above command.
editor.ui.addButton( 'beforeafter', {
// The text part of the button (if available) and the tooltip.
label: 'Insert A Before And After Image',
// The command to execute on click.
command: 'beforeafter',
// The button placement in the toolbar (toolbar group name).
toolbar: 'insert'
});
// Register our dialog file -- this.path is the plugin folder path.
CKEDITOR.dialog.add( 'beforeafterDialog', this.path + 'dialogs/beforeafter.js' );
}
});
In the dialog file (beforeafter.js) I have this code below.
CKEDITOR.dialog.add( 'beforeafterDialog', function( editor ) {
return {
title: 'Before and After Image Tool',
minWidth: 400,
minHeight: 200,
contents: [
{
id: 'tab-basic',
label: 'Basic Settings',
// The tab content.
elements: [
{
type: 'text',
id: 'beforeimage',
label: 'paste your BEFORE image URL below',
validate: CKEDITOR.dialog.validate.notEmpty( "Please add a URL in the Before image field." )
},
{
type: 'text',
id: 'afterimage',
label: 'paste your AFTER image URL below',
validate: CKEDITOR.dialog.validate.notEmpty( "Please add a URL in the After image field." )
}
]
},
],
onOk: function() {
var dialog = this;
var result = editor.document.createElement('div');
result.setHtml("<div class=\"ba-slider-element\">\n" +
"<div class=\"ba-slider\">\n" +
"<img src=\"" + dialog.getValueOf( 'tab-basic', 'beforeimage' ) + "\" alt=\"\">\n" +
"<div overlay-lable=\"Before\" class=\"before-lable-1\">\n" +
"<div overlay-lable=\"Before\" class=\"before-lable-2\">\n" +
"<div class=\"resize\">\n" +
"<img src=\"" + dialog.getValueOf( 'tab-basic', 'afterimage' ) + "\" alt=\"\">\n" +
"<div overlay-lable=\"After\" class=\"after-lable-1\">\n" +
"</div>\n" +
"<div overlay-lable=\"After\" class=\"after-lable-2\"></div></div>\n" +
"<div class=\"handle\">\n" +
"</div>");
editor.insertElement( result );
}
};
});
In the ckeditor posting edit window, when I click the source button to view the source, this is the code that is generated below.
<div>
<div class="ba-slider-element">
<div class="ba-slider">
<img alt="" src="https://pepsized.com/wp-content/uploads/2018/09/beerslider/demo-assets/images/man-hold-beer.jpg">
<div overlay-lable="Before" class="before-lable-1">
<div overlay-lable="Before" class="before-lable-2">
<div class="resize">
<img alt="" src="https://pepsized.com/wp-content/uploads/2018/09/beerslider/demo-assets/images/man-hold-beer-after1logo.jpg">
<div overlay-lable="After" class="after-lable-1">
</div>
<div overlay-lable="After" class="after-lable-2">
</div>
</div>
<div class="handle">
</div>
</div>
</div>
</div>
</div>
The slider works fine but I am not able to edit the URL fields.
When I double click the slider to edit it the dialog window will pop up with an empty URL fields.
ckeditor diolog
What I need help with is.
1. I need the element to highlight in yellow and blue when I hover over the area
2. When I double click to edit, the dialog fields should show the previous inputted URL.
3. How would be able to preview the slider wile in edit mode. the slider use jquery script.
Your help will be truly appreciated.

How to put an if condition under columns in kendo grid

Can we add a if Condition inside the column while describing the columns of the grid? Whats wrong in this code
I want to display one button in the grid under a column ,if length of the text exceeds more than 40char.
I am trying to put an if condition if the content/data is less than 40 char then display the content else display a button , On click of button open a pop-up to display the complete content inside that pop-up?
How we can put the command conditionally to display the button?
Here is my code
columns: [{
field: "id",
title: "ID",
width: "100px"
}, // fields in the grid
{
field: "name",
title: "Name",
width: "100px"
}, {
field: "remarks",
title: "Remarks",
width: "160px", // under this column button will be displayed in each
var length = 40;
if (data.remarks.length > length) { //here this condition seems to be wrong, is there any other way to display the button for this condition
command: {
name: "remarks",
text: "Remarks",
click: function (e) {
var tr = $(e.target).closest("tr");
var data = this.dataItem(tr);
var win = $('#remarksWindow');
win.html(data.remarks);
if (!win.data('kendoWindow')) {
win.kendoWindow({
width: '600px',
height: '200px',
title: 'Remarks',
actions: ['Close']
});
}
win.parent().css({
top: e.pageY - 50,
left: e.clientX - 640,
width: '600px',
height: '200px'
});
win.data('kendoWindow').open(); // open the pop-up which contains the data
return false;
}
}
}
}
},
First of all, you have a syntax error in JavaScript. Note that you can't put statements or declarations between the properties of an object:
var obj = {
a: 1,
if (true) {
b: 2;
}
}
Or
var obj = {
a: 1,
var b = 1;
}
The examples above doesn't works. So in your column property you have to use a template property:
{
field: "remarks",
title: "Remarks",
width: "160px",
template: "" // <- here goes your logic
}
So a simple template can be set as a string containing html with JavaScript logic, e.g.:
# if (remarks.length > 40) { # <input type='button' class='btn-remarks' /> # } #
Yes, you will have to set the button html by yourself. There is no way to add a condition to a command button(and that is a shame, actually).
You can check how template works here.
Then your column item should be:
{
field: "remarks",
title: "Remarks",
width: "160px",
template: "# if (remarks.length > 40) { # <input type='button' class='remarks' /> # } #"
}
Then you have to set the event for all your buttons(probably in the dataBound event):
$("#yourGrid").on("click", ".btn-remarks", function()
{
// all your click logic here
});
Give it a try and tell me what happens.
Hopefully this dojo is what you are looking for: http://dojo.telerik.com/ETora
(I have used one of Telerik's grid demos and modified to show you the principles)
The functionality you are looking for can be achieved by two means:
1) Apply a client Template to the column
2) Add a databound event that then hooks up the buttons
columns:[ {
field: "CompanyName",
title: "Company Name",
template: "#= displayTextorButton(data.CompanyName) #"
}]
function displayTextorButton(data){
var retString = '';
console.log(data);
if(data !== null && data !== undefined)
{
if(data.length > 20)
{
retString = ' <button type="button" class="btn btn-xs btn-primary"' +
'data-toggle="popover" data-placement="auto right" data-container="body" ' +
'data-content="' + kendo.htmlEncode(data) + '"' +
'data-title="Running Log Information" data-trigger="click" data-role-me="content-popover" > <span class="glyphicons glyphicons-pencil"></span> View</button>';
}
else
{
retString = '<span>' + data + '</span>';
}
}else
{
retString = '<span> - </span>';
}
return retString;
}
so the first bit I have done is added a template to the Company Name column that checks if the name is more than 20 characters if it is then it will display a button if it isn't then it will display the text as normal.
function(e){
$('button[data-role-me="content-popover"]').popover({ trigger: "focus", html: true });
}
I then hook up a databound event to the grid to then attach the event features to the "pop up" in my sample
Also note I have hooked in the bootstrap features just to make things a little easier for the demo. So this is using their popover feature. You could modify this code to work with your window.
Any issues let me know.
This is the kendo grid code
{ field: "marks", title: "marks",width: "160px",
template: function(dataItem) {
var marks = dataItem.marks;
var retString = '';
if(marks !== null && marks !== undefined)
{
if(marks.length > 40)
{
marks1 = marks.substring(0, 40)+'...';
retString1 ='<span>'+ marks1 +'</span>';
retString = retString1 + ' <button id="marksButton" type="button"' +
'data-toggle="popover" data-placement="auto right" data-container="body" ' +
'data-content="' + kendo.htmlEncode(addlRemarks) + '"' +
'data-title="marks" data-trigger="click" data-role-me="content-popover" > marks</button>';
}
else
{
retString = '<span>' + marks + '</span>';
}
}else
{
retString = '<span> - </span>';
}
return retString;
}
And its being called from a HTMl
<div class="panel-body" ng-show="accOpen[$index]">
<!-- Marks TABLE -->
<div marks-table=""
accordion-flag="accOpen[$index]"
name="name"
id="id"
>
</div>
</div>

How do I configure a Kendo UI grid to use a DropDownList to edit a cell?

I'm having trouble configuring a `Kendo UI' grid to use a DropDownList as an editor. I have a JS Bin example to reproduce my behavior. The goal is to populate the BinNumber, PartNumber and StockNumber fields once a selection is made from the dropdown. Currently I can't even get the DropDown to bind to the recordset properly. If I make a selection and move to another field, I get [object Object] in the BinNumber field. If I go back in and make another selection, the BinNumber then sticks. I have read the documentation thoroughly but I am still thoroughly confused by it.
For the [object object] mess have a look at this post, there is an attribute introduced back in late 2013 dealing with this issue data-value-primitive="true". In the past I just used to re-map the selection back to ds manually, but the attribute does it all for you, I tested in you jsBin and works fine.
binDropdownEditor: function (container, options) {
$('<input data-text-field="BinNumber" data-value-field="BinNumber" data-value-primitive="true" data-bind="value:' + options.field + '"/>')
.appendTo(container)
.kendoDropDownList({
autoBind: false,
dataSource: viewModel.binDropDownDataSource
});
}
On change binding (please paste into your JSBin javascript tab):
var bins =["BinNumber:12121"];
var gridDS = new kendo.data.DataSource({
transport: {
read: function (e) {
e.success(bins);
}
},
schema: {
model: {
id:"Row",
fields: {
Row:{type:"string"},
BinNumber: {type:"string"},
PartNumber: {type:"string"},
StockNumber:{type:"string"}
}
}
},
pageSize: 50
});
var binDropDownDataSource = [
{ BinNumber: "12345",PartNumber:"P-2929",StockNumber:"S-06565" },
{ BinNumber: "23456",PartNumber:"P-2323",StockNumber:"S-956565" },
{ BinNumber: "34567",PartNumber:"P-4344",StockNumber:"S-67676" } ];
function appendEditor (container, options) {
$('<input data-text-field="BinNumber" data-value-primitive="true" data-value-field="BinNumber" data-bind="value:' + options.field + '"/>')
.appendTo(container)
.kendoDropDownList({
autoBind: false,
dataSource: binDropDownDataSource,
change:function(e){
var ddldataitem = this.dataItem();
var griditem = gridDS.at(0); // you might need to tweak this line
griditem.set("PartNumber",ddldataitem.PartNumber);
griditem.set("StockNumber",ddldataitem.StockNumber);
}
});
}
var grid= $("#bins").kendoGrid({
dataSource: gridDS,
scrollable: false,
autoBind:false,
batch:true,
editable : true,
navigatable: true,
toolbar: [ {name: 'custom-create', text: "Add New Line Item"}],
columns: [ {"field":"Row", title: "Row", width: "20px"},
{"field": "BinNumber","title":"Bin", editor: appendEditor},
{"field": "PartNumber", title: "Part ", width: "200px",editable: false },
{"field": "StockNumber", title: "Stock ", width: "200px",editable: false }
]
}).data("kendoGrid");
$(".k-grid-custom-create").on("click", function (e) {
gridDS.add({ Row:"1"});
});
The observable you had plugged in is not really necessary the underling data source is already observable, I have removed it. Please consider improving following line the index won't be always 0 var griditem = gridDS.at(0);
Here's how my DropDown is setup. This is a boolean field, so you will have to adjust it accordingly to your field
columns.Bound(m => m.IsInForecast).Title("Is Forecasted").ClientTemplate(
"# if (IsInForecast == true) { #" +
"<select id='#= OrderId #' onchange=save('#= OrderId #'); style='Width: 80px; color: 'navy' > " +
"<option id='yes' selected value='1'>Yes</option>" +
"<option id='no' value='0'>No</option>" +
"</select>" +
"# } else { #" +
"<select id='#= OrderId #' onchange=save('#= OrderId #'); style='Width: 80px; color: 'navy' > " +
"<option id='yes' value='1'>Yes</option>" +
"<option id='no' selected value='0'>No</option>" +
"# } #"
);

Can't scroll to the bottom if content too long Sencha Touch 2

Can't scroll to the bottom if content too long
Why it can't scroll to the bottom if the content too long?
this._panel = {
xtype: 'panel',
height: '100%',
scrollable: true,
items: [{
html: '<img src="http://images5.fanpop.com/image/photos/29400000/Iron-Man-Tony-Stark-the-avengers-29489238-2124-2560.jpg" />'
}, {
html: '<img src="http://images5.fanpop.com/image/photos/29400000/Iron-Man-Tony-Stark-the-avengers-29489238-2124-2560.jpg" />'
}]
};
this.add(this._panel);
Im adding your code as an item of Ext.Container, Ext.Panel, or Ext.navigation.View and in all cases I can scroll to the bottom. I think is due to some config you have set in 'this'.
What component (xtype) is it?

onclick event not fired on the button which is added to each subgrid cell of jqGrid

I have added a button to each row of the subgrid of a jqGrid. I just followed the documentation of inline_editing for this.
I want to call the server side code on click of the button. But when I see the firebug it shows no request been made (not showing any url request) on click of the button.
Below is my code,
subGridRowExpanded: function (subgrid_id, row_id) {
var subgrid_table_id, pager_id;
subgrid_table_id = subgrid_id + "_t";
pager_id = "p_" + subgrid_table_id;
$("#" + subgrid_id)
.html("<table id='" + subgrid_table_id + "' class='scroll'></table><div id='" + pager_id + "' class='scroll'></div>");
$mysubgrid = jQuery("#" + subgrid_table_id);
$mysubgrid.jqGrid({
url: "serversub.php",
datatype: "json",
colNames: ['Product Id', 'Product Name', 'status', ''],
width: 700,
colModel: [{
name: 'productid',
index: 'productid',
width: 55
}, {
name: 'productname',
index: 'productname',
width: 90
}, {
name: 'status',
index: 'status',
width: 80,
search: false
}, {
name: 'link',
index: 'link',
width: 80,
search: false
}],
rowNum: 20,
sortname: 'num',
sortorder: "asc",
gridComplete: function () {
var ids = $mysubgrid.jqGrid('getDataIDs');
for (var i = 0; i < ids.length; i++) {
var cl = ids[i];
se = "<input style='height:22px;width:20px;'
type='button' value='Update' onclick=\"$mysubgrid.saveRow('" + cl + "');\" />";
$mysubgrid.jqGrid('setRowData', ids[i], {
link: se
});
}
},
editurl: "saveserversub.php"
});
Am I missing something here?
Thanks
The function which you call in onclick have contains only global variables. You can't use local $mysubgrid variable.
I would recommend you to create buttons which you need inside of custom formatter and to use (like in all other your grids) the option gridview: true. It will improve performance of the grid.
Additionally I think that you don't need to set any onclick on the buttons which you insert in the grid column. If the click event is fire and there are no event handler for the click the bubbling take place. So you can just use onCellSelect callback. If you need have the original DOM object of the clicked button you find it in e.target.

Resources