AutoCompleteExtender positioning menu incorrectly when scrolled - ajaxcontroltoolkit

We have an AutoCompleteExtender linked to a TextBox. Both controls are placed inside an UpdatePanel, and the UpdatePanel is displayed as a pop-up dialog using a Javascript library (Ext.BasicDialog).
The pop-up is a div on the page, not a separate window.
The problem is that when the user scrolls inside the pop-up, the AutoCompleteExtender shows its menu in the wrong place. It looks like it is taking the visible distance from the top of the popup and positioning the menu from the top of the inner html of the popup (which is not visible)
We are using Version 1.0.20229.20821 of the AjaxControlToolkit, and we are targetting ASP.NET Framework vewrsion 2.0.
I have tried to fix the menu by attaching the following Javascript to the OnClientShown event, but it pretty much does the same thing:
function resetPosition(object, args) {
var tb = object._element; // tb is the associated textbox.
var offset = $('#' + tb.id).offset();
var ex = object._completionListElement;
if (ex) {
$('#' + ex.id).offset(offset);
}
}

I fixed this by setting position:relative on a div containing the TextBox and the auto-complete extender. The extender must have been using the wrong element to position on when inside the popup panel.

Add an empty <div id="AutoCompleteContainer"></div> element right after the AutoCompleteExtender. In AutoCompleteExtender, add an attribute pointing to this container, CompletionListElementID="AutoCompleteContainer". The list items should be contained in that div then.

I know this is an old post, but thought this information may help someone else. There is a newer version 15.x of the Ajaxtoolkit now (April 2015) and it fixes this issue. From my reading the CompletionListElementID property was deprecated some time ago, and at the least seems to behave differently in different versions. I upgraded my references to the 15.x version and it just started working as needed.

Related

Change menus and menu items programmatically in Eclipse E4

I am having trouble removing existing menus from the model, in a running app.
For example:
MMenu menu = modelService.findElements(app, "idMenuFoo", MMenu.class,
Collections.<String>emptyList(), EModelService.IN_MAIN_MENU).get(0);
menu.setLabel("X");
menu.setVisible(false);
menu.setToBeRendered(false);
After this code gets executed:
The label has been changed to 'X'
But the menu entry is still visible/rendered
If I start the app without clearPersistedState, then restart it, the menu has disappeared. This leads me to be believe the the visibility and rendering attributes were set in the first place, but not applied to the model (unlike the label attribute).
How can I programmatically trigger a main menu bar "refresh" after such changes?
As a Greg in the comment above posted, there is an open bug filed to address this issue. An easy to implement a workaround involves manually refreshing the underlying SWT menu. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=365724#c9 for details. In a gist:
// retrieve the main menu, containing the top-level menu element that needs to be refreshed
MMenu mainMenu = ...
// org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer
MenuManagerRender renderer = (MenuManagerRenderer)mainMenu.getRenderer();
renderer.getManager(mainMenu).update(true);

Wicket AjaxLink javascript handler shows strange behaviour

I have a ListView that displays a list of Panels, one below the other. Every panel features a button (implemented via AjaxLink) that closes the panel and removes it from the list.
This is how the ListView is initalized and how the panels are created:
panelsList = new ArrayList<MyPanel>();
pnlContainer = new WebMarkupContainer("pnlContainer");
ListView<MyPanel> pnlItems = new ListView<MyPanel>("pnlItems", panelsList) {
#Override
protected void populateItem(final ListItem<MyPanel> item) {
item.add(item.getModelObject());
item.add(new AjaxLink<Void>("pnlClose") {
#Override
public void onClick(AjaxRequestTarget target) {
panelsList.remove(item.getModelObject());
target.add(pnlContainer); // repaint panel container
}
});
}
};
pnlContainer.setOutputMarkupId(true);
pnlContainer.add(pnlItems);
add(pnlContainer);
This works so far - the actions that trigger adding new panels (usually also AjaxLinks) do what they should and the new panel is added and displayed correctly. But I have problems getting the close button to fully work.
Please see the following steps:
1) I start the server and navigate to the main page. The ListView is initially populated with one panel.
Close-button-code of this panel:
<a wicket:id="pnlClose" id="pnlClose7" href="javascript:;">Close</a>
Searching the page code for pnlClose7 finds the following javascript code that makes the button work as expected:
Wicket.Ajax.ajax({"u":"./?0-1.IBehaviorListener.0-pnlContainer-pnlItems-0-pnlClose","e":"click","c":"pnlClose7"});;
Note: I do not press the button now, if i would, it would work as expected (thoroughly tested).
2) I trigger an action that opens a second panel. The panel is displayed below the first one as expected.
Close-button of the first panel:
<a wicket:id="pnlClose" id="pnlClosef" href="javascript:;">X</i></a>
Close-button of the second panel:
<a wicket:id="pnlClose" id="pnlClose10" href="javascript:;">X</i></a>
But now, neither searching for pnlClosef nor pnlClose10 finds some javascript code. The buttons (both!) do not work. I can still find the javascript code for pnlClose7.
3) I reload the page via pressing F5.
The button IDs change to pnlClose1a and pnlClose1b. Both IDs have javascript counterparts and work.
4) I press the first button (upper panel, ID pnlClose1a). The panel is closed as expected.
The remaining button's ID changes to pnlClose1c, again without a javascript counterpart. Javascript code for pnlClose1a and pnlClose1b is still present.
To make a long story short, the javascript handlers for my AjaxLinks seem to have shyness issues and only appear after I press F5 or reload the whole page in any other manner. I guess thats because repainting the pnlContainer changes the IDs of the current panels - but why is the linked javascript not updated at the same time? Is there anything I can change in my code to update the whole page without completely reloading it?
Wierd thing is that I am pretty sure this worked before... But I checked the whole class history and can't find any major change that would have triggered that. The ListView-code is mainly static since I added it.
I was had similiar problem. if you have any hardcoded javascript code in your page or panels html file (using <script> tag) remove it and set that js code in renderHead of your panel.

