Adjusting columns of jQuery Datatables - javascript

I know this was already asked but I still cannot sort it out.
Due to app architecture, I have a datatable inside a modal.
This datatable is initialized once at page load (with no data), put inside the modal in the DOM, which is hidden, with no width and height.
Every time the modal is opened, the underlying data are reloaded with
$('#datatable').DataTable().ajax.reload()
The problem is that, when opening the modal, the columns layout is not right. The columns are thin and they don't take all the space of the modal.
I read that I should call
$('#datatable').DataTable().columns.adjust();
$('#datatable').DataTable().responsive.recalc();
to re-adjust columns width, but nothing happens.
index.html
<link href="/materialize.min.css" type="text/css" rel="stylesheet" media="screen,projection"/>
<link href="/datatables.min.css" type="text/css" rel="stylesheet" media="screen,projection"/>
</head>
<body>
<button id="button">Open</button>
<div id="modal-bom" class="modal">
<div class="modal-content">
<table class="striped" id="table">
<thead>
<tr>
<th>Position</th>
<th>Code</th>
<th>Description</th>
<th>Quantiy</th>
</tr>
</thead>
</table>
</div>
</div>
<script src="/jquery-3.4.1.min.js"></script>
<script src="/materialize.min.js"></script>
<script src="/datatables.min.js"></script>
<script src="/mainApp.js"></script>
</body>
</html>
mainApp.js
var initialized = false;
$(document).ready(() => {
$('#button').click(() => {
$('#modal-bom').modal({
onOpenEnd: () => {
$('#table').DataTable().ajax.reload(() => {
$('#table').DataTable().columns.adjust();
$('#table').DataTable().responsive.recalc();
});
},
});
$('#modal-bom').modal('open');
});
$('#table').DataTable({
ajax: (dataToSend, callback) => {
loadData().then((dataReceived) => {
callback(dataReceived);
});
},
columns: [
{ data: 'position' },
{ data: 'code' },
{ data: 'description' },
{ data: 'qty' }
],
initComplete: () => initialized = true
});
});
function loadData() {
return new Promise((resolve) => {
if (!initialized) {
resolve({ data: {} });
}
else {
$.ajax({
url: 'http://127.0.0.1:5500/data.txt',
method: "GET",
dataType: 'json',
success: json => resolve({ data: json.data })
});
}
});
}
data.txt
{"data": [
{
"level": 0,
"position": "1",
"code": "ART001",
"description": "Article one description",
"qty": "1"
},
{
"level": 1,
"position": "1.1",
"code": "ART002",
"description": "Article two description",
"qty": "10"
},
{
"level": 1,
"position": "1.2",
"code": "ART003",
"description": "Article three description",
"qty": "1"
},
{
"level": 2,
"position": "1.2.1",
"code": "ART004",
"description": "Article four description",
"qty": "2"
},
{
"level": 2,
"position": "1.2.2",
"code": "ART005",
"description": "Article five description",
"qty": "15"
},
{
"level": 3,
"position": "1.2.2.1",
"code": "ART006",
"description": "Article six description",
"qty": "5"
},
{
"level": 2,
"position": "1.2.3",
"code": "ART007",
"description": "Article seven description",
"qty": "4"
},
{
"level": 1,
"position": "1.3",
"code": "ART008",
"description": "Article eight description",
"qty": "1"
}
]}
What else should I try?
Thank you for any help

Inside your onOpenEnd option, instead of
$('#table').DataTable().columns.adjust();
Try
$('#table1').DataTable().columns.adjust().draw();
This was what allowed my tables to redraw its columns whenever the modal is opened.

This code below will detect Bootstrap modal and adjust the table.
$('#modal-id').on('shown.bs.modal', function () {
var table = $('#table-id').DataTable();
table.columns.adjust();
//// if the above code is not working set width:100% to a table
$('.dataTables_scrollHeadInner, .dataTable').css({'width':'100%'})
});

Related

Search a word in select2

