jtable not triggering to clicks made on custom action buttons - javascript

My site is code in ASP.NET MVC 3.0.
with libraries:
jQuery 3.0.0,
jQuery Validation 1.17.0,
(I'm not sure which others can be useful mentioning).
My problem happens when testing in Internet Explorer 11, exactly when user press a button created as a "Custom Action" using jTable.org. This test happens in a Windows 2012 Server.
The same site tested on Firefox in same server is working without this or any other issue.
In IE, the regular buttons created by jTable for Create, Edit and Delete actions, are working.
This is the code for the View:
#model SuperSBL2.WebMVC3.ViewModels.HTEList
#{
ViewBag.Title = "Administrar HTEs";
}
#section CssImport{
<style>
div.filtering
{
border: 1px solid #999;
margin-bottom: 5px;
padding: 10px;
background-color: #EEE;
}
</style>
}
<h2>Administrar HTEs</h2>
<div class="filtering">
<form>
<label>Línea de Producción: <input type="text" name="ProductionLineName" id="ProductionLineName" /></label>
<label>Area: <input type="text" name="AreaName" id="AreaName" /></label>
<label>Operación: <input type="text" name="OperationName" id="OperationName" /></label>
<br /><label>Modelo: <input type="text" name="ModelName" id="ModelName" /></label>
<label>Tipo (ensameble/subensamble): <input type="text" name="HTETypeName" id="HTETypeName" /></label>
<button type="submit" id="LoadRecordsButton" class="btn btn-primary">Buscar registros</button>
</form>
</div>
<div id="HTEContainer" style="width: 1200px; "></div>
<br />
<button type="submit" id="GoBack" class="btn btn-default">REGRESAR</button>
<script type="text/javascript">
$(document).ready(function () {
//Localization texts
var spanishMessages = {
serverCommunicationError: 'Error de comunicación con el servidor, no puedo conectarme a la API.',
loadingMessage: 'Obteniendo datos...',
noDataAvailable: 'No hay datos disponibles!',
addNewRecord: 'Nuevo HTE',
editRecord: 'Editar HTE',
areYouSure: 'Estás seguro?',
deleteConfirmation: 'Estás a punto de borrar éste registro. Por favor confirma.',
save: 'Guardar HTE',
saving: 'Grabando',
cancel: 'Cancelar',
deleteText: 'Borrar HTE',
deleting: 'Borrando',
error: 'Error',
close: 'Cerrar',
cannotLoadOptionsFor: 'No puedo cargar opciones para campo {0}',
pagingInfo: 'Mostrando {0} a {1} de {2} registros',
pageSizeChangeLabel: 'Registros',
gotoPageLabel: 'Ir a página',
canNotDeletedRecords: 'No puedo borrar {0} de {1} registros!',
deleteProggress: 'Borrado {0} de {1} registros, procesando...'
};
$('#HTEContainer').jtable({
messages: spanishMessages, //Localizacion
title: 'Lista de HTEs',
paging: true,
pageSize: 10,
sorting: true,
defaultSorting: 'AreaName ASC',
selecting: true,
actions: {
listAction: '#Url.Action("HTEListForGrid")',
deleteAction: '#Url.Action("DeleteHTE")',
updateAction: '#Url.Action("UpdateHTE")',
createAction: '#Url.Action("CreateHTE")'
},
fields: {
HTEHeaderId: {
key: true,
create: false,
edit: false,
list: false
},
HTETypeID: {
title: 'Tipo',
list: true,
edit: false,
create: true,
options: '#Url.Action("GetHTETypeOptions","HTE")'
},
LineID: {
title: 'Línea de Producción',
//width: '35%',
list: true,
options: '#Url.Action("GetProductionLinesOptions","MasterData")'
},
AreaId: {
title: 'Area',
dependsOn: 'LineID', // jTable builds cascade dropdowns!
//width: '35%',
list: true,
options: function (data) {
if (data.source == 'list') {
//Return url of all countries for optimization.
//This method is called for each row on the table and jTable caches options based on this url.
return '/MasterData/GetAreasOptionsByProductionLineID?productionLineId=0';
}
//This code runs when user opens edit/create form or changes continental combobox on an edit/create form.
//data.source == 'edit' || data.source == 'create'
return '/MasterData/GetAreasOptionsByProductionLineID?productionLineId=' + data.dependedValues.LineID;
}
},
OperationID: {
title: 'Operación',
dependsOn: 'AreaId', // jTable builds cascade dropdowns!
//width: '35%',
list: true,
options: function (data) {
if (data.source == 'list') {
//Return url of all countries for optimization.
//This method is called for each row on the table and jTable caches options based on this url.
return '/MasterData/GetOperationOptionsByAreaID?areaId=0';
}
//This code runs when user opens edit/create form or changes continental combobox on an edit/create form.
//data.source == 'edit' || data.source == 'create'
return '/MasterData/GetOperationOptionsByAreaID?areaId=' + data.dependedValues.AreaId;
}
},
ModelID: {
title: 'Modelo',
dependsOn: 'LineID', // jTable builds cascade dropdowns!
//width: '35%',
list: true,
options: function (data) {
if (data.source == 'list') {
//Return url of all countries for optimization.
//This method is called for each row on the table and jTable caches options based on this url.
return '/MasterData/GetModelOptionsByProductionLine?productionLineId=0';
}
//This code runs when user opens edit/create form or changes continental combobox on an edit/create form.
//data.source == 'edit' || data.source == 'create'
return '/MasterData/GetModelOptionsByProductionLine?productionLineId=' + data.dependedValues.LineID;
}
},
OperationAvailableTime: {
title: 'Tiempo disponible',
//width: '35%',
list: true,
edit: false,
create: false
} ,
Effiency: {
title: 'Effciencia',
//width: '35%',
list: true
} ,
RevisionNumber: {
title: '# Revisión',
//width: '35%',
list: true,
edit: false,
create: false,
defaultValue: '0'
},
RevisionDate: {
title: 'Fecha Revisión',
//width: '15%',
type: 'date',
list: true,
edit: false,
create: false,
displayFormat: 'yy-mm-dd'
},
ProductionRate: {
title: 'Producción Diaria',
//width: '35%',
list: true
},
Taktime: {
title: 'Taktime',
//width: '35%',
list: true
},
RequiredHeadCount: {
title: 'Head Count',
//width: '35%',
list: true
},
HTEStatus: {
title: 'Status',
//width: '35%',
list: true,
edit: false,
create: false,
options: '#Url.Action("GetHTEStatusOptions","HTE")'
},
Active: {
title: 'Activo?',
//width: '12%',
type: 'checkbox',
list: true,
edit: false,
create: false,
values: { 'false': 'No Activo', 'true': 'Activo' },
defaultValue: 'true'
},
Overspeed: {
title: 'OverSpeed',
create: true,
edit: true,
list: true
//, defaultValue: #Html.Raw(Json.Encode(ViewBag.OverSpeed))
},
CustomActionAdmin: {
title: '',
//width: '1%',
sorting: false,
create: false,
edit: false,
list: true,
display: function (data) {
if (data.record) {
return '<button title="" id="btnAdmin" class="jtable-command-button glyphicon glyphicon-cog" onclick="transferAdmin(' + data.record.HTEHeaderId + '); return false;"></button>';
}
}
},
CustomActionActivities: {
title: '',
//width: '1%',
sorting: false,
create: false,
edit: false,
list: true,
display: function (data) {
if (data.record) {
return '<button title="" id="btnAdmin" class="jtable-command-button glyphicon glyphicon-wrench" onclick="transferHTEDetails(' + data.record.HTEHeaderId + '); return false;"></button>';
}
}
}
}
});
//Re-load records when user click 'load records' button.
$('#LoadRecordsButton').click(function (e) {
e.preventDefault();
$('#HTEContainer').jtable('load', {
ProductionLineName: $('#ProductionLineName').val(),
AreaName: $('#AreaName').val(),
OperationName: $('#OperationName').val(),
ModelName: $('#ModelName').val(),
HTETypeName: $('#HTETypeName').val()
});
});
//Load all records when page is first shown
$('#LoadRecordsButton').click();
$('#GoBack').click(function (e) {
e.preventDefault();
window.location.replace("/HTE");
});
});
function transferAdmin(hteHeaderId) {
window.location.replace("/HTE/AdminSettings/" + hteHeaderId);
};
function transferHTEDetails(hteHeaderId) {
window.location.replace("/HTE/HTEActivitiesList/?HTEHeaderId=" + hteHeaderId);
};
</script>
<br />
#section scripts {
}
Now, this is the code for the _Layout.cshtml in use:
<!DOCTYPE html>
#{
var jTableStyle = "metro/blue/jtable.css";
if (!string.IsNullOrEmpty(Request["jTableStyle"]))
{
jTableStyle = Request["jTableStyle"];
}
}
<html lang="es-mx">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Super Sistema Balanceo de Líneas - #ViewBag.Title - </title>
<link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/themes/metroblue/jquery-ui.css")" rel="stylesheet" type="text/css" />
#*<link href="#Url.Content("~/Content/highlight.css")" rel="stylesheet" type="text/css" />*#
<link href="#Url.Content("~/Scripts/jtable/themes/" + jTableStyle)" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Scripts/syntaxhighligher/styles/shCore.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Scripts/syntaxhighligher/styles/shThemeDefault.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/bootstrap.min.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/themes/base/jquery-ui.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/themes/base/core.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/themes/base/datepicker.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/themes/base/theme.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/bootstrap-theme.min.css")" rel="stylesheet" type="text/css" />
#RenderSection("CssImport", false)
<script src="#Url.Content("~/Scripts/jquery-3.0.0.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery-migrate-3.0.0.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery-ui-1.12.1.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery-ui.unobtrusive-3.0.0.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.date.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#* <script src="#Url.Content("~/Scripts/jquery.validate-vsdoc.js")" type="text/javascript"></script>*#
<script src="#Url.Content("~/Scripts/modernizr-2.8.3.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/syntaxhighligher/shCore.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/syntaxhighligher/shBrushJScript.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/syntaxhighligher/shBrushXml.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/syntaxhighligher/shBrushCSharp.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/syntaxhighligher/shBrushSql.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/bootstrap.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/moment.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/respond.min.js")" type="text/javascript"></script>
<script type="text/javascript" src="#Url.Content("~/Scripts/jtable/jquery.jtable.js")"></script>
<script src="#Url.Content("~/Scripts/jtablesite.js")" type="text/javascript"></script>
</head>
<body>
#Html.Partial("_NavBar")
<div class="container body-content">
#RenderBody()
<hr />
<footer>
<p>© #DateTime.Now.Year - Super Sistema Balanceo de Líneas</p>
</footer>
</div>
#RenderSection("scripts", required: false)
#RenderSection("CustomScripts", required: false)
</body>
</html>
This is a picture of system in Internet Explorer, displayed as expected:
page displayed in Internet Explorer
You can see the rendering is as expected, not issue on this area with Internet Explorer.
Red arrows indicates the buttons created as Custom Action, once pressed up, nothings happens. When the IE developer tools are displayed, I press the buttons indicated with Read arrows, nothing happens: not even an error in console, not even an error in Network tab, nothing at all. This is error I'm having.
Green arrows indicates the buttons created by jTable for EDIT, CREATE and DELETE actions as part of the grid. These buttons are working perfect. No issue on this area. See these pictures:
Page in IE showing modal for New record
Page in IE showing modal for Edit record
I hopes you guys can provide any idea.
Thanks,
Gerardo.

