I have a datatable and one of the coloumns is editable( using jeditable plugin) . So now i need a common submit button which will submit the entire changes.
Here is my datatable entry.
$(document).ready(function(){
$('#jtable').html( '<table cellpadding="1" cellspacing="1" border="1" class="pretty" id="edit_table"></table>' );
$("#edit_table").dataTable({
"aaData": {{ result | safe }},
"aLengthMenu" : 100,
"aaSorting": [],
"aoColumns" : [
{'sTitle' : 'Options' },
{'sTitle' : 'Values'}
],
"iDisplayLength": -1,
"bFilter" : false,
"bSearchable" :false,
"bInfinite" :true,
"bSort" :false,
"bPaginate": false
});
$('#edit_table tbody td:eq(3),td:eq(5),td:eq(7)').editable( 'Reschedule.html',{
"callback": function( sValue, y ) {
var aPos = oTable.fnGetPosition( this );
oTable.fnUpdate( sValue, aPos[0] );
},
"submitdata": function ( value, settings ) {
return {
"row_id": this.parentNode.getAttribute('id'),
"column": oTable.fnGetPosition( this )[2]
};
}
} );
} );
So i need a common submit button to submit the data on the table. I have to update the data to DB using python. ( I am using python + flask frame work). Any Help will be appreciated.
I'm yet to use Python to handle forms, so the information here may be wrong, however I hope it is of some use.
Your html form should only have one method, either get or post, not both. Post is more secure. Also you should use an action, and point it to your .py file that will handle the posted data. action="myPy.py"
You can also create a generic button and provide an onclick function to do something else before submitting the form. For example..
html part:
<input type="button" value="Submit Form" class="btn_submit" onclick="submitOrder()" />
alternatively you could use a submit button "input type='submit'..." and then use jQuery to call a function first before submitting, e.g.
$('#yourFormID').submit(function(e) {
//prevent default submit action
e.preventDefault();
//run your function instead
submitOrder();
});
I also found an article about form submission using Python, it may be of help to you...
http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-iii-web-forms
Related
I'm using DataTables (datatables.net) and I would like my search box to be outside of the table (for example in my header div).
Is this possible ?
You can use the DataTables api to filter the table. So all you need is your own input field with a keyup event that triggers the filter function to DataTables. With css or jquery you can hide/remove the existing search input field. Or maybe DataTables has a setting to remove/not-include it.
Checkout the Datatables API documentation on this.
Example:
HTML
<input type="text" id="myInputTextField">
JS
oTable = $('#myTable').DataTable(); //pay attention to capital D, which is mandatory to retrieve "api" datatables' object, as #Lionel said
$('#myInputTextField').keyup(function(){
oTable.search($(this).val()).draw() ;
})
As per #lvkz comment :
if you are using datatable with uppercase d .DataTable() ( this will return a Datatable API object ) use this :
oTable.search($(this).val()).draw() ;
which is #netbrain answer.
if you are using datatable with lowercase d .dataTable() ( this will return a jquery object ) use this :
oTable.fnFilter($(this).val());
You can use the sDom option for this.
Default with search input in its own div:
sDom: '<"search-box"r>lftip'
If you use jQuery UI (bjQueryUI set to true):
sDom: '<"search-box"r><"H"lf>t<"F"ip>'
The above will put the search/filtering input element into it's own div with a class named search-box that is outside of the actual table.
Even though it uses its special shorthand syntax it can actually take any HTML you throw at it.
For recent and new version of DataTables, You should follow these steps:
1- searching option must be true.
2- Hide default search input:
.dataTables_filter {
display: none;
}
3- Add new search input:
<input type="text" id="search">
4- Request search:
$('#search').keyup(function() {
var table = $('.table-meetups').DataTable();
table.search($(this).val()).draw();
});
This one helped me for DataTables Version 1.10.4, because its new API
var oTable = $('#myTable').DataTable();
$('#myInputTextField').keyup(function(){
oTable.search( $(this).val() ).draw();
})
I had the same problem.
I tried all alternatives posted, but no work, I used a way that is not right but it worked perfectly.
Example search input
<input id="searchInput" type="text">
the jquery code
$('#listingData').dataTable({
responsive: true,
"bFilter": true // show search input
});
$("#listingData_filter").addClass("hidden"); // hidden search input
$("#searchInput").on("input", function (e) {
e.preventDefault();
$('#listingData').DataTable().search($(this).val()).draw();
});
More recent versions have a different syntax:
var table = $('#example').DataTable();
// #myInput is a <input type="text"> element
$('#myInput').on('keyup change', function () {
table.search(this.value).draw();
});
Note that this example uses the variable table assigned when datatables is first initialised. If you don't have this variable available, simply use:
var table = $('#example').dataTable().api();
// #myInput is a <input type="text"> element
$('#myInput').on('keyup change', function () {
table.search(this.value).draw();
});
Since: DataTables 1.10
– Source: https://datatables.net/reference/api/search()
I want to add one more thing to the #netbrain's answer relevant in case you use server-side processing (see serverSide option).
Query throttling performed by default by datatables (see searchDelay option) does not apply to the .search() API call. You can get it back by using $.fn.dataTable.util.throttle() in the following way:
var table = $('#myTable').DataTable();
var search = $.fn.dataTable.util.throttle(
function(val) {
table.search(val).draw();
},
400 // Search delay in ms
);
$('#mySearchBox').keyup(function() {
search(this.value);
});
This should be work for you:(DataTables 1.10.7)
oTable = $('#myTable').dataTable();
$('#myInputTextField').on('keyup change', function(){
oTable.api().search($(this).val()).draw();
})
or
oTable = $('#myTable').DataTable();
$('#myInputTextField').on('keyup change', function(){
oTable.search($(this).val()).draw();
})
You could move the div when the table is drawn using the fnDrawCallback function.
$("#myTable").dataTable({
"fnDrawCallback": function (oSettings) {
$(".dataTables_filter").each(function () {
$(this).appendTo($(this).parent().siblings(".panel-body"));
});
}
});
$('#example').DataTable({
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": "../admin/ajax/loadtransajax.php",
"fnServerParams": function (aoData) {
// Initialize your variables here
// I have assign the textbox value for "text_min_val"
var min_val = $("#min").val(); //push to the aoData
aoData.push({name: "text_min_val", value:min_val});
},
"fnCreatedRow": function (nRow, aData, iDataIndex) {
$(nRow).attr('id', 'tr_' + aData[0]);
$(nRow).attr('name', 'tr_' + aData[0]);
$(nRow).attr('min', 'tr_' + aData[0]);
$(nRow).attr('max', 'tr_' + aData[0]);
}
});
In loadtransajax.php you may receive the get value:
if ($_GET['text_min_val']){
$sWhere = "WHERE (";
$sWhere .= " t_group_no LIKE '%" . mysql_real_escape_string($_GET['text_min_val']) . "%' ";
$sWhere .= ')';
}
If you are using JQuery dataTable so you need to just add "bFilter":true. This will display default search box outside table and its works dynamically..as per expected
$("#archivedAssignments").dataTable({
"sPaginationType": "full_numbers",
"bFilter":true,
"sPageFirst": false,
"sPageLast": false,
"oLanguage": {
"oPaginate": {
"sPrevious": "<< previous",
"sNext" : "Next >>",
"sFirst": "<<",
"sLast": ">>"
}
},
"bJQueryUI": false,
"bLengthChange": false,
"bInfo":false,
"bSortable":true
});
I have an ajax datatable for my SKUs. For this I am using the ajax-datatables-rails gem. Searcing and sorting works perfectly, but now I'm trying to add a filtering function to my table and it doesn't seem to do anything. I used this example for the filter function: https://datatables.net/examples/api/multi_filter_select.html.
In the example, select boxes are drawn in the footer, but for me the footer is empty. Like the code doesn't run at all. I also don't get any errors.
I initialize my datatable in my coffeescrip file (assets/javascripts/vendor_skus.js.coffee) so I had to translate it to coffeescript. I'm not experienced with coffeescript or using ajax with rails so I'm kind of lost as to what is going wrong.
How I solved my problem:
The standard select boxes were problematic for my situation, as I am using AJAX for my table and the select boxes seemed to only work properly on client side tables. Instead of going with the standard select boxes, I decided to make my own custom filters. These are regular select boxes like so:
<%= select_tag "store-id", options_from_collection_for_select(#stores, "id", "name"), include_blank: true, class:"store-id form-control" %>
<%= select_tag "status", options_for_select([ "Open", "On Hold", "Cancelled", "Closed", "Error" ]), include_blank: true, class:"form-control", multiple:true %>
This is my coffeescript to make jQuery submit the parameters to the server and reload the table onchange:
$ ->
$('#orders-table').DataTable
processing: true
serverSide: true
retrieve: true
pageLength: 50
title: 'orders'
lengthMenu: [[10, 25, 50, -1], [10, 25, 50, "All"]]
ajax: data: (d) ->
d.store_id = $('#store-id').val();
d.status = $('#status').val();
return
$ ->
$('#store-id').on 'change', ->
$('#orders-table').DataTable().ajax.reload()
return
$ ->
$('#status').on 'change', ->
$('#orders-table').DataTable().ajax.reload()
return
In your controller, make sure to pass the parameters along to Datatables like so:
respond_to do |format|
format.html
format.json { render json: OrderDatatable.new(view_context, { store_id: params[:store_id], status: params[:status] }) }
end
And then in your Datatable file, use the parameters to filter your results. In this case I am using a multi select for status, so when the blank value is selected, params[:status].present? results in true. That's why I added a check to see if the first item is an empty string.
def get_raw_records
# insert query here
query = Order.all
query = query.status(params[:status]) if params[:status].present? && (params[:status].count == 1 && params[:status][0] == "") == false
query = query.store(params[:store_id]) if params[:store_id].present?
query.joins(:store)
end
I ran into the same issue when implementing this. I found out that the issue was with this line:
column.search((if val then '^' + val + '$' else ''), true, false).draw()
where coffee script did not like the following bit:
, true, false
After removing it like so:
column.search(if val then '^' + val + '$' else '').draw()
everything worked fine. The caveat to this is, I am not a javascript/coffeescript guy, so what negative impact the result does is beyond me. But like you I am currently battling to get all results to appear in the selectable drop down filter. It only shows any unique values from the current page of data - which is not helpful.
FYI, to get pagination working on this, go to your datatable.rb file and uncomment the correct line toward the top that refers to the pagination you're using. I am using "will_paginate" for bootstrap, so mine looked like this:
include AjaxDatatablesRails::Extensions::WillPaginate
Hope that helps. By chance, did you find a way to show all results in the select filter?
My working code for an ajax datatable filter using the ajax-datatables-rails gem.
in the datatable view I created a table above the datatable to input the range variables, then add some javascript to reload the datatable on change:
<table>
<tbody><tr>
<td>Minimum CWD:</td>
<td><input type="text" id="minCWD" name="minCWD"></td>
</tr>
<tr>
<td>Maximum CWD:</td>
<td><input type="text" id="maxCWD" name="maxCWD"></td>
</tr>
</tbody></table>
<script>
$(document).ready(function () {
// other options
var table = $('#example').DataTable()
$("#minCWD").change(function () {
table.ajax.reload();
});
$("#maxCWD").change(function() {
table.ajax.reload();
});
});
</script>
then to add the filter variables to the ajax call (in the coffee file):
ajax: {
url: $('#example').data('source'),
beforeSend: (xhr) => xhr.setRequestHeader('Content-Type', 'application/json'),
data: (d) ->
$.extend {}, d, 'minCWD': $('#minCWD').val(),
$.extend {}, d, 'maxCWD': $('#maxCWD').val()
}
// note: the beforeSend may not be required
then add a filter in the model_datatable.rb:
def get_raw_records
#YOUR TYPICAL SELECTION...note: I'm using AREL and joining schools with pstats
#now filter by your max min variables
if params['minCWD'].present?
schools = schools.where(pstats[:cwd_percent].gteq(params['minCWD']))
end
if params['maxCWD'].present?
schools = schools.where(pstats[:cwd_percent].lteq(params['maxCWD']))
end
return schools
end
My controller looks like this:
respond_to do |format|
format.html
format.json { render json: ExampleDatatable.new(params, view_context: view_context) }
end
working example here: https://schoolsparrow.com/arizona/schools
I am creating a jqgrid i m creating a row with 2 columns with dropdown box. The dropdowns are getting populated using ajax call. My requirement is I want to replicate this row on click on ADD button in UI. For example for now one row is coming into jqgrid, after clicking ADD button a new row with same content with out refreshing the changed value in first row should be displayed. Is there any way to do that? My jqgrid code is
$("#tbl").jqGrid('GridUnload');
$("#tbl").jqGrid(
{
url : "/searchCriteria.do",
datatype : 'json',
colModel :
[
{name : "test1",label : "TEST1", search : false,cellEdit:true, editable: true,edittype:"select",width:150 ,formatter: createDropDown,title:false},
{name : "test2",label : "TEST2", search : false,cellEdit:true, editable: true,edittype:"select",width:150 ,formatter: createDropDown,title:false}
],
viewrecords: true,
loadonce:true,
width: 1000,
multiselect : true
});
});
You can use a combination of the getLocalRow and addRowData methods to achieve your functionality. Docs for these methods.
Let's say in your HTML you have a button:
<button id="add" type="button">ADD</button>
In your javascript you could have:
<script>
$("#add").click(function(){
var id_of_new_row = something; //you haven't specified which are the exact rows you'd like selected.
//you could use the getDataIDs method to get the row-IDs you're looking for
var new_row_data = $("#gridId").jqGrid('getLocalRow', id_of_new_row));
$("#gridId").jqGrid('addRowData',id_of_new_row+1, new_row_data, "last");
});
</script>
I have the following html rendered from templating (jsRender)
<div class="noteActions top" style="z-index: 3;">
<span onclick="noteAction('add', 13808, 0 );"></span>
<span onclick="noteAction('update',13808, 106344 );"></span>
<span onclick="noteAction('delete', 13808, 106344 );"></span>
</div>
My issue is I have a function outside the document ready that is setting a data array that later, a jquery dialog window submits via ajax to the handler to update the database
What's happening is the data array correctly passes everything except the jquery vals by class selector (pr-body, pr-title), they pass as NULL
javascript - outside document (ready)
var updateUrl = 'handlers/Poster.ashx',
data;
function noteAction(action, prospectID, noteID){
data = {
'operation': action,
'prospectid':prospectID,
'note-body' : $('.pr-body').val(),
'note-title' : $('.pr-title').val(),
'note-id':noteID,
};
if (action == 'add'){
$( "#dialogPostIt" ).dialog("open", "option", "title", "Add Post It");
} else if (action == 'update'){
$( "#dialogPostIt" ).dialog("open", "option", "title", "Edit Post It");
} else if (action == 'delete'){
if (!confirm('Are you sure you want to delete')) return false;
$.post(updateUrl+"?operation=delete¬eid="+noteID, function(data) {
$('#stickyNote-'+noteID).remove();
});
}
}
jquery - document ready
$(document).ready(function() {
$( "#dialogPostIt" ).dialog({autoOpen: false, modal:true,
buttons: {
'Save': function() {
$.ajax({
url: updateUrl,
data: data,
success: function(json, textStatus, jqXHR){
.....
html
<div id="dialogPostIt" >
<form id="postItNow" action="" method="post" class="note-form">
<label for="note-title">Title (description)</label>
<input type="text" name="note-title" id="note-title" class="pr-title" value="" />
<label for="note-body">Text of the note</label>
<textarea name="note-body" id="note-body" class="pr-body" cols="30" rows="6"> </textarea>
</form></div>
I previously was setting the data array inside the dialog save button function(), which worked fine, but I needed to make some of the array elements dynamic based on event
The array doesnt have to be global from my requirements, i just couldnt think of another way todo this
As Always, any help is greatly appreciated
Well, i feel like a real dope, it actually is working fine, issue was pilot error -_-
The data array was returning the values correctly, problem is there was no values yet , as the data was set prior to the subsequent dialog containing the form, so no form vals couldve been filled in yet
the fix
javascript outside the document ready
function noteAction(action, prospectID, noteID){
data = {
'operation': action,
'prospectid':prospectID,
'notebody' : '',
'notetitle' : '',
'noteid':noteID,
};
jquery in dialog (document ready)
$( "#dialogPostIt" ).dialog({autoOpen: false, modal:true,
buttons: {
'Save': function() {
data.notebody = $('.pr-body').val();
data.notetitle= $('.pr-title').val(),
$.ajax({
url: updateUrl,
data: data,
HI,
I'm looking at SlickGrid and I can see example on how to edit the cell, however do I save these changes. I have yet to find an example that tells me how to do this.
The trick to saving the SlickGrid is to realise that the grid will update the array of data that you supplied when creating the grid as the cells are edited.
The way I then save that is to include a form with a submit button and a hidden field below the grid. I trap the submit event and use the JSON plugin to serialise the array and place it in the hidden field. On the server side you'll receive a JSON string which you can deserialise, loop through and write to the database.
Assuming your array of data is called "data" like the samples, the following should work for you:
<form action="?" method="POST">
<input type="submit" value="Save">
<input type="hidden" name="data" value="">
</form>
<script>
$(function() {
$("form").submit(
function() {
$("input[name='data']").val($.JSON.encode(data));
}
);
});
</script>
For completeness, a minimal example demonstrating the usage of onCellChange, referred to in Jim OHalloran's post.
For more information, and to see all events that can be utilized similarly to onCellChange, see comments at the beginning of the SlickGrid source.
<head>
<!-- boilerplate omitted ... -->
<script type="text/javascript">
var grid;
var options = {
enableCellNavigation: true,
enableColumnReorder: false,
autoEdit: false,
editable: true,
};
var columns = [
{id: "item_key", name: "Key", field: "item_key" },
{id: "value", name: "value", field: "value", editor: LongTextCellEditor }
];
var data = [
{item_key: "item1", value: "val1"},
{item_key: "item2", value: "val2"},
];
$(document).ready(function () {
grid = new Slick.Grid($("#myGrid"), data, columns, options);
//Earlier code for earlier version of slickgrid
// grid.onCellChange = function (currentRow, currentCell, item) {
// alert(currentRow+":"+currentCell+"> key="+item['item_key']+", value="+item['value']);
//Updated code as per comment.
grid.onCellChange.subscribe(function (e,args) {
console.log(args);
});
};
});
</script>
</head>
<body>
<div id="myGrid" style="height:10em;"> </div>
</body>
While I'm personally using the JSON serialize and submit in a hidden field approach from my previous answer another approach could be to trap the onCellChange event fired by SlickGrid after a cell value has changed and make an Ajax call to the server to save the changed value. This will result in lots of small Ajax requests to the server (which may increase load) but updates the server as soon as changes are made.