I have an ajax result as follow:
{
"data": [
{
"id": "AABB",
"text": "AABB"
},
{
"id": "BBCC",
"text": "BBCC"
},
{
"id": "CCDD",
"text": "CCDD"
},
{
"id": "DDEE",
"text": "DDEE"
}
]
}
by that I load it to select2 using ajax below:
$("#timezone").select2({
ajax: {
url: "/User/Timezone",
dataType: 'json',
delay: 250,
type: 'GET',
data: function (params) {
return {
q: params.term, // search term
};
},
processResults: function (data) {
var arr = []
$.each(data, function (index, value) {
arr.push({
id: value.id,
text: value.text
})
})
return {
results: arr
};
},
cache: true
},
escapeMarkup: function (markup) { return markup; },
minimumInputLength: 3,
minimumResultsForSearch: 20
})
I try to search the word CCD, of course I expect the pointer brings me to the CCDD line, but it keeps staying on the first data, did I miss something?
It seems I can't reproduce it, it should not show results that do not match your input.
$("#timezone").select2({
data: [{
"id": "AABB",
"text": "AABB"
},
{
"id": "BBCC",
"text": "BBCC"
},
{
"id": "CCDD",
"text": "CCDD"
},
{
"id": "DDEE",
"text": "DDEE"
},
{
"id": "AABB1",
"text": "AABB1"
},
{
"id": "BBCC1",
"text": "BBCC1"
},
{
"id": "CCDD1",
"text": "CCDD1"
},
{
"id": "DDEE1",
"text": "DDEE1"
},
{
"id": "AABB2",
"text": "AABB2"
},
{
"id": "BBCC2",
"text": "BBCC2"
},
{
"id": "CCDD2",
"text": "CCDD2"
},
{
"id": "DDEE2",
"text": "DDEE2"
},
{
"id": "AABB3",
"text": "AABB3"
},
{
"id": "BBCC3",
"text": "BBCC3"
},
{
"id": "CCDD3",
"text": "CCDD3"
},
{
"id": "DDEE3",
"text": "DDEE3"
}
],
escapeMarkup: function(markup) {
return markup;
},
minimumInputLength: 3,
minimumResultsForSearch: 20
})
select {
width: 200px;
}
<select id="timezone"></select>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/select2#4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/select2#4.1.0-rc.0/dist/js/select2.min.js"></script>

Getting next and previous element of json array

I need help with my code. I want to have a previous and a next button, these will call a function viewBlogItem(direction,cat,blogid);
in that function i'll be reading out the json file, categorizing by the "category".
Every blogItem has a articleid and a category, if click the next button I want to have the next blogItem.articleid and have that one shown (I use append for that one). If the direction == "next", then it look if it has a next item in category, if not then hide $('.next'). Same goes for previous button $('.previous')
blogItems.json
{
"blogItem":[
{
"id": 1,
"title": "animals blog 1",
"category":"animals",
"text":"text",
"articleid":1
},
{
"id": 2,
"title": "lifestyle blog 1",
"category":"lifestyle",
"text":"text",
"articleid": 1
},
{
"id": 3,
"title": "animals blog 2",
"category":"animals",
"text":"text",
"articleid": 2
},
{
"id": 5,
"title": "animals blog 4",
"category":"dieren",
"text":"text",
"articleid":4
},
{
"id": 4,
"title": "animals blog 5",
"category":"animals",
"text":"text",
"articleid":3
}
]
}
jquery
function viewBlogItem(direction,cat,blogid) {
var id = "";
if(direction == "next"){
// code for showing next blogitem
//if no next then
$('').hide();
}
else{
// if no previous then hide
//code for showing previous blogitem
}
loadBlog(id);
}
function loadBlog(blogid){
$.getJSON('blogitems.json', function (data) {
$.each(data.blogItem, function (i, item) {
if (item.id == blogid) {
$('.view').append('all sorts of stuff');
return;
}
});
});
}
I would also like to have some suggestions for the structure my json.
How can I tell that there ain't another blog after or previous?
Look at the index of the current blog item and see if the next one is bigger than than the number of items in the array or if the previous one is less than 0.
var blogs = {
"blogItem": [{
"id": 1,
"title": "animals blog 1",
"category": "animals",
"text": "text",
"articleid": 1
}, {
"id": 2,
"title": "lifestyle blog 1",
"category": "lifestyle",
"text": "text",
"articleid": 1
}, {
"id": 3,
"title": "animals blog 2",
"category": "animals",
"text": "text",
"articleid": 2
}, {
"id": 5,
"title": "animals blog 4",
"category": "dieren",
"text": "text",
"articleid": 4
}, {
"id": 4,
"title": "animals blog 5",
"category": "animals",
"text": "text",
"articleid": 3
}]
};
var index = 0;
var item = blogs.blogItem[index];
var title = document.getElementById('title');
var text = document.getElementById('text');
var previous = document.getElementById('previous');
var next = document.getElementById('next');
displayItem(item);
previous.addEventListener('click', function() {
displayItem(blogs.blogItem[--index]);
});
next.addEventListener('click', function() {
displayItem(blogs.blogItem[++index]);
});
function displayItem(item) {
title.innerText = item.title;
text.innerText = item.text;
previous.disabled = index <= 0;
next.disabled = index >= blogs.blogItem.length -1;
}
[disabled] {
opacity: 0.5;
}
<link href="//cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css" rel="stylesheet"/>
<div class="container">
<div>
<div id="title"></div>
<div id="text"></div>
</div>
<button id="previous">Previous</button>
<button id="next">Next</button>
</div>