CKEditor Plugin: text fields not editable

I am creating a CKEditor plugin, using version 4.2.1. I am trying to follow the tutorial on a Simple Plugin. However, the text inputs in my dialog window are not editable / clickable in the dialog, even when I just copy in the entire abbr plugin from the tutorial with no changes.
I can still click the dialog tabs, OK / Cancel buttons, and drag the dialog around. I have added in other elements (like selects) to the dialog in my custom version, and I can interact with those.
When I check the text input elements in Chrome's Dev Tools, I can add text via the Console / jQuery and it appears. I get no failures in the Console.
$('#cke_229_textInput').val('help');
Will add text to the text input and display it on the screen. But I can't interact with the element via mouse / keyboard / browser. Is there something obvious in the CKEditor configuration that I am missing? Sorry if this is a really stupid question--first time working with CKEditor. I have also searched the CKEditor forums and Google, without finding any related issues.
This happens in both Chrome 30 and FF 24.
My call to create the editor:
var me = document.getElementById('resource_editor_raw');
editor = CKEDITOR.replace(me, {
fullPage: true,
removePlugins: 'newpage,forms,templates',
extraPlugins: 'abbr',
allowedContent: true
});
Thanks for any tips or hints!
Update #1
Thinking this might be related, I have also tried setting the z-index of the text element to very high, using Chrome's Dev Tools. No luck, it is still not editable / highlightable...
Update #2
This seems to be this conflict with jQuery UI. The suggested fix doesn't work for me yet, but will poke around...leaving this up for anyone who might stumble across it.
Final Update
So Brian's tip helped me. Both the Bootbox modal backdrop (what I am using to generate the original dialog) and the CKEditor dialog backdrop have tabindex=-1, so they conflict somehow. Manually turning off the Bootbox backdrop (i.e. setting tabindex='') works with Chrome dev tools, so I think I can hack something together with jQuery or whatnot. Amazing stuff...thanks for the help!! Not sure why I got this working in a jsFiddle...if I recall correctly, I might not have had a backdrop on those dialogs.
Also, for reference, a tabindex of -1 makes things untabbable, which makes sense for a backdrop.
The modal html attribute tabindex='-1' is what seems to be causing the issues for me.
The tabindex='-1' is actually in the bootstrap documentation and is needed for some reason that I am unaware of.
Use the 100% working script..
<script type="text/javascript">
// Include this file AFTER both jQuery and bootstrap are loaded.
$.fn.modal.Constructor.prototype.enforceFocus = function() {
modal_this = this
$(document).on('focusin.modal', function (e) {
if (modal_this.$element[0] !== e.target && !modal_this.$element.has(e.target).length
&& !$(e.target.parentNode).hasClass('cke_dialog_ui_input_select')
&& !$(e.target.parentNode).hasClass('cke_dialog_ui_input_textarea')
&& !$(e.target.parentNode).hasClass('cke_dialog_ui_input_text')) {
modal_this.$element.focus()
}
})
};
</script>
Note: Include this file after both jQuery and bootstrap are loaded.
OMG I have been googling this for hours and finally fond some code that works!!
Stick this in your dialog page that will have a ckeditor in it:
orig_allowInteraction = $.ui.dialog.prototype._allowInteraction;
$.ui.dialog.prototype._allowInteraction = function(event) {
if ($(event.target).closest('.cke_dialog').length) {
return true;
}
return orig_allowInteraction.apply(this, arguments);
};
I found the fix here:
https://forum.jquery.com/topic/can-t-edit-fields-of-ckeditor-in-jquery-ui-modal-dialog
Not sure if anyone else is having this issue now. I was ripping my hair out trying to create a hack. It was a pretty simple solution after a while of digging and search the web. This fix helped me. Just place it on the same page where you want to place your editor - when loading from jQuery. The issue is conflicting tabindex, so I simply removed that attribute from the modal.
<script>
$(function(){
// APPLY THE EDITOR TO THE TEXTAREA
$(".wysiwyg").ckeditor();
// FIXING THE MODAL/CKEDITOR ISSUE
$(".modal").removeAttr("tabindex");
});
</script>
I am using Semantic UI and fix this problem by create an instance of CKEDITOR after create Modal.
$('#modal-send').modal('attach events', '.btn-close-modal').modal('show');
var ckeOptions = {
entities: false,
htmlEncodeOutput: false,
htmlDecodeOutput: true
}
CKEDITOR.replace('message', ckeOptions);
CKEDITOR.config.extraPlugins = 'justify';
I also faced this issue when I updated the CKEditor into 4.14
I found the fix in here - http://jsfiddle.net/kamelkev/HU8Qt/3/
In this case,
$.widget("ui.dialog", $.ui.dialog, {
_allowInteraction: function (event) {
return !!$(event.target).closest(".cke").length || this._super(event);
}
});
It will return false, so the textbox gets disabled/ unfocused (losing focus)
As a solution, we need to return true or need to modify the class .cke in the return statement into .cke_dialog
return !!$(event.target).closest(".cke").length || this._super(event);
I tried to upload images to server from CK Editor[without CKFinder] and on positive side i am able to do. whenever we are trying to create some dialog, they are creating one div on the fly which will hold your dialog box. Better you check the CSS property for your text box using chrome and change it. Hope this will help you.

