How to use a jQuery modal with React view switching? - jquery-ui

I'm a bit of a novice when it comes to React, so hopefully someone can help.
I've been able to create a generic view switching component using React.
var ViewSwitcherContainer = React.createClass({
getInitialState: function() {
return {
activeViewName : this.props.views[0].Name
};
},
selectView: function(name) {
this.state.activeViewName = name;
this.forceUpdate();
},
render: function () {
return <div>
<ViewSwitcher views={this.props.views} onViewSelection={this.selectView}/>
<ViewSwitcherContent views={this.props.views} activeViewName={this.state.activeViewName}/>
</div>;
}
});
Here is a JSFiddle demonstration...
http://jsfiddle.net/paheal/j8Ubc/
However when I try to load that switching component in a modal component I sometimes get an'Uncaught Error: Invariant Violation: findComponentRoot(..., .r[3iziq].[1].[0].[1]): Unable to find element. This probably means the DOM was unexpectedly mutated (e.g. by the browser).' error from react.
var ModalView = React.createClass({
getInitialState: function () {
this.viewDefinitions = [
{DisplayName:'View A', Name:'viewA', View:ViewA},
{DisplayName:'View B', Name:'viewB', View:ViewB}
];
return {};
},
componentDidMount: function () {
$("#" + this.props.modalId ).dialog({
autoOpen: false,
height: 400,
width: 400,
modal: true,
draggable: false,
resizable: false
});
},
render: function () {
return <div id={this.props.modalId} title={this.props.modalId}>
<ViewSwitcherContainer views={this.viewDefinitions}/>
</div>;
}
});
Here is a JSFiddle demonstration...
http://jsfiddle.net/paheal/j8Ubc/7/
What am I missing? Is the problem in my modal component or in the view switching components?

I actually worked out what was wrong. It seems that the dialog functionality in jQueryUI adds to the DOM, by dynamically creating div for the dialog and its title bar.
Depending on the timing of things, that can cause issues when React is doing its reconciliation.
To resolve I implemented a Reactified version of a modal dialog.

Related

Jquery UI dialog, remove scrollbar if bootstrap columns are used

I created this fiddle to show my problem.
Isn't it possible to use bootstrap columns in a jquery ui dialog without getting this annoying horizontal scrollbar?
Soory, I don't know how to insert the fiddle code with the right depencies in the right way.
First think then write...
Just remove the "row" div and it works.
Look here.
Soory, I don't know how to insert the fiddle code with the right depencies in the right way.
Just add "style='overflow-x:hidden;'" to the dialog container div.
function CreateBusinessDialog(action, formId) {
var contId = 'dlgcont_' + GetUidString();
var container = document.createElement('div');
container.setAttribute('id', contId);
container.setAttribute('style', 'overflow-x:hidden;');
document.body.appendChild(container);
$('#' + contId).dialog({
autoOpen: false,
modal: true,
title: 'Create New',
width: '75%', //$(window).width() - 150,
height: $(window).height() - 150,
open: function (event, ui) {
$(this).load(action);
},
buttons: [{
text: 'Create',
click: function () {
var form = $('#' + formId);
form.validate();
if (form.valid()) {
//alert('valid');
form.submit();
}
}
}, {
text: 'Close',
click: function () {
$(this).dialog('close');
}
}],
close: function () {
container.parentNode.removeChild(container);
}
});
$('#' + contId).dialog('open');
}

Error: cannot call methods on dialog prior to initialization; attempted to call method 'open'

