Jquery Inline editor plugin saving numbers on dropdown select - datatables

Good day,
I have a datatable with the jQuery plugin that makes it editable and transform to text all the table rows.
Need to create a dropdown menu to select and store on database what is selected.
Everything is fine, since the plugin have an option to create a row with select options, the problem here is that the field that i have on the database is based on VARCHAR and the plugin only stores data with ENUM on the selected dropdown field.
So i cannot change the database field to ENUM because its going to delete or alter the already exixting data and could be a problem.
Example of what i see when i click on EDIT and see the dropdown options:
When i hit on SAVE button it shows this on the database:
This happens because the column type on the database is VARCHAR and the plugin needs it to be ENUM to read the data as text.
This is the code to draw the table and the edit plugin data:
$(document).ready(function(){
var dataTable = $('#tabla_clientes').DataTable({
"language": {
"url": "https://cdn.datatables.net/plug-ins/1.10.20/i18n/Spanish.json"
},
"processing" : true,
"serverSide" : true,
"order" : [],
"ajax" : {
url:"fectch.php",
type:"POST"
}
});
$('#tabla_clientes').on('draw.dt', function(){
$('#tabla_clientes').Tabledit({
url:'action.php',
deleteButton: false,
autoFocus: false,
buttons: {
edit: {
class: 'btn btn-sm btn-primary',
html: '<span class="glyphicon glyphicon-pencil"></span> &nbsp Editar',
action: 'edit'
}
},
dataType:'json',
columns:{
identifier : [0, 'id_customer'],
editable:[[1, 'customerID'], [2, 'RFC'], [3, 'firstname'], [4,'lastname'],[5,'email'],[6, 'tipo_cliente','{"1":"CONTADO","2":"CREDITO"}']]
},
restoreButton:false,
onSuccess:function(data, textStatus, jqXHR)
{
}
});
});
I already did some research on the internet but i cannot find anyone with a solution or with this problem.
Like i said, i cannot simply change the field to ENUM because there is a LOT of information that may be changed or deleted because of the type change.
Does anyone know a solution to store the value as text with the VARCHAR type when selecting the dropdown info?
Thanks for the time and patience. Have a excelent day.

I already found a workaround very simple for this.
Instead of adding directly the value as number on database.
Added an IF to compare the number and store text on a variable.
$tipo_cliente = $_POST['tipo_cliente'];
$sitio = $_POST['sitio']
if ($tipo_cliente == 1) {
$tipo_cliente = 'CONTADO';
} else
{
$tipo_cliente = 'CREDITO';
}

Related

Vuetify / Vue (2) data table not sorting / paginating upon new bound prop

Keeping the table as basic as possible to figure this out. I am struggling to learn how to create server side sorting/pagination to function in vuetify. When I add the :options or :server-items-length bind the table no longer sorts or paginates.
Without either of those, I get a default listing of 10 items per row - and the sorting all works perfectly fine as well the pagination. However, parameters in the api require a page item count thus forcing a hardcoded number or using the :options bind. If i just place a hard coded number things work fine, but when I bind I get proper items per page but no sorting and pagination.
Very simple data table:
<v-data-table
:items="ItemResults.items"
:headers="TableData.TableHeaders"
:loading="TableData.isLoading"
>
</v-data-table>
//Base data returns, with headers and options as well the array that items are stored in.
data() {
return {
ItemResults:[],
TableData: {
isLoading: true,
TableHeaders: [
{ value: "title", text: "Title" },
{ value: 'artist', text: 'Artist' },
{ value: 'upc', text: 'UPC' },
{ value: "retailPrice", text: "Price/Quantity"},
],
},
options:
{
page: 1,
itemsPerPage: 15
},
}
},
//Then last, my async method to grab the data from the api, and place it in the itemresults array.
async getProducts(){
this.TableData.isLoading = true;
const { page, itemsPerPage } = this.options;
var temp = await this.$axios.get(`Inventory/InventoryListing_inStock/1/${page}/${itemsPerPage}`);
this.ItemResults = temp.data;
this.TableData.isLoading = false;
return this.ItemResults;
},
I have tried following Vuetify Pagination and sort serverside guide, but I'm not sure where they are recommending to make the axios call.
The lead backend dev is working on setting a sorting function up in the api for me to call paramaters to as well - Im not sure how that will function along side.
but I dont know how to have this controlled by vuetify eithier, or the best practice here.
EDIT:
I've synced the following:
:options.sync="options"
:sort-by.sync="sortBy"
:sort-desc.sync="sortDesc"
but i think I dont need to sync the last two. My options:
options:
{
page: 1,
itemsPerPage: 15,
sortBy: ['title'],
sortDesc: [false]
},
and in my data I put the array for sort by and sort desc
sortBy: [
'title', 'artist', 'upc', 'retailPrice'
],
sortDesc:[true, false],
pagination is now working, and sort ascending is now working, but when I click to descend the header I get an error that the last two params are empty on update to / / instead of /sortBy/sortDesc result. So its not listing the values on changes.
When your component mounts, you need to fetch the total number of items available on the server and the first page of data, and set these as :items and :server-items-length. The latter will (as you observed) disable paging and sorting, as your server will take care of it, and it is used to calculate the total number of pages given a selected page size.
Now you need to know when to reload data. For this, you either bind options to the v-data-table with two-way binding (.sync) and set a watcher on it, or you listen to the update:options event. And whenever options change, you fetch the selected data from the server.
That's basically all it takes.
In your template:
<v-data-table
:items="items"
:headers="headers"
:loading="true"
:server-items-length="numberOfItemsOnServer"
#update:options="options => loadPage(options)"
/>
In your component:
methods: {
async loadPage(options){
this.items = [] // if you want to show DataTable's loading-text
this.items = await fetch('yourUrl' + new URLSearchParams({
// build url params from the options object
offset: (options.page - 1) * options.itemsPerPage,
limit: options.itemsPerPage,
orderBy: options.sortBy.map((sb,ix) => [sb, options.sortDesc[ix] ? 'desc' : 'asc'])
}))
}
}

Tabulator, vue.js - how to set focus of a cell after table refeshData

Using Tablulator (great product!), I am trying to keep the cursor from resetting to the first editable cell in the table after editing a cell. The replaceData function is updating the data element, and while the scroll position does not change, the cursor is reset. I'm not sure how to do this correctly. The documentation, while great, is silent about cursor position beyond the next(), etc methods, which I cannot quite get to work.
In my vue.js table definition component, I have a watch like this:
watch: {
tableData: {
handler: function (newData) {
this.tabulator.replaceData(newData);
},
deep: true,
}
},
and a cellEdited method inside mounted like this:
mounted() {
let self = this;
//todo Possibly validate that cater tips is less than total tips since cater tips is a portion of total tips
self.tabulator = new Tabulator(self.$refs.myTable, {
height: 380, // set height of table (in CSS or here)
placeholder: 'Click "Load Store Tips" to edit data',
data: self.tableData, //link data to table
reactiveData: true, //enable data reactivity
downloadConfig: {columnCalcs: false},
addRowPos:"bottom",
history:true,
layout: "fitDataFill",
initialSort:[
{column:"storeID", dir:"asc"},
],
//Define Table Columns
columns: [
{title: "Store ID", field: "storeID", sorter:"number"},
{title: "Store Tips", field: "inStore_tips", align: "right", formatter: "money", editor: "number", bottomCalc: "sum"},
{title: "Cater Tips", field: "cater_tips", align: "right", formatter: "money", editor: "number", bottomCalc: "sum"},
{title: "Client ID", field: "clientID"},
],
////////////////////////////////////////////////////////////////////////////
// When a cell is edited, write the data out to the server to ensure it is
// always in a saved state.
////////////////////////////////////////////////////////////////////////////
cellEdited: function (e, cell) {
//self.colPos = cell.getColumn(); //trying to save the cursor pos, but generating error
//self.rowPos = cell.getRow(); // generating error
self.PostTipsEventMethod();
}
});
Here is what I have tried:
Tried capturing the row and column position, and then setting that after the replaceData table render, and after the cellEdited method
Tried using the next() method to move the cursor to the next cell inside the cellEdited method, before and after the replaceData function.
Can someone guide me a bit further on this? I've searched through the tabulator element in the debugger trying to find the row and column numbers of the cell I'm editing, but so far, no joy. I guess I don't understand the lifecycle of the table rendering well enough.
Thank you!

How to use a cell-renderer without specifying a field in ag-grid

I want to use the last column as the expand row functionality. For this I'm using master/detail. The last column of master will just be an arrow down icon which on click will show the detail row. I'm unable to add a last column without providing a field name. The column is rendered empty. How can I use something like this:
{
headerName: '',
field: "", // as not associated to any column data
cellRenderer: "agGroupCellRenderer"
}
Here's the working example that you may be looking for, I did not had to rely on field for it. https://plnkr.co/edit/RxjZ9rUt7HUhlw5ejUd6?p=preview
Example is in ReactJS ag-grid code but the same thing applies to any framework as ag-grid relies on the columnDefinition array that you pass it in.
Here's the code change:
{
colId: "action", // optional
headerName: "Action", // set it to single space if you dont want any text
cellRendererFramework: (params) => <button onClick={() => (console.log(params), params.node.setSelected(true))}>+</button>, // this can be your any custom function
suppressSorting: true, // sorting for this field dont make sense, but optional
},
Hope that helps.

AnyColumn option added as new column in Dojo enhanced grid view

I am working on dojo enhanced grid view. I am able to display the grid in UI. But AnyColumn option is added as new column.
Example:
Any help will be appreciated...
Here is the Code
var mygrid = new EnhancedGrid({
id: "grid",
store: gridStore, //Data store passed as input
structure: gridStructure, //Column structure passed as input
autoHeight: true,
autoWidth: true,
initialWidth: width,
canSort : true,
plugins: {
filter: {
//Filter operation
isServerSide: true,
disabledConditions : {"anycolumn" : ["equal","less","lessEqual","larger","largerEqual","contains","startsWith","endsWith","equalTo","notContains","notEqualTo","notStartsWith","notEndsWith"]},
setupFilterQuery: function(commands, request){
if(commands.filter && commands.enable){
//filter operation
}
}
}
}, dojo.byId("mydatagrid"));
mygrid.startup();
Thanks,
Lishanth
First, do not use EnhancedGrid, instead use either dgrid or gridx.
I think by default anycolumn is added to the dropdown. If you want to remove then, I would suggest to
Register for click event on the filter definition
Iterate through the drop-down and remove the first entry which is anyColumn
or you can also try something like
dojo.forEach(this.yourgrid.pluginMgr.getPlugin('filter').filterDefDialog._cboxes, function(dropdownbox) {
dropdownbox._colSelect.removeOption(dropdownbox.options[0]);
});
Updated answer is. I know this is not the elegant way of doing it but it works.
//reason why I'm showing the dialog is that _cboxes of the filter are empty initially.
dijit.byId('grid').plugin('filter').filterDefDialog.showDialog();
dojo.forEach(dijit.byId('grid').pluginMgr.getPlugin('filter').filterDefDialog._cboxes, function(dropdownbox) {
var theSelect = dropdownbox._colSelect;
theSelect.removeOption(theSelect.options[0]);
});
//Closing the dialog after removing Any Column
dijit.byId('grid').plugin('filter').filterDefDialog.closeDialog();

Integrate Bootstrap typeahead js with Bootstrap Datatable

I am using bootstrap data-tables Datatables and bootstrap-taginput with typehead.js. I am new with bootstrap data-tables.
Here is the layout of my bootstrap data-tables Example and please consider Bootstrap tagging input box on top.
I want to search data-tables records with bootstrap tagging elements. but somehow i am unable to search with bootstrap tagging.
Thanks in advance.
If you start out with an empty array of the data you've got on your table you could do something clever by replacing the built in search box. In the example I'm linking to I don't care about one of the columns and the other columns need a little formatting:
var words = [];
var table = $('#example').DataTable({
"columns": [
null, {
"render": function(data, type, row) {
~words.indexOf(data) || words.push(data);
return data;
}
}, {
"render": function(data, type, row) {
var d = data.replace(/\, /g, " ");
~words.indexOf(d) || words.push(d);
return data.split(", ").join("<br/>");
}
}
],
"initComplete": function() {
var searchBox = $("#example_wrapper").find("input[type='search']");
var searchBoxHolder = searchBox.parent();
searchBox.empty().remove();
searchBoxHolder.append($("<input/>", {
"type": "text"
}).typeahead({
source: words,
afterSelect: function(word) {
table.search(word).draw();
}
}).on("keyup", function(x) {
if (words.indexOf($(x.target).val()) === -1) {
table.search($(x.target).val()).draw();
}
}));
}
});
Basically what we're doing here is creating a blank array of search terms then iterating over each second and third cell and adding the term to the array if it doesn't exist. In the case of the third cell I need to clear some formatting (extra comma). Then we get the original search box and it's parent. Remove the original and append the new one to the parent. We then set it up as a typeahead with the list of search terms. We need to make sure it still acts like the original so we add the keyup function. I hope that makes sense.
Working example is here, hope that helps.