Why tree view not rendered in div is it DOM element positioning error?

I am trying to render a tree with certain childs in a div using javascript and html. I am wondering why it is not rendering given all the objects are created and everything is fine in read of tree and parent
from Json (see "data" in my code).
NOTE:I have Layout.cshtml and it shares the top most menu which is "Application Name" at the top and is like this http://prntscr.com/7czhas
Could some one please let me know why tree don't appear in my div with ID:jqxTree
My code is 2nd edit:
I am trying to render a tree with certain childs in a div using javascript and html. I am wondering why it is not rendering given all the objects are created and everything is fine in read of tree and parent
from Json (see "data" in my code).
Could some one please let me know why tree don't appear in my div with ID:jqxTree
My code is 2nd edit:
#{
ViewBag.Title = "TreeCreation";
}
<h2>TreeCreation</h2>
<head>
<title></title>
<script src="~/bootstrap/js/LiveMap/Ajax/JsonStringCarryingData/jqx-all.js"></script>
<link href="~/bootstrap/css/LiveMap/jqx.base.css" rel="stylesheet" />
<link href="~/bootstrap/css/LiveMap/jqx.energyblue.css" rel="stylesheet" />
</head>
<body>
<div id='jqxTree' style="background-color:green; height:400px;width:200px;">
</div>
<script type="text/javascript">
var data = [
{
"text": "Chocolate Beverage",
"id": "1",
"parentid": "-1"
}, {
"id": "2",
"parentid": "1",
"text": "Hot Chocolate"
}, {
"id": "3",
"parentid": "1",
"text": "Peppermint Hot Chocolate"
}, {
"id": "4",
"parentid": "1",
"text": "Salted Caramel Hot Chocolate"
}, {
"id": "5",
"parentid": "1",
"text": "White Hot Chocolate"
}, {
"id": "6",
"text": "Espresso Beverage",
"parentid": "-1"
}, {
"id": "7",
"parentid": "6",
"text": "Caffe Americano"
}, {
"id": "8",
"text": "Caffe Latte",
"parentid": "6"
}, {
"id": "9",
"text": "Caffe Mocha",
"parentid": "6"
}, {
"id": "10",
"text": "Cappuccino",
"parentid": "6"
}, {
"id": "11",
"text": "Pumpkin Spice Latte",
"parentid": "6"
}, {
"id": "12",
"text": "Frappuccino",
"parentid": "-1"
}, {
"id": "13",
"text": "Caffe Vanilla Frappuccino",
"parentid": "12"
}, {
"id": "15",
"text": "450 calories",
"parentid": "13"
}, {
"id": "16",
"text": "16g fat",
"parentid": "13"
}, {
"id": "17",
"text": "13g protein",
"parentid": "13"
}, {
"id": "14",
"text": "Caffe Vanilla Frappuccino Light",
"parentid": "12"
}]
function run() {
// alert('Inside buidldata');
var source = [];
var items = [];
// build hierarchical source.
alert('data length:' + data.length);
for (i = 0; i < data.length; i++) {
var item = data[i];
var label = item["text"];
var parentid = item["parentid"];
var id = item["id"];
if (items[parentid]) {
var item = { parentid: parentid, label: label, item: item };
if (!items[parentid].items) {
items[parentid].items = [];
}
items[parentid].items[items[parentid].items.length] = item;
items[id] = item;
}
else {
items[id] = { parentid: parentid, label: label, item: item };
source[id] = items[id];
}
}
return source;
}
// create jqxTree
var source = run();
alert('source:' + source);
$('#jqxTree').jqxTree(
{
source: source, width: '350px'
});
</script>
</body>
It also gives 2 errors http://prntscr.com/7czj92 and it makes me feel that there is some problem in this jqx-all.js file which i copy and pasted from the link http://jqwidgets.com/public/jqwidgets/jqx-all.js . Please help me i am stuck here since last 4 days
Add reference to the required js files.
i.e http://jqwidgets.com/public/jqwidgets/jqx-all.js - Will contain the source for all jq widgets.
The files required are jqx-all.js, jqx.base.css and jqx.energyblue.css.
Add reference to the files as shown below.
<script type='text/javascript' src="jqx-all.js"></script>
<link rel="stylesheet" type='text/css' href='jqx.base.css'>
<link rel="stylesheet" type='text/css' href='jqx.energyblue.css'>
Note : The above code is assuming that the required files are in the same folder as the current html.
If you are using only jqxtree, get the specific files from the vendor.
Please refer the working fiddle here http://jsfiddle.net/sherin81/ccegq/274/
The external resources section on the left pane will show you the references required to run the code.

