Execute script after razor syntax is executed - javascript

I have some razor syntax which is dynamically generating an html table and populating with data while generating it. I needed to make a jQuery ajax call to my MVC ASP.Net controller to get some data to go in another field in this exact table. Now what I was trying to do is to iterate through the child nodes of this table and append this field cell by cell in these rows after it loads.
However this is not being successful, the table is showing as if it doesn't have any child nodes i.e. the razor syntax is not done executing by that time.
What can I do so that this script for adding the extra field is executed after the html table has been filled up with data? This is the code I have. This is the razor and html syntax.
#if (Model.ToList().Count > 0) {
<table id ="groupTable">
<thead>
<tr>
<th>Group Name</th>
<th>Description</th>
</tr>
</thead>
<tbody id="innerTable">
#foreach (var group in Model) {
// display a link with each GroupName as a list which directs to that group with that id
<tr>
<td> #Html.ActionLink(group.Group.GroupName,"DisplayGroup","Groups", new {id = group.GroupId},null) </td>
<td>
#if(group.Group.Description.Length > 40){
#group.Group.Description.Substring(0, 40)
<span>...</span>
}
else
{
#group.Group.Description.Substring(0, group.Group.Description.Length - 1)
}
</td>
</tr>
}
</tbody>
</table>
}
And this is the script executed on document.ready
$(document).ready( function() {
#foreach (var group in Model)
{
<text>
jQuery.ajax({
type: 'POST',
url: '/Groups/GetInvitedFriends',
data: { groupId: '#group.Group.GroupId' },
success: function (friendMembers) {
$.each(friendMembers, function (index, friendName) {
// append friend Members at row with index index at that cell
var tbody = $('#innerTable')[0];
var trow = tbody.childNodes[index];
if (trow.index() === 0) {
trow.append('<td> Members </td>');
} else {
trow.append('<td>' + friendName + '</td>');
}
});
},
traditional: true
});
</text>
}
})

As the javascript will only be executed on the client browser, you can store the group's id in an javascript array and then in document load, loop on this array to add each of your extra cells.
This is the javascript code :
<script type="text/javascript">
//List of groups id
var groupIds = [];
$(function() {
//Initializing the array with values
#foreach (var group in Model) {
<text>groupIds .push(#group.Group.GroupId);</text>
}
InsertExtraCells(groupIds.pop()); //Insert for the first groupid in the array
});
function InsertExtraCells(groupId) {
jQuery.ajax({
type: 'POST',
url: '/Groups/GetInvitedFriends',
data: { groupId: '#group.Group.GroupId' },
success: function (friendMembers) {
//Do your work
$.each(friendMembers, function (index, friendName) {
// append friend Members at row with index index at that cell
var tbody = $('#innerTable')[0];
var trow = tbody.childNodes[index];
if (trow.index() === 0) {
trow.append('<td> Members </td>');
} else {
trow.append('<td>' + friendName + '</td>');
}
});
//If ids remaining in the array, loop to the next group id
if (groupIds.length > 0) {
InsertExtraCells(groupIds.pop());
}
else {
//Do whatever when finish
}
},
traditional: true
});
}
</script>

Related

Looping through JSON and display each array item in HTML table

