I've been fighting with this for some time now and I'm hoping someone here has run into a similar problem and solution.
Background
Our project is an ASP.NET MVC 4 site. It uses both jQuery 1.11.3 and Sencha ExtJs 4.2.2. One of the features I'm working on is a page that will call different partial views that have individual report parameters. The partials are also used in their own respectable pages. However, this feature dynamically loads the partial views via jQuery ajax and displayed inside of a jQuery dialog. Some of the partial view are using the ExtJs Ext.Button with a menu of Ext.menu.DatePicker. On their own respectable page the date pickers work perfectly fine. However, when the partial is loaded inside of the jQuery dialog it causes the datepicker calendar to set the position incorrectly causing massive overflow in the dialog.
Markup & code for the date picker on the partial
<td width="35%" class="tr35_form_input_normal">
#Html.TextBoxFor(model => model.CutOff, new { #style = "float:left;" })
<div id="datePickerButton" style="float:left;margin-top:-2px;"></div>
<div style="clear:both;">
#Html.ValidationMessageFor(model => model.CutOff)
</div>
#Html.HiddenFor(model => model.BeginDate)
#Html.HiddenFor(model => model.EndDate)
</td>
<script type="text/javascript">
Ext.create('Ext.Button', {
iconCls: 'x-form-date-trigger',
renderTo: 'datePickerButton',
handler: function () {
this.menu = new Ext.menu.DatePicker({
renderTo: 'datePickerButton',
autoShow: true,
handler: function (picker, date) {
$(cutOffDate).val(Ext.Date.format(date, 'n/j/Y')).change();
}
});
this.menu.picker.setMinDate(new Date($(hfBeginDate).val()));
this.menu.picker.setMaxDate(new Date($(hfEndDate).val()));
if (!isNaN(Date.parse($(cutOffDate).val()))) {
this.menu.picker.setValue(new Date($(cutOffDate).val()));
}
}
});
</script>
This is how it looks & works on it's own page.
How the dialog looks before I click on the date picker button.
What's happening when I click the button.
I can see what's happening and have an idea on how to fix it by using the jQuery widget factory to use the _allowInteraction method, which I've done before to fix an issue with ExtJs grids and their filters inside of a jQuery dialog. The problem though is, the DatePicker has not been created yet when I first click the button so there's no way I can find the element/component.
The other thing you'll notice how the jQuery dialog seems to overflow. I've tried to set the overflow to hidden on all the underlying elements and no matter what it still repositions the inner form element at some negative position.
Any help would be greatly appreciated.
OK, so after some more playing around here's my solution and it's quite simple.
<script type="text/javascript">
Ext.override(Ext.menu.DatePicker, {
initComponent: function(){
this.callParent();
},
listeners: {
show: function(){
var el = $('#' + this.id);
var dlg = $(el).parents('.ui-dialog');
//Make sure we are dealing with a datepicker
//inside of a jQuery dialog.
if($(dlg).length > 0){
$(dlg).find('div.x-css-shadow').remove()
$(el).appendTo('body');
}
}
}
});
</script>
Related
Below I've tried to simplify more complex TreeView usage, where I'm failing to implement a ContextMenu on TreeView node items, into a fiddle that exhibits potentially related issues. Steps: In my simplified example one left clicks to select a node, then right clicks on another node, and finally dismisses with escape, and then selection indications are confused. I've tried "return false", select(nothing), and preventDefault() to no avail.
My question is: is this a bug in Kendo UI, or am I missing something in my usage of TreeView?
https://jsfiddle.net/3cp9m8wo/
<div id='Tree_Space'></div>
<script type='text/x-kendo-template' id='Tree_template'>
#= item.Name#
</script>
<script>
$('#Tree_Space').kendoTreeView({
dataSource: [ { Name: 'Top', items: [ { Name:'Item' }, { Name:'Item' } ] } ],
template: kendo.template($('#Tree_template').html())
});
$("#Tree_Space").data("kendoTreeView").expand('.k-item');
</script>
My full goal would be to disable Kendo UI selection on TreeView nodes completely, allowing me to implement left clicks (actions) and right clicks (ContextMenus) for elements I placed within tree nodes. However, I've not seen a way to disable select on TreeView. I do find JQuery.click() does seem to work and deselect Kendo UI selections, but Kendo UI Context Menu fails to popup on right click, and displays other artifacts - one of which I think I've isolated here in hopes of learning something.
You could try using something in your template to control this:
<script type='text/x-kendo-template' id='Tree_template'>
//Ideally, your server will return a collection that determines if the item can be selected, likewise, you could add a IsParentNode or something to indicate the item should be treated differently.
#if (item.CanSelect != 'null' && item.CanSelect==true) { #
<span>#: item.Name#</span>
#}else{#
<span class='no-select'>#: item.Name#</span>
#}#
</script>
<script type="text/javascript">
$(document).ready(function () {
//Add code here to tie into the onmousedown of all .no-select elements
$(document).on("click", "no-select", function (e) {
e.preventDefault();
});
});
</script>
Disclaimer: ExtJS - intermediate level;
jQuery - beginner
I've looked for a solution for this but had not found anything yet.
I have both ExtJS and jQuery in one file and I want to be able to execute the jQuery right after the ExtJS is done building a page (is this even possible).
Example:
function renderPage(){
// ExtJS goes here
}
How do I call jQuery after renderPage() is completed?
I tried the following:
$(document).ready(function() {
$("tr").css("background-color", "yellow");
});
$(document).ready(function(renderPage) {
$("tr").css("background-color", "yellow");
});
function renderPage(){
// ExtJS goes here
// ...
$("tr").css("background-color", "yellow");
}
but it doesn't work. I assume it is because the ExtJS is not done rendering the page when jQuery is getting called and it is not finding anything to select.
Additional information:
I know my jQuery works and is connected to the library because I was able to select HTML elements that are rendered before any script ExtJS or jQuery script is run and modify their style.
Thanks!
Ext components fire an afterrender event that you can hook into, but you have to be careful here because it can fire more than once if you render more than once (which is easy to do accidentally). This is an example of a simple app that fires afterrender once for a panel.
Ext.application({
name : 'Fiddle',
launch : function() {
var panel = Ext.create('Ext.Panel',{
renderTo:Ext.getBody(),
title:'myPanel',
items: [
Ext.create('Ext.Button', {
text: 'Click me!!!!',
handler: function() {
alert('You clicked the button!');
}
}),
{
xtype:'toolbar',
items: [{text:'Button 1'}, {text:'Button 2'}],
listeners: {
afterrender: function () {
Ext.Msg.alert('Fiddle', 'done with ext rendering, do jQuery stuff');
}
}
}
]
});
}
});
sencha fiddle: https://fiddle.sencha.com/#fiddle/eqg
I would recommend not mixing these two libraries without a really good reason - Ext has virtually the same DOM helper functionality as jQuery - if you are just changing a class something like Ext.dom.Element.addCls might be more appropriate (http://docs-origin.sencha.com/extjs/4.2.2/#!/api/Ext.dom.Element)
I have the following situation on a web application.
A dialog is built and opened on the fly when clicking on a link:
var dialogInitiator = $("<div id='dialog-initiator' style='background-color: "+bgcolor+";'>Loading...</div>");
dialogInitiator.appendTo(parentFrame);
dialogInitiator.dialog({
modal:true,
autoOpen: false
}).on('keydown', function(evt) {
if (evt.keyCode === $.ui.keyCode.ESCAPE) {
dialogInitiator.dialog('close');
}
evt.stopPropagation();
});
dialogInitiator.dialog('open');
Right after that, I load a new html page into the dialog, with an < object >, like this:
var objectFrame = $('<object style="border: 0;width:'+(dlwidth-30)+'px;min-height:'+(dlheight-46)+'px;" type="text/html" style="overflow:auto;" data="'+url+'"></object>');
dialogInitiator.html(objectFrame);
Now, the "url" variable contains a link to this new html document. When that page is ready, it will focus on an input field. This prevents the ESCAPE key from closing the dialog. So, I am trying to manually trigger the .dialog('close') event on escape keypress.
I do the following, from within the loaded document:
$('#dialog-initiator', window.parent.document).dialog('close');
It get the following error:
"Error: cannot call methods on dialog prior to initialization; attempted to call method 'close'"
Strange thing is, when i call:
console.log( $('#dialog-initiator', window.parent.document).html() );
it shows me the html from the dialog. So it actually IS initiated.
Well, I have tried to fix this error with the help of Google, but without success. I guess my situation is quite specific.
Note: we are forced to use the technique with loading this whole webpage into the dialog due to older functionality we used in modalDialogs. Since they are depricated in the latest Google Chrome, we've built a temporary solution with jQuery dialog.
I hope someone can help me out. I appreciate it!
You can try a global method created after the modal is created
dialogInitiator.dialog({
modal: true,
autoOpen: false,
create: funtion(e,ui) {
window.closeMyDialog = function() {
$('#dialog-initiator').dialog('close');
};
}
})...
Then call it by doing window.parent.closeMyDialog();.
Why not use JQuery UI? It's easier than making your own.
http://jqueryui.com/dialog/#default
I'm using Ember.js with handlebars and I need to make a div within my page collapse/expand when clicked. I know how to do this in jQuery, but I can't use any jQuery. Does anyone know how to accomplish this? Also I don't want to just toggle a hide attribute, I need the full sliding up and down feature for collapsing. If anyone has any ideas, I'd really appreciate it.
Thanks
Clicking on your view will cause a click event to be triggered. You can code your animation in any manner you want inside a click event handler in your view:
CollapsableView = Ember.View.extend({
click : function(event) {
this.$().toggle('fast');
}
})
The proper way of doing this in Ember is via the awesome Liquid Fire addon.
The outline:
Install Liquid Fire into your project.
Define a transition like this:
this.transition(
this.hasClass('transition-spoiler'),
this.toValue(true),
this.use('toDown'),
this.reverse('toUp')
);
In your controller/component, create a property spoilerIsVisible and a toggleSpoiler property:
spoilerIsVisible: false,
actions: {
toggleSpoiler: function() {
this.toggleProperty('spoilerIsVisible');
}
}
In your page/component template, create a button and a spoiler wrapper like this:
<button {{action 'toggleSpoiler'}}>
{{if spoilerIsVisible 'Show spoiler' 'Hide spoiler'}}
</button>
{{#liquid-if spoilerIsVisible class="transition-spoiler"}}
<p>Dumbledore dies</p>
{{/liquid-if}}
Note that you can wrap steps 3-4 into an x-spoiler component or something.
I do something similar, but with a tree-structure. I have written a blog post about this previously here: http://haagen-software.no/blog/post/2012-05-05-Ember_tree
It has the features you need in it, in that it adds and removed elements from the DOM when the nodes are clicked on.
A working example can be seen in an app I am currently building here: https://github.com/joachimhs/EurekaJ/tree/netty-ember/EurekaJ.View/src/main/webapp
I am creating a small wrapper for the fantastic BlockUI plugin used in my application to easily create dialogs that meet my needs.
Sometimes I am a bit jQuery retarded and would like to know from any of the aficionados out there how they would do this particular task.
This function creates a header, middle and footer custom to my application. Uses some passed in options to fill out the HTML further. Composes the dialog and then inserts it into the BlockUI plugin.
function blockApp(element, options){
var header = jQuery('<div class="modal-header clearfix"><h2></h2><span></span></div>'),
center = jQuery('<div class="modal-content"></div>'),
footer = jQuery('<div class="modal-footer"></div>');
//Compose dialog
var opts = jQuery.extend({}, dialogDefaults, options);
header.find('h2').html(opts.title);
center.html(jQuery(element).html());
var comp = jQuery('<div></div>').append(header).append(center).append(footer);
jQuery('#notificationUI').block(jQuery.extend({}, standardBlock, {
message: comp,
}));
jQuery('.blockOverlay').click(function(){
jQuery('#notificationUI').unblock();
});
}
I tried using wrap() and wrapInner() at first with no success also.
My question is How would John Resig do this?
Not sure if this is what you're looking for but I've recently used BlockUI w/ another jQuery plug-in called jConfirm which you can download from here. With the jConfirm (or jAlert or jPrompt) you can fully customize your alert box via CSS. My scenario is probably way different than yours but in my app, user's can make changes to a document. If they choose to click my "cancel" button to erase all of their changes I have a jConfirm alert pop up while using BlockUI to dim out the interface from them. It looks pretty slick. Using jQuery I can catch the click event of my "cancel" button and do something like:
$('.cancel').click(function () {
$.alerts.dialogClass = 'my_css';
$.blockUI({ message: null });
jConfirm('Are you sure you want to cancel?', 'Cancel Changes?',
function (r) {
if (r.toString() == 'false') {
$.unblockUI();
} else {
//close window
}
});
return false;
});
Hope this helps!