jQuery UI Autocomplete - accessing nested objects in JSON

I'm trying to use the jQuery UI Autocomplete widget with a custom JSON feed I'm getting back from an API, which is formatted as follows:
{
"SearchTerm": "ches",
"HasDirectCountyHit": false,
"DirectCountyHitId": null,
"HasDirectLocationHit": false,
"DirectLocationHitId": null,
"Developments": [
{
"Id": "45339ae3e55a",
"Label": "Chestnut Walk, Bilston",
"Url": "/developments/chestnut-walk-bilston"
},
{
"Id": "4835f52e053a",
"Label": "Crown Park, Chester",
"Url": "/developments/crown-park-chester"
},
{
"Id": "757964964cc6",
"Label": "The Birches, West Timperley",
"Url": "/developments/the-birches-west-timperley"
}
],
"Counties": [
{
"Id": "7",
"Label": "Cheshire",
"Url": "/search?cid=7"
},
{
"Id": "24",
"Label": "Greater Manchester",
"Url": "/search?cid=24"
}
],
"Locations": [
{
"Id": "12061",
"Label": "Cheselbourne, Dorset (DT2 7)",
"Url": "/search?lid=12061"
},
{
"Id": "12062",
"Label": "Chesham, Buckinghamshire (HP5 1)",
"Url": "/search?lid=12062"
},
{
"Id": "12063",
"Label": "Chesham, Greater Manchester (BL9 6)",
"Url": "/search?lid=12063"
},
{
"Id": "12064",
"Label": "Chesham Bois, Buckinghamshire (HP6 5)",
"Url": "/search?lid=12064"
},
{
"Id": "12065",
"Label": "Cheshunt, Hertfordshire (EN8 9)",
"Url": "/search?lid=12065"
},
{
"Id": "12066",
"Label": "Chesley, Kent (ME9 7)",
"Url": "/search?lid=12066"
},
{
"Id": "12067",
"Label": "Cheslyn Hay, Staffordshire (WS6 7)",
"Url": "/search?lid=12067"
},
{
"Id": "12068",
"Label": "Chessetts Wood, Warwickshire (B94 6)",
"Url": "/search?lid=12068"
},
{
"Id": "12069",
"Label": "Chessington, Kingston upon Thames - Greater London (KT9 2)",
"Url": "/search?lid=12069"
},
{
"Id": "12070",
"Label": "Chessmount, Buckinghamshire (HP5 1)",
"Url": "/search?lid=12070"
}
]
}
The API I'm calling returns results based on my search term, so I know that all of the results in the nested objects are matches - my problem is how to access these objects ('Developments', 'Counties' and 'Locations') so that the autocomplete widget can pick up the 'Label' values?
Thanks,
Robin
Ok - here's what you can do:
//put all the keys you want to pull out of your json in an array
var props = [
"Locations", "Counties", "Developments"
];
//empty array for your autocomplete
var labels = [];
//loop thru all the properties you care about
$.each(props, function () {
$.each(source[this], function () {
//and pull out all the labels and add them to the labels array
labels.push(this.Label)
});
});
$("#autocomplete").autocomplete({
source: labels
});
and to see it all in action I created a quick fiddle
http://jsfiddle.net/fr5yb3n0/

