Related
I am trying to do a simple ipc.send and ipc.on but for some reason I am getting undefined on this electron require.
libs/custom-menu.js:
'use-strict';
const BrowserWindow = require('electron').BrowserWindow;
const ipcRenderer = require('electron').ipcRenderer;
exports.getTemplate = function () {
const template = [
{
label: 'Roll20',
submenu: [
{
label: 'Player Handbook',
click() {
console.log('test');
},
},
],
},
{
label: 'View',
submenu: [
{
label: 'Toggle Fullscreen',
accelerator: 'F11',
click(item, focusedWindow) {
if (focusedWindow) {
focusedWindow.setFullScreen(!focusedWindow.isFullScreen());
}
},
},
{
label: 'Toggle Developer Tools',
accelerator: (function () {
if (process.platform === 'darwin') {
return 'Alt+Command+I';
}
return 'Ctrl+Shift+I';
}()),
click(item, focusedWindow) {
if (focusedWindow) {
focusedWindow.toggleDevTools();
}
},
},
{
label: 'Reload',
accelerator: 'F5',
click() {
BrowserWindow.getFocusedWindow().reloadIgnoringCache();
},
},
],
},
{
label: 'Random Generators',
submenu: [
{
label: 'World Generator',
click() {
ipcRenderer.send('show-world');
},
},
],
},
];
return template;
};
The error is
cannot read property 'send' of undefined.
The BrowserWindow module is only available in the main process, the ipcRenderer module is only available in the renderer process, so regardless of which process you run this code in it ain't gonna work. I'm guessing since ipcRenderer is not available you're attempting to run this code in the main process.
I know this answer might have been too late for you but for other
If you're trying access any of main process modules from renderer process you will need to go through remote module,
const {BrowserWindow} = require('electron').remote
see documentation remote
Just for those who can't get this to work in react app ipcRenderer or in any environment that requires preload file.
preload setup
These lines worked for me:
app.commandLine.appendSwitch('ignore-certificate-errors', 'true')
app.commandLine.appendSwitch('allow-insecure-localhost', 'true')
In the renderer process, the script tags that have the "require" statement needs to be:
<script type="javascript"></script>
Placing your call to require in a script tag without the type set doesn't work.
I am using data table with Grails. I have a check box outside the data table and on its event I want to load the table again with the check box value. Here are my attempts below :
In my view where the check box is >>
<g:checkBox id="wrapCheck" name="wrapCheck"/> Wrapped
Here is my attempts in view where I am calling server method >>
$('#wrapCheck').on('click', function (e) {
setWrapActiveStatus();
var referenceId = $('#callForWrap').val();
jQuery.ajax({
type: 'POST',
dataType: 'JSON',
url: "${g.createLink(controller: 'androidGame',action: 'ajaxAndroidGameList')}?wrapCheck=" + referenceId,
%{--url: "${g.createLink(controller: 'androidGame',action: 'ajaxListByWrapActiveStatus')}?wrapCheck=" + referenceId,--}%
success: function (data, textStatus) {
if (data.isError == false) {
$('#example').DataTable().ajax.reload();
} else {
alert(data.message);
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
}
});
});
here is my setWrapActiveStatus() function >>
function setWrapActiveStatus(){
if($("#wrapCheck").prop('checked') == true){
$('#callForWrap').val("1");
}else{
$('#callForWrap').val("");
}
}
And here is my Controller Action >>
def ajaxAndroidGameList() {
LinkedHashMap gridData
String result
LinkedHashMap resultMap = androidGameService.androidGamePaginateList(params)
if(params.wrapCheck == "1"){
resultMap = androidGameService.androidGamePaginateListByWrapStatus(params)
}
// LinkedHashMap resultMap = androidGameService.androidGamePaginateList(params)
if(!resultMap || resultMap.totalCount== 0){
gridData = [iTotalRecords: 0, iTotalDisplayRecords: 0, aaData: []]
result = gridData as JSON
render result
return
}
int totalCount = resultMap.totalCount
gridData = [iTotalRecords: totalCount, iTotalDisplayRecords: totalCount, aaData: resultMap.results]
result = gridData as JSON
render result
}
My action is response well only wrapped list but data table does not update.
EDIT - Data table Initialization
$('#example').dataTable({
"sPaginationType": "full_numbers",
"bAutoWidth": true,
"bServerSide": true,
"iDisplayLength": 10,
"deferLoading": ${totalCount?:0},
"sAjaxSource": "${g.createLink(controller: 'androidGame',action: 'ajaxAndroidGameList')}",
"fnRowCallback": function (nRow, aData, iDisplayIndex) {
if (aData.DT_RowId == undefined) {
return true;
}
$('td:eq(4)', nRow).html(getStatusIcon(nRow, aData[4])).css({textAlign: 'center'});
$('td:eq(5)', nRow).html(getStatusIcon(nRow, aData[5])).css({textAlign: 'center'});
$('td:eq(6)', nRow).html(getActionBtn(nRow, aData)).css({textAlign: 'center'});
return nRow;
},
"aoColumns": [
null,
{ "bSortable": false },
{ "bSortable": false },
{ "bSortable": false },
{ "bSortable": false },
{ "bSortable": false },
{ "bSortable": false }
]
});
In your DataTables initialization code you need to use option fnServerParams to modify data sent to the server.
I have also corrected deferLoading which should be iDeferLoading, see iDeferLoading.
Below is modified DataTables initalization code:
$('#example').dataTable({
"sPaginationType": "full_numbers",
"bAutoWidth": true,
"bServerSide": true,
"iDisplayLength": 10,
"iDeferLoading": ${totalCount?:0},
"sAjaxSource": "${g.createLink(controller: 'androidGame',action: 'ajaxAndroidGameList')}",
"fnServerParams": function (aoData){
aoData.push({
"name": "wrapCheck",
"value": $("#wrapCheck").prop('checked') ? "1" : ""
});
},
"fnRowCallback": function (nRow, aData, iDisplayIndex) {
if (aData.DT_RowId == undefined) {
return true;
}
$('td:eq(4)', nRow).html(getStatusIcon(nRow, aData[4])).css({textAlign: 'center'});
$('td:eq(5)', nRow).html(getStatusIcon(nRow, aData[5])).css({textAlign: 'center'});
$('td:eq(6)', nRow).html(getActionBtn(nRow, aData)).css({textAlign: 'center'});
return nRow;
},
"aoColumns": [
null,
{ "bSortable": false },
{ "bSortable": false },
{ "bSortable": false },
{ "bSortable": false },
{ "bSortable": false },
{ "bSortable": false }
]
});
Then for checkbox click event handler all you need to do is:
DataTables 1.10
$('#wrapCheck').on('click', function (e) {
$('#example').DataTable().ajax.reload();
});
DataTables 1.9
$('#wrapCheck').on('click', function (e) {
$('#example').dataTable().fnDraw();
});
NOTE:
Please note, that your DataTables initialization code and server-side code are using older naming conventions for DataTables 1.9. DataTables 1.10 is backward compatible, meaning that it supports both new and old naming conventions. But with the release of new versions, the compatibility may be dropped, and you may want to consider updating your code according to 1.9 to 1.10 upgrade guide and Converting 1.9 naming to 1.10.
I am using select2 in tag mode. My item text is a link, e.g.:
<a href='url'>tag1</a>.
select2 seems to be swallowing the click event on the tag (selected choice) so I cannot navigate to the link.
Any ideas on how to get the link to work?
Select2 disables click events by default and for the moment, you must use a workaround to achieve the desired results. Here's an example of how I accomplished this, thanks to the resources below. This won't work if you don't re-instantiate the variable with the return value of .data('select2')
First, add a class to your links:
hello
Then you have to listen to the onSelect event of Select2
var search = $("#searchBox");
search.select2({
placeholder: "Search...",
allowClear: true,
minimumInputLength: 3,
maximumSelectionSize: 1,
escapeMarkup: function(m) { return m; },
ajax: { blah blah blah },
formatResult: window.App.formatFunction
});
search= search.data('select2');
search.onSelect = (function(fn) {
return function(data, options) {
var target;
if (options != null) {
target = $(options.target);
}
if (target && target.hasClass('detail-link')) {
window.location = target.attr('href');
} else {
return fn.apply(this, arguments);
}
}
})(search.onSelect);
This question/answer/JFiddle helped me out but its important to note the .data('select2') line
EDIT: forgot the resource -- https://stackoverflow.com/a/15637696
I use select2-selecting event:
var $q = $('#select2input');
$q.select2({
// your settings
});
$q.on('select2-selecting', function(e){
window.location = e.choice.url;
});
My AJAX payload looks like this:
{
"items":[
{
"id": "1",
"text": "Foo",
"url": "/foo"
},
{
"id": "8",
"text": "Bar",
"url": "/bar"
}
]
}
I have written a code to integrate timepicker with editable which is being used to make all coulmns except the hidden id coulmn and the first shown coulmn editable . I couldn't get the fnupdate make my edited coulmn to be updated to the new value when it is posted to server side . I am able to get the posted values for server side processing but the clientside is not gettting updated by fnupdate .
Please see the code below and try to tell me what i am doing wrong because i am having many pages which function the same way .
$(document).ready(function() {
oTable = $('#scheduleTable').dataTable(
{
"sDom" : '<"top"flip>rt<"bottom"<"clear">',
"bAutoWidth" : false,
"bProcessing" : true,
bJQueryUI:true,
"bServerSide": true,
"bFilter":false,
"bSort": false,
"bInfo": false,
"bPaginate":false,
"aoColumns":[
{
"bVisible" : false
},
{
},
{},
{},
{},
{}
],
"fnRowCallback" : function (nRow, aData, iDisplayIndex) {
$(nRow).attr('id', '' + aData[0]);
//i starting from one to make the first element in td non editable
for (i = 1; i < aData.length; i ++) {
$('td:eq(' + i + ') ', nRow).editable("<?= $aupdateUrl; ?>", {
'callback': function (sValue, y) {
var aPos = oTable.fnGetPosition(this);
oTable.fnUpdate(sValue, aPos[0], aPos[1]);
},
"submitdata": function ( value, settings ) {
return {
"row_id": this.parentNode.getAttribute('id'),
"column": oTable.fnGetPosition( this )[2]
};
},
'height': '14px',
indicator : 'Saving...',
tooltip : 'Doubleclick to edit...',
type : "timepicker",
placeholder : ' '
});
}
return nRow;
},
"sAjaxSource" : "<?= $aSourceList; ?>/startdate/<?= $this->startdate; ?>"
}
);
});
$('.ui-datepicker-close').live('click', function (e){
e.preventDefault();
$('#scheduleTable tbody td input').parents("form").submit();
});
$.editable.addInputType('timepicker',{
/*create input element*/
element:function(settings,orginal){
var form = $(this),
input = $('<input type="text">');
form.append(input);
return (input);
},
plugin:function(settings,original){
/*Don't cancel inline editing onblur to allow clicking datepicker*/
settings.onblur = 'nothing';
$("input",this).filter(":text").timepicker(
{ timeFormat: 'hh:mm',
'hourMin':6,
'hourMax':21,
'showSecond': false,
'hourGrid':2,
'minuteGrid':10
}
);
}
});
I was able to solve the problem .The main thing that i was doing wrong was that i didn't have json response with only one value from my server side zend framework action.Therefore it caused the editable to function in a way that it couldn't put the value(the response) as the new value in the td element. Hope some on find it usefull peace!!
i have just shifted to unobtrusive ajax that ships with mvc-3 but it is breaking at one point.
Here is my link
<%:Ajax.ActionLink("Edit", "Home", "Edit", new{id = Model.SomeID}, new AjaxOptions{OnSuccess = "DoSomething"})%>
this is my js function that will be called on success
<script type="text/javascript">
function DoSomething(data)
{
var clickedLinkID = this.id; // this line breaks it used to work with microsoft ajax
//rest of code goes here
}
</script>
i found this article in which imran describes how to solve the problem. but it involves adding one line to jquery.unobtrusive-ajax.js. Does it have any side effects? should i be changing jquery files? if not how can i get id of the link that was clicked without changing jquery.unobtrusive-ajax.js file
Here is a complete copy of edited MS unobtrusive AJAX including a newly minified version. It contains the context (source element missing) fix plus another important fix whereby the documented "cancel" class was not honoured when applied to submit items (should prevent validation but doesn't).
jquery.unobtrusive-ajax
/*!
** Unobtrusive Ajax support library for jQuery
** Copyright (C) Microsoft Corporation. All rights reserved.
** Fixed version (see full comments for details)
*/
/*
Fix for "validation ignores cancel class" applied from
http://stackoverflow.com/questions/11561496/jquery-unobtrusive-validation-ignores-cancel-class-on-submit-button-if-used-in
Line 144 changed to:
// Fixed to pass class name (needed for other fixes and useful anyway)
$(form).data(data_click, name ? [{ name: name, value: evt.target.value, className: evt.target.className }] : []);
Line 154 changed to:
// Fixed for "cancel" class not honoured (so correct documented behavior of non-validating/cancel buttons are restored)
if (clickInfo.length > 0 && clickInfo[0].className.indexOf('cancel') < 0 && !validate(this)) {
*/
/*
Fix for "source element missing on post-back event handler" applied from
http://forums.asp.net/t/1663285.aspx?How+to+get+source+Element+when+using+Unobtrusive+Ajax+in+ASP+NET+MVC+3
Line 101 inserted:
// Fixed to pass source element in context (so source element can be discovered in handlers)
options.context = element;
*/
/*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */
/*global window: false, jQuery: false */
(function ($) {
var data_click = "unobtrusiveAjaxClick",
data_validation = "unobtrusiveValidation";
function getFunction(code, argNames) {
var fn = window, parts = (code || "").split(".");
while (fn && parts.length) {
fn = fn[parts.shift()];
}
if (typeof (fn) === "function") {
return fn;
}
argNames.push(code);
return Function.constructor.apply(null, argNames);
}
function isMethodProxySafe(method) {
return method === "GET" || method === "POST";
}
function asyncOnBeforeSend(xhr, method) {
if (!isMethodProxySafe(method)) {
xhr.setRequestHeader("X-HTTP-Method-Override", method);
}
}
function asyncOnSuccess(element, data, contentType) {
var mode;
if (contentType.indexOf("application/x-javascript") !== -1) { // jQuery already executes JavaScript for us
return;
}
mode = (element.getAttribute("data-ajax-mode") || "").toUpperCase();
$(element.getAttribute("data-ajax-update")).each(function (i, update) {
var top;
switch (mode) {
case "BEFORE":
top = update.firstChild;
$("<div />").html(data).contents().each(function () {
update.insertBefore(this, top);
});
break;
case "AFTER":
$("<div />").html(data).contents().each(function () {
update.appendChild(this);
});
break;
default:
$(update).html(data);
break;
}
});
}
function asyncRequest(element, options) {
var confirm, loading, method, duration;
confirm = element.getAttribute("data-ajax-confirm");
if (confirm && !window.confirm(confirm)) {
return;
}
loading = $(element.getAttribute("data-ajax-loading"));
duration = element.getAttribute("data-ajax-loading-duration") || 0;
$.extend(options, {
type: element.getAttribute("data-ajax-method") || undefined,
url: element.getAttribute("data-ajax-url") || undefined,
beforeSend: function (xhr) {
var result;
asyncOnBeforeSend(xhr, method);
result = getFunction(element.getAttribute("data-ajax-begin"), ["xhr"]).apply(this, arguments);
if (result !== false) {
loading.show(duration);
}
return result;
},
complete: function () {
loading.hide(duration);
getFunction(element.getAttribute("data-ajax-complete"), ["xhr", "status"]).apply(this, arguments);
},
success: function (data, status, xhr) {
asyncOnSuccess(element, data, xhr.getResponseHeader("Content-Type") || "text/html");
getFunction(element.getAttribute("data-ajax-success"), ["data", "status", "xhr"]).apply(this, arguments);
},
error: getFunction(element.getAttribute("data-ajax-failure"), ["xhr", "status", "error"])
});
options.data.push({ name: "X-Requested-With", value: "XMLHttpRequest" });
// Fixed to pass source element in context (so source element can be discovered in handlers)
options.context = element;
method = options.type.toUpperCase();
if (!isMethodProxySafe(method)) {
options.type = "POST";
options.data.push({ name: "X-HTTP-Method-Override", value: method });
}
$.ajax(options);
}
function validate(form) {
var validationInfo = $(form).data(data_validation);
return !validationInfo || !validationInfo.validate || validationInfo.validate();
}
$(document).on("click", "a[data-ajax=true]", function (evt) {
evt.preventDefault();
asyncRequest(this, {
url: this.href,
type: "GET",
data: []
});
});
$(document).on("click", "form[data-ajax=true] input[type=image]", function (evt) {
var name = evt.target.name,
$target = $(evt.target),
form = $target.parents("form")[0],
offset = $target.offset();
$(form).data(data_click, [
{ name: name + ".x", value: Math.round(evt.pageX - offset.left) },
{ name: name + ".y", value: Math.round(evt.pageY - offset.top) }
]);
setTimeout(function () {
$(form).removeData(data_click);
}, 0);
});
$(document).on("click", "form[data-ajax=true] :submit", function (evt) {
var name = evt.target.name,
form = $(evt.target).parents("form")[0];
// Fixed to pass class name (needed for other fixes and useful anyway)
$(form).data(data_click, name ? [{ name: name, value: evt.target.value, className: evt.target.className }] : []);
setTimeout(function () {
$(form).removeData(data_click);
}, 0);
});
$(document).on("submit", "form[data-ajax=true]", function (evt) {
var clickInfo = $(this).data(data_click) || [];
evt.preventDefault();
// Fixed for "cancel" class not honoured (so correct documented behavior of non-validating/cancel buttons are restored)
if (clickInfo.length > 0 && clickInfo[0].className.indexOf('cancel') < 0 && !validate(this)) {
return;
}
asyncRequest(this, {
url: this.action,
type: this.method || "GET",
data: clickInfo.concat($(this).serializeArray())
});
});
}(jQuery));
jquery.unobtrusive-ajax-fixed.min.js
/*
** Unobtrusive Ajax support library for jQuery
** Copyright (C) Microsoft Corporation. All rights reserved.
** Fixed version (see full comments for details)
*/
(function(a){var b="unobtrusiveAjaxClick",g="unobtrusiveValidation";function c(d,b){var a=window,c=(d||"").split(".");while(a&&c.length)a=a[c.shift()];if(typeof a==="function")return a;b.push(d);return Function.constructor.apply(null,b)}function d(a){return a==="GET"||a==="POST"}function f(b,a){!d(a)&&b.setRequestHeader("X-HTTP-Method-Override",a)}function h(c,b,e){var d;if(e.indexOf("application/x-javascript")!==-1)return;d=(c.getAttribute("data-ajax-mode")||"").toUpperCase();a(c.getAttribute("data-ajax-update")).each(function(f,c){var e;switch(d){case"BEFORE":e=c.firstChild;a("<div />").html(b).contents().each(function(){c.insertBefore(this,e)});break;case"AFTER":a("<div />").html(b).contents().each(function(){c.appendChild(this)});break;default:a(c).html(b)}})}function e(b,e){var j,k,g,i;j=b.getAttribute("data-ajax-confirm");if(j&&!window.confirm(j))return;k=a(b.getAttribute("data-ajax-loading"));i=b.getAttribute("data-ajax-loading-duration")||0;a.extend(e,{type:b.getAttribute("data-ajax-method")||undefined,url:b.getAttribute("data-ajax-url")||undefined,beforeSend:function(d){var a;f(d,g);a=c(b.getAttribute("data-ajax-begin"),["xhr"]).apply(this,arguments);a!==false&&k.show(i);return a},complete:function(){k.hide(i);c(b.getAttribute("data-ajax-complete"),["xhr","status"]).apply(this,arguments)},success:function(a,e,d){h(b,a,d.getResponseHeader("Content-Type")||"text/html");c(b.getAttribute("data-ajax-success"),["data","status","xhr"]).apply(this,arguments)},error:c(b.getAttribute("data-ajax-failure"),["xhr","status","error"])});e.data.push({name:"X-Requested-With",value:"XMLHttpRequest"});e.context=b;g=e.type.toUpperCase();if(!d(g)){e.type="POST";e.data.push({name:"X-HTTP-Method-Override",value:g})}a.ajax(e)}function i(c){var b=a(c).data(g);return!b||!b.validate||b.validate()}a(document).on("click","a[data-ajax=true]",function(a){a.preventDefault();e(this,{url:this.href,type:"GET",data:[]})});a(document).on("click","form[data-ajax=true] input[type=image]",function(c){var g=c.target.name,d=a(c.target),f=d.parents("form")[0],e=d.offset();a(f).data(b,[{name:g+".x",value:Math.round(c.pageX-e.left)},{name:g+".y",value:Math.round(c.pageY-e.top)}]);setTimeout(function(){a(f).removeData(b)},0)});a(document).on("click","form[data-ajax=true] :submit",function(c){var e=c.target.name,d=a(c.target).parents("form")[0];a(d).data(b,e?[{name:e,value:c.target.value,className:c.target.className}]:[]);setTimeout(function(){a(d).removeData(b)},0)});a(document).on("submit","form[data-ajax=true]",function(d){var c=a(this).data(b)||[];d.preventDefault();if(c.length>0&&c[0].className.indexOf("cancel")<0&&!i(this))return;e(this,{url:this.action,type:this.method||"GET",data:c.concat(a(this).serializeArray())})})})(jQuery)
I am disappointed that these critical normal behavioural fixes have not been corrected in such a long time (especially since there are just three simple edits). Even the latest September 2013 release of the AJAX toolkit is still using the now legacy "Sys" Microsoft AJAX Library whilst the rest of the world already migrated to jQuery UI. Maybe this will all be clarified with the RTM of Visual Studio 2013 specifically MVC 5?
As you are now using jQuery you need to wrap it in the $ to get the context. So the code will be something like
$(this).addClass("someclass");
You can find more from the api docs here.