I have a modal that displays a table. And I use datatable plugin so that the data is searchable and sortable. It works properly at first but when I close the modal and click other link to the same modal, it displays error. I have found solution to destroy the DataTable and I put the destroy() before the initialization of the datatable but then no data is displayed inside the table.. if I put it after the initialization it gave me the initialization error the second time I click the button. How am I going to solve this?
here's my code:
$.ajax({
url: "<?php echo site_url('admin/group/getMember')?>",
type: 'POST',
data: { 'groupID': id},
dataType: 'JSON',
success: function(result){
$('#records_table tbody').empty();
// $('#records_table').DataTable({
// "bLengthChange": false,
// "paging":false,
// });
$('.modal-header #hdrmsg').text(result[0].fname);
var trHTML='';
$.each(result, function (i, item) {
trHTML += '<tr><td>' + item.fname + '</td><td>' + item.mname + '</td><td>' + item.lname + '</td></tr>';
});
$('#records_table tbody').append(trHTML);
$('#records_table').DataTable({
"bLengthChange": false,
"paging":false,
});
$('#records_table').DataTable().fnDestroy();
}
});
The main reason for destroying a dataTables instance is if you want to change the initialisation options - like change paging and so on. Or if the table structure should be altered. None of those circumstances seems to be the case here? To answer the question, the safest way to destroy and reinitialise a table is to use the shorthand option destroy: true :
var table = $('#records_table').DataTable({
...
destroy : true
});
To go further, I think you are doing it a little backwards.
Why empty the table with jQuery $('#records_table tbody').empty(); instead of table.clear() ?
Why inject records with jQuery $('#records_table tbody').append(trHTML); instead of using table.row.add([...]) ?
Here is a code scenario similar to the one in the question, which reinitialises the dataTable without conflicts, each time the modal is shown :
var table;
$('#modal').on('show.bs.modal', function() {
$.ajax({
url: url,
dataType: 'JSON',
success: function(response) {
var response = $.parseJSON(response.contents);
//clear the table, if it exists
if (table) table.clear();
//reinitialise the dataTable
table = $('#records_table').DataTable({
destroy: true,
bLengthChange: false,
paging: false
});
$.each(response, function(i, item) {
console.log("inserting", item);
table.row.add([
item.name,
item.position
]).draw();
});
}
});
});
see demo -> http://jsfiddle.net/bz958dxj/
But you really dont need to destroy the table at all, it just slows down performance :
//global table object
table = $('#records_table').DataTable({
bLengthChange: false,
paging: false
});
$('#modal').on('show.bs.modal', function() {
$.ajax({
url: url,
dataType: 'JSON',
success: function(response) {
var response = $.parseJSON(response.contents);
//clear the table
table.clear();
//insert data
$.each(response, function(i, item) {
console.log("inserting", item);
table.row.add([
item.name,
item.position
]).draw();
});
}
});
});
demo -> http://jsfiddle.net/8mjke9ua/
NB: I just assume we are talking about bootstrap modals, based on the reference to .modal-header in the question.
NBĀ²: Notice the $.parseJSON(response.contents), you should do it as you are doing it in the question. The only reason for this is that the examples go trough a proxy to avoid the same-origin policy.
Related
I have a question, that I can't seem to find the 'best' solution for my question.. I have an AJAX call that displays data in the DOM, via jQuery.
JSON
[{
"id":"123"
},
{ "id":"456"
}]
JS
$(document).ready(function() {
$.ajax({
url: 'get/data',
dataType: 'json',
data: '{}',
success: function(data) {
var html = '';
$.each(data, function(i) {
html += '<p>My ID: ' + data[i].id + '</p>';
}
$('#id').append(html);
},
error: function(err) {
console.log(err);
}
})
});
As you can see I am displaying that data here. I would like to pass that ID to another AJAX call by selecting a checkbox and pushing a button or perhaps clicking a link. Whats the best way to accomplish this?
EDIT: I apologize, my actual issue is related to array data. I have updated the code. I am displaying an JSON array in the html now, and I want to pass the id of the user/row that I click?
Thanks,
Andy
$(document).ready(function() {
var resid;
$.ajax({
url: 'get/data',
dataType: 'json',
data: '{}',
success: function(data) {
resid = data.id;
var html = '';
html += '<p>My ID: ' + data.id + '</p>'; $('#id').append(html);
},
error: function(err){
console.log(err);
}
});
$('link').click(function () {
// pass id to second ajax
});
});
try jquery-template
https://github.com/codepb/jquery-template
hope help you
I am using this Image Picker jQuery plugin (http://rvera.github.io/image-picker/) and I'm facing a problem with the following:
Repopulating the select control with new data after ajax call.
$.ajax({
type: "GET",
url: requestURL,
dataType: 'json',
success: function(result)
{
$.each(result, function(i, obj) {
console.log(obj.description);
$('#cake-filling-types-select')
.append($("<option data-img-src='" + obj.image + "'></option>")
.attr("value", obj.code)
.text(obj.description));
});
$("#cake-filling-types-select").imagepicker({
show_label : true
});
$("#cake-filling-types-select").data("picker").sync_picker_with_select();
}});
For more details please find the issue here: https://github.com/rvera/image-picker/issues/79
Thanks.
The issue is solved. With the help of #ArmindoMaurits # GitHub, so using the ' $("#cake-filling-types-select").empty();' is fine for clearing this plugin select.
Also, for the other issue where some items are not getting into the select control, I found that these the ones that is missing the img src.
Updated working code:
`$.ajax({
type: "GET",
url: requestURL,
dataType: 'json',
success: function(result){
$("#cake-filling-types-select").empty();
$.each(result, function(i, obj) {
if(obj.image != null)
{
var imgSrc = obj.image;
}else{
imgSrc = '';
}
$('#cake-filling-types-select')
.append($("<option data-img-src='" + imgSrc + "'></option>")
.attr("value", obj.code)
.text(obj.description));
});
$("#cake-filling-types-select").imagepicker({
show_label : true
});
}});`
I am populating some data from a webservice in a span element. The data which I am getting from the webservices is first adding in a table and then adding that table in the Span element. The table is adding initially in the Span element but after loading it disappeared certainly.In the code snippet I am giving below it is the Span element is giving desired outcome till 'second alert' but after that it is getting disappeared.
$.ajax({
cache: false,
type: "GET",
async: false,
url: GetAStudent + "(" + nextStudentID + ")",
dataType: "json",
success: function (student) {
jPendingStudent = student;
nextStudentID++;
//debugger;
var table = makeTable(student);
$("#spanStudentList").html("").append(table);
alert("span 1 created");
//$("#divNewStudent").css("visibility", "visible");
//$("#divNewStudent").visible();
$("#divNewStudent").show();
alert("span2 created");
//return false;
},
I try to get several series of data from employees and get them drawed through HighCharts.
I don't know the company till the user click, so then I get trough ajax all the employees and their data (points).
I have a select box where I choose the company. Once done, I call via AJAX/jQuery the server to get data added to HighChart:
$("#company").change(function(){
$.ajax({
type: 'POST',
dataType: 'json',
url: xxxxx,
async: false,
data: { company: company},
success: function(data) {
$.each(data, function(val, text) {
alert (val);
alert (text);
chart2.addSeries({
name: val,
data: text
});
});
}
...
Data I get from the server trough Firebug is in this way:
{"Employee1":[["1356908400000","10.00"],["1359586800000","11.00"], ["1362006000000","12.00"],["1364684400000","13.45"]],"Employee2":[["1356908400000","10.00"],["1359586800000","11.00"],["1362006000000","12.00"],["1364684400000","13.45"]]}
Employee1 and Employee2 should be the series.
However when I call addseries method I get this error:
Uncaught Highcharts error #14: www.highcharts.com/errors/14
It seems data doesn't like to Highcharts.
When I debug through alerts, I get this:
alert (val)->Employee1
alert (text)=1356908400000,10.00,1359586800000,11.00,1362006000000,12.00,1364684400000,13.45
This example is working fine when I put data without ajax.
Any idea?
I've found the answer :-)
text is an array so I need another $.each to read it and format the result:
success: function(data) {
$("html").css('cursor','auto');
$.each(data, function(val, text) {
counter = 0;
$.each(text, function() {
if (counter==0) {
employee_data= "[" + this + "]";
}
else{
employee_data= employee_data + "," + "[" + this + "]";
}
counter=1
});
employee_data = "["+ + "]";
chart.addSeries({
name: val,
data: employee_data
});
});
},
I'm trying to convert some of my code to reusable plugins.
Many times I'm filling selects with dynamic options that comes from Ajax request.
I've managed to create something like this:
$.fn.fillSelect = function fillSelect(options) {
var self = this;
options = $.extend({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "Data.asmx/StatusList",
dataType: "json",
async: true,
success: function(data) {
var list = "";
$.each(data.d, function(i) {
list += '<option value='
+ data.d[i].ID + '>'
+ data.d[i].Nazwa
+ '</option>';
});
self.filter("select").each(function() {
$(this).empty();
$(this).append(list);
//use selectmenu
if ($.ui.selectmenu) $(this).selectmenu();
});
}//,
//error: function(result) {
// alert("Error loading data!");
//}
}, options);
$.ajax(options);
return self;
}
Idea behind this is to be able to fill multiple selects with the same data multiple times with one request.
I have default options for Ajax request, but I would like to add some more options to it.
For example:
clear - fill determinate if I want new options to replace existing ones or append.
Also I would like to add some callbacks to my function that I could pass as parameters.
If for example server request will fail I would like to specify a function that will be called after this error occurs - for example to show alert or disable my selects.
My question is how should I change my plugin or which pattern (boilerplate) I should use?
Every boilerplate I found is for creating plugins that will 'stay' inside selected item, so that it is possible to call method of that plugin later.
I need a simple plugin that will allow user to fill select and then it will end it's life :)
My main idea is to do only one request to server for all elements.
Here is jsfiddle demo: http://jsfiddle.net/JC7vX/2/
A basic plugin can be built as follows
(function ($){
$.fn.yourPlugin = function (options){
// this ensures that function chaining can continue
return this.each(function (){
// merge defaults and user defined options
var params = $.extend({},defaultOptions,options);
// your plugin code
});
}
/* these options will help define the standard functionality of the plugin,
* and also serves as a nice reference
*/
var defaultOptions = {
someProperty : true
}
})(jQuery)
There are other things that you can do to extend the functionality of your plugin and give public methods that retain the context, but that would be overkill for your example.
This is my version of answer http://jsfiddle.net/Misiu/ncWEw/
My plugin looks like this:
(function($) {
$.fn.ajaxSelect = function(options) {
var $this = this;
//options
var settings = $.extend({}, defaults, options);
//disable select
if ($.ui.selectmenu && settings.selectmenu && settings.disableOnLoad) {
$this.selectmenu('disable');
}
//ajax call
$.ajax({
type: settings.type,
contentType: settings.contentType,
url: settings.url,
dataType: settings.dataType,
data: settings.data
}).done(function(data) {
var n = data.d || data;
var list = "";
$.each(n, function(i) {
list += '<option value=' + n[i].Id + '>' + n[i].Nazwa + '</option>';
});
$this.filter("select").each(function() {
$(this).empty();
$(this).append(list);
if ($.ui.selectmenu && settings.selectmenu) {
$this.selectmenu();
}
settings.success.call(this);
});
}).fail(function() {
settings.error.call(this);
});
return this;
};
var defaults = {
type: "POST",
contentType: "application/json; charset=utf-8",
url: '/echo/json/',
dataType: 'json',
data: null,
async: true,
selectmenu: true,
disableOnLoad: true,
success: function() {},
error: function() {}
};
})(jQuery);
I understand that it is very simple, but it has all functionality that I needed:
-You can select multiple elements at one time
-It filters only selects from Your selected items
-It makes only one request to server
-First it builds option string and then append it instead of adding items in loop
-You can specify 2 callbacks: one for error and second for success
And it is my first plugin, so there is much places for improvements.
As always comments and hints are welcome!