Just a little preface... I am fairly new to jQuery so if something looks wrong or redundant please feel free to offer any helpful suggestions.
Now for the issue. I have 2 modals that are initiated from 2 separate links on the page.
The first modal was fairly problem free. It is a simple form that posts back to the same page. If you are wondering what the items in the "close:" section are, they are form fields that I want to clear the values on when the dialog is closed.
Once I added the second one I have had problems. This modal calls a coldfusion page into a modal to display pictures. The problems occur after opening up the second one. I can not close the second modal from the "close" button. I get the following error.
Error: cannot call methods on dialog prior to initialization; attempted to call method 'close'
I have to close it from the "x" in the upper right hand corner of the modal. After I close it, I get an error when trying to open up the first on.
Error: cannot call methods on dialog prior to initialization; attempted to call method 'open'
Here is the code for it.
$(document).ready(function() {
$(".dig").click(function() {
//based on which we click, get the current values
var cItemName = $("#checklistItemName").attr( "title");
var c2id = $("#check2id").attr( "title");
$("#ItemName").html(cItemName);
$("#ItemID").html(c2id);
$("#objCheckItemName").val(cItemName);
$("#objCheck2ID").val(c2id);
console.log(cItemName);
console.log(c2id);
});
$( "#image-form" ).dialog({
autoOpen: false,
height: 450,
width: 650,
modal: true,
buttons: {
"Submit": function() {
$('#mForm').submit();
return true;
},
Cancel: function() {
$( this ).dialog( "close" );
}
},
close: function() {
$('#defaultSectionName')
.val('');
$('#defaultSectionDesc_hidden')
.val('');
$('#Photo')
.val('');
$('#objCheck2ID')
.val('');
$('#Check21')
.val('');
},
zIndex: 500
});
The next piece of code is where I believe the problems are occurring.
$( "#image_trigger" )
.click(function() {
$( "#image-form" ).dialog( "open" );
});
var dlg=$('#register').dialog({
title: 'Case Pictures',
resizable: true,
autoOpen:false,
modal: true,
hide: 'fade',
width:650,
height:450,
buttons: {
close: function() {
$( this ).dialog( "close" );
}
},
zIndex: 500
});
$('#reg_link').click(function(e) {
e.preventDefault();
var linkurl=('assets/includes/modalPictures.cfm' + '?'
+ 'id=' + $("#objCheck2ID").val()
);
dlg.load(linkurl, function(){
dlg.dialog('open');
});
});
jQuery UI: 1.10.1
jQuery: 1.9.1
Server Side: Coldfusion
The HTML is pretty extensive. If you need to see any part of it please let me know. Thanks for your help!
Upper case?
Close: function() {
You have to initialize your jquery dialog before calling the open function.
<script type="text/javascript">
$(document).ready(function () {
initializeDialog();
});
</script>
And change your js file to have the dialog code in initializeDialog() function.
function initializeDialog(){
$("#your-dialog-id").dialog({
autoOpen: false,
buttons: {
"Cancel": function() {
$(this).dialog("close");
}
},
modal: true,
resizable: false,
width: 600px,
height: 400px
});
}
Thanks #bpjoshi

jQueryUI Datepicker in Dialog auto focus in IE9

I'm able to load and reopen jQueryUI Dialogs with a Datepicker as the first element in all browsers I've tried ... except IE 9.
If a Datepicker is the first element to receive focus when the Dialog opens, the Datepicker will auto launch. I'm able to suppress this behavior in FireFox and Chrome. IE 9 still launches the Datepicker on creation.
My open and close function for the Dialog are:
open: function (event, ui) {
$('#Date').blur(); // kill the focus
if ($('#Date').hasClass('hasDatepicker')) {
$("#Date").datepicker('enable');
}
else {
$("#Date").datepicker();
}
},
close: function (event, ui) {
$("#Date").datepicker('disable');
}
Here is the 'click' code
var dialogs = {};
$('#clicker').click(function (e) {
if (!dialogs['dlg']) {
loadAndShowDialog('dlg');
} else {
dialogs['dlg'].dialog('open');
}
});
var loadAndShowDialog = function (id) {
dialogs[id] = $('#dlg').clone().find('#ChangeMe').attr('id', 'Date').end()
.appendTo(document.body)
.dialog({ // Create the jQuery UI dialog
title: 'Testing',
modal: true,
resizable: true,
draggable: true,
width: 300,
open: see above
close: see above
};
jsfiddle showing this IE9 problem http://jsfiddle.net/stocksp/DdRLp/8/
What can I do to get IE to behave, short of not placing the Datepicker as the first element?
I don't have IE9 available at home so give this a try: http://jsfiddle.net/DdRLp/10/
I added a class to the datepicker input to make it easier to grab.
$(function() {
$(document).on("dialogcreate", "#dlg", function() {
$(".date_picker").datepicker();
$(".date_picker").datepicker("disable");
});
var dialogs = {};
$('#clicker').click(function(e) {
if (!dialogs['dlg']) {
loadAndShowDialog('dlg');
} else {
dialogs['dlg'].dialog('open');
}
});
var loadAndShowDialog = function(id) {
dialogs[id] = $('#dlg').clone().find('#ChangeMe').attr('id', 'Date').end().appendTo(document.body).dialog({ // Create the jQuery UI dialog
title: 'Testing',
modal: true,
resizable: true,
draggable: true,
width: 300,
open: function(event, ui) {
$("div#dlg form input").blur(); //takes focus off inputs
$(".date_picker").datepicker("enable");
},
close: function(event, ui) {
$(".date_picker").datepicker("disable");
}
});
};
});

jquery ui autocomplete inside jQuery Ui Dialog

Hi I have a JQuery Ui (jquery-ui-1.8.13.custom.min.js) inside a Dialog. When I start typing on the box I get the dropdown of items but it hides right away? Does anyone know why? Here is my code:
$(".openDialog").live("click", function (e) {
e.preventDefault();
var itemId = $(this).attr("data-item-id");
var ajaxurl = $(this).attr('data-ajax-refresh-url');
var dialogId = $(this).attr("data-dialog-id");
$('<div><img src="Content/images/spinner.gif" /> Loading...</div>')
.addClass("dialog")
.attr("id", $(this).attr("data-dialog-id"))
.appendTo("body")
.dialog({
width: 'auto',
title: $(this).attr("data-dialog-title"),
buttons: {
"Save": function () {
$(this).find('form').submit();
},
close: function () {
if (typeof itemId != "undefined") {
$.get(ajaxurl, { id: itemId },
function (data) {
// The data returned is a table <tr>
$("#Row" + itemId).replaceWith(data);
});
bindConfirm();
}
$(this).remove();
}
},
modal: true
}).load(this.href, function () {
$(this).find("input[data-autocomplete]").autocomplete({ source: $(this).find("input[data-autocomplete]").attr("data-autocomplete") });
});
});
They also had problems in early 1.8 releases. I remember applying a custom CSS selector to increase zIndex manually.
See also: http://forum.jquery.com/topic/autocomplete-inside-a-dialog-1-8rc2

How would I reference a dynamically created jQuery dialog box so I can close it programatically?

When I began using jQuery a little over a year ago, I needed to load remote content into a pop-up dialog box. After scouring the internet and trying out several suggested methods for doing this, I came upon a function that worked exactly as I needed it to. However, one problem I've never solved is how to reference the dynamic dialog box so it can be closed from an outside function.
Here's the function that creates the dialog box, appends it to the body, and then loads a page into it:
function openDynamicDialog() {
var url = 'mypage.cfm';
var dialog = $('`<div style="display:hidden"></div>`').appendTo('body');
$(dialog).dialog({
autoOpen: true,
title: 'My Title',
resizable: true,
modal: true,
width: 250,
height: 100,
close: function(ev, ui) {
$(this).remove(); // ensures any form variables are reset.
},
buttons: {
"Close": function(){
$(this).dialog("close");
}
}
});
// load remote content
dialog.load(
url,
{},
function (responseText, textStatus, XMLHttpRequest) {
dialog.dialog();
}
);
//prevent the browser from following the link
return false; };
I've considered giving that hidden div a hard-coded id value, but I'm not sure if there are drawbacks to that approach.
Any suggestions would be most appreciated.
I would use a hard-coded id value for the <div> element.
No there shouldn't be any drawback giving it an ID. If you fear of some kind of conflicts then you can give it a class instead, or save a reference to the div object in a global variable.
Well im not sure what the return false is at the end. so if you don't need that, do this:
function openDynamicDialog() {
var url = 'mypage.cfm';
var dialog = $('<div>').css('display','none').appendTo('body');
$(dialog).dialog({
autoOpen: true,
title: 'My Title',
resizable: true,
modal: true,
width: 250,
height: 100,
close: function(ev, ui) {
$(this).remove(); // ensures any form variables are reset.
},
buttons: {
"Close": function() {
$(this).dialog("close");
}
}
});
// load remote content
dialog.load(
url, {}, function(responseText, textStatus, XMLHttpRequest) {
dialog.dialog();
});
return dialog;
}
//call it like this:
var dialog = openDynamicDialog();
//..code
//close it:
dialog.dialog('close');
OR
if you still need that return false, you can do this on the var dialog line of the function:
var dialog = $('<div>', {id: 'dialog_id'}).css('display','none').appendTo('body');
and then reference it from the outside:
var dialog = $('#dialog_id');

Resources