I'm trying to open a Kendo UI kendoWindow from within an MVC View. I also use a Partial View as the content of the kendoWindow. Moreover, I use the Kendo UI MVVM pattern to bind my elements.
First let me to show you my main View and my pop-up Partial View (kendoWindow).
The important part of my main View (Parent) is as follows:
#{
ViewBag.Title = "My Main View";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script src="~/Scripts/ViewModel/main.js"></script>
<script src="~/Scripts/InitView/main.js"></script>
<script type="text/javascript">
var viewModel;
$(function () {
viewModel = initVm({
GetPartialContent_Url: '#Url.Action("GetPartialContent")'
});
initView(viewModel);
kendo.bind($("#container"), viewModel);
viewModel.Onread();
});
</script>
<div id="container">
<div id="Window-box"></div>
// Some other elements like the button which opens the kendoWindow are defined here.
</div>
My initVm is as follows:
function initVm(arg) {
var vm = kendo.observable({
onOpenKendoWindow: function () {
$("#Window-box").kendoWindow({
iframe: true,
content: arg.GetPartialContent_Url,
title: 'Some Title',
width: 500,
height: 'auto',
close: function (e) {
//Is it possible to get some data from kendoWindow (Partial View) here?
}
});
var dialog = $("#Window-box").data("kendoWindow");
dialog.maximize();
}
});
return vm;
}
Until now, I showed you the important parts of my main View. Now I want to show you the important parts of my kendoWindow (Partial View).
My Partial View which is used as the content of the kendoWindow is as follows:
#{
Layout = "~/Views/Shared/_PartialLayout.cshtml";
}
<script src="~/Scripts/ViewModel/partial.js"></script>
<script src="~/Scripts/InitView/partial.js"></script>
<script type="text/javascript">
var partialVM;
$(function () {
partialVM = initPartialVm({
GetTransactions_Url: '#Url.Action("GetTransactions", "Account")'
});
initPartialView(partialVM);
kendo.bind($("#container"), partialVM);
});
</script>
<div id="container">
<div id="gridTransactions"></div>
</div>
And my initPartialVm is as follows:
function initPartialVm(arg) {
var vm = kendo.observable({
onSelectTransaction: function () {
// KendoWindow should be closed here and passing some data from here to main View (close event of kendowWindow);
}
});
return vm;
}
Note: The 'gridTransactions' is a Kendo UI GridView (inside of kendoWindow - Partial View). Each rows of this grid has a select button and the 'onSelectTransaction' function is fired when each of these select buttons is clicked.
And finally, the main question is that, how can I close the kendowWindow by clicking each select button of the GridView and pass some data to the close event of the kendowWindow?
Yes it is possible. I found it much easier and a bit cleaner to wrap all the dialog functionality up into a dialog controller and extend it a bit in javascript.
Once the .js part is done it makes for a cleaner use. If you don't prefer to do this then look for the findDialog function below (it shows how get a handle to a dialog and call the close method on it).
As far as sending data on close, It would be easy to add a callback in the dialog to be called when the dialog is closed, supplied on invocation, then add a property in the widget to set the custom data to pass through in the dialogs close() back to the consumers event handler.
Also, please note I am no javascript expert, it took me longer than I would like to admit to work the bugs out of this but it has held up solidly for about 6 years. Feel free to offer suggestions.
In Bundle Config:
bundles.Add(new ScriptBundle("~/bundles/myCustom").Include(
...
"~/Scripts/MyCustom/MyCustomDialogs.js",
...
));
Where you register scripts:
#Scripts.Render("~/bundles/MyCustom")
In your index view or parent view :
<div id="_applicationDialogs"></div>
<div id="_mainAppContentLoadsHere"></div>
var _mainDialogController;
$(document).ready(function () {
...
_mainDialogController = $("#_applicationDialogs").kendoMyCustomDialogController().data("kendoMyCustomDialogController");
...
}
Where you want to invoke the dialog: SomePartial
function lnkDetailsOnClick(someID) {
_mainDialogController.createDialog({
dialogId: "frmUserDetail_" + someID,
modal: false,
title:"Daily Details",
pin: true,
height: 575,
width: 1025,
actions: ["Refresh", "Maximize", "Minimize", "Pin", "Close"],
url: '#Url.Action("SomePartialView", "SomeController")',
data:{
someID: someID,
dialogName:'frmUserDetail_'+ someID //NOTE : This will come back in the invoked partial as Model.DialogName so it can be dismissed with ease.
}
});
}
Dismissing the Dialog Inside of SomePartial :
#model MyModelThatHasTheDialogHandle
function btnClose_Click() {
var dialog = _mainDialogController.findDialog('#Model.DialogName');
dialog.close();
}
Now for the long .js file :
(function ($) {
var kendo = window.kendo,
ui = kendo.ui,
Widget = ui.Widget;
var MyCustomDialogController = Widget.extend({
init: function (element, options) {
var that = this;
Widget.fn.init.call(this, element, options);
that._create();
},
onResize: function () { },
options: {
modal: true,
dialogId: "dlgController1",
url: "",
data: null,
pin: false,
width: 300,
height: 300,
actions:["Close"],
title: "Information",
disableMaximize:false,
name: "MyCustomDialogController",
autosize: false,
onDialogClosed: null,
hideOnClose: false
},
_create: function () {
var that = this;
},
createDialog: function (options) {
var that = this;
var wrapperName = options.dialogId + "_wrapper";
that.element.append("<div id='" + wrapperName + "'></div>");
var wrapperElement = that.element.find("#" + wrapperName);
wrapperElement.kendo_MyCustomDialog(options);
},
findDialog: function (dialogId) {
that = this;
var wrapperName = dialogId+"_wrapper";
var dialog = $("#" + wrapperName);
//var dialog = wrapper.find("#" + dialogId);
return dialog.data("kendo_MyCustomDialog");
},
forceCloseAllDialogs: function ()
{
that = this;
$('.MyCustom-window').each(function () {
$(this).data("kendoWindow").close();
});
},
isModalWindowActive: function ()
{
that = this;
return $('.MyCustom-window-modal').length > 0;
},
currentModalWindow: function () {
that = this;
return that.findDialog($('.MyCustom-window-modal')[0].id);
}
});
ui.plugin(MyCustomDialogController);
})(jQuery);
(function ($) {
var kendo = window.kendo,
ui = kendo.ui,
Widget = ui.Widget;
var _MyCustomDialog = Widget.extend({
init: function (element, options) {
var that = this;
Widget.fn.init.call(this, element, options);
that._create();
},
onResize: function () { },
options: {
modal: true,
dialogId: "frmMain",
url: "",
data: null,
pin: false,
width: 300,
height: 300,
actions: ["Close"],
title: "Information",
name: "_MyCustomDialog",
disableMaximize:false,
autosize: false,
onDialogClosed: null,
hideOnClose:false
},
_create: function () {
var that = this;
that.isModalWindowActive = true;
that.modifiedData = false;
that.frmElement = $("#" + that.options.dialogId).data("kendoWindow");
if (that.frmElement == null) {
var template ;
if(that.options.modal)
template = kendo.template(that._templates.divModalFormWrapper);
else
template = kendo.template(that._templates.divFormWrapper);
that.wrapper = $(template(that.options));
that.element.append(that.wrapper);
if (that.options.autosize)
{
that.options.height =null;
that.options.width = null;
}
that.frmElement = that.wrapper.kendoWindow({
title: "Loading...",
modal: that.options.modal,
visible: that.options.autosize,
draggable: true,
resizeable:!that.options.disableMaximize,
width: that.options.width,
height: that.options.height,
resizeable: true,
pinned:that.options.pin,
resize: function () {
that.onResize();
},
content: {
url: that.options.url,
data: that.options.data,
type: "POST",
datatype: "json",
traditional: true
},
refresh: function () {
that.frmElement.title(that.options.title);
if (that.options.autosize) {
that.frmElement.center();
}
},
actions: that.options.actions,
close: function (e) {
that.IsModalWindowActive = false;
if (that.options.hideOnClose == false) {
if (that.frmElement != null)
that.frmElement.destroy();
this.destroy();
that.wrapper.remove("#" + that.options.dialogId);
that.wrapper.empty();
}
if (that.options.onDialogClosed) {
that.options.onDialogClosed(that.modifiedData);
}
}
}).data("kendoWindow");
}
if (that.options.autosize)
that.frmElement.center().open();
else if (that.options.hideOnClose == true)
that.frmElement.open();
else
that.frmElement.center().open();
if (that.options.pin)
that.frmElement.pin();
},
setModifiedFlag:function(modified)
{
var that = this;
that.modifiedData = modified;
},
close: function () {
var that = this;
that.frmElement.close();
},
show: function () {
var that = this;
that.wrapper.show();
that.frmElement.open();
},
setTitle: function (title) {
var that = this;
that.frmElement.title(title);
},
height: function () {
var that = this;
var wtfHeight = that.frmElement.options.height;
if (isNaN(wtfHeight)) {
if (wtfHeight.indexOf("px") >= 0)
wtfHeight = wtfHeight.replace("px", "");
}
return wtfHeight;
},
_templates: {
divModalFormWrapper: "<div id='#=dialogId#' class='MyCustom-window MyCustom-window-modal'></div>",
divFormWrapper: "<div id='#=dialogId#' class='MyCustom-window'></div>"
}
});
// add the widget to the ui namespace so it's available
ui.plugin(_MyCustomDialog);
})(jQuery);
Related
I am going to add remove cross sign with each event of calendar which are getting from database. But how to add this and i want when click on cross sign(delete) then specific url will be triggered and i want to delete event from database. Please let me know how can i do this? How to add delete event with cross sign.
call-init.js
!function($) {
"use strict";
var CalendarApp = function() {
this.$body = $("body")
this.$calendar = $('#calendar'),
this.$event = ('#calendar-events div.calendar-events'),
this.$categoryForm = $('#add-new-event form'),
this.$extEvents = $('#calendar-events'),
this.$modal = $('#my-event'),
this.$saveCategoryBtn = $('.save-category'),
this.$calendarObj = null
};
/* Initializing */
CalendarApp.prototype.init = function() {
this.enableDrag();
/* Initialize the calendar */
var events = [];
$.ajax({
type: 'POST',
async: false,
url: '/Booking/GetBookings',
success: function (mems) {
//states contains the JSON formatted list
//of states passed from the controller
$.each(mems, function (_, member) {
debugger;
events.push({
title: member.guestname,
start: new Date(member.checkindatetime),
end: new Date(member.checkoutdatetime),
allDay: true,
url: '/Booking/Booking/' + member.encryptedId,
className: member.classnamecolor
});
});
},
error: function (ex) {
alert('Buchungen konnten nicht geladen werden.');
}
});
var $this = this;
$this.$calendarObj = $this.$calendar.fullCalendar({
defaultView: 'month',
handleWindowResize: true,
header: {
left: 'prev,next today',
center: 'title',
right: ''
},
navLinks: false, // can click day/week names to navigate views
events: events
//eventStartEditable: false // disable drag&drop of events
});
},
//init CalendarApp
$.CalendarApp = new CalendarApp, $.CalendarApp.Constructor = CalendarApp
}(window.jQuery),
//initializing CalendarApp
function($) {
"use strict";
$.CalendarApp.init()
}(window.jQuery);
other calendar view is
#model FewoVerwaltung.Models.Booking.BookingListModel
<div id="calendar"></div>
<!-- Calendar JavaScript -->
<script src="~/plugins/calendar/dist/locale/de.js"></script>
<script src="~/plugins/calendar/dist/fullcalendar.min.js"></script>
<script src="~/plugins/calendar/dist/cal-init.js"></script>
i want modification the base_calendar.js with new custom function like below
CalendarNotification = require('base_calendar.base_calendar');
console.log("Masuk sini bawah");
CalendarNotification.include({
'click .link2showed': function() {
console.log("ndak yo mlebu kene to");
var action = {
type: 'ir.actions.act_window',
res_model: 'crm.lead',
view_mode: 'form',
view_type: 'form',
views: [[false, 'form']],
res_id: 16644
};
this.do_action(action);
},
});
and this a base_calendar.js odoo addons
var Notification = require('web.notification').Notification;
var CalendarNotification = Notification.extend({
template: "CalendarNotification",
init: function(parent, title, text, eid) {
this._super(parent, title, text, true);
this.eid = eid;
this.events = _.extend(this.events || {}, {
'click .link2event': function() {
var self = this;
this.rpc("/web/action/load", {
action_id: "calendar.action_calendar_event_notify",
}).then(function(r) {
r.res_id = self.eid;
return self.do_action(r);
});
},
'click .link2recall': function() {
this.destroy(true);
},
'click .link2showed2': function() {
this.destroy(true);
this.rpc("/calendar/notify_ack");
},
});
},
});
How do I fix that and what causes it? I've been several times custom function JS like that and it worked well.
Thank in advance for any pointers.
I am trying to make the creation of my new object happen inside a bootbox modal.
How can i access this.collection inside the bootbox callback?
it seems to me that _bind would be useful, but i dont know how.
the following happens inside a Marionette.compositeView
create: function(evt) {
console.log('create');
evt.preventDefault();
var modal = bootbox.dialog({
title: "Nueva Seccion",
message: Module.Templates['documents/create/course/chapter/chapterModal'],
buttons: {
success: {
label: "Guardar",
className: "btn-success",
callback: function() {
var chapterNo = $('#chapterNo').val();
var chapterDesc = $('#chapterDesc').val();
var chapter = new Module.Models.Chapter({
chapterNo: chapterNo,
chapterDesc: chapterDesc,
});
var sub = new Module.Models.subChapter({});
chapter.get('subChapters').add(sub)
this.collection.add(chapter);
}
}
}
});
modal.modal('show')
},
I usually do this trick, create a new variable (usually self) that hold the correct this value, something like this:
create: function(evt) {
var self = this;
console.log('create');
evt.preventDefault();
var modal = bootbox.dialog({
title: "Nueva Seccion",
message: Module.Templates['documents/create/course/chapter/chapterModal'],
buttons: {
success: {
label: "Guardar",
className: "btn-success",
callback: function () {
alert(self.collection);
var chapterNo = $('#chapterNo').val();
var chapterDesc = $('#chapterDesc').val();
var chapter = new Module.Models.Chapter({
chapterNo: chapterNo,
chapterDesc :chapterDesc,
});
var sub = new Module.Models.subChapter({});
chapter.get('subChapters').add(sub)
self.collection.add(chapter);
}
}
}
});
modal.modal('show');
}
Hope this helps
I have almost working code, but I can't make autocomplete work in pop-up window.
If I do next thing: when project is running, open Pop-up window and type in FireBug console:
$(":input[data-autocomplete]").each(function() {
$(this).autocomplete({ source: $(this).attr("data-skillsautocomplete") });
});
then everything works perfect.
So, the problem is that I don't know how to pass my jquery function to pop-up window.
Help me with that, please.
JS
ko.bindingHandlers.jqDialog = {
init: function(element, valueAccessor) {
var options = ko.utils.unwrapObservable(valueAccessor()) || {};
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$(element).dialog("destroy");
});
setTimeout(function() {
$(element).dialog(options);
}, 0);
}
};
ko.bindingHandlers.openDialog = {
update: function(element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
if (value) {
$(element).dialog("open");
} else {
$(element).dialog("close");
}
}
};
ko.bindingHandlers.jqButton = {
init: function(element, valueAccessor) {
var options = ko.utils.unwrapObservable(valueAccessor()) || {};
//handle disposal
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$(element).button("destroy");
});
$(element).button(options);
}
};
$(":input[data-autocomplete]").each(function() {
$(this).autocomplete({ source: $(this).attr("data-skillsAutocomplete") });
});
function pageModel() {
self.selectedVacancyForEdit = ko.observable();
self.skillToAdd = ko.observable();
self.editVacancy = function(){
self.selectedVacancyForEdit(new Vacancy());
//here pop-up window opens
}
self.addSkill = function(){
//adding skill
}
}
UI
....code....
//Pop-up window
<div id="details" data-bind="jqDialog: { autoOpen: false, resizable: true, modal: true, width:'auto'}, template: { name: 'editTmpl', data: selectedVacancyForEdit, if: selectedVacancyForEdit }, openDialog: selectedVacancyForEdit"></div>
<script id="editTmpl" type="text/html">
<fieldset>
<form data-bind="submit: $root.addSkill">
Add skill: <input type="text" data-bind="value: $root.skillToAdd,
valueUpdate: 'blur'"
data-skillsAutocomplete="#Url.Action("SearchSkill", "Home")"
name="search"/>`
</fieldset>
</script>
</div>
try to change
$(":input[data-autocomplete]")
to
$("input[data-autocomplete]")
I have problems with a Jquery function.
I get the jquery library from google.
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.1/jquery-ui.min.js"></script>
First, I put the following the code on a .js
(function($){
jQuery.fn.jConfirmAction = function (options) {
var theOptions = jQuery.extend ({
question: "Are You Sure ?",
yesAnswer: "Yes",
cancelAnswer: "Cancel"
}, options);
return this.each (function () {
$(this).bind('click', function(e) {
var submitBtn = $(this);
if($(this).attr("jconfirmed")){
submitBtn.removeAttr("jconfirmed");
}else{
e.preventDefault();
thisHref = $(this).attr('href');
var btns = {};
btns[theOptions.yesAnswer]=function() {
$( this ).dialog( "close" );
if (thisHref!=null){
window.location = thisHref;
}else{
submitBtn.attr("jconfirmed", true);
submitBtn.click();
}
};
btns[theOptions.cancelAnswer]=function() {
$( this ).dialog( "close" );
submitBtn.removeAttr("jconfirmed");
};
var content='<p>'+theOptions.question+'</p>';
if(theOptions.checkboxText!=undefined){
content='<p>'+'<input type="checkbox" id="cbox">'+theOptions.checkboxText+'<br/><br/>'+theOptions.question+'</p>';
}
$('#dialog-confirm').html(content);
$('#cbox').click(function() {
/*
if($('#cbox').attr("checked")){
$('.ui-dialog-buttonset button:first-child').show();
}else{
$('.ui-dialog-buttonset button:first-child').hide();
}
*/
});
$('#dialog-confirm').dialog({
resizable: false,
modal: true,
buttons: btns,
show: {
effect: "blind",
duration: 1000
},
hide: {
effect: "explode",
duration: 1000
},
draggable: false,
dialogClass: 'main-dialog-class'
});
}
});
});
};
})(jQuery);
And, in a jsp file call the function.
<script type="text/javascript">
$(document).ready(function() {
$('.confirm').jConfirmAction();
});
</script>
But i have the following error in console:
Uncaught TypeError: Object [object Object] has no method 'jConfirmAction'
I tried to fix this by putting the function code in the same jsp, between <script type="text/javascript"></script>. That works for some pages, but in others pages have the same error. Is there a way to call the function only if jquery has been loaded?
Wrap your entire JS code with document.ready()
$(document).ready(function () {
(function ($) {
jQuery.fn.jConfirmAction = function (options) {
var theOptions = jQuery.extend({
question: "Are You Sure ?",
yesAnswer: "Yes",
cancelAnswer: "Cancel"
}, options);
return this.each(function () {
$(this).bind('click', function (e) {
var submitBtn = $(this);
if ($(this).attr("jconfirmed")) {
submitBtn.removeAttr("jconfirmed");
} else {
e.preventDefault();
thisHref = $(this).attr('href');
var btns = {};
btns[theOptions.yesAnswer] = function () {
$(this).dialog("close");
if (thisHref !== null) {
window.location = thisHref;
} else {
submitBtn.attr("jconfirmed", true);
submitBtn.click();
}
};
btns[theOptions.cancelAnswer] = function () {
$(this).dialog("close");
submitBtn.removeAttr("jconfirmed");
};
var content = '<p>' + theOptions.question + '</p>';
if (theOptions.checkboxText !== undefined) {
content = '<p>' + '<input type="checkbox" id="cbox">' + theOptions.checkboxText + '<br/><br/>' + theOptions.question + '</p>';
}
$('#dialog-confirm').html(content);
$('#cbox').click(function () {
/*
if($('#cbox').attr("checked")){
$('.ui-dialog-buttonset button:first-child').show();
}else{
$('.ui-dialog-buttonset button:first-child').hide();
}
*/
});
$('#dialog-confirm').dialog({
resizable: false,
modal: true,
buttons: btns,
show: {
effect: "blind",
duration: 1000
},
hide: {
effect: "explode",
duration: 1000
},
draggable: false,
dialogClass: 'main-dialog-class'
});
}
});
});
};
})(jQuery);
});
Include all your JS files at the end of the file and try again, and one side note ? use '!==' to compare variables with 'null' and 'undefined'