jQuery UI autocomplete is not working

This is my JavaScript code:
<script type="text/javascript">
//<![CDATA[
$(document).ready(function() {
$("input#suggestZams").autocomplete({
source: "content/prevadzky/zam/zam_json2.php?letter=all",
minLength: 1,
delay: 0,
select: function(event, ui) {
alert(1);
}
});
});
//]]>
</script>
This is my HTML:
<input id="suggestZams" class="input" size="10" />
The URL zam_json2.php?letter=all returns this json:
[
{ "id": "31440", "value": "Andrej\u010d\u00e1k, Ing." },
{ "id": "31690", "value": "Alexovi\u010d , Ing." },
{ "id": "31796", "value": "Antoni\u010d , Ing." },
{ "id": "31989", "value": "Antolik , Ing." },
{ "id": "32010", "value": "Ambrozov\u00e1 RNDr., PhD." },
{ "id": "32014", "value": "Aksam\u00edt" },
{ "id": "32024", "value": "Angelovi\u010d" },
{ "id": "32102", "value": "Andrej\u010d\u00e1k" },
{ "id": "32168", "value": "Avukov\u00e1 , Ing." },
{ "id": "32177", "value": "Andr\u00e1\u0161" },
{ "id": "32181", "value": "Andrej\u010d\u00e1kov\u00e1 , Mgr." },
{ "id": "32403", "value": "Arend\u00e1\u0161 , Bc." },
{ "id": "47379", "value": "An\u010fal" },
{ "id": "47399", "value": "Adam\u00edk , Ing." },
{ "id": "50022", "value": "Abo\u0161i" },
{ "id": "50085", "value": "Armer\u00eda Olmedo , Ing." },
{ "id": "53468", "value": "Anto\u0161" },
{ "id": "54837", "value": "Adamec , Ing." },
{ "id": "56659", "value": "Apostolou" },
{ "id": "57820", "value": "Alez\u00e1r" },
{ "id": "58576", "value": "Andrej\u010d\u00e1k , Bc." },
{ "id": "58587", "value": "Aronov\u00e1 , Ing." },
{ "id": "58595", "value": "Abaffy , Bc." },
{ "id": "58607", "value": "Adamec , Bc." },
{ "id": "58643", "value": "Antu\u0161 , Ing." },
{ "id": "62277", "value": "Adam\u010d\u00e1k , Mgr." },
{ "id": "62379", "value": "Andruch" },
{ "id": "63415", "value": "Adamkovi\u010d , Ing." }
]
Quote:
Autocomplete can be customized to work
with various data sources, by just
specifying the source option. A data
source can be:
an Array with local data
a String, specifying a URL
a Callback
When a String is used, the
Autocomplete plugin expects that
string to point to a URL resource that
will return JSON data. It can be on
the same host or on a different one
(must provide JSONP). The request
parameter "term" gets added to that
URL. The data itself can be in the
same format as the local data
described above.
What you are doing looks odd to me. I think that you will actually need to edit the server side script so that it expects the query string variable term instead of letter and returns an array of strings or an array of {label, value} objects instead of {value, id}.
If the URL content/prevadzky/zam/zam_json2.php?letter=all is provides the "complete" list of words at once, you can do something along these lines:
$.getJSON("content/prevadzky/zam/zam_json2.php?letter=all", function(data) {
var datacopy = $.map(data, function(item) {
return {
label: item.value,
value: item.id
};
});
$("input#suggestZams").autocomplete({
source: datacopy,
minLength: 1,
delay: 0,
select: function(event, ui) {
alert(typeof ui);
}
});
});
If you want to get the data from a url you have to define a function for source:
source: function( request, response ) {
$.ajax({url: "content/prevadzky/zam/zam_json2.php?letter=all",
dataType: "json",
...
});
},
...
EDIT:
In the docs it says: source can be a URL. In this case, try to change the JSON response to have 'label' instead of 'id' in the returned objects.
Here an Script that work for me in jQuery 1.5.1.
source: function( request, response ) {
$.ajax({
url: "...",
dataType: "json",
...
success: function( data ) {
# data = json response
}
});
}

Categories