So, I was just about getting comfortable getting JSON data and displaying it in HTML when I ran in to the need to loop through items and display each keys and values. My objective is to display all 50 items in the JSON array and their information in a table. But whatever I try to do, the only output is nr 50. The last item in the array.
Here is my JSON:
{
"_embedded": {
"enheter": [
{
"organisasjonsnummer": "995742594",
"navn": "0-TAXI , KHAN TAIMUR",
"organisasjonsform": {
"kode": "ENK",
"beskrivelse": "Enkeltpersonforetak",
"_links": {
"self": {
"href": "https://data.brreg.no/enhetsregisteret/api/organisasjonsformer/ENK"
}
}
},
"registreringsdatoEnhetsregisteret": "2010-07-15",
"registrertIMvaregisteret": true,
"naeringskode1": {
"beskrivelse": "Drosjebiltransport",
"kode": "49.320"
},
"antallAnsatte": 0,
"forretningsadresse": {
"land": "Norge",
"landkode": "NO",
"postnummer": "1473",
"poststed": "LØRENSKOG",
"adresse": [
"Kulturhusgata 1"
],
"kommune": "LØRENSKOG",
"kommunenummer": "0230"
},
"institusjonellSektorkode": {
"kode": "8200",
"beskrivelse": "Personlig næringsdrivende"
},
"registrertIForetaksregisteret": false,
"registrertIStiftelsesregisteret": false,
"registrertIFrivillighetsregisteret": false,
"konkurs": false,
"underAvvikling": false,
"underTvangsavviklingEllerTvangsopplosning": false,
"maalform": "Bokmål",
"_links": {
"self": {
"href": "https://data.brreg.no/enhetsregisteret/api/enheter/995742594"
}
}
},//This is just the one item, the list goes on all the way up to 50.'
This is the code for extracting the data:
jQuery.ajax({
url: 'https://data.brreg.no/enhetsregisteret/api/enheter?page=0&size=50&naeringskode=49.3,49.4,49.5&sort=navn.norwegian,asc',
type: 'GET',
data: {},
dataType: 'json',
success: (response) => {
var listenhet = (response);
var enhetArray = listenhet._embedded.enheter;
for (var i = 0; i < enhetArray.length; i++) {
console.log(enhetArray[i].navn);
//Creating table
var table ="<tr><td>"+enhetArray[i].forretningsadresse.kommune+"</td><td>"+enhetArray[i].navn+"</td><td>"+enhetArray[i].registrertIMvaregisteret+"</td><td>"+enhetArray[i].registreringsdatoEnhetsregisteret+"</td><td>"+enhetArray[i].naeringskode1.beskrivelse+"</td></tr>";
//Showing the table inside tbody
document.getElementById("myTB").innerHTML = table;
}
console.log(response);
},
error: (response) => {
console.log(response);
}
})
Here is the table
<table class="table">
<thead>
<tr>
<th scope="col">Sted</th>
<th scope="col">Firmanavn</th>
<th scope="col">MVA Registrert</th>
<th scope="col">Reg Dato</th>
<th scope="col">Beskrivelse</th>
</tr>
</thead>
<tbody id="myTB">
</tbody>
</table>
This is my output:
This is my console:
So, as you see, the console logs all 50 items. While my table only displays the last item in the array. How can I display all 50 items to the table so it becomes 50 table rows with the information I need about each item?
You are creating a new variable 'var table' on each iteration
which leads to erase the last contained data from the table variable and initialize with latest data. So that the data from the last iteration only exists in the table variable.
Try creating a global variable outside of the loop
var table = "";
for (var i = 0; i < enhetArray.length; i++) {
console.log(enhetArray[i].navn);
//Creating table
var rowData ="<tr><td>"+enhetArray[i].forretningsadresse.kommune+"</td><td>"+enhetArray[i].navn+"</td><td>"+enhetArray[i].registrertIMvaregisteret+"</td><td>"+enhetArray[i].registreringsdatoEnhetsregisteret+"</td><td>"+enhetArray[i].naeringskode1.beskrivelse+"</td></tr>";
// Store the value in 'table'
table+= rowData;
}
And assign the 'table' variable to the 'myTB' from out side of the loop.
document.getElementById("myTB").innerHTML = table;
just replace
document.getElementById("myTB").innerHTML = table;
with
document.getElementById("myTB").innerHTML += table;
You are creating this variable:
var table ="<tr><td>"+enhetArray[i].forretningsadresse.kommune+"</td><td>"+enhetArray[i].navn+"</td><td>"+enhetArray[i].registrertIMvaregisteret+"</td><td>"+enhetArray[i].registreringsdatoEnhetsregisteret+"</td><td>"+enhetArray[i].naeringskode1.beskrivelse+"</td></tr>";
And adding it to the innerHTML of #myTB
document.getElementById("myTB").innerHTML = table;
But that means table has a new value in each iteration of the loop. So in the last iteration, whatever value is assigned to it, that is displayed in the table.
You need to store the value in a variable outside the loop like:
var total = ""; // Let this contain all the text
for (var i = 0; i < enhetArray.length; i++) {
console.log(enhetArray[i].navn);
//Creating table
var table ="<tr><td>"+enhetArray[i].forretningsadresse.kommune+"</td><td>"+enhetArray[i].navn+"</td><td>"+enhetArray[i].registrertIMvaregisteret+"</td><td>"+enhetArray[i].registreringsdatoEnhetsregisteret+"</td><td>"+enhetArray[i].naeringskode1.beskrivelse+"</td></tr>";
// Store the value in 'total'
total+= table;
}
// Set innerHTML to the combined value
document.getElementById("myTB").innerHTML = total;

Dynamically add values from a csv in an html table using javascript/jquery

I have a dynamically generated CSV file from another vendor that I am puling in and need to show in a table on my site. The problem is I need to be able to manipulate the data from the CSV so it can show the corrected values in the html table. In the end I need the HTML table to just display the Products, not the Mixed Sets.
I am using jquery and the papaparse library to get the data and parse it in a table in html. My codepen is here:
https://codepen.io/BIGREDBOOTS/pen/YQojww
The javascript pulls the initial csv values and display in a table, but I can't figure out how to to add together the values. If there is a better way of going about this, like converting the CSV to some other form of data like JSON, That is fine too.
My CSV looks like this:
product_title,product_sku,net_quantity
Product 1,PRD1,10
Product 2,PRD2,20
Product 3,PRD3,30
Mixed Set 1,MIX1,100
Mixed Set 2,MIX2,50
Mixed Set 3,MIX3,75
The Javascript I am using is:
function arrayToTable(tableData) {
var table = $('<table></table>');
$(tableData).each(function (i, rowData) {
var row = $('<tr class="rownum-' + [i] + '"></tr>');
$(rowData).each(function (j, cellData) {
row.append($('<td class="' + [i] + '">'+cellData+'</td>'));
});
table.append(row);
});
return table;
}
$.ajax({
type: "GET",
url: "https://cdn.shopify.com/s/files/1/0453/8489/t/26/assets/sample.csv",
success: function (data) {
$('body').append(arrayToTable(Papa.parse(data).data));
}
});
My rules for the mixed set:
Mixed Set 1 should add 100 to Product 1 and Product 2.
Mixed Set 2 should add 50 to Product 2 and Product 3.
Mixed Set 3 should add 75 to Product 1, Product 2 and Product 3.
I'd like to end up with Just the products output, and the correct numbers added to the formula.
The end result would be a table with Product 1 = 185, Product 2 = 245, and Product 3 = 155.
While it would be even better if the top THEAD elements were in a "th", It's fine if that is too complicated.
<table>
<tbody>
<tr class="rownum-0">
<td class="0">product_title</td>
<td class="0">product_sku</td>
<td class="0">net_quantity</td>
</tr>
<tr class="rownum-1">
<td class="1">Product 1</td>
<td class="1">PRD1</td>
<td class="1">185</td>
</tr>
<tr class="rownum-2">
<td class="2">Product 2</td>
<td class="2">PRD2</td>
<td class="2">245</td>
</tr>
<tr class="rownum-3">
<td class="3">Product 3</td>
<td class="3">PRD3</td>
<td class="3">155</td>
</tr>
</tbody>
</table>
Without knowing the size of the dataset you're working with, I suggest you first iterate through all the CSV dataset in order to populate a list of products with the correct values, and then iterate again on that to populate your HTML table:
function datasetToMap(data) {
var ret = {};
//Initialize a map with all the product rows
$(data).each(function(index, row) {
if(row[0].startsWith("Product")) {
ret[row[1]] = row; //Using the SKU as the key to the map
}
});
//Apply your mixed sets rules to the elements in the ret array
$(data).each(function(index, row) {
if(row[1] === "MIX1") {
ret["PRD1"][2] += 100;
ret["PRD2"][2] += 100;
}
//Do the same for Mixed sets 2 and 3
});
return ret;
}
function appendMapToTable(map) {
var $table = $('#my-table');
Object.keys(map).forEach(function(key, i) {
var rowData = map[key];
var row = $('<tr class="rownum-' + [i] + '"></tr>');
$(rowData).each(function (j, cellData) {
row.append($('<td class="' + [j] + '">'+cellData+'</td>'));
});
$table.append(row);
});
}
$.ajax({
type: "GET",
url: "https://cdn.shopify.com/s/files/1/0453/8489/t/26/assets/sample.csv",
success: function (data) {
appendMapToTable(datasetToMap(Papa.parse(data).data));
}
});
Note that this expects a table with id my-table to be already present in your HTML: you could manually parse the first row of your CSV data to add the table headings.
Also note that if your CSV dataset is very big this is definitely not an optimal solution, since it requires iterating through all its lines twice and then iterating again through all the list built with computed values.

Retrieve all records by checkbox in jQuery DataTable

Is it possible to retrieve all records by checking a checkbox located on the top of DataTable? I mean that I want to add a checkbox and if the user check it, it pass a parameter (for example bool isAll) to the Controller via AJAX and the records are obtained according to isAll parameter by changing the search query. I look at many different sections on Offical Documentation but there is no seem to have this feature. It is something like shown below. Any idea?
If your HTML looks like this:
<table>
<thead>
<tr>
<th><input type="checkbox" onClick="checkAll(this)"></th>
<th >x</th>
<th >y</th>
<th >z</th>
</tr>
</thead>
<tbody>
</tbody>
I would do something like this to check all 'checkboxes' named myCheckBox:
function checkAll(x) {
checkboxes = document.getElementsByName('myCheckBox');
for(var i=0, n=checkboxes.length; i<n; i++) {
checkboxes[i].checked = x.checked;
}
}
Then if you want to send that to your AJAX as a string:
function getCheckedBoxes(chkboxName) {
var checkboxes = document.getElementsByName(chkboxName);
var checkboxesChecked = [];
for (var i=0; i<checkboxes.length; i++) {
if (checkboxes[i].checked) {
checkboxesChecked.push({"ID":checkboxes[i].value});
}
}
return checkboxesChecked.length > 0 ? checkboxesChecked : null;
}
var checkedBoxes = getCheckedBoxes("cluster_checkbox");
var data = JSON.stringify(checkedBoxes);
Then in your AJAX call the var data with the string:
$.ajax({type : "POST",
url : "/new_custCluster.php",
data: {'IDs': data},
}).done(function(result) {
alert("Success");
}).fail(function() {
alert("Failure");
});

td's in table creating with jquery without html

Here is my jsfiddle work. I have some issues with generating table without any html. I have one json object that i need to itterate and to put keys and values in table like:
<tr> <td> key </td> <td> key </td> ... </tr>
<tr> <td> val </td> <td> val </td> ... </tr>
I tried first to generate the table like this one, but next i wanted to use jquery version of creating td's and tr's, but the all keys and values were appended in only one td and actually this is not what i want.
You have to loop through keys the first time to set the head of table, after that make the rows inside each and append every one to the table to make the body of your table, check example code bellow :
$.ajax({
type : "POST",
dataType : "json",
url : '/echo/json/',
data : { json: JSON.stringify( jsonData ) },
success : function(data){
var jsn = $(data.markers);
//First time append table head
if(!header)
{
var row = $('<tr></tr>');
for(key in jsn[0])
{
row.append('<th>'+key+'</th>');
}
table.append(row);
header = true;
}
for ( var i = 0; i < jsn.length ; i++){
var row = $('<tr></tr>');
$.each(jsn[i], function(key,val)
{
row.append('<td>'+val+'</td>');
});
table.append(row);
}
}
});
Take a look at Working fiddle.
Hope this helps.
The issue was in the scope of the col and row variables. You must reassign them in the loop, or redeclare.
Here is the updated jsfiddle. By the way there is no need to use for loop. In jQuery it is enough to use the $.each function on the object.
From here you can see how to create table structure and replace the key and val with the actual data you need.
You need to create new row object in each for iteration:
for (var mrksIndex = 0, mrksLength = jsn.length; mrksIndex <= mrksLength; ++mrksIndex) {
row = $("<tr/>");
$.each(jsn[mrksIndex], function (key, val) {
col = $("<td/>");
col.append(key);
row.append(col);
table.append(row);
});
}
Demo: https://jsfiddle.net/6dw2u8uz/15/

Traversing Table with jQuery

I have a table with an HTML attribute on the TR element titled "data-order" which simply holds an integer indicating the order in which to sort the table (descending). Right now the code only checks the row ahead of the TR clicked - what I'm attempting to do is to get it to scan all rows ahead of its position in the table and once it finds a number greater than (not greater than or equal to) then call the swaprow function...
Here is the javascript used to move the row up.
function adjustRank(id, e) {
var url = "/ajax/moveup/" + aid;
var row = $(e).closest("tr").get(0);
var prevRow = $(row).prev().get(0);
var moveUp = false;
var prevRowOrder = parseInt($(prevRow).attr("data-order"));
var rowOrder = parseInt($(row).attr("data-order"));
$.ajax({
type: "POST",
url: url,
data: {aid: aid},
dataType: "json",
success: function ()
{
if(rowOrder + 1 > prevRowOrder) // think this is where I need to traverse the table
swapRows(row, prevRow);
},
failure: function () { alert("Error processing request."); }
});
}
and here are a couple of items in the table for example:
<table id="listings" style="min-height:150px; width:100%;">
<tr id="1" data-order="11"><td>1</td><td align="left"><span onclick="adjustRank('ace93485-cea5-4243-8294-9f3d009aba3d', this)" style="cursor:pointer;">Lindsey Vonn</span></td><td></td></tr>
<tr id="2" data-order="6"><td>2</td><td align="left"><span onclick="adjustRank('9f83aed6-b99a-4674-a8b7-9f3d009aba38', this)" style="cursor:pointer;">Al Horford</span></td><td></td></tr>
<tr id="3" data-order="5"><td>3</td><td align="left"><span onclick="adjustRank('d48a52bd-17e9-4631-9a2e-9f3d009aba39', this)" style="cursor:pointer;">Derek Jeter</span></td><td></td></tr>
</table>
You may use recursion to solve that problem. Please, see the code.
window.adjustRank = function(id, el) {
var orderDiff = 1;
var row = $(el).closest("tr");
var order = parseInt(row.attr("data-order")) + orderDiff;
row.attr("data-order", order);
var prevRow = row.prev();
if(prevRow.get(0)){
moveUp(order, row, prevRow);
}
}
window.moveUp = function(order, row, prevRow){
if(order > parseInt(prevRow.attr("data-order"))){
var prevPrevRow = prevRow.prev();
if(prevPrevRow.get(0)){
moveUp(order, row, prevPrevRow);
} else {
prevRow.before(row);
}
} else {
prevRow.after(row);
}
}
If you get orderDiff via AJAX, then place the code into your AJAX call success function. Please, see this demo

Categories