This a complex senario, so I cannot replicate it.
I observe from your code, that you are adding click handlers via javascript in the button definitions. Have you tried applying the click handler via jQuery
display: function (data) {
var $but = '';
if (data.record) {
$but = $('<button title="" class="jtable-command-button glyphicon glyphicon-cog" ></button>');
$but.click(transferAdmin(data.record.HTEHeaderId));
}
return $but;
}
I would also point out your original code was creating a button using the same id btnAdmin on every row of the table which is neither good practice or useful, so I have omitted that, as it is possibly another reason why IE gets confused.

Thanks #misterP for his reply. After having bad times with this, I managed to understand what was wrong, and fixed it.
Let me try to explain fixes to issue I was having.
1) Main problem was that in IE, my jQuery logic was not working, when it worked in Firefox and Chrome. I was not aware of IE compatilibity modes that are fixed with the meta tag at level. So, on file _layout.chtml, I set the following:
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
...
2) Regarding how I managed the functionality on the custom action, I read online that when working with jQuery targeting dynamic elements, we should start the filtering against a fixed tag --- hence I used ContainerForJTable. I declare a custom attribute seleccionable on the dynamic object:
display: function (data) {
if (data.record) {
return '<button id="' + data.record.FileID + '" class="jtable-command-button glyphicon glyphicon-eye-open seleccionable"></button>';
}
}
3) I wrote a function (outside of the jtable object creation --- $('#ContainerForJTable').jtable({..) to add an event to objects matching a filter using my custom attribute:
$('#ContainerForJTable').on('click', '.seleccionable', function () {
var theID = $(this).attr("id");
//console.log("The id is " + theID);
viewFiles(theID);
});
After these changes, the jtables objects had been working without any issues.
thanks,

Related

jQuery conversion onclick to onload

I have one website link which currently is working when clicking the link a window pop-up, but I want the onclick to happen automatically without clicking. The onclick should work like onload.
I tried a lot of Google and StackOverflow searches.. but I couldn't find the exact solution to my problem.
Here's my code below:
<!DOCTYPE html>
<html>
<head>
<title>mygame | Browser</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<script type="text/javascript" src="../api.js"></script>
<script type="text/javascript">
function initialize() {
document.getElementById('robrowser').addEventListener("click", function(){
var ROConfig = {
type: ROBrowser.TYPE.POPUP,
application: ROBrowser.APP.ONLINE,
remoteClient: "http://play.mygame.com/client",
width: 1024,
height: 768,
development: false,
servers: [{
display: "mygame",
desc: "mygame Revolution",
address: "94.99.190.98",
port: 6900,
version: 46,
langtype: 12,
packetver: 20170614,
packetKeys: false,
socketProxy: "ws://196.66.646.179:5999/"
}],
saveFiles: true,
skipServerList: true,
skipIntro: true,
version: 1,
plugins: {
IntroMessage: {}
}
};
var RO = new ROBrowser(ROConfig);
RO.start();
}, false );
}
window.addEventListener("load", initialize, false);
</script>
</head>
<body>
<input type="button" value="Run roBrowser" id="robrowser"/>
</body>
You can simulate a buttonclick like this:
$("#robrowser").click();
In this case you want to run the method when a page is loaded.
You can just remove the entire onclick listener and call the function initialize() directly:
function initialize() {
var ROConfig = {
type: ROBrowser.TYPE.POPUP,
application: ROBrowser.APP.ONLINE,
remoteClient: "http://play.mygame.com/client",
width: 1024,
height: 768,
development: false,
servers: [{
display: "mygame",
desc: "mygame Revolution",
address: "94.99.190.98",
port: 6900,
version: 46,
langtype: 12,
packetver: 20170614,
packetKeys: false,
socketProxy: "ws://196.66.646.179:5999/"
}],
saveFiles: true,
skipServerList: true,
skipIntro: true,
version: 1,
plugins: {
IntroMessage: {}
}
};
var RO = new ROBrowser(ROConfig);
RO.start();
}
initialize();
The following changes have been made:
button on click event listener moved into the window load function
The source code from the button click event moved into initialize()
button on click event to target the function initialize
window load function calls/executes initialize()
Source code:
<!DOCTYPE html>
<html>
<head>
<title>mygame | Browser</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<script type="text/javascript" src="../api.js"></script>
<script type="text/javascript">
function initialize() {
var ROConfig = {
type: ROBrowser.TYPE.POPUP,
application: ROBrowser.APP.ONLINE,
remoteClient: "http://play.mygame.com/client",
width: 1024,
height: 768,
development: false,
servers: [{
display: "mygame",
desc: "mygame Revolution",
address: "94.99.190.98",
port: 6900,
version: 46,
langtype: 12,
packetver: 20170614,
packetKeys: false,
socketProxy: "ws://196.66.646.179:5999/"
}],
saveFiles: true,
skipServerList: true,
skipIntro: true,
version: 1,
plugins: {
IntroMessage: {}
}
};
var RO = new ROBrowser(ROConfig);
RO.start();
}
window.addEventListener("load", function(){
document.getElementById('robrowser').addEventListener("click", initialize, false );
initialize();
}, false);
</script>
</head>
<body>
<input type="button" value="Run roBrowser" id="robrowser"/>
</body>
</html>
If you have any questions about the source code above please leave a comment below and I will get back to you as soon as possible.
I hope this helps, happy coding!

FullCalendar: Use Location attribute of Google Calendar Event

I have setup FullCalendar (v3.8.0) to pull event data from Google Calendar, using qTip2 for displaying event information. This works fine.
I am now trying to display the event's location attribute. Sadly, I cannot seem to figure out how to get FullCalendar to save the information from Google Calendar in the event.
<head>
<meta charset="utf-8">
<title>Test</title>
<meta name="description" content="Test">
<meta name="author" content="Test">
<link rel='stylesheet' href='fullcalendar/fullcalendar.css' />
<link rel='stylesheet' href='qtip/jquery.qtip.min.css' />
<script src='lib/jquery.min.js'></script>
<script src='qtip/jquery.qtip.min.js'></script>
<script src='lib/moment.js'></script>
<script src='fullcalendar/fullcalendar.js'></script>
<script type='text/javascript' src='fullcalendar/gcal.js'></script>
</head>
<body>
<script type='text/javascript'>
$(document).ready(function() {
$('#calendar').fullCalendar({
googleCalendarApiKey: '<<hidden>>',
events: {
googleCalendarId: '<<hidden>>'
},
header: {
left: 'title',
center: 'listWeek, agendaWeek, month',
right: 'prev,next'
},
weekends: false,
eventRender: function(event, element) {
element.qtip({
content: event.description,
title: event.title,
position: {
my: 'center', //Ecke des Tooltips
at: 'center', //Position auf der Seite (auch Target möchlich)
target: $(window)
},
show: 'click'
});
},
eventClick: function(event) {
if (event.url) {
return false;
}
}
});
});
</script>
<div id='calendar'></div>
</body>
I have tried to add the location attribute to EventDef.defineStandardProps, but this apperas to have no effect.
EventDef.defineStandardProps({
// not automatically assigned (`false`)
_id: false,
id: false,
className: false,
source: false,
// automatically assigned (`true`)
title: true,
url: false,
rendering: true,
constraint: true,
overlap: true,
editable: true,
startEditable: true,
durationEditable: true,
color: true,
backgroundColor: true,
borderColor: true,
textColor: true,
location: true
});
This was also discussed at "fullcalendar jQuery - Possible to retrieve description from Google Calendar events?", but the solution provided appears to be outdated and not applicable anymore.
Every other thread about this topic has either no or no conclusive answer.
Which steps can I take to be able to use the event location?
During the eventRender callback (https://fullcalendar.io/docs/event_rendering/eventRender/) you shuld be able to access event.location, assuming Google has provided you with that field in the JSON you receive. You can check the content of the event by inserting the line console.log(JSON.stringify(event)); into your eventRender code, to log the event properties available to you.
FullCalendar happily keeps custom properties on the event object, if the data source supplies them. Once you've got that data, you can insert it into the event's HTML however you please.
I don't know where in the process you were trying to add things to the event standard properties, but anyway that makes no sense - it would just pre-define an empty attribute, it doesn't cause it to be actually populated with anything.

Node js, Express and handlebars rendering fullcalendar plugin not working

I have been unable to implement fullcalendar into my application and cannot find any information detailing exactly how to implement it using node, express and handlebars. I've tried multiple ways of adding fullcalendar without any luck. Other web pages in my application are working and render their information so I don't know why fullcalendar won't work after following the instructions on the website.
<!-- main.handlebars -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M"
crossorigin="anonymous">
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
<!-- Page level plugin CSS-->
<link href="vendor/datatables/dataTables.bootstrap4.css" rel="stylesheet">
<!-- Custom styles for this template-->
<link href="css/sb-admin.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<!-- Link and script for calendar -->
<link rel='stylesheet' href='../../node_modules/fullcalendar/dist/fullcalendar.css' />
<script src='../../node_modules/jquery/dist/jquery.min.js'></script>
<script src='../../node_modules/moment/min/moment.min.js'></script>
<script src='../../node_modules/fullcalendar/dist/fullcalendar.js'></script>
<script>
$(document).ready(function() {
// page is now ready, initialize the calendar...
$('#calendar').fullCalendar({
// put your options and callbacks here
header: {
left: 'prev, next, today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
editable: true,
timezone: "local",
defaultView: "month",
firstHour: "7",
weekMode: "liquid"
});
});
</script>
<title>Workmate</title>
</head>
<body>
{{#if user}}
{{> _appNavbar}}
{{else}}
{{> _navbar}}
{{/if}}
<div class="container">
{{> _msg}}
{{> _errors}}
{{{body}}}
</div>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4"
crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1"
crossorigin="anonymous"></script>
</body>
</html>
After the main.handlebars I have the schedule.handlebars which should load the empty calendar.
<div id='calendar'></div>
I've followed the instructions on the fullcalendar website and it doesn't render the calendar on the schedule.handlebars page.
// webapp.js
//App schedules route
router.get('/schedules', ensureAuthenticated, (req, res) =>{
res.render('webapp/schedules');
});
This is all the code I have to implement the application. Any help will be greatly appreciated as this is for my final year project in college.
Thanking you all in advance.
Not sure if anyone would be interested, but after quite some time spent on trial & errors (lots of errors), I managed to make this work in conjunction with Handlebars.
First, I had to write a separate .js file (calendar.js) for the $(document).ready function:
$(document).ready(function() {
// Let's make sure that this 2 little critters get loaded, otherwise fullcalendar wont work.
$.when (
$.getScript("/s/js/moment.min.js"),
$.getScript("/s/calendar/fullcalendar.min.js"))
.done(function()
{
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'listDay,listWeek,month'
},
// customize the button names,
// otherwise they'd all just say "list"
views: {
listDay: { buttonText: 'list day' },
listWeek: { buttonText: 'list week' }
},
defaultView: 'listWeek',
defaultDate: '2018-03-12',
navLinks: true, // can click day/week names to navigate views
editable: true,
eventLimit: true, // allow "more" link when too many events
events: [
{
title: 'All Day Event',
start: '2018-03-01'
},
{
title: 'Long Event',
start: '2018-03-07',
end: '2018-03-10'
},
{
id: 999,
title: 'Repeating Event',
start: '2018-03-09T16:00:00'
},
{
id: 999,
title: 'Repeating Event',
start: '2018-03-16T16:00:00'
},
{
title: 'Conference',
start: '2018-03-11',
end: '2018-03-13'
},
{
title: 'Meeting',
start: '2018-03-12T10:30:00',
end: '2018-03-12T12:30:00'
},
{
title: 'Lunch',
start: '2018-03-12T12:00:00'
},
{
title: 'Meeting',
start: '2018-03-12T14:30:00'
},
{
title: 'Happy Hour',
start: '2018-03-12T17:30:00'
},
{
title: 'Dinner',
start: '2018-03-12T20:00:00'
},
{
title: 'Birthday Party',
start: '2018-03-13T07:00:00'
},
{
title: 'Click for Google',
url: 'http://google.com/',
start: '2018-03-28'
}
]
}
);
}
);
});
Then onto the Handlebars template:
<section>
<style>
#calendar {
max-width: 800px;
margin: 0 auto;
}
</style>
<div id='calendar'></div>
and finally my app.jes file looked something like this:
app.get("/", async(req, res, next) => {
try {
let projectid = '2188'
let users = await req.app.locals.db.getRate(projectid);
res.render("listview", {
title: "Calendar",
rows: users,
scripts: ["/js/views/calendar.js"]
});
} catch (ex) {
return next(ex);
}
});
There are a couple of required css files, which were linked on the master Handlebars template.
I'm sure this isn't the best way to integrate it, as I'm really new to NodeJS and overall Javascript, but after a long weekend trying to figure this out, seeing the calendar render was refreshing.
Hope this helps anyone.
cheers!
I can see two potential issues. You are including some local scripts like that:
<!-- Link and script for calendar -->
<link rel='stylesheet' href='../../node_modules/fullcalendar/dist/fullcalendar.css' />
<script src='../../node_modules/jquery/dist/jquery.min.js'></script>
<script src='../../node_modules/moment/min/moment.min.js'></script>
<script src='../../node_modules/fullcalendar/dist/fullcalendar.js'></script>
Do you expose the node_modules directory through express in order to be able to serve those files? Have a look here:
https://expressjs.com/en/starter/static-files.html
It is not good practice though to expose the node_modules directory though, it is better if you have a building step of your application that will copy over all your libraries into a dedicated dist directory and ideally will minify and uglify them as well.
The second thing that can be problematic is the place that you include your script. It is good practice to move all the js imports inside the body just before the body closing tag (). You already defined some there. The document ready function will run but the div with the id calendar will not be there. More details here: Where should I put <script> tags in HTML markup?
Update 1
You need to be able to server the files in the node_modules (it is not a good practice though) like that:
app.use('/modules', express.static(path.join(__dirname, 'node_modules')))
And then include your script paths like that:
<link rel='stylesheet' href='/modules/fullcalendar/dist/fullcalendar.css' />
<script src='/modules/jquery/dist/jquery.min.js'></script>
<script src='/modules/moment/min/moment.min.js'></script>
<script src='/modules/fullcalendar/dist/fullcalendar.js'></script>

jqGrid | add-edit-delete buttons not working

sorry if my questions are simple , i'm totaly new to jqGrid :)
1- i want to use (add,edit,delete) feature of jqGrid , as you see there are buttons on the footer part of my grid but when i click just a dialog box comes and no fields to enter !! i want it just like this page
see my screen picture of what happens !
2- what happens when i click on submit button ( after fixing part 1 ) , i want to know how datas post to server!
no matter what language , i want to not for example they sent as object or sth , to know how to process them !
tnx alot
my source code :
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Index Page</title>
<!-- external scripts -->
<!-- jQuery & Bootstrap -->
<script type="text/javascript" src="{% static "js/jquery.js" %}"/></script>
<script type="text/javascript" src="{% static "js/jquery.jqGrid.min.js" %}"/></script>
<link rel="stylesheet" type="text/css" media="all" href="{% static "css/bootstrap.min.css?id=1" %}"/>
<script type="text/javascript" src="{% static "js/bootstrap.min.js" %}"/></script>
<!-- jQuery & Bootstrap -->
<!-- jqGrid -->
<link rel="stylesheet" type="text/css" media="screen" href="{% static "css/ui.jqgrid.css" %}" />
<link rel="stylesheet" type="text/css" media="screen" href="{% static "css/ui-lightness/jquery-ui.min.css" %}" />
<script type="text/javascript" src="{% static "js/grid.locale-en.js" %}"/></script>
<!-- jqGrid -->
<!-- own implemented scripts -->
<script type="text/javascript" src="{% static "js/script.js" %}"/></script>
<!-- own implemented scripts -->
<!-- external scripts-->
<script type="text/javascript">
$(function () {
$("#list").jqGrid({
url: "http://localhost:8000/getdata",
datatype: "json",
mtype: "GET",
colNames: ["شناسه", "کد","نام", "عنوان" ,"عنوان انگلیسی", "ظرفیت", "ظرفیت اضافه","قیمت روز"],
colModel: [
{ name: "id", index:"id", width: 60 , editable:true,editoptions: {readonly: "readonly"}},
{ name: "code", width: 60 , editable:true},
{ name: "name", width: 90 , editable:true},
{ name: "title", width: 90 ,editable:"true", editable:true},
{ name: "english_title", width: 100, align: "left", editable:true },
{ name: "capacity", width: 90, align: "left", editable:true },
{ name: "extra_capacity", width: 90, align: "left", editable:true },
{ name: "today_price", width: 80, align: "left" , editable:true},
],
rowNum:10,
rowList:[10,20,30],
pager: '#pager',
loadonce:true,
sortname: 'id',
viewrecords: true,
sortorder: "desc",
rownumbers: true,
rownumWidth: 40,
gridview: true,
multiselect: false,
caption: "اتاق ها",
onSelectRow: function(ids) {
if(ids == null) {
ids=0;
if(jQuery("#list_d").jqGrid('getGridParam','records') >0 )
{
jQuery("#list_d").jqGrid('setGridParam',{url:"getpricelist?q=1&id="+ids,page:1}).trigger('reloadGrid');
}
} else {
jQuery("#list_d").jqGrid('setGridParam',{url:"getpricelist?q=1&id="+ids,page:1}).trigger('reloadGrid');
jQuery("#list_d").jqGrid('setCaption',"لیست قیمت اتاق شماره : "+ids)
}
}
});
jQuery("#list").jqGrid('navGrid','#pager',{edit:true,add:true,del:true,search:false},
/* {
recreateForm: true,
beforeShowForm: function ($form) {
$form.find(".FormElement[readonly]")
.prop("disabled", true)
.addClass("ui-state-disabled")
.closest(".DataTD")
.prev(".CaptionTD")
.prop("disabled", true)
.addClass("ui-state-disabled")
},
}, */
//edit options
{ // Edit option (parameters of editGridRow method)
recreateForm:true,
reloadAfterSubmit:true,
closeOnEscape:true,
savekey: [true,13],
closeAfterEdit:true,
url:'/edit',
ajaxEditOptions: {
beforeSend: function(jqXHR) {
var csrf_token = getCookie('csrftoken');
jqXHR.setRequestHeader('X-CSRF-Token', csrf_token);
}
},
afterSubmit: function () {
jQuery("#list").jqGrid("setGridParam", {datatype: 'json'});
console.log('changed data type');
return [true];
},
editData: {
csrfmiddlewaretoken: getCookie('csrftoken')
}
},
//add options
{
recreateForm:true,
reloadAfterSubmit:true,
closeOnEscape:true,
savekey: [true,13],
closeAfterAdd: true,
url:'/add',
ajaxEditOptions: {
beforeSend: function(jqXHR) {
var csrf_token = getCookie('csrftoken');
jqXHR.setRequestHeader('X-CSRF-Token', csrf_token);
}
},
afterSubmit: function () {
jQuery("#list").jqGrid("setGridParam", {datatype: 'json'});
console.log('changed data type');
return [true];
},
editData: {
csrfmiddlewaretoken: getCookie('csrftoken')
}
},
//delete options
{
recreateForm:true,
reloadAfterSubmit:true,
closeOnEscape:true,
savekey: [true,13],
url:'/delete',
ajaxEditOptions: {
beforeSend: function(jqXHR) {
var csrf_token = getCookie('csrftoken');
jqXHR.setRequestHeader('X-CSRF-Token', csrf_token);
}
},
afterSubmit: function () {
jQuery("#list").jqGrid("setGridParam", {datatype: 'json'});
console.log('changed data type');
return [true];
},
editData: {
csrfmiddlewaretoken: getCookie('csrftoken')
}
}
);
jQuery("#list").jqGrid('filterToolbar',{stringResult: true,searchOnEnter : false});
jQuery("#list_d").jqGrid({
height: 100,
width:345,
url:'getpricelist?q=1&id=2',
datatype: "json",
colNames:['از','تا', 'قیمت'],
colModel:[
{name:'from',index:'from', width:100},
{name:'to',index:'to', width:100},
{name:'price',index:'price', width:80, align:"right"},
],
rowNum:5,
rowList:[5,10,20],
pager: '#pager_d',
sortname: 'item',
viewrecords: true,
sortorder: "asc",
multiselect: false,
caption:"لیست قیمت"
}).navGrid('#pager_d',{add:false,edit:false,del:false});
});
</script>
</head>
<body>
<table id="list"><tr><td></td></tr></table>
<div id="pager"></div>
<table id="list_d"></table>
<div id="pager_d"></div>
</body>
</html>
views.py
from django.shortcuts import render
from django.utils import simplejson
from django.http import HttpResponse
from rooms.models import *
from django.db.models import Q
from django.core import serializers
def index(request):
return render(request, 'index.html')
def getdata(request):
data=room_type.objects.all()
json=[]
for o in data:
json.append({'id':o.id, 'code':o.code,'name':o.name,'title':o.title,
'english_title':o.english_title, 'capacity':o.capacity,
'extra_capacity':o.extra_capacity, 'today_price':o.today_price })
return HttpResponse(simplejson.dumps(json), mimetype='application/json',content_type='application/json' )
def getpricelist(request):
requested_room_id = request.GET.get('id', '')
room = room_type.objects.get(id = requested_room_id)
price_list_set = room.price_list_set.all()
json=[]
for price_list in price_list_set:
json.append({'from':price_list.from_date, 'to':price_list.to_date, 'price':price_list.price})
return HttpResponse(simplejson.dumps(json), mimetype='application/json',content_type='application/json' )
def edit(request):
print "################ediit#################"
return render(request, 'index.html')
def add(request):
print "################addddddddddd#################"
return render(request, 'index.html')
def delete(request):
print "################deeeeeeeeeeeeeel#################"
return render(request, 'index.html')
The first problem is very easy to solve. The editing form (Add and Edit) includes only the information about editable columns. So you need include editable: true property in every column of colModel which you want to allow the user to edit.
It's important to understand that there are default value for every known property of colModel. I recommend you to examine the last ("Default") column of the table on the place of the documentation. You will find that default value of align is "left", so you can remove align: "left" from all colModel items. In the same way you can see that default value of editable property is false. It way the reason why you had empty editing form. If you need to set editable: true to more as the half of columns of colModel I would recommend you to use cmTemplate option of jqGrid (see the answer for more details). After including cmTemplate: {editable: true} option for example you will need to include editable: false in all columns which you want don't make editable. All other columns will be editable.
If you need to include some column information in Add/Edit form, but don't permit the user to edit it you can use editable: true together with editoptions: {readonly: "readonly"} or editoptions: {disabled: "disabled"}. The option will include the information in the edit form, but set additional readonly="readonly" or disabled="disabled" attribute on the corresponding editing field. One can add additional "ui-state-disabled" class on such filed like described in the answer. In the way you can make some fields editable, but only for example in Add dialog and hold it disabled/readonly in Edit dialog. Don't forget to use recreateForm: true option.
To make editing successful it's very important to fill rowid of the grid correctly. If you have column with name: "id" or if some column have key: true property then the corresponding value will be used as rowid. The information which will be send to the server is described here (about Edit), here (about Add) and here (about Delele). The information contains always id=rowidvalue property. Add/Edit form post additionally information about all (inclusive hidden) editable columns in the form: name=value, where the name is the value of name property of the column definition in the colModel.

First extjs example doesn't work

I'm want to learn extjs so I'm a newbie, so sorry for any stupid question here..
Here is my index.html page :
<html>
<head>
<meta charset="UTF-8">
<title>Test Hello</title>
<script type="text/javascript" src="extjs-4.2.1-gpl/ext-all.js"></script>
<script type="text/javascript" src="extjs-4.2.1-gpl/ux/form/LoginForm.js"></script>
<!-- <link href="extjs-4.1.1a/KitchenSink-all.css" rel="stylesheet" type="text/css" /> -->
<link href="extjs-4.2.1-gpl/resources/css/ext-all.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div align="center" id= "content" >
<script type="text/javascript">
var loginForm = Ext.create("test.view.form.LoginForm", {
id : "panellogin",
renderTo : 'content'
});
</script>
</div>
</body>
</html>
And LoginForm :
Ext.define('test.view.form.LoginForm', {
extend: 'Ext.form.Panel',
xtype : "test.view.form.LoginForm",
title: 'Login',
frame:true,
width: 320,
bodyPadding: 20,
defaultType: 'textfield',
defaults: {
anchor: '100%'
},
initComponent: function() {
var me = this;
me.items = [me.contentPanel];
me.contentPanel = Ext.create("Ext.grid.Panel", {
border: true,
align :"center",
layout: {
type: "hbox",
align: "center"
},
items: [
{
allowBlank: false,
fieldLabel: 'User ID',
name: 'user',
emptyText: 'user id'
},
{
allowBlank: false,
fieldLabel: 'Password',
name: 'pass',
emptyText: 'password',
inputType: 'password'
},
{
xtype:'checkbox',
fieldLabel: 'Remember me',
name: 'remember'
}
]
});
}
});
What did I exactly is:
Downloaded extjs 4.2.1-gpl from sencha website (about 65 Mo compressed)
When I found the huge size I delete things like examples, docs
Moved src inside a directory named ux inside 4.2.1-gpl directory
Kept resources, images and locale folders.
I need advice please, is this a good way to do? I can't put the whole content since it is more than 300 Mio! What to keep, please?
Firebug is showing me this error : TypeError: c is undefined (in ext-all.js line 21)
Google chrome is showing this : Uncaught TypeError: Cannot read property 'length' of undefined
Kind regards,
Could you please tell what's happen
Execute your code after the extjs sources are loaded (Ext.onReady...):
Ext.onReady(function () {
var loginForm = Ext.create("test.view.form.LoginForm", {
id : "panellogin",
renderTo : 'content'
});
});
This is not like you should have done. Especially deleting stuff and renaming src to ux. Also a class definition of test.view.form.LoginForm should be in the file app/view/form/LoginForm.js, not ux/form.
Read the doc how to get started, especially MVC Application Architecture and the App Architecture Series.

Categories

Resources