jQgrid tableToGrid inside jQuery UI tabs in AJAX mode - javascript

I have an issue with jgrid's tableToGrid. I have three nested tabs (inside an another tab) that generate out of the following three list items
<div id='sub_nav_menu >
<ul>
<li><a href='workorders.php'/>Open WorkOrders</a><li>
<li><a href='workorders.php?status=overdue'/>Stale WorkOrders</a><li>
<li><a href='workorders.php?status=closed'/>closed WorkOrders</a><li>
</ul>
</div>
jQuery-ui will create a content div for each one of these links in an unobtrusive manner, where the result obtained from the server will be shown inside that div as a table, with the same class selector of the other tables obtained from selecting the other siblings tabs. The tables will be shown inside the dynamically created div, which associate with each of these tabs. The table looks like this:
<table class='result-table'>
<thead>...</thead>
<tbody>You know what's here ...</tbody>
</table>
and the jquery ui code which creates the grid is this
$('#nav').tabs({
load: function() {
// first: load the inner tabs
$('#sub_nav_menu').tabs({
load: function (event,ui) {
// second: load jqGrid stuff after loading the tabs content
tableToGrid(".result-table:eq(" + ui.index + ")",{
defaults : {
recordtext: "View {0} - {1} of {2}",
emptyrecords: "No records to view",
loadtext: "Loading...",
pgtext : "Page {0} of {1}"
},
loadonce: true,
rowNum: 10,
caption: 'Showing "Open Work orders"'
});
} //inner nav 'load' function
});
} //upper nav 'load' function
});
The table is converting properly to a jqGrid, the data of the original table is carried over properly inside the plugin code in a "data" array; however, the plugin fails when it reaches to the point of
jQuery(this).jqGrid(jQuery.extend({
datatype: "local",
width: w,
colNames: colNames,
colModel: colModel,
multiselect: selectMultiple
//inputName: inputName,
//inputValueCol: imputName != null ? "__selection__" : null
}, options || {}));
Which is followed by the code
$.fn.jqGrid = function( pin ) {
if (typeof pin == 'string') {
//var fn = $.fn.jqGrid[pin];
var fn = $.jgrid.getAccessor($.fn.jqGrid,pin);
if (!fn) {
throw ("jqGrid - No such method: " + pin);
}
var args = $.makeArray(arguments).slice(1);
return fn.apply(this,args);
}
return this.each( function() { // it failes where the "chaining" happens
if(this.grid) {return;}
However, the code fails where the "chaining" happens with the error code
Uncaught Error: Syntax Error, unrecognized expression "#"
It seems it's related to the 'class' vs. 'id' selector as when I change the table selection to 'id' it works.
I am just wondering if this could be a bug in the plugin of jqGrid. Even if it's the case, what would you suggest as a different way to go around this problem. I was thinking of generating different ids for each one of the tables, but I am just annoyed with the issue of not being able to use tables class as a selector!
The jQuery version is 1.7.1,
The jQuery-UI 1.8.17
The jqGrid is 4.3.1
Thanks alot!
Workaround
I managed to make it work with server-side generated ids for easier reference and then doing a switch at the client-side on these ids as they are previously known. However, I see this method as being inefficient because it don't deal with general case selectors, but rather specific ones and do not address the real problem.

Related

Can't find element using UI hash in Marionette Layout

I'm not sure why I can't get the button element using my UI hash. This is what my Layout looks like:
Layout: App.Base.Objects.BaseLayout.extend({
// Rest of the code left out for brevity
ui: {
btnSave: "#btnSave"
},
events: {
"click #ui.btnSave": "onSave"
},
onInitialize: function () {
this.listenTo(App.vent, "DisableSaveButton", function(val) {
this.disableSaveButton(val);
},this);
},
disableSaveButton: function () {
this.ui.btnSave.prop("disabled",val).toggleClass("ui-state-disabled",val);
},
onSave: function () {
alert("saved!");
}
})
In VS2013, when my breakpoint hits the line inside disableSaveButton method, I entered $("#btnSave") into the Watch window and I was able to get the element back. I could tell because it had a length of 1. From this, I know the button is rendered. However, if I enter this.ui.btnSave into the Watch window, I would get an element with length of 0.
My BaseLayout object is basically a custom object extended from Marionette.Layout
Marionette version: 1.8.8
Any ideas why I can't find the button element using this.ui.btnSave?
Thanks in advance!
Got some help from a coworker and the issue might be because the element is out of scope. Basically, inside the Layout object, 'this' does not contain the element. We were able replace 'this.ui.btnSave' with '$("#btnSave",this.buttonset.el)' and that works fine. buttonset is the region that actually contains the html element.
This seems like an inconsistency because even though the ui hash didn't work, the click event utilizing the ui hash did work.
UPDATE 6/3/2015:
Another coworker of mine provided a better solution. Basically, in my Layout I use a display function to display my view. It looks something like this:
Layout: App.Base.Objects.BaseLayout.extend({
// Rest of the code left out for brevity
display: function() {
$(this.buttonset.el).html(_.template($("#buttonset-view").html(), {"viewType": viewType}));
}
})
Basically, I'm saying to set the html of my region, which is this.buttonset.el, to my template's html. As of now, my layout doesn't know any of the elements inside the region. It just contains a region which displays the elements. So there is some sort of disconnect between my layout and the elements in my region.
The correct solution, as opposed to my earlier workaround, is to simply add the following line of code at the end:
this.bindUIElements();
From Marionette Annotated Source:
This method binds the elements specified in the “ui” hash inside the
view’s code with the associated jQuery selectors.
So this final code looks like this:
Layout: App.Base.Objects.BaseLayout.extend({
// Rest of the code left out for brevity
display: function() {
$(this.buttonset.el).html(_.template($("#buttonset-view").html(), {"viewType": viewType}));
this.bindUIElements();
}
})
With this, I was able to finally able to retrieve my element using this.ui.btnSave.

Jquery UI slider events not working Drupal 7

I am trying to implement a slider for a view form ( i have hidden the text field and want to make a script to display a slider and on change / stop to set the value to hidden text field. My problem is that the events are not firing at all. I added the jquery UI library and my script in the template.php of my template ( using ZEN ) :
function ThemeName_preprocess_page(&$variables) {
drupal_add_library('system', 'ui');
drupal_add_library('system', 'ui.slider');
drupal_add_js('URL/js/search.js');
}
and this is the javascript/jquery code :
(function ($, Drupal, window, document, undefined) {
Drupal.behaviors.customSearch = {
attach: function(context, settings) {
$(document).ready(function (){
$("#distanta_slider").slider({
orientation: "horizontal",
range: "min",
max: 150,
min: 1,
value: 1,
//change: slider_change(),
//slide: slider_change(),
//stop: slider_change()
});
$("#distanta_slider").on("slidestop",slider_change());
$("#distanta_slider").on("slide",slider_change());
$("#distanta_slider").on("slidechange",slider_change());
});
function slider_change(){
alert($("#distanta_slider").slider("value"));
}
}
};
})(jQuery, Drupal, this, this.document);
I tried binding the event using $(selector).on , and also tried to declare them in the constructor ( the 3 commented lines ). In the first scenario at page load i received 3 alerts with the current value , in the second scenario i receive 3 alerts saying "Object Object" , but in both scenarios if I move the slider absolutely nothing happens ... No errors , nothing .
Any help is most appreciated. Thank you in advance,
Cristi
Call function name without arguments in on statement.
$("#distanta_slider").on("slidestop",slider_change);
$("#distanta_slider").on("slide",slider_change);
$("#distanta_slider").on("slidechange",slider_change);
Wrong Assumption
$("#distanta_slider").on("slidestop",slider_change());
the function slider_change executes immediately here

Sorting Before Event in jQuery jqGrid

I am working on jQuery's jqGrid and I am not using paging in my jqGrid. My code fetch more than 1000 rows data and all data shows in jqGrid without paging and use loadonce: true property. Now my requirement is that when user sort any column it takes 3-5 seconds to sorting data so i want to show at that time loading image. I wrote
beforeRequest: function () { jQuery(".imgLoading").show(0);},
gridComplete: function () {jQuery(".imgLoading").hide(0);}
these 2 events and it works fine when data comes with server and manipulating with server.
But I want to sorting on client side by using loadonce: true and want to show loading image also but I don't know on which event I will write down image show hide code.
Please tell me the name of BeforeSortEvent and AfterSortEvent of jqGrid.
I checked on this URL : http://www.trirand.com/jqgridwiki/doku.php?id=wiki:events but didn't find right event.
Please help me out.....
Try:
onSortCol: function(index, iCol, sortorder) {
jQuery(".imgLoading").show(0);
},
gridComplete: function() {
jQuery(".imgLoading").hide(0);
}
EDIT
Since you said the alert() fires off, I'm thinking your problem is in the way you are showing/hiding those .imgLoading elements.
Try:
onSortCol: function(index, iCol, sortorder) {
alert("I'm about to SHOW the loading message");
$(".imgLoading").show();
},
gridComplete: function() {
alert("I'm about to HIDE the loading message");
$(".imgLoading").hide();
}
Be sure those two alert()'s fire off, and if they do, then something is still off with those .imgLoading elements you are trying to show/hide.

CKEditor: call a plugin function without toolbar button

How can I call a plugin function without a toolbar button?
I have an external floating toolbar integrated in my cms. I insert images, videos and other pieces of static code with the InsertHTML() API of CKEditor.
Now I need to insert also video from URL, and there is the fantastic oembed plugin. How can I fire that plugin using a button in my cms without the toolbar button?
I load the plugin in my config, and I try to create this function:
function oembed() {
// Get the editor instance that we want to interact with.
var editor = CKEDITOR.instances.editor1;
var url = 'http://www.youtube.com/watch?v=AQmbsmT12SE'
var wrapperHtml = jQuery('<div />').append(editor.config.oembed_WrapperClass != null ? '<div class="' + editor.config.oembed_WrapperClass + '" />' : '<div />');
// Check the active editing mode.
if ( editor.mode == 'wysiwyg' )
{
// Insert HTML code.
// http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertHtml
editor.embedCode(url, editor, false, wrapperHtml, 650, 400, false);
}
else
alert( 'You must be in WYSIWYG mode!' );
}
The result is this:
Uncaught TypeError: Object [object Object] has no method 'embedCode'
Is there any way to create a new API like "InsertHTML" to call plugin functions without toolsbar buttons?
EDIT
Maybe I can use the createFakeElement API.
http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-createFakeElement
I add the class fakegallery to my doc.
I use this code but nothing happens:
function Fake()
{
var editor = CKEDITOR.instances.editor1;
var element = CKEDITOR.dom.element.createFromHtml( '<div class="bold"><b>Example</b></div>' );
alert( element.getOuterHtml() );
editor.createFakeElement( element, 'fakegallery', 'div', false );
}
I found this post looking for the answer...
Checked out the link provided in the answers here [ http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-fire ], scrolled down to execCommand
This worked for me and only requires that you know the name of your plugin, so it'll always work. Obviously, you may need to change "editable" to your editor instance.
CKEDITOR.instances['editable'].execCommand('YOUR_PLUGIN_NAME_HERE');
If above fails, HACK:
This would work (first line of code below), but requires you to look at the source to find the correct #. If you have 1 custom plugin, no big deal. But if you have a dozen or more, like me, this is annoying, and could change as more plugins are added.
CKEDITOR.tools.callFunction(145,this);
Hope this helps!
Read this:
http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-fire
editor.fire( 'MediaEmbed', data);
I think that this is the structure that your data needs to have:
var data = {title : 'Embed Media',
minWidth : 550,
minHeight : 200,
contents :
[
{
id : 'iframe',
expand : true,
elements :[{
id : 'embedArea',
type : 'textarea',
label : 'Paste Embed Code Here',
'autofocus':'autofocus',
setup: function(element){
},
commit: function(element){
}
}]
}
]}
I'm not secure but this will help you on the way.
Look at the Source code of the plugin to find the available commands.
The command name that i specified above is the only one that your plugin haves.
EDIT - Manual inserting
var div = editor.document.createElement('div');
div.setHtml("<embed src=" + url +" width=" + width +" height=" + height + ">");
editor.insertElement(div);
You can add every attribute you like, Type?? maby? Autofocus??

Modify CKEditor link dialog to add custom attribute to links

I am using CKEditor on a website and I need to be able to put a special data attributes on some of the links created through the editor. The user would indicate that they need the special attribute put on the link by checking a checkbox in the link dialog. I have managed to add a checkbox to the link dialog with the following code:
CKEDITOR.on('dialogDefinition', function(ev) {
if (ev.data.name == "link") {
var info = dialog.getContents("info");
info.elements.push({
type: "vbox",
id: "urlOptions",
children: [{
type: "hbox",
children: [{
id: "button",
type: "checkbox",
label: "Button",
commit: function(data) {
data.button = this.getValue()
console.log("commit", data.button, data);
},
setup: function(data) {
this.setValue(data.button);
console.log("setup", data.button, data);
}
}]
}]
});
}
});
Now I have two problems. The first one is that despite me adding the code in the commit and setup functions that should save the state of the checkbox, it's not working. It's as if the data can't hold any other parameters but the ones there by default.
The second problem is that I don't know how to add / remove the data attribute on my links. It seems to me that I should be doing that in my onOk callback on the dialog, however, the link dialog already has an onOk callback, so I'm not sure how I should be proceeding. I, of course, do not want to modify any of CKEditor's files directly.
How can I accomplish these things?
You best option is to modify the plugin. So you need to open the source code and find the file links.js in c:\ckeditor_3.6.5\ckeditor\_source\plugins\link\dialogs\
The source code is quite big (40k) but here you can modify the dialog however you want. When you finish just copy it to your plugins folder, and compress it: http://jscompress.com/
I have done what you need myself. The whole uncompressed file is here: https://gist.github.com/3940239
What you need to do:
First add this line just before the dialog "browse" button is appended. Approx. in line: 547:
{
id: "button",
type: "checkbox",
label: "Button",
setup: function (data) {
this.allowOnChange = false;
if (data.button)
this.setValue(data.button);
this.allowOnChange = true;
},
commit: function (data) {
data.button = this.getValue()
this.allowOnChange = false;
}
},
This part is actually your code. I just copied and pasted it.
Then, go to the onOk function, approx. in line 1211: and after commitContent add this code:
this.commitContent( data );
//My custom attribute
if (data.button)
attributes["custom-attribute"] = "button";
else
attributes["custom-attribute"] = "";
This will modify your link adding the attribute to the element such as text
That's it. Although, you may also like to load the current status of the checkbox. Then, go to the function parseLink . Approx. line 179 to load the attributes:
...
if ( element )
{
retval.button = element.getAttribute('custom-attribute');
var target = element.getAttribute( 'target' );
...
I am exploring the same thing now. What I have decided to do at this point is to:
Get a base ckeditor install without the link plugin
create my own fork of the link plugin, and add my changes to it, then activate and use this plugin within the group that link normally shows up in.
...working with it as a custom plugin (albeit a copy of the original) should alleviate the problem of upgrading. You just simply do not use the original link plugin at all. Copy and rename it, and use your custom copy instead.

Categories

Resources