Google Closure add onclick to button after adding this button with custom editor plugin

I am making a custom plugin for the editor provided by Google Closure. The plugin makes it able to add a button.
I am having problems by setting an onclick on the button, the other values are nicely set.
button.innerHTML = event.label;
button.className = event.initialClass;
var extraClasses = event.extraClasses;
if (extraClasses)
{
button.className += ' ' + extraClasses
}
button.onclick = function() { event.onclick };
Does anyone know what I am doing wrong and how I can fix this?
After creating a button it is added to the editors SeamlessField. A second problem that I currently have is that after creating the button, my pointer is inside the button and I can't seem to get it out of there.
I've got the follow piece of code for handling this at the moment. The var button is the created button. button contains: <button class="orange">test</button>
// We want to insert the button in place of the user's selection.
// So we restore it first, and then use it for insertion.
this.restoreOriginalSelection();
var range = this.fieldObject.getRange();
button = range.replaceContentsWithNode(button);
// Done making changes, notify the editor.
this.fieldObject.dispatchChange();
// Put the user's selection right after the newly inserted button.
goog.editor.range.placeCursorNextTo(button, false);
// Dispatch selection change event because we just moved the selection.
this.fieldObject.dispatchSelectionChangeEvent();
Any ideas about how I could fix this second problem aswell?
For the first, it does not look like you have begun using Google Closure event code. Wiring up the button to the 'click' event in Google Closure would be as follows:
goog.events.listen(button, goog.events.EventType.CLICK, event.onclick)
You should also be investigating the goog.dom and goog.dom.classes namespaces if you'd like to use Google Closure's wrappers around standard CSS class and text DOM manipulation.
For the second, were you testing in Chrome? If so, you might have ran into a range issue in Webkit, documented within the Closure code itself:
https://code.google.com/p/closure-library/source/browse/closure/goog/editor/range.js#174
I have gotten around this in the past by inserting an empty <span> element as a sibling after the offending element (the button, in your case), and placing the cursor next to the <span> instead. However, there's nothing stopping the user from moving the cursor back inside your button. You'll have to add more logic to prevent a user from placing the cursor within the button's text.

DataFormWebPart accessing previous versions of an item in WSS3.0

I am running WSS3.0 and have a custom list which contains versioning on a couple of fields. When I click on an item and I view the item page I see the history of all the fields which I have made changes to. This works fine as expected.
I have also created a page using Microsoft Office Sharepoint Designer and using a DataFormWebPart I have created a page that shows all the items in the list in a list view, I have also changed the XSL node of the DFWP to display the datain a way that my client wants.
The issue that I have is, it is only showing the latest version of the item record e.g. some of the fields are blank as the client did not update those fields the last time that the item was saved. I can fully understand why it is not showing these previous versions of the item but is there anyway that I can change an option in the webpart that will return that last non blank version of the field?
If this is not possible does anybody know if it is possible to change the edit page for the item so that it defaults certain fields to have the previous value of the field.
Many thanks for you ideas in advance
Jonathan
I eventually was able to add the following jQuery code at the bottom of the page (using Sharepoint Designer). You will also need to add a link at the top of the page to include a link to the jQuery code (or you can install it as a feature).
<script>
jQuery.fn.GetLastUpdate = function () {
$updates = this.parent().next().clone();
$("nobr", $updates).remove();
$("a", $updates).remove();
$("br", $updates).remove();
$lastUpdate = $updates.text().split("(): ")[1]; //.find("a").replaceWith("##++##").text();
this.text($lastUpdate);
return $lastUpdate;
}
$("[title='CONTROL_TITLE']").GetLastUpdate();
</script>
Then you just have to replace the CONTROL_TITLE with the title of the text box that you want to auto fill.