Related
I am having some problems using datatables.net with requirejs and some buttons and data loaded through the ajax request from datatables.net (JSON). I have tried and tried but still no luck.
The problem I face is: Uncaught ReferenceError: editPermission is not defined at HTMLButtonElement.onclick (permissions.php:1)
Here is the full backend PHP function that is connecting to the DB:
public function getAllPermissions($request, $columns): array
{
$bindings = array();
try {
$sql = "SELECT p.id, p.name, p.description, p.category, NULL AS roles,
CASE WHEN
p.required = 0 THEN concat('<button id=\'editpermission_', p.id, '\' onclick=\'editPermission(',p.id,')\' class=\'btn btn-warning\'>Edit</button>')
ELSE null END
AS edit
FROM ".$this->tbl_permissions." p";
$stmt = $this->conn->prepare($sql);
$stmt->execute();
$data = $stmt->fetchAll(\PDO::FETCH_ASSOC);
$return_data = array(
"data" => MiscFunctions::data_output($columns, $data)
);
return $return_data;
} catch (\PDOException $e) {
http_response_code(500);
$result = ["Error" => $e->getMessage()];
return $result;
}
}
Under here is the file that ajax asks for the data (permissions_getall.php):
<?php
try {
require '../../vendor/autoload.php';
session_start();
$request = new PHPLogin\CSRFHandler;
$auth = new PHPLogin\AuthorizationHandler;
$admin = new PHPLogin\AdminFunctions;
if ($request->valid_token() && ($auth->isSuperAdmin() || $auth->hasPermission('View Permissions'))) {
unset($_GET['csrf_token']);
$columns = array(
array( 'db' => 'id', 'dt' => 0 ),
array( 'db' => 'name', 'dt' => 1 ),
array( 'db' => 'description', 'dt' => 2 ),
array( 'db' => 'category', 'dt' => 3 ),
array( 'db' => 'roles', 'dt' => 4 ),
array( 'db' => 'edit', 'dt' => 5 )
);
$data = $admin->getAllPermissions($_GET, $columns);
echo json_encode($data);
} else {
http_response_code(401);
throw new Exception('Unauthorized');
}
} catch (Exception $e) {
error_log($e->getMessage());
echo json_encode($e->getMessage());
}
This is the JS file:
require(['jquery', 'multiselect', 'datatables', 'datatables.net', 'datatables.net-bs4', 'datatables.net-buttons', 'datatables.net-buttons-bs4', 'datatables.net-select-bs4', 'loadingoverlay'], function ($) {
console.log($);
//User Management scripts
/* HANDLES POPOVERS FOR USER INFO */
function userInfoPull(id, elem) {
$.ajax({
type: "POST",
url: "ajax/user_getinfo.php",
data: {"user_id": id, "csrf_token": $('meta[name="csrf_token"]').attr("value")},
async: false,
beforeSend: function () {
$.LoadingOverlay('show', {
image: '../login/images/Spin-0.8s-200px.svg',
imageAnimation: false,
imageColor: '#428bca',
fade: [200, 100]
});
},
complete: function () {
$.LoadingOverlay("hide");
},
success: function (user_info) {
user_info = JSON.parse(user_info);
var user_info_html = '';
for (var prop in user_info) {
if (user_info[prop] != '' && user_info[prop] != null) {
if (prop == 'UserImage') {
user_info_html += '<br><div class="img-thumbnail"><img src="' + user_info[prop] + '" height="240px"></div>';
} else {
user_info_html += '<div><b>' + prop.replace(/([A-Z])/g, ' $1') + ': </b>' + user_info[prop] + '</div>';
}
}
}
$(elem).attr('data-content', user_info_html).popover('show', {"html": true});
},
error: function (xhr, error, thrown) {
console.log(error);
}
});
};
$('body').on('mouseover', "a[id^='info_']", function () {
if ($(this).attr('data-content')) {
$(this).popover('show', {"html": true});
} else {
var id = this.id.split('_')[1];
userInfoPull(id, this);
}
});
$('body').on('mouseleave', "a[id^='info_']", function () {
$(this).popover('hide');
});
/****************************/
/* HANDLES MODAL FOR PERMISSION ROLES */
$('body').on('click', "button[id^='rolesbtn_']", function () {
var id = this.id.split('_')[1];
permissionRolesList(id);
});
function permissionRolesList(id) {
$.ajax({
type: "POST",
url: "ajax/permission_getroles.php",
data: {"permission_id": id, "csrf_token": $('meta[name="csrf_token"]').attr("value")},
beforeSend: function () {
$.LoadingOverlay('show', {
image: '../login/images/Spin-0.8s-200px.svg',
imageAnimation: false,
imageColor: '#428bca',
fade: [200, 100]
});
},
complete: function () {
$.LoadingOverlay("hide");
},
success: function (role_array) {
role_array = JSON.parse(role_array);
$('#permissionsButton').click();
$('#roles-selected').empty();
$('#roles-available').empty();
$('#permission_id').val(id);
$.each(role_array['permission_roles'], function (key, value) {
$('#roles-selected').append("<option value='" + value.id + "'>" + value.name + "</option>");
});
$.each(role_array['diff_roles'], function (key, value) {
$('#roles-available').append("<option value='" + value.id + "'>" + value.name + "</option>");
})
$("select[id^='roles-']").multiselect({
search: {
left: '<input type="text" name="q" class="form-control" placeholder="Search..." />',
right: '<input type="text" name="q" class="form-control" placeholder="Search..." />',
},
fireSearch: function (value) {
return value.length > 3;
}
});
},
error: function (xhr, error, thrown) {
console.log(error);
}
});
};
function editPermission(id) {
var id = id;
$.ajax({
type: "POST",
url: "ajax/permission_getdata.php",
data: {"permission_id": id, "csrf_token": $('meta[name="csrf_token"]').attr("value")},
beforeSend: function () {
$.LoadingOverlay('show', {
image: '../login/images/Spin-0.8s-200px.svg',
imageAnimation: false,
imageColor: '#428bca',
fade: [200, 100]
});
},
complete: function () {
$.LoadingOverlay("hide");
},
success: function (response) {
var respdata = JSON.parse(response);
$("#editPermissionForm").trigger("reset");
$("#edit_permission_id").val(respdata.id);
$("#edit_PermissionName").val(respdata.name);
$("#edit_PermissionDescription").val(respdata.description);
$("#edit_PermissionCategory").val(respdata.category);
$('#editPermission').modal('show');
},
error: function (xhr, error, thrown) {
console.log(error);
}
});
}
$('#saveRoles').click(function () {
var sendData = new FormData();
var formData = [];
var new_roles = [];
var id = $('#permission_id').val();
$('#roles-selected > option').each(function () {
new_roles.push($(this).val());
});
formJson = JSON.stringify(new_roles);
sendData.append('formData', formJson);
sendData.append('permissionId', id);
sendData.append('csrf_token', $('meta[name="csrf_token"]').attr("value"));
$.ajax({
type: "POST",
url: "ajax/permission_updateroles.php",
processData: false,
contentType: false,
data: sendData,
beforeSend: function () {
$.LoadingOverlay('show', {
image: '../login/images/Spin-0.8s-200px.svg',
imageAnimation: false,
imageColor: '#428bca',
fade: [200, 100]
});
},
complete: function () {
$.LoadingOverlay("hide");
},
success: function (response) {
response = JSON.parse(response);
permissionTable.ajax.reload();
$('#permissionsModal').modal('toggle');
},
error: function (xhr, error, thrown) {
console.log(error);
}
});
});
/****************************/
/* DATATABLE INITIALIZATION */
$(document).ready(function () {
permissionTable = $('#permissionList').DataTable({
dom: "<'row'<'col-sm-3'l><'col-sm-6 text-center'B><'col-sm-3'f>>" +
"<'row'<'col-sm-12'tr>>" +
"<'row'<'col-sm-5'i><'col-sm-7'p>>",
order: [[3, "asc"], [1, "asc"]],
columns: [
{
name: "id",
visible: true,
searchable: false,
sortable: false,
render: function (data, type, row) {
return "";
}
},
{
name: "name",
searchable: true
},
{
name: "description",
searchable: true
},
{
name: "category",
searchable: true
},
{
name: "assign roles",
width: "90px",
searchable: false,
render: function (data, type, row) {
return "<button id='rolesbtn_" + row[0] + "' class='btn btn-info'>Assign roles</button>"
}
},
{
name: "edit permission",
width: "40px",
searchable: false
}
],
columnDefs: [{
className: 'select-checkbox',
targets: 0
}],
paging: true,
ajax: {
url: "ajax/permissions_getall.php?csrf_token=" + $('meta[name="csrf_token"]').attr("value"),
error: function (xhr, error, thrown) {
alert(xhr.responseJSON.Error);
}
},
scrollY: "600px",
scrollCollapse: true,
lengthMenu: [[15, 30, -1], [15, 30, "All"]],
select: {
style: "multi",
selector: 'td:first-child'
},
buttons: [
{
extend: 'selectAll',
className: 'selectall',
action: function (e) {
e.preventDefault();
permissionTable.rows({page: 'current'}).select();
permissionTable.rows({search: 'removed'}).deselect();
}
},
"selectNone",
{
text: 'Add New Permission',
action: function (e, dt, node, config) {
$('#newPermission').modal('show');
},
className: "btn-success"
},
{
text: 'Delete Selected',
action: function (e, dt, node, config) {
var selected_array = dt.rows({selected: true}).data();
if (confirm("Are you sure you want to delete the selected permissions?")) {
for (var i = 0, len = selected_array.length; i < len; i++) {
deletePermission(selected_array[i][0], 'rolesbtn_' + selected_array[i][0]);
}
}
},
className: "btn-danger"
}
]
}).on("select", function () {
//console.log("selected");
});
});
/****************************/
function deletePermission(id, btn_id) {
var idJSON = "[" + JSON.stringify(id) + "]";
$.ajax({
type: "POST",
url: "ajax/permissions_delete.php",
data: {"ids": idJSON, "csrf_token": $('meta[name="csrf_token"]').attr("value")},
async: false,
success: function (resp) {
permissionTable.row($('#' + btn_id).parents('tr')).remove().draw();
},
error: function (err) {
console.log(err);
alert(err.responseText);
}
});
}
$("#newPermissionForm").submit(function (event) {
event.preventDefault();
var permissionName = $("#new_PermissionName").val();
var permissionDescription = $("#new_PermissionDescription").val();
var permissionCategory = $("#new_PermissionCategory").val();
$.ajax({
url: "ajax/permissions_add.php",
type: "POST",
data: {
"permissionName": permissionName,
"permissionDescription": permissionDescription,
"permissionCategory": permissionCategory,
"csrf_token": $('meta[name="csrf_token"]').attr("value")
},
beforeSend: function () {
$.LoadingOverlay('show', {
image: '../login/images/Spin-0.8s-200px.svg',
imageAnimation: false,
imageColor: '#428bca',
fade: [200, 100]
});
},
complete: function (resp) {
$.LoadingOverlay("hide");
},
success: function (response) {
permissionTable.ajax.reload();
$("#newPermission").modal('hide');
$("#newPermissionForm")[0].reset();
},
error: function (err) {
console.log(err);
}
});
});
$("#editPermissionForm").submit(function (event) {
event.preventDefault();
var permissionId = $("#edit_permission_id").val();
var permissionName = $("#edit_PermissionName").val();
var permissionDescription = $("#edit_PermissionDescription").val();
var permissionCategory = $("#edit_PermissionCategory").val();
$.ajax({
url: "ajax/permission_update.php",
type: "POST",
data: {
"permissionId": permissionId,
"permissionName": permissionName,
"permissionDescription": permissionDescription,
"permissionCategory": permissionCategory,
"csrf_token": $('meta[name="csrf_token"]').attr("value")
},
beforeSend: function () {
$.LoadingOverlay('show', {
image: '../login/images/Spin-0.8s-200px.svg',
imageAnimation: false,
imageColor: '#428bca',
fade: [200, 100]
});
},
complete: function (resp) {
$.LoadingOverlay("hide");
},
success: function (response) {
permissionTable.ajax.reload();
$("#editPermission").modal('hide');
$("#editPermissionForm")[0].reset();
},
error: function (err) {
console.log(err);
}
});
});
//Role assignment box button logic
(function () {
$('#btnRight').click(function (e) {
var selectedOpts = $('#roles-available option:selected');
if (selectedOpts.length == 0) {
alert("Nothing to move.");
e.preventDefault();
}
$('#roles-selected').append($(selectedOpts).clone());
$(selectedOpts).remove();
e.preventDefault();
});
$('#btnAllRight').click(function (e) {
var selectedOpts = $('#roles-available option');
if (selectedOpts.length == 0) {
alert("Nothing to move.");
e.preventDefault();
}
$('#roles-selected').append($(selectedOpts).clone());
$(selectedOpts).remove();
e.preventDefault();
});
$('#btnLeft').click(function (e) {
var selectedOpts = $('#roles-selected option:selected');
if (selectedOpts.length == 0) {
alert("Nothing to move.");
e.preventDefault();
}
$('#roles-available').append($(selectedOpts).clone());
$(selectedOpts).remove();
e.preventDefault();
});
$('#btnAllLeft').click(function (e) {
var selectedOpts = $('#roles-selected option');
if (selectedOpts.length == 0) {
alert("Nothing to move.");
e.preventDefault();
}
$('#roles-available').append($(selectedOpts).clone());
$(selectedOpts).remove();
e.preventDefault();
});
}(jQuery));
// Converts array to object
function toObject(arr) {
var rv = {};
for (var i = 0; i < arr.length; ++i)
rv[i] = arr[i];
return rv;
}
});
Here is a image of the page with the button that is causing problems circled:
Here is what I have tried so far:
Attempted to move the function editPermission around as well as placing it inside the $(document).ready
I have noticed that when I click it in Chrome it seems to open a new page where it executes the script. Sort of weird. Screenshot (Normal page file circled):
What things can I try to solve this?
I am having some trouble with a JQWidget-jqxGrid i'm developing. I will like to change the format information is being send to an API from a row edition. I need to change some Dates to a specific string notation. This is the code i am using right now:
updaterow: function (rowid, rowdata, commit)
{
//console.log(rowdata);
var output = rowdata;
for (property in output) {
if (output[property] instanceof Date && schema.properties[property].format === "time") {
output[property] = output[property].getHours() + ":" + output[property].getMinutes();
//console.log('hola');
}
if (output[property] instanceof Date && schema.properties[property].format === "date")
{
output[property] = output[property].getFullYear() + "-" + output[property].getMonth() + 1 + '-' + output[property].getDate();
}
}
/*console.log(event.args.row);*/
console.log(output);
console.log(rowdata);
var token = $('input[name="__RequestVerificationToken"]').val();
$.ajax({
url: "/api/" + entity + "/" + rowdata.uid,
cache: false,
method: "put",
data: JSON.stringify(rowdata),
processData: false,
headers: {
"RequestVerificationToken": token,
"Content-type": "Application/json"
},
success: function () {
console.log("Okey dokey!");
commit(true);
},
error: function () {
alert("El dato no se ha actualizado correctamente");
}
});
}
I tried many things before doing this. Originally, i was doing the update on a “oncelledit” event, the problem was the same (And this is like some kind of paranormal activity for me):
As you can see, i am doing the reformating of data in output variable, instead of rowdata. Even so, before output variable gets modified for the ajax request, if i uncomment “console.log(rowdata);”, data will already be changed even before the “for” scope where data is modified. How this is really possible? I have checked cache by using another browser, but no luck.
Although data is correctly posted to my API with this code, data format is changed on the grid displayed to the user, and data gets ouwfull. I will like to send the information in the appropriate format, but not to change format data shown in the grid.
This is how the data is shown before edition:
fecha de inicio | hora de inicio
1/10/2018 | 8:00 AM
And this is after edition:
fecha de inicio | hora de inicio
2001-01-1 |13:0
I post my full code just in case:
—JSGrid.js—
$.ajaxSetup({ cache: false });
var FKSources = [];
var FKAdapters = {};
var dataFieldsArr = [];
var columnsArr = [];
var FKPropertySelection;
var entity;
var schema;
function createGrid()
{
$.ajax({
url: "/api/" + entity + "/schema",
success: function (data) {
schema = data;
for (property in data.properties) {
if (data.properties[property]["type"].indexOf("lhcrud") > -1) {
FKSources.push({
datatype: "json",
datafields:
[
{ name: data.fkAttributes[property] },
{ name: 'id', type: 'int' }
],
id: 'id',
url: '/api/' + data.properties[property]["type"].substring(data.properties[property]["type"].indexOf("models.") + "models.".length)
});
FKAdapters[property] = new $.jqx.dataAdapter(FKSources[FKSources.length - 1]);
dataFieldsArr.push({
name: property + 'Id',
value: property + 'Id',
values:
{
source: FKAdapters[property].records,
value: 'id',
label: data.fkAttributes[property]
},
type: 'int'
});
dataFieldsArr.push({
name: property + 'Nombre',
type: 'string',
map: property + '>' + data.fkAttributes[property]
});
columnsArr.push(
{
text: data.properties[property]["title"],
columntype: 'dropdownlist',
datafield: property + 'Id',
width: 150,
filtertype: 'checkedlist',
displayfield: property + 'Nombre',
createeditor: function (row, value, editor) {
editor.jqxDropDownList({ source: FKAdapters[FKPropertySelection], displayMember: data.fkAttributes[FKPropertySelection], valueMember: 'id' });
}
}
);
}
else if (data.properties[property]["type"].indexOf("integer") > -1) {
dataFieldsArr.push({ name: property, type: 'int' });
columnsArr.push({ text: data.properties[property]["title"], datafield: property, width: 80, cellsalign: 'right' });
}
else if (data.properties[property]["type"].indexOf("boolean") > -1) {
dataFieldsArr.push({ name: property, type: 'bool' });
columnsArr.push({ text: data.properties[property]["title"], datafield: property, width: 65, columntype: 'checkbox' });
}
else if (data.properties[property]["format"].indexOf("date") > -1) {
dataFieldsArr.push({ name: property, type: 'date' });
columnsArr.push({
text: data.properties[property]["title"], datafield: property, width: 150, columntype: 'datetimeinput', cellsalign: 'right', cellsformat: 'd'
});
}
else if (data.properties[property]["format"].indexOf("time") > -1) {
dataFieldsArr.push({ name: property, type: 'date' });
columnsArr.push({
text: data.properties[property]["title"], datafield: property, width: 100, columntype: 'datetimeinput', cellsalign: 'right', cellsformat: 't', createeditor: function (row, column, editor) {
editor.jqxDateTimeInput({
showTimeButton: true,
showCalendarButton: false
});
}
});
}
else {
dataFieldsArr.push({ name: property, type: 'string' });
columnsArr.push({ text: data.properties[property]["title"], datafield: property, width: 150 });
}
}
columnsArr.push({
text: 'Delete', datafield: 'Delete', columntype: 'button', width: 90, cellsrenderer: function () {
return "Delete row";
}, buttonclick: function (row) {
var deleteConfirm = confirm("Sure?");
if (deleteConfirm) {
var id = $("#jqxgrid").jqxGrid('getrowid', row);
deleteEntity(entity, id, $('input[name="__RequestVerificationToken"]').val());
$('#jqxgrid').jqxGrid('deleterow', id);
}
}
});
var source =
{
datatype: "json",
datafields: dataFieldsArr,
id: 'id',
url: '/api/' + entity,
addrow: function (rowid, rowdata, position, commit) {
var token = $('input[name="__RequestVerificationToken"]').val();
//console.log(rowid);
//console.log(rowdata);
$.ajax({
url: "/api/" + entity,
method: "post",
data: JSON.stringify(rowdata),
processData: false,
headers: {
"RequestVerificationToken": token,
"Content-type": "Application/json"
},
success: function () {
commit(true);
//reload Data in order to manage correctly new data
$("#jqxgrid").jqxGrid(
{
source: dataAdapter,
sortable: true,
filterable: true,
editable: true,
showeverpresentrow: true,
everpresentrowposition: "top",
selectionmode: 'singlecell',
editmode: 'dblclick',
theme: 'light',
columns: columnsArr
});
},
error: function (xhr) {
console.log(xhr);
commit(false);
}
});
},
updaterow: function (rowid, rowdata, commit)
{
//console.log(rowdata);
var output = rowdata;
for (property in output) {
if (output[property] instanceof Date && schema.properties[property].format === "time") {
output[property] = output[property].getHours() + ":" + output[property].getMinutes();
//console.log('hola');
}
if (output[property] instanceof Date && schema.properties[property].format === "date")
{
output[property] = output[property].getFullYear() + "-" + output[property].getMonth() + 1 + '-' + output[property].getDate();
}
}
/*console.log(event.args.row);*/
console.log(output);
console.log(rowdata);
var token = $('input[name="__RequestVerificationToken"]').val();
$.ajax({
url: "/api/" + entity + "/" + rowdata.uid,
cache: false,
method: "put",
data: JSON.stringify(rowdata),
processData: false,
headers: {
"RequestVerificationToken": token,
"Content-type": "Application/json"
},
success: function () {
console.log("Okey dokey!");
commit(true);
},
error: function () {
alert("El dato no se ha actualizado correctamente");
}
});
}
};
var dataAdapter = new $.jqx.dataAdapter(source);
$("#jqxgrid").jqxGrid(
{
source: dataAdapter,
width: '100%',
sortable: true,
filterable: true,
editable: true,
showeverpresentrow: true,
everpresentrowposition: "top",
selectionmode: 'singlecell',
editmode: 'dblclick',
theme: 'light',
columns: columnsArr
});
},
error: function () {
alert("Error Getting Data");
}
});
}
$("#jqxgrid").on('cellselect', function (event) {
FKPropertySelection = event.args.datafield.substring(0, event.args.datafield.indexOf('Id'));
});
—JSGrid.cshtml—
#{
ViewData["Title"] = "JSGrid";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>JSGrid for #ViewBag.entity</h2>
#Html.AntiForgeryToken()
<div id="jqxgrid">
</div>
#section scripts
{
<link rel="stylesheet" href="~/lib/jqwidgets/styles/jqx.base.css" type="text/css" />
<link rel="stylesheet" href="~/lib/jqwidgets/styles/jqx.light.css" type="text/css" />
<script type="text/javascript" src="~/lib/jqwidgets/jqxcore.js"></script>
<script type="text/javascript" src="~/lib/jqwidgets/jqxdata.js"></script>
<script type="text/javascript" src="~/lib/jqwidgets/jqxbuttons.js"></script>
<script type="text/javascript" src="~/lib/jqwidgets/jqxscrollbar.js"></script>
<script type="text/javascript" src="~/lib/jqwidgets/jqxmenu.js"></script>
<script type="text/javascript" src="~/lib/jqwidgets/jqxlistbox.js"></script>
<script type="text/javascript" src="~/lib/jqwidgets/jqxdropdownlist.js"></script>
<script type="text/javascript" src="~/lib/jqwidgets/jqxcheckbox.js"></script>
<script type="text/javascript" src="~/lib/jqwidgets/jqxgrid.js"></script>
<script type="text/javascript" src="~/lib/jqwidgets/jqxdatetimeinput.js"></script>
<script type="text/javascript" src="~/lib/jqwidgets/jqxcalendar.js"></script>
<script type="text/javascript" src="~/lib/jqwidgets/jqxtooltip.js"></script>
<script type="text/javascript" src="~/lib/jqwidgets/jqxgrid.selection.js"></script>
<script type="text/javascript" src="~/lib/jqwidgets/jqxgrid.columnsresize.js"></script>
<script type="text/javascript" src="~/lib/jqwidgets/jqxgrid.filter.js"></script>
<script type="text/javascript" src="~/lib/jqwidgets/jqxgrid.sort.js"></script>
<script type="text/javascript" src="~/lib/jqwidgets/jqxgrid.pager.js"></script>
<script type="text/javascript" src="~/lib/jqwidgets/jqxgrid.grouping.js"></script>
<script type="text/javascript" src="~/lib/jqwidgets/jqxgrid.edit.js"></script>
<script type="text/javascript" src="~/js/JSGrid.js"></script>
<script>
entity = '#ViewBag.entity';
createGrid();
</script>
}
Thanks in advance!
All right! I found my solution here:
https://www.jqwidgets.com/community/topic/rowdata-changed-even-before-statement-to-do-so/#post-98256
and here:
https://www.jqwidgets.com/community/topic/difference-between-refreshdata-and-updatebounddata/
(¡Haya PAZ! - Les luthiers)
I partially solved my issue reloading binded data with 'updatebounddata' method from jqxgrid.
Just in case someone has the same problem, i will leave here my updateRow function updated. Look at the ajax block:
updaterow: function (rowid, rowdata, commit)
{
//console.log(rowdata);
var output = rowdata;
for (property in output) {
if (output[property] instanceof Date && schema.properties[property].format === "time") {
output[property] = output[property].getHours() + ":" + output[property].getMinutes();
//console.log('hola');
}
if (output[property] instanceof Date && schema.properties[property].format === "date")
{
output[property] = output[property].getFullYear() + "-" + (output[property].getMonth() + 1) + '-' + output[property].getDate();
}
}
//console.log(event.args.row);
//console.log(output);
//console.log(rowdata);
var token = $('input[name="__RequestVerificationToken"]').val();
$.ajax({
url: "/api/" + entity + "/" + rowdata.uid,
cache: false,
method: "put",
data: JSON.stringify(rowdata),
processData: false,
headers: {
"RequestVerificationToken": token,
"Content-type": "Application/json"
},
success: function () {
console.log("Okey dokey!");
commit(true);
$("#jqxgrid").jqxGrid('updatebounddata');
},
error: function () {
alert("El dato no se ha actualizado correctamente");
$("#jqxgrid").jqxGrid('updatebounddata');
}
});
}
Hope this will help someone in the future!
I am using selectize with meteor via this example:
meteor is not working with selectize.js
Template.hello.onRendered(function(){
$('#select-links').selectize({
maxItems: null,
valueField: 'id',
searchField: 'title',
options: [
{id: 1, title: 'DIY', url: 'https://diy.org'},
{id: 2, title: 'Google', url: 'http://google.com'},
{id: 3, title: 'Yahoo', url: 'http://yahoo.com'},
],
render: {
option: function(data, escape) {
return '<div class="option">' +
'<span class="title">' + escape(data.title) + '</span>' +
'<span class="url">' + escape(data.url) + '</span>' +
'</div>';
},
item: function(data, escape) {
return '<div class="item">' + escape(data.title) + '</div>';
}
},
create: function(input) {
return {
id: 0,
title: input,
url: '#'
};
}
});
});
<!-- html -->
<template name="hello">
<select id="select-links" placeholder="Pick some links..."></select>
</template>
So on the onChange event I want to get the
value and id
of that value to save to the database.
The result could be something like this: {id: 1, text: google}
So How can I do that ?
from a newber of meteor
You can leverage the onChange callback that selectize supports out of the box. Here's a working example.
import { Template } from 'meteor/templating';
import { $ } from 'meteor/jquery';
import { _ } from 'meteor/underscore';
import selectize from 'selectize';
import './main.html';
import 'selectize/dist/css/selectize.css';
const selectLinks = [
{ id: 1, title: 'DIY', url: 'https://diy.org' },
{ id: 2, title: 'Google', url: 'http://google.com' },
{ id: 3, title: 'Yahoo', url: 'http://yahoo.com' },
];
const getLinkTitle = (id) => {
let title;
if (id) {
const selectedLink = _.find(selectLinks, (link) => {
return link.id === parseInt(id);
});
if (selectedLink) {
title = selectedLink.title;
}
}
return title;
};
Template.body.onRendered(function onRendered() {
$('#select-links').selectize({
maxItems: null,
valueField: 'id',
searchField: 'title',
options: selectLinks,
render: {
option: function(data, escape) {
return '<div class="option">' +
'<span class="title">' + escape(data.title) + '</span>' +
'<span class="url">' + escape(data.url) + '</span>' +
'</div>';
},
item: function(data, escape) {
return '<div class="item">' + escape(data.title) + '</div>';
}
},
create: function(input) {
return {
id: 0,
title: input,
url: '#'
};
},
onChange: function (values) {
if (values) {
values.forEach((value) => {
// Can save to your collection/database here; for now
// just logging in the format you requested.
console.log({
id: value,
text: getLinkTitle(value)
});
});
}
}
});
});
Note this point:
const getLinkTitle = (id) => { let title; if (id) {
const selectedLink = _.find(selectLinks, (link) => {
`return link.id === parseInt(id);`
});
if (selectedLink) {
title = selectedLink.title;
} } return title; };
`return link.id === parseInt(id);`
Take care that line of code. It depend on your id. I am using mongoDB so it's not a number anymore in my real application.
On click on #add I am calling add_table_row() to add new row in table
<tr class="item" id="item1">
<td><input type="text" name="billProductList[0].product.name"
id="billProductList_0__product_name" class="name></td>
..............
</tr>
Each row in similar to above one only the numbers are incremented by one.
For first .name jquery autocomplete is working properly but for dynamically added row it is not working
function add_table_row() {
var t = $('.table .item:last').attr('id');
var prs = t.slice(4);
var num1 = parseInt(prs) + 1;
var dataString = 'rowId=' + num1;
$.ajax({
type: "POST",
url: "getNewBillRow",
data: dataString,
dataType: "html",
success: function(data) {
$(".table .item:last").after(data);
}
});
}
$(document).on('click', '#add', function(event) {
event.preventDefault();
add_table_row();
});
$(".name").autocomplete({
source: function(request, response) {
$.ajax({
url: "ProductByName",
dataType: "json",
data: {
name: request.term,
maxRows: 12
},
success: function(data) {
response($.map(data.productList, function(item) {
console.log(item);
return {
label: item.name,
value: item.name,
id: item.id,
desc: item.desc,
}
}));
},
error: function(data) {
console.log(typeof data);
}
});
},
minLength: 1,
select: function(event, ui) {
log(ui.item ?
"Selected: " + ui.item.label :
"Nothing selected, input was " + this.value);
var pid = $(this).parents('.item').attr('id');
//alert(ui.item.id + " " + ui.item.desc);
$("#" + pid + " .id").val(ui.item.id);
$("#" + pid + " .description").val(ui.item.desc);
},
open: function() {
$(this).removeClass("ui-corner-all").addClass("ui-corner-top");
},
close: function() {
$(this).removeClass("ui-corner-top").addClass("ui-corner-all");
}
});
How to make it to work for all .name .
This is because when you bind autocomplete() to .name, the other controls (dynamic controls) doesn't exist in the DOM. So you need to rebind the function after adding the control to the DOM.
You can do something like this:
function BindAutoComplete() {
$(".name").autocomplete({
source: function(request, response) {
$.ajax({
url: "ProductByName",
dataType: "json",
data: {
name: request.term,
maxRows: 12
},
success: function(data) {
response($.map(data.productList, function(item) {
console.log(item);
return {
label: item.name,
value: item.name,
id: item.id,
desc: item.desc,
}
}));
},
error: function(data) {
console.log(typeof data);
}
});
},
minLength: 1,
select: function(event, ui) {
log(ui.item ?
"Selected: " + ui.item.label :
"Nothing selected, input was " + this.value);
var pid = $(this).parents('.item').attr('id');
//alert(ui.item.id + " " + ui.item.desc);
$("#" + pid + " .id").val(ui.item.id);
$("#" + pid + " .description").val(ui.item.desc);
},
open: function() {
$(this).removeClass("ui-corner-all").addClass("ui-corner-top");
},
close: function() {
$(this).removeClass("ui-corner-top").addClass("ui-corner-all");
}
});
}
Then in your ajax call :
function add_table_row() {
var t = $('.table .item:last').attr('id');
var prs = t.slice(4);
var num1 = parseInt(prs) + 1;
var dataString = 'rowId=' + num1;
$.ajax({
type: "POST",
url: "getNewBillRow",
data: dataString,
dataType: "html",
success: function(data) {
$(".table .item:last").after(data);
BindAutoComplete();
}
});
}
After you add the new row, you need to initialize autocomplete on the newly added .name field.
success: function(data) {
$(".table .item:last").after(data);
$(".table .item:last .name").autocomplete({
source: function(request, response) {
$.ajax({
url: "ProductByName",
dataType: "json",
data: {
name: request.term,
maxRows: 12
},
success: function(data) {
response($.map(data.productList, function(item) {
console.log(item);
return {
label: item.name,
value: item.name,
id: item.id,
desc: item.desc,
}
}));
},
error: function(data) {
console.log(typeof data);
}
});
},
minLength: 1,
select: function(event, ui) {
log(ui.item ?
"Selected: " + ui.item.label :
"Nothing selected, input was " + this.value);
var pid = $(this).parents('.item').attr('id');
//alert(ui.item.id + " " + ui.item.desc);
$("#" + pid + " .id").val(ui.item.id);
$("#" + pid + " .description").val(ui.item.desc);
},
open: function() {
$(this).removeClass("ui-corner-all").addClass("ui-corner-top");
},
close: function() {
$(this).removeClass("ui-corner-top").addClass("ui-corner-all");
}
});
}
I have created form with haml and I just want to optimize with this jsonForm builder.
Following is sample form I created with reference document:
https://github.com/joshfire/jsonform
$('form').jsonForm({
schema: {
name: {type: 'string', title: 'Name', required: true},
age: {type: 'number', title: 'Age', required: true},
choice: {type: 'string',title: 'Title', 'enum': ['choice-1','choice-2','choice-3']}
},
onSubmit: function (errors, values) {
if (errors) {
$('#res').html('<p>I beg your pardon?</p>');
}
else {
$('#res').html('<p>Hello ' + values.name + '.' +
(values.age ? '<br/>You are ' + values.age + '.' : '') +
'</p>');
}
}
});
But I also need to get those values globally.
How can I do this?
One way is to serialize the form to array using jQuery helper methods and then convert the array to JSON format. I have created a fiddle for it here:
http://jsfiddle.net/kamatanay/fchgS/
HTML:
<form></form>
<button id="theButton">Try</button>
Javascript:
$("#theButton").click(function(){
var dataJson = {};
$($("form").serializeArray()).map(function(){
dataJson[this.name] = this.value;
});
console.log(dataJson);
});
$('form').jsonForm({
schema: {
name: {
type: 'string',
title: 'Name',
required: true
},
age: {
type: 'number',
title: 'Age'
}
},
onSubmit: function (errors, values) {
if (errors) {
$('#res').html('<p>I beg your pardon?</p>');
}
else {
$('#res').html('<p>Hello ' + values.name + '.' +
(values.age ? '<br/>You are ' + values.age + '.' : '') +
'</p>');
}
}
});
I hope that it helps!