I have two arrays that I had already successfully used to make a table in JavaScript. Now, I would like to make the table a jQuery DataTable because of its UI features. I thought I had the correct way of creating one, but I get an error.
This is also within a Flask app, if that makes a difference
Code
<body>
<!-- Load jQuery -->
<script src = "http://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js" crossorigin = "anonymous"></script>
<!-- jQuery dataTables script-->
<script type="text/javascript" src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
<!-- If that fails, we have a backup in our directory-->
<script type = text/javascript src = "{{
url_for('static', filename = 'jquery.js') }}"></script>
<script type = text/javascript src = "{{
url_for('static', filename = 'jQuery.dataTables.min.js') }}"></script>
<!-- Form for submitting our NBA Data-->
<form id = "nameForm" role = "form">
<!-- Input box so we can search by player name -->
<input name = "text" type = "text" id = "searchBox">
<!-- Button that we will use to make the actual ajax call -->
<button id = "searchBtn"> Search </button>
</form>
<!-- Container that we will add our data table to later -->
<table id = "myTable" class = "display" width = "25%"></table>
<!-- Script for the button click action -->
<script type = text/javascript>
//Root stuff
$SCRIPT_ROOT = {{ request.script_root|tojson|safe }};
var dataList;
var titles;
var dtColumns;
//Root so we can get the data from our form
$('button#searchBtn').click(function(e) {
//Prevent our form from submitting, which is its default action/purpose
e.preventDefault();
//Get the data from our function in the Flask App
$.getJSON($SCRIPT_ROOT + '/_get_data', {
//Our searchName variable will be the one from our HTML input box
searchName: $('input[name = "text"]').val(),
}, function(data) {
dataList = data.dataList;
titles = data.headers;
dtColumns = [];
for (var i = 0; i < titles.length; i++) {
dtColumns.push({ title : titles[i] });
}
});
});
//When our page is fully loaded, convert the table to a jQuery data table
$(document).ready(function () {
$('#myTable').DataTable( {
data: dataList,
columns: dtColumns
});
})
</script>
</body>
EDIT: The arrays that I am working with, and the newest errors
dtColums is
["Player", "Pos", "Age", "Tm", "G", "GS", "MP", "FG", "FGA", "FG%", "3P", "3PA", "3P%", "2P", "2PA", "2P%", "eFG%", "FT", "FTA", "FT%", "ORB", "DRB", "TRB", "AST", "STL", "BLK", "TOV", "PF", "PTS"]
And dataList is
["James Harden", "SG", "30", "HOU", "7", "7", "35.3", "9.1", "24.0", ".381", "3.4", "13.6", ".253", "5.7", "10.4", ".548", ".452", "14.9", "16.1", ".920", "1.4", "3.7", "5.1", "7.4", "1.0", "0.4", "5.7", "3.6", "36.6"]
Current errors that are being returned in a alert in my browser window:
DataTables warning: table id=myTable - Requested unknown parameter '12' for row 0, column 12. For more information about this error, please see http://datatables.net/tn/4
DataTables warning: table id=myTable - Requested unknown parameter '1' for row 4, column 1. For more information about this error, please see http://datatables.net/tn/4
You are making an async call but not waiting it to return before initializing DataTable. Basically, you are trying to create dataTable from a variable that has not the values you need. You can try to initialize table within callback of getJSON function.
I have not used DataTables for a long time and as I remember I have always written the data to table before initializing but you can try this;
<script type = text/javascript>
//Root stuff
$SCRIPT_ROOT = {{ request.script_root|tojson|safe }};
var dataList;
var titles;
var dtColumns;
//Root so we can get the data from our form
$('button#searchBtn').click(function(e) {
//Prevent our form from submitting, which is its default action/purpose
e.preventDefault();
//Get the data from our function in the Flask App
$.getJSON($SCRIPT_ROOT + '/_get_data', {
//Our searchName variable will be the one from our HTML input box
searchName: $('input[name = "text"]').val(),
}, function(data) {
dataList = data.dataList;
titles = data.headers;
dtColumns = [];
for (var i = 0; i < titles.length; i++) {
dtColumns.push({ title : titles[0] });
}
$('#myTable').DataTable( {
data: dataList,
columns: dtColumns
});
});
});
</script>
Related
I am trying to get data stored in attributes of dynamically created elements that have been added to the DOM.
When a button is clicked, an AJAX call is made which returns a collection of objects. Using Javascript/JQuery, I am then adding new HTML elements for each of these returned objects, and adding their property values to attributes on the element. I am then adding a click listener to each of these dynamically created elements. When clicked I want to get the value in these attributes.
At the moment the id value is present, but the value of name is undefined.
For example, given the following HTML:
<input type="button" id="button" value="Get objects" />
<div id="objects-wrapper"></div>
Json response from server:
[
{
"id": 16,
"name": "eeeee",
},
{
"id": 17,
"name": "MIT Top New"
}
]
$(document).ready(function() {
$('#button').click(function() {
var id = $(this).attr('id');
var posting = $.post('/get/objects', {
id: id
});
posting.done(function(data) {
var objectsWrapper = $('#objects-wrapper');
objectsWrapper.empty();
if (data.length == 0) {
$(objectsWrapper).html('No objects found...');
} else {
$(objectsWrapper).empty();
for (i = 0; i < data.length; i++) {
var object = $('<div class="object">' + data[i].name + '</div>').on('click', function() {
var objectId = $(this).attr('id'); // <-- is present
var name = $(this).attr('name'); // <-- undefined
// do something with name
});
objectsWrapper.append(object);
}
}
});
return false;
});
});
The name value is present and is being used as the anchor text. Which I have verified as the following markup:
MIT Top New
How do I correctly get at the attribute name of the dynamically created anchor element?
You can use .find() of jQuery to find for the elements with selector in the DOM and make it work
Here is an example with your data.
var data = [
{
"id": 16,
"name": "eeeee",
},
{
"id": 17,
"name": "MIT Top New"
}
];
data.forEach(e=>{
$("#objects-wrapper").append(` </br> ${e.name} </br>`)
});
$("#button").click(function(){
$("#objects-wrapper").find("a").each(function(){
console.log($(this).attr("name"))
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="button" id="button" value="Get objects" />
<div id="objects-wrapper"></div>
By the way in your code, why you need to get it from DOM ? you're assigning the name yourself why not use it ? data[i].name this is the name right. Use it instead of getting from the DOM again
I want to retrieve a JSON object when the user clicks the html link. i want to retrieve it by it's ID and display everything in the object on the html page. I am also using session storage..... I want the user to be taken to the info.html page after they follow the html link.
my html code so far:
<div class="col">
<!-- team-img -->
<div class="team-block">
<div class="team-content">
<h4 class="text-white mb0">Chocolate Cake </h4>
<p class="team-meta">Large</p>
</div>
<div class="overlay">
<div class="text">
<h4 class="mb0 text-white"> Chocolate Cake </h4>
<p class="mb30 team-meta"> Large </p>
<p>Large Chocolate cake. 15 servings.</p>
<p>Further info</p>
</div>
</div>
</div>
</div>
The ID of the cake is "1" In the JSON file. I want all the details of the cake to be displayed when the user clicks the link. I want the user to be taken to info.html. The data of the cake which is stored in the JSON should be displayed there. The problem is with this line:
<p>Further info</p>
My JSON file is called cakes.json
below is my .js file
var ajax=function(url,success)
{
var ajaxRequest = new XMLHttpRequest();
var handleResponse=function()
{
if(ajaxRequest.readyState===4)
{
if(ajaxRequest.status===200)
{
var data=JSON.parse(ajaxRequest.responseText);
success(data); //this will call populateList
}
}
}
ajaxRequest.addEventListener("readystatechange",handleResponse,false);
ajaxRequest.open('GET', url, true);
ajaxRequest.send(null);
}
var navList;
var contentDiv;
function createHandler(car)
{
return function(){
sessionStorage.setItem("cake",JSON.stringify(cake));
}
}
function populateList(cakes)
{
navList=document.getElementById("nav");
contentDiv=document.getElementById("content");
cakes.forEach(function(cake){
var newLi=document.createElement("ul");
var newLink=document.createElement("a");
newLink.innerHTML=cake.name;
newLink.setAttribute("href","info.html");
newLink.addEventListener("click", createHandler(cake), false)
newLi.appendChild(newLink);
navList.appendChild(newLi);
})
}
function init(){
ajax("data/cakes.json",populateList);
}
init();
JSON file:
[
{
"id":1,
"cake":"chocolate cake",
"servings":"15",
"size":"10",
"code":"ed39"
},
]
Any Help would be greatly appreciated.
I've done an example of how this can be done using your structure of array containing multiple objects. Also I've modified your html added data-id parameter instead of id usually you don't save the id of an object in the id of html element(not best practice), you can use the data- params, there is also a function in jQuery that reads these parametes $(selector).data('identifier')
var json = [{
"id": 1,
"cake": "chocolate cake",
"servings": "15",
"size": "10",
"code": "ed39"
}, {
"id": 2,
"cake": "vanilla cake",
"servings": "15",
"size": "10",
"code": "ed39"
}];
$(document).on('click', '.cakeDetailsButton', function() {
var id = $(this).data('id'),
details = getDetailsById(id), //Here all the details for the cake
resultDiv = $('.result');
resultDiv.text('');
$.each(details, function(key, value) {
resultDiv.append(key + ' -- ' + value + '<br/>') // Here you can do whatever with the details
})
});
function getDetailsById(id) {
for (var i = 0; i < json.length; i++) {
if (json[i].id == id) {
return json[i];
}
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p><a class="cakeDetailsButton" href="#" data-id="1">Further info 1</a></p>
<p><a class="cakeDetailsButton" href="#" data-id="2">Further info 2</a></p>
<div class="result">
</div>
EDIT - Update
In order to add your json in the localStorage in order to access it from anywhere update the following
.js file
function populateList(cakes)
{
localStorage.setItem('cakesJson', cakes); //This adds an object to the localStorage with the key cakesJson and value the cakes object
navList=document.getElementById("nav");
contentDiv=document.getElementById("content");
cakes.forEach(function(cake){
var newLi=document.createElement("ul");
var newLink=document.createElement("a");
newLink.innerHTML=cake.name;
newLink.setAttribute("href","info.html");
newLink.addEventListener("click", createHandler(cake), false)
newLi.appendChild(newLink);
navList.appendChild(newLi);
})
}
Also then in the code provided by me above you should change the following
function getDetailsById(id) {
var json = localStorage.getItem("cakesJson"); // Here you retrieve the values stored in the localStorage
for (var i = 0; i < json.length; i++) {
if (json[i].id == id) {
return json[i];
}
}
}
The event listener remains the same as in the snippet
$(document).on('click', '.cakeDetailsButton', function() {
var id = $(this).data('id'),
details = getDetailsById(id), //Here all the details for the cake
resultDiv = $('.result');
resultDiv.text('');
$.each(details, function(key, value) {
resultDiv.append(key + ' -- ' + value + '<br/>') // Here you can do whatever with the details
})
});
I want to consume ajax returned data in my JQuery DataTables. I have created loop to view every row and also need to add a view button for them. I pass all data to JQuery DataTables. I cannot understand how to do that.
This is my ajax request
<script>
$(document).ready(function () {
$("#searchArea").show();
var uID = $("#userName").val();
var tableProduct = $('#dataTbl').DataTable({
"bSort": false
, "oLanguage": {"sZeroRecords": "", "sEmptyTable": ""}
});
$.ajax({
type: 'GET',
url: '${pageContext.request.contextPath}/restservice/viewApplication/' + uID,
success: function (result) {
var jString = JSON.stringify(result);
var jdata = JSON.parse(jString);
for (var x = 0; x < jdata.length; x++) {
var td1 = jdata[x].snumber;
var td2 = jdata[x].date;
var td3 = jdata[x].slsNo + " in " + jdata[x].slsiUnit;
var td4 = jdata[x].productDesc;
var td5 = jdata[x].status;
var td6 = "view btn1";
var td7 = "view btn2";
var td8 = "view btn3";
tableProduct.row.add([td1, td2, td3, td4, td5, td6, td7, td8]).draw(true);
}
}
});
});
</script>
I want to add this code for every row. How can I do that ?
<form method="post" action="${pageContext.request.contextPath}/viewApplication" target="_blank">
<input type="hidden" name="snumber" value="jdata[x].snumber"/>
<input type="submit" class="btn btn-primary btn-block" value="View" />
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>
Consuming Ajax data in DataTables
There is already a handy feature in DataTables to fetch data from ajax and consume them as you configure your table. Just use the ajax option and tell about the data source you want to consume
$('#dataList').DataTable({
ajax: {
url: 'url',
type: 'GET',
dataSrc: ''
}
}
See this documentation for complete guideline.
Note: here passing dataSrc option as empty tells dataTable to expect an array rather than objects from ajax response
Following is a example that depicts a senario where datatable is configured to consume a api response. For demonastration purpose I used a public dummy api service that returned an json array. See this dummy api response.
$(function() {
var columnArray = [{
title: "Photo ID",
data: "id",
targets: 0
},
{
title: "Photo Title",
data: "title",
targets: 1
}
];
$('#dataList').DataTable({
ajax: {
url: 'https://jsonplaceholder.typicode.com/photos',
type: 'GET',
dataSrc: ''
},
bBootstrapLayout: true,
columns: columnArray,
columnDefs: [{
render: function(data, type, row) {
return data + ' (' + row['albumId'] + ')';
},
targets: 0
}, {
render: function(data, type, row) {
var html = '<button>view</button>';
return html;
},
targets: 2
}]
});
});
<head>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
<link href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css" rel="stylesheet" />
<head>
<body>
<br>
<br>
<div class="row">
<div class="col-lg-1"></div>
<div class="col-lg-6">
<div>
<table id="dataList" class="table" data-page-length="1" cellspacing="0" width="100%" />
</div>
</div>
</div>
</body>
Having Custom button or form in row
In your datatable you can configure each column rendering logic. Like the case you are dealing, you want separate columns of button behave as form submission.
You should tell this in columnDefs option as passing an array of definations.
In the code snippet above I also showed how you can achive that. In that example I added 3rd column (target: 2) by defining its rendering logic. In render callback you can return html that should be placed in that column. I only added <button>view</button> but as you see you can return any html like forms with input fields and buttons and whats not. render option takes a function that is provided with data, type, row parameters. Hence you can exploit these data for rendering your column html or any logic you what. Thats a lot of flexibility, isn't it ?
You will find a complementary guildline from this columnDefs documentation.
I have looked all over for a reason behind why this code does not work and I am stumped.
I have an ASPX page with C# code behind. The HTML mark-up has a JQuery dialog that functions properly. When the submit button is clicked the dialog closes and the data is passed to a web exposed method and is written to the database. All values are saved for the ddl and chkbox controls but the string value of the text box is empty. The database is set to NOT NULL for the field the text box is populating and the data is being saved so I know data is being passed but it is not the value entered into the text box.
The text box ID is txtCategoryName and the Client ID mode is set to static. I have tried to get the values using the following:
var CategoryName = $('#txtCategoryName').val();
var CategoryName = $('#txtCategoryName').text();
var CategoryName = $(document.getElementById('txtCategoryName')).text();
var CategoryName = $(document.getElementById('txtCategoryName')).val();
var CategoryName = document.getElementById('txtCategoryName').value;
All of these return the same blank field. I tried them one at a time.
Currently I am using this JS Code:
$(document).ready(function () {
var CategoryDialog = $(".EditCategories");
var BtnNew = $("#btnNew");
var CatDDL = document.getElementById("ddlCategoryParent3");
var CatChk = $("#chkCatActive").val();
var CategoryID = 0;
var CategoryName = $("#txtCategoryName").val();
var ParentID = CatDDL.options[CatDDL.selectedIndex].value;
if (CatChk) { CatChk = 1; } else { CatChk = 0; }
var CatDialog = $(CategoryDialog.dialog({
maxHeight: 1000,
closeOnEscape: true,
scrollable: false,
width: 650,
title: 'Category Editor',
autoOpen: false,
buttons: [
{
width: 170,
text: "Save",
icons: {
primary: "ui-icon-disk"
},
click: function () {
$(this).dialog("close");
window.alert(PageMethods.saveCat(CategoryName, ParentID, CategoryID, CatChk));
}
},
{
width: 170,
text: "Delete",
icons: {
primary: "ui-icon-circle-minus"
},
click: function () {
$(this).dialog("close");
}
},
{
width: 170,
text: "Cancel",
icons: {
primary: "ui-icon-circle-close"
},
click: function () {
$(this).dialog("close");
}
}
]
})
);
BtnNew.click(function () {
$(CatDialog).dialog('open');
$(CatDialog).parent().appendTo($("form:first"));
});
});
The code markup for the aspx page (categories.aspx)
<div class="EditCategories">
<div class="Table">
<div class="TableRow">
<div class="TableCell">
<div class="TextBlock220">Category Name </div>
</div><!-- End Table Cell -->
<div class="TableCell">
<input id="txtCategoryName" class="ControlTextBox" />
<!--<asp:TextBox ID="txtCategoryName" CssClass="ControlTextBox" runat="server" ClientIDMode="Static"></asp:TextBox>-->
</div><!--End Table Cell-->
</div><!-- End Row 1 -->
<div class="TableRow">
<div class="TableCell">
Parent Category
</div><!-- End Table Cell -->
<div class="TableCell">
<asp:DropDownList ID="ddlCategoryParent3" runat="server" CssClass="ControlDropDownList" ClientIDMode="Static"></asp:DropDownList>
</div><!--End Table Cell-->
</div>
<div class="TableRow">
<div class="TableCell">
Active
</div><!-- End Table Cell -->
<div class="TableCell">
<asp:Checkbox ID="chkCatActive" CssClass="ControlCheckBox" runat="server" ClientIDMode="Static"></asp:Checkbox>
</div><!--End Table Cell-->
</div><!-- End Row 3-->
</div>
</div>
The C# Code behind method for the ASPX page:
[System.Web.Services.WebMethod()]
[System.Web.Script.Services.ScriptMethod()]
public static string saveCat(string _Name_, int _parent_id_, int ID, int _Status_)
{
Category eCT = new Category();
eCT.CategoryName = _Name_;
eCT.ParentID = _parent_id_;
eCT.ID = ID;
eCT.Status = _Status_;
eCT.Save();
return eCT.resultMessage;
}
And the save method:
/// <summary>
/// If the ID = 0 the data is written as a new category.
/// If the ID is greater than 0 the data is updated.
/// </summary>
/// <returns>The objects result value will hold the result of the attempt to update data as type Boolean. The objects resultMessage value will contain the string result of the attempt to add data.</returns>
public void Save()
{
result = dl.CategoryExists(this);
if (result) { resultMessage = "The parent category already contains a category named " + CategoryName.Trim(); }
else {
if (ID > 0)
{
if (!result) { resultMessage = "There was an unexpected error updating " + CategoryName.Trim() + ". No changes were saved."; }
}
else
{
result = dl.InsertCategory(this);
if (!result) { resultMessage = "There was an unexpected error creating the Category."; }
}
}
if (result) { resultMessage = "New Category Successfully Created"; }
}
Any help is greatly appreciated thanks.
The issue here is you're attempting to get the value right as soon as the page loads, before the input field gets filled out. Place this code inside the button click function:
var CategoryName = document.getElementById('txtCategoryName').value;
and it should work for you. If not, let us know.
Your code should look something like this:
click: function () {
// note: CategoryID not used yet.
var CategoryName = $("#txtCategoryName").val();
var CatChk = $("#chkCatActive").val();
var CatDDL = document.getElementById("ddlCategoryParent3")
var ParentID = CatDDL.options[CatDDL.selectedIndex].value;
if (CatChk) { CatChk = 1; } else { CatChk = 0; }
$(this).dialog("close");
window.alert(PageMethods.saveCat(CategoryName, ParentID, CategoryID, CatChk));
}
You are fetching the values from your dialog at page startup time BEFORE they have been edited.
It looks like this:
var CategoryName = $("#txtCategoryName").val();
is run at page startup time before the page has been edited. This will fetch the default value for the input field and will never reflect any editing that is done on the page. The line of code above does not create a "live" connection with the input field on the page. It just gets the value at the time that line of code is run and from then on there is no connection to any edits made to the field.
I would think you want to fetch the value only later when you actually need to value for something. In general, you do not want to cache a value like this because the cached value gets out of sync with what is in the actual field on the page. Just fetch it at the very moment that you need it for something and it will never have a stale value.
If the place that you're using this value is inside the dialog click handler, then fetch it there so you are getting the latest value:
click: function () {
$(this).dialog("close");
var CatChk = $("#chkCatActive").val() ? 1 : 0;
var CategoryName = $("#txtCategoryName").val();
var CatDDL = document.getElementById("ddlCategoryParent3");
var ParentID = CatDDL.options[CatDDL.selectedIndex].value;
window.alert(PageMethods.saveCat(categoryName, ParentID, CategoryID, CatChk));
}
I would like to get the row id of selected item in my autocomplete function, I get the values of my source from a php variable.
<script>
$(function() {
var availableTags = [ <? php echo($toto); ?> ];
$("#foo").autocomplete({
source: availableTags
});
});
</script>
I already tried this function but it does not seem to work. In fact, when I add it to my script, my autocomplete won't work anymore.
<script>
$(function () {
var availableTags = [ <? php echo($ListeNomsFormateeFinale); ?> ];
$("#nomClient").autocomplete({
source: availableTags
select: function (event, ui) {
$("#textfield1").val(ui.item.label); // display the selected text
$("#textfield2").val(ui.item.value); // display selected id
return false;
}
});
});
</script>
What am I doing wrong here? and is there a quick fix to this problem?
Edit:
I actualy needed to add a comma after source: availableTags, I also deleted the return false. but it dosen't return the id of the selected row, it actually writes the same value in the two textfields textfield1 and textfield2
From : Api Jquery UI - Autocomplete - option source
Array: An array can be used for local data. There are two supported formats:
An array of strings: [ "Choice1", "Choice2" ]
An array of objects with label and value properties: [ { label: "Choice1", value: "value1" }, ... ]
The label property is displayed in the suggestion menu. The value will be inserted into the input element when a user selects an item. If just one property is specified, it will be used for both, e.g., if you provide only value properties, the value will also be used as the label.
The second point (2.) give a way to store the "id" (or something else) of the selected object. By example :
var yourSource = [ { label: "Choice1", id: "id1" } ];
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<link href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css" rel="stylesheet" />
<form>
<input type="text" id="fooInput" />
</form>
<div id="result">
</div>
<script type="text/javascript">
var yourSource = [
{
label: "A",
id: "id1"
},
{
label: "B",
id: "id2"
}];
$("#fooInput").autocomplete({
source: yourSource,
select: function(event, ui) {
var e = ui.item;
var result = "<p>label : " + e.label + " - id : " + e.id + "</p>";
$("#result").append(result);
}
});
</script>
So try to format your data source like this :
var source = [ {label:"Foo", id:"1"}, ... ];