How can I add buttons REMOVE and EDIT to my table? - javascript

It is my teacher table in index.html which displayed only after click on button Teachers :
<div class="container">
<table class="teacherTable" border="1" width="100%" cellpadding="5">
<thead>
<th>TEACHER ID</th>
<th>TEACHER NAME</th>
<th>TEACHER POSITION</th>
<tbody id="teacherBody">
</tbody>
</table>
</div>
because I have in my styles :
<style>
.container table {
display: none;
}
</style>
And here is my getTeachers.js file :
GET: $(document).ready(
function () {
// GET REQUEST
$("#getAllTeachers").click(function (event) {
event.preventDefault();
ajaxGet();
});
// DO GET
function ajaxGet() {
$.ajax({
type: "GET",
url: "checkTeachers",
success: function (result) {
if (result.status == "success") {
var custList = "";
$.each(result.data,
function (i, teacher) {
var Html = "<tr>" +
"<td>" + teacher.teacherId + "</td>" +
"<td>" + teacher.teacherName + "</td>" +
"<td>" + teacher.position + "</td>" +
"<td>" + 'X' + "</td>" +
"</tr>";
console.log("Teacher checking: ", teacher);
$('#teacherBody').append(Html);
$('#groupBody').empty();
$('.groupTable').hide();
$('.teacherTable').show();
});
console.log("Success: ", result);
} else {
console.log("Fail: ", result);
}
},
error: function (e) {
console.log("ERROR: ", e);
}
});
}
})
And also in index.html I have this button for looking for all teachers in my database :
<button id="getAllTeachers" type="button" class="btn btn-primary">Teachers</button>
So, my question is how to add one more or two fields to my table which should be called REMOVE and EDIT.
I saw some solutions but I have no idea how to use it with my js file.
Maybe I can use bootstrap for it or do it manually..

Created a snippet to show you a possible way to solve the question. I used a "placeholder API" to simulate your code (so there's no "position", instead I used username).
The edit function is just mocked here - that can have so many possible directions, that I didn't want to elaborate the function.
// fetching the data from the API
const fetchAllTeachers = async() => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/users')
const json = await response.json()
return json
} catch (err) {
console.error(err)
return []
}
}
// data array for teachers
let teachers = []
// table row "template"
const tableRowHTML = (teacher) => {
const {
id,
name,
username
} = teacher // this is source-dependent
let html = ''
html += `<tr>`
html += `<td>${ id }</td>`
html += `<td>${ name }</td>`
html += `<td>${ username }</td>`
html += `<td><button data-editid="${ id }">EDIT</button></td>`
html += `<td><button data-removeid="${ id }">REMOVE</button></td>`
html += `</tr>`
return html
}
// updating table
const updateTable = (teachers) => {
const tableBody = jQuery('#teacherBody')
let html = ''
teachers.forEach(teacher => {
html += tableRowHTML(teacher)
})
tableBody.html(html)
}
// jQuery action bindings
jQuery(document).ready(function($) {
$('#fetchAllTeachers').on('click', async function() {
teachers = await fetchAllTeachers()
updateTable(teachers)
})
$('body').on('click', '[data-removeid]', function() {
teachers = removeTeacher(this.getAttribute('data-removeid'), teachers)
updateTable(teachers)
})
$('body').on('click', '[data-editid]', function() {
teachers = editTeacher(this.getAttribute('data-editid'), teachers)
updateTable(teachers)
})
})
// remove action
const removeTeacher = (id, teachers) => {
const teacher = teachers.find(({
id: tId
}) => tId == id)
let ret = [...teachers]
if (ret.indexOf(teacher) !== -1) {
ret.splice(teachers.indexOf(teacher), 1);
}
return ret
}
// edit action
const editTeacher = (id, teachers) => {
let ret = [...teachers]
console.log('create the edit feature; teacher ID:', id)
return ret
}
table {
border-collapse: collapse;
}
.container table {
/*display: none;*/
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<button id="fetchAllTeachers">GET ALL TEACHERS</button>
<table class="teacherTable" border="1" width="100%" cellpadding="5">
<thead>
<th>TEACHER ID</th>
<th>TEACHER NAME</th>
<th>TEACHER POSITION</th>
<th colspan="2"></th>
<tbody id="teacherBody"></tbody>
</table>
</div>

Related

Pagination for Dropdownlist filter data in ASP.NET MVC

My default start page has no data
Then filter out the data in the database after the two drop-down list
I hope that the filtered data can be displayed in pagination if there are more than ten records.
But I don't know how to do.
I'm new in this.
Here is my javascript
<script type="text/javascript">
$(document).ready(function () {
$("#CITY").change(function () { ChangeCity(); });
$("#AREA").change(function () { ChangeArea(); });
$(document).on('submit', '#ButtonSubmit', function () {
return false;
});
})
function SetareaEmpty() {
$('#CITY').empty();
$('#CITY').append($('<option></option>').val('').text('select'));
}
function ChangeCity() {
var selectedCity = $.trim($('#CITY option:selected').val());
if ($.trim(selectedCity.length) > 0) {
ChangeArea(selectedCity);
}
else {
SetareaEmpty()
}
}
function ChangeArea(selectedCity) {
$.ajax({
type: "POST",
url: '#Url.Action("GetSecondDDL", "Getarea")',
dataType: "json",
data: { cityName: selectedCity },
success: function (mems) {
if (mems.length > 0) {
$('#AREA').empty();
$('#AREA').append($('<option></option>').val('').text('select'));
}
$.each(mems, function (i, member) {
$("#AREA").append($('<option></option>').val(member).text(member));
});
}
});
}
function SerchallData(selectedCity) {
var selectedCity = $('#CITY option:selected').val();
var selectedValue = $('#AREA option:selected').val();
if ($.trim(selectedValue).length > 0) {
$.ajax({
url: '#Url.Action("Getmap", "Getarea")',
data: { cityName: selectedCity, areaName: selectedValue },
type: 'POST',
dataType: 'json',
success: function (data) {
$('#Mytable>tbody').empty();
for (var i = 0; i < data.length; i++) {
var row = $('<tr><td>'>+</td><td>' + data[i].ID + '</td><td>' + data[i].Name + '</td><td>' + data[i].Address + '</td><td>' + data[i].Phone + '</td><td>' +'</td></tr>');
$('#Mytable>tbody').append(row);
}
$('#Mytable').show(); //show filter data
},
error: function (jqXHR, textStatus, errorThrown) {
alert('Error: ' + textStatus + ' - ' + errorThrown);
}
});
}
}
my dropdownlist is use js to connection
filter data also
that's means after user selected city and area
data will be displayed
here is my html:
<form>
<div class="row well">
<div class="col-lg-3">
<div class="input-group">
<span class="input-group-addon">City</span>
<p>
#Html.DropDownList("City", (IEnumerable<SelectListItem>)ViewBag.Allcity, "Please select", new { id = "CITY" })
</p>
</div>
</div>
<div class="col-lg-3">
<div class="input-group">
<span class="input-group-addon">Area</span>
<p> <select id="AREA" name="AREA"><option>Please select</option></select></p>
</div>
</div>
<div class="col-lg-2">
<button type="button" onclick="SearchallData()" id="ButtonSubmit" class="btn btn-primary">
<span class="glyphicon glyphicon-search"></span>search
</button>
</div>
</div>
<table id="Mytable" class="table table-bordered table-hover" style="display:none;">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Address</th>
<th>Phone</th>
</tr>
</thead>
<tbody>
//first page table will not show any data so is null
</tbody>
and my controller
public async Task<ActionResult> Index()
{
var b = new GetCollection();
var areasource = await b.GetInserchdata();
ViewBag.AllCity = areasource.Select(s => s.City).Distinct().Select(item => new SelectListItem()
{
Text = item,
Value = item
});
DataTable dt = new DataTable();
using (SqlConnection con = new SqlConnection(connstr))
{
con.Open();
string q = "Select * from Shopmap";
SqlDataAdapter da = new SqlDataAdapter(q, con);
da.Fill(dt);
}
return View(dt);
}
//js for first selected dropdownlist
[HttpPost]
public async Task<JsonResult> GetSecondDDL(string cityName)
{
var CitySlectList = this.GetSelectList(await GetCity(), cityName);
if (string.IsNullOrEmpty(cityName))
{
return Json(new EmptyResult());
}
var AreaSlectList = await this.GetArea(cityName);
return Json(AreaSlectList);
}
//js for selected second dropdownlist then search data
[HttpPost]
public JsonResult GetShopmap(string cityName, string areaName)
{
var b = new GetCollection();
List<Inserch> shop = b.GetDBdata();
var a = shop.FindAll(x => x.Address.Contains(cityName));
var Alldata = a.FindAll(x => x.Address.Contains(areaName)).AsEnumerable();
if (string.IsNullOrEmpty(areaName))
{
return Json(new EmptyResult());
}
return Json(Alldata);
}
I think it will use js to do what I want
then maybe c# code will put in
[HttpPost]
public JsonResult GetShopmap(string cityName, string areaName)->this function
please tell me what to do
I desperately need.
thank's.
Pagination for Dropdownlist filter data in ASP.NET MVC
You can achieve that in following way:
HTML
<table id="userTable_info">
<thead>
<tr>
<th>Id </th>
<th>Controller </th>
<th>Page_name</th>
<th>Action</th>
</tr>
</thead>
<tbody id="tBody"> </tbody>
</table>
Script:
#section scripts {
<link rel="stylesheet" type="text/css" href="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/css/jquery.dataTables.css">
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js"></script>
<script type="text/javascript" charset="utf8" src="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/jquery.dataTables.min.js"></script>
<script>
$(document).ready(function () {
$('#userTable_info').hide();
//On Submit Method
$("#Submit").click(function () {
var ddlCategory = parseInt($("#ddlCategory").val());
var ddlSubCategorie = parseInt($("#ddlSubCategorie").val());
$.ajax({
type: "POST",
url: 'http://localhost:5094/Member/GetShopmap',
dataType: "json",
data: { cityName: ddlCategory, areaName: ddlSubCategorie },
success: function (response) {
console.log(response);
$.each(response, function (index, value) {
var tr = "<tr>";
tr += "<td>" + value.ulogo_id + "</td>";
tr += "<td>" + value.controller + "</td>";
tr += "<td>" + value.page_name + "</td>";
tr += "<td>" + "<input type='button' id='" + value.id + "' class='btn btn-warning' onclick='EditFunc(" + value.id + ")' value='Edit'>" + " " + "<input type='button' id='" + value.id + "' class='btn btn-danger' onclick='DeleteFunc(" + value.id + ")' value='Delete'>" + "</td>" + "</tr>";
$("#tBody").append(tr);
});
$("#userTable_info").DataTable();
$('#userTable_info').show();
}
});
});
});
</script>
}
Output:
Note: Based on your table defination please implement the neccessary chnages. It ill work as expected.

Sorting table using only Javascript

I have this table in which I read the tbody contents from a JSON API and now I need to make it sortable by columns and using only javascript and no Jquery.
Any help would be appreciated
i have found this code which is exactly what i want, but i don't know how to refer to tbodies from my api
var myRequest = new XMLHttpRequest();
myRequest.open('GET', 'https://jsonplaceholder.typicode.com/todos');
myRequest.onload = function () {
var myData = JSON.parse(myRequest.responseText);
dataTable(myData);
};
myRequest.send();
function dataTable(data) {
if (data.length > 0) {
var temp = '';
data.forEach((u) => {
temp += '<tr>';
temp += "<td style='text-align: center'>" + u.userId + '</td>';
temp += "<td style='text-align: center'>" + u.id + '</td>';
temp += '<td>' + u.title + '</td>';
temp += "<td style='text-align: center'>" + u.completed + '</td></tr>';
document.getElementById('data').innerHTML = temp;
});
}
}
<table class="table_id">
<thead>
<tr>
<th>UserID</th>
<th>ID</th>
<th>Title</th>
<th>Completion</th>
</tr>
</thead>
<tbody id="data">
</tbody>
</table>
var myData, asc = {'userId':true, 'id':true, 'title':true, 'completed':true};
var myRequest = new XMLHttpRequest();
myRequest.open('GET', 'https://jsonplaceholder.typicode.com/todos');
myRequest.onload = function () {
myData = JSON.parse(myRequest.responseText);
dataTable(myData);
};
myRequest.send();
function sortTable(key){
myData.sort(function(a, b) {
if(asc[key]){
return a[key] > b[key]? 1:-1;
}
else{
return a[key] > b[key]? -1:1;;
}
});
asc[key] = !asc[key];
document.getElementById('data').innerHTML = '';
dataTable(myData);
}
function dataTable(data) {
if (data.length > 0) {
var temp = '';
data.forEach((u) => {
temp += '<tr>';
temp += "<td style='text-align: center'>" + u.userId + '</td>';
temp += "<td style='text-align: center'>" + u.id + '</td>';
temp += '<td>' + u.title + '</td>';
temp += "<td style='text-align: center'>" + u.completed + '</td></tr>';
document.getElementById('data').innerHTML = temp;
});
}
}
<table class="table_id">
<thead>
<tr>
<th onclick="sortTable('userId');">UserID</th>
<th onclick="sortTable('id');">ID</th>
<th onclick="sortTable('title');">Title</th>
<th onclick="sortTable('completed');">Completion</th>
</tr>
</thead>
<tbody id="data">
</tbody>
</table>
Here is a quick class I made.
You first load your data with dt.load(), then when someone clicks one of the headers, you can add an event that does:
elm.addEventListener("click", (e) => {
prop = e.target.textContent.trim();
dt.sort(prop);
dt.render();
})
class DataTable{
load(arr){
if(arr) this.data = arr;
}
sort(prop){
this.data.sort((a, b) => a[prop] - b[prop]);
}
render(selector="#data"){
if(data.length){
html = data.map(u => {
return [
"<tr>",
`<td style='text-align: center'>${u.userId}</td>`,
`<td style='text-align: center'>${u.id}</td>`,
`<td>${u.title}</td>`,
`<td style='text-align: center'>${u.completed}</td></tr>`
].join("");
}).join("");
document.querySelector(selector).innerHTML = html;
}
}
}
Important - are you wanting to be able to sort multiple columns at the same time or just one column at a time?
Initialize myData outside of onload first. You'll want to be able to access those results outside of onload to sort them. The actual sort function JS offers is a pretty confusing but it's really the only way to go about vanilla JS array sorting.
function sortData(col, asc = true) {
//JS sort function
myData = myData.sort((first, second) => {
//sort logic
if (first[col] == second[col]) {
return 0;
}
if (asc) {
if (first[col] > second[col]) {
return 1;
}
else {
return -1;
}
}
else {
if (first[col] > second[col]) {
return -1;
}
else {
return 1;
}
}
});
//Re-Create table
dataTable(myData);
}
EDIT:
I added in sort logic, but it's definitely possible I messed up. I can't actually test this right now and I haven't touched the sort function in years.

build unique table with JQuery AJAX

I have a script that builds a table and makes it editable once the user clicks on a cell. The User then leaves a comment and it will update the JSON file as well as the HTML table.
The problem I am having is that if I have two tables with separate JSON files, how can I implement the same script on both of the tables? Would I have to have two separate scripts for each table? How can I do it based off the ID of the table
JSON1:
[{"GLComment":"comment from table 1","EnComment":""},
{"GLComment":"","EnComment":""}]
JSON2:
[{"GLComment":"comment from table 2","EnComment":""},
{"GLComment":"","EnComment":""}]
I have tried doing this to append to my existing table
var tblSomething = document.getElementById("table1");
<table class="table 1">
<thead>
<th id = "white">GL Comment</th>
<th id = "white">En Comment</th>
</thead>
</table>
//table does not get built here only for table 1
<table class="table 2">
<thead>
<th id = "white">GL Comment</th>
<th id = "white">En Comment</th>
</thead>
</table>
<script>
//this only works for table1
$(document).ready(function() {
infoTableJson = {}
buildInfoTable();
});
function buildInfoTable(){
$.ajax({ //allows to updates without refreshing
url: "comment1.json", //first json file
success: function(data){
data = JSON.parse(data)
var tblSomething = '<tbody>';
$.each(data, function(idx, obj){
//Outer .each loop is for traversing the JSON rows
tblSomething += '<tr>';
//Inner .each loop is for traversing JSON columns
$.each(obj, function(key, value){
tblSomething += '<td data-key="' + key + '">' + value + '</td>';
});
//tblSomething += '<td><button class="editrow"></button></td>'
tblSomething += '</tr>';
});
tblSomething += '</tbody>';
$('.table').append(tblSomething)
$('.table td').on('click', function() {
var row = $(this).closest('tr')
var index = row.index();
var comment = row.find('td:nth-child(1)').text().split(',')[0]
var engcomment = row.find('td:nth-child(2)').text().split(',')[0]
var temp1 = row.find('td:nth-child(1)').text().split(',')[0]
var temp2 = row.find('td:nth-child(2)').text().split(',')[0]
var newDialog = $("<div>", {
id: "edit-form"
});
newDialog.append("<label style='display: block;'>GL Comment</label><input style='width: 300px'; type='text' id='commentInput' value='" + comment + "'/>");
newDialog.append("<label style='display: block;'>Eng Comment</label><input style='width: 300px'; type='text' id='engInput' value='" + engcomment + "'/>");
// JQUERY UI DIALOG
newDialog.dialog({
resizable: false,
title: 'Edit',
height: 350,
width: 350,
modal: true,
autoOpen: false,
buttons: [{
text: "Save",
click: function() {
console.log(index);
user = $.cookie('IDSID')
var today = new Date();
var date = (today.getMonth()+1)+'/'+today.getDate() +'/'+ today.getFullYear();
var time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
var dateTime = date+' '+time;
//FIXME
var comment = newDialog.find('#commentInput').val() + ", <br> <br>" + dateTime + " " + user;
var engcomment = newDialog.find('#engInput').val() + ", <br><br>" + dateTime + " " + user; //it updates both of them no
row.find('td[data-key="GLComment"]').html(comment) //this is what changes the table
row.find('td[data-key="EngComment"]').html(engcomment) //this is what changes the table
// update data
data[index].GLComment = comment;
data[index].EngComment =engcomment;
$.ajax({
type: "POST",
url: "save.asp",
data: {'data' : JSON.stringify(data) , 'path' : 'comments.json'},
success: function(){},
failure: function(errMsg) {
alert(errMsg);
}
});
$(this).dialog("close");
$(this).dialog('destroy').remove()
}
}, {
text: "Cancel",
click: function() {
$(this).dialog("close");
$(this).dialog('destroy').remove()
}
}]
});
//$("body").append(newDialog);
newDialog.dialog("open");
})
},
error: function(jqXHR, textStatus, errorThrown){
alert('Hey, something went wrong because: ' + errorThrown);
}
});
}
</script>
The "key" here is prebuilt table... And that is a good job for the jQuery .clone() method.
$(document).ready(function() {
// call the function and pass the json url
buildInfoTable("comment1.json");
buildInfoTable("comment2.json");
// Just to disable the snippet errors for this demo
// So the ajax aren't done
// No need to run the snippet :D
$.ajax = ()=>{}
});
function buildInfoTable(jsonurl){
$.ajax({
url: jsonurl,
success: function(data){
data = JSON.parse(data)
// Clone the prebuild table
// and remove the prebuild class
var dynamicTable = $(".prebuild").clone().removeClass("prebuild");
// Loop the json to create the table rows
$.each(data, function(idx, obj){
rows = '<tr>';
$.each(obj, function(key, value){
rows += '<td data-key="' + key + '">' + value + '</td>';
});
rows += '</tr>';
});
// Append the rows the the cloned table
dynamicTable.find("tbody").append(rows)
// Append the cloned table to document's body
$("body").append(dynamicTable)
}
})
}
</script>
/* This class hides the prebuid table */
.prebuild{
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- This table is a "template" It never will be used but will be cloned -->
<table class="prebuild">
<thead>
<th id = "white">GL Comment</th>
<th id = "white">En Comment</th>
</thead>
<tbody>
</tbody>
</table>

update status function should not refresh which onchange the dropdownlist using mvc?

When onclick the status update then only corresponding row should be refresh . before that i written the drop down onchange function based on that only table row is display.
cs.html:
<section class="card ">
<div class="card-block">
<h5 class="with-border m-t-lg">View Module List</h5>
<div class="row">
<div class="col-lg-4">
<fieldset class="form-group">
<label class="form-label" for="exampleInput">Domain Name</label>
#Html.DropDownList("DomainID", null, "--- Select Domain Name ---", new { #class = "select2-arrow" })
</fieldset>
</div>
</div>
<br />
<div class="table-responsive" id="findValue" style="display:none;">
<table id="example" class="display table table-bordered" cellspacing="0" width="100%;">
<thead>
<tr>
<th>S#</th>
<th>Module Name</th>
<th>Url</th>
<th>Roles</th>
<th>Action</th>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</section>
Dropdown based on view tables code:
<script>
$(document).ready(function () {
$("#DomainID").change(function () {
var id = $(this).val();
$("#example tbody tr").remove();
$.ajax({
type: 'POST',
url: '#Url.Action("ViewModules")',
dataType: 'json',
data: { id: id },
success: function (data) {
var items = '';
$.each(data.EmpList, function (i, item) {
$("#findValue").show();
/*Find Role here - Comparing Emp List ModuleId to RoleList ModuleId*/
var RoleName = $(data.role).filter(function (index, item) {
return item.ModuleID == item.ModuleID
});
if (item.ParentModuleID == -1) {
item.ModuleName = " -- " + item.ModuleName
}
else {
item.ModuleName = item.ModuleName
}
var Status = '';
if (item.Status == "Y") {
Status = '<img src="/img/Active.png" height="22" width="42"/>'
} else {
Status = '<img src="/img/InActive.png" height="22" width="42"/>'
}
var rows = "<tr>"
+ "<td>" + (i + 1) + "</td>"
+ "<td>" + item.ModuleName + "</td>"
+ "<td>" + item.Url + "</td>"
+ "<td>" + RoleName[i].RoleName + "</td>"
+ "<td>" + ' ' + Status + "</td>"
+ "</tr>";
$('#example tbody').append(rows);
});
},
error: function (ex) {
var r = jQuery.parseJSON(response.responseText);
alert("Message: " + r.Message);
alert("StackTrace: " + r.StackTrace);
alert("ExceptionType: " + r.ExceptionType);
}
});
return false;
});
});
</script>
Update status Code
<script>
$(document).ready(function () {
$("#example tbody").on('click', '.user-status', function () {
var getId = $(this).data('id');
var status = $(this).attr('data-status');
$.ajax({
type: 'POST',
url: '#Url.Action("UpdateStatusModule")',
dataType: 'json',
data: { ModuleID: getId },
success: function (data) {
if (data.success) {
alert(data.message);
$("#example tbody").load("/Account/UpdateStatusModule");
}
},
error: function (ex) {
alert('Failed to retrieve Sub Categories : ' + ex);
}
});
});
});
</script>
i written the drop down onchange function based on that only table row is display. When onclick the status update then only corresponding row should be refresh onchange no value should not be change
#region Update Status
[Authorize]
[HttpPost]
public ActionResult UpdateStatusModule(int ModuleID)
{
try
{
int refID = Convert.ToInt32(Session["RefID"]);
int typeID = Convert.ToInt32(Session["ComTypeID"]);
if (ModelState.IsValid && refID > 0)
{
userType type = new userType();
type.UpdateStatusModule(ModuleID);
}
return Json(new { success = true, message = "updated successfully" }, JsonRequestBehavior.AllowGet);
}
catch
{
return View();
}
}
#endregion
If you append html after the initialization it can't work.
You need to register events on document(without $(document).ready)
$(document).on("change","#DomainID", function () {
alert("domain changed");
}).on('click', '.user-status', function () {
alert("clicked");
});
For async POST:
$.post("MyUrl",{myId: myId},function(data){
do wathever
}).fail(function(x,y,z){
alert("ops");
});
More simple

Update totals in a table

I have:
$('#createStockOrder').click(function () {
modal('create-stock-order', {}, function () {
var $modal = $(this);
var submitted = false;
var model = [];
$('.glyphicon-plus').click(function () {
var product_id = $('#productSelect option:selected').text(),
size_id = $('#sizeSelect option:selected').text(),
colour_id = $('#colourSelect option:selected').text(),
quantity = $('#quantity').val();
// Get index of the element where all the fields matches
var index = getObjectIndex(model, product_id, size_id, colour_id);
// If object found in the array
if (index !== false) {
// Update the quantity in the same element
model[index].quantity = quantity;
} else {
// Add the element in the array
model.push({
product_id: product_id,
size_id: size_id,
colour_id: colour_id,
quantity: quantity
});
}
printStock(model);
});
var form = document.getElementById('create_sale');
var $form = $(form);
$form.on('submit', function (e) {
e.preventDefault();
if (!submitted) {
submitted = true;
$('#create_sale .btn-primary').addClass('disabled');
var formData = new FormData(form);
qwest.post(form.action, formData)
.then(function (resp) {
$modal.modal('hide');
})
.catch(function (xhr, response, e) {
var html = '';
$.each(response, function (i, v) {
html += '<p>' + v + '</p>';
});
$('#create_sale .alert').html(html).removeClass('hide');
$('#create_sale .btn-primary').removeClass('disabled');
submitted = false;
});
}
})
}, {width: 1000});
});
// Currently the function is Static, but it can be changed to dynamic
// by using nested loop and a flag to store the match status
function getObjectIndex(arr, product_id, size_id, colour_id) {
// Loop over array to find the matching element/object
for (var i = 0; i < arr.length; i++) {
var obj = arr[i];
if (obj.product_id === product_id && obj.size_id === size_id && obj.colour_id === colour_id) {
// When all key-value matches return the array index
return i;
}
}
// When no match found, return false
return false;
}
function printStock(model) {
var html = '';
var total_row_quantity = 0;
var total_row_value = 0;
$.each(model, function (i1, v1) {
html += '<tr>';
$.each(v1, function (i2, v2) {
html += '<td>' + v2 + '</td>';
$('#product_totals tr').each(function(i3, v3){
var product_code = $('td', v3).eq(0).html();
if(product_code == v2) {
total_row_quantity += parseInt(model[i1].quantity);
total_row_value += parseFloat($('td', v3).eq(2).html()*model[i1].quantity);
$('td', v3).eq(1).html(total_row_quantity);
$('td', v3).eq(3).html(accounting.formatMoney(total_row_value, ''));
} else {
total_row_quantity = 0;
total_row_value = 0;
}
})
});
html += '</tr>';
});
$('#stock_order tbody').html(html);
}
The HTML is:
<tbody id="product_totals">
<tr data-id="1">
<td>JW1501</td>
<td class="code-quantity-total">0</td>
<td>79.00</td>
<td class="code-cost-total">0</td>
</tr>
<tr data-id="2">
<td>JW1502</td>
<td class="code-quantity-total">0</td>
<td>99.00</td>
<td class="code-cost-total">0</td>
</tr>
<tr data-id="3">
<td>JW1501-1</td>
<td class="code-quantity-total">0</td>
<td>20.00</td>
<td class="code-cost-total">0</td>
</tr>
<tr data-id="4">
<td>JW1502-2</td>
<td class="code-quantity-total">0</td>
<td>25.00</td>
<td class="code-cost-total">0</td>
</tr>
</tbody>
The list of rows (JW1501, JW1502) is dynamic.
The problem I am having is that if a variant of e.g. JW1502 is added, only the total quantity and value is calculated for that one. Any previous different variants of JW1502 are ignored.
How can I fix this?
Example content of var model:
[
{"product_id":"JW1501","size_id":"70A","colour_id":"小豹纹","quantity":"1"},
{"product_id":"JW1501","size_id":"75B","colour_id":"小豹纹","quantity":"2"},
{"product_id":"JW1502","size_id":"85A","colour_id":"黑色","quantity":"1"}
]
The above for JW1501 would show the incorrect quantity of 2, not 3.
...
$('#product_totals tr').each(function (i3, v3) {
console.log(v1, v2, v3)
...
Outputs:
Object {product_id: "JW1501", size_id: "70A", colour_id: "小豹纹", quantity: "2"}
"JW1501"
<tr data-id=​"1">​<td>​JW1501​</td>​<td class=​"code-quantity-total">​2​</td>​<td>​79.00​</td>​<td class=​"code-cost-total">​158.00​</td>​</tr>​
I have completely changed your printStock function to achieve your goal:
function printStock(model) {
$("#product_totals tr").each(function(){
var id = $("td:eq(0)", this).text().trim();
var price = parseFloat($("td:eq(2)", this).text());
var count = 0;
$.each(model, function(i, item){
if (item.product_id == id) count += (+item.quantity);
});
$("td:eq(1)", this).text(count);
$("td:eq(3)", this).text((count * price).toFixed(2));
});
var rows = $.map(model, function(item){
return [
"<td>" + item.product_id + "</td>",
"<td>" + item.size_id + "</td>",
"<td>" + item.colour_id + "</td>",
"<td>" + item.quantity + "</td>"
].join("");
});
var html = "<tr>" + rows.join("</tr><tr>") + "</tr>";
$('#stock_order tbody').html(html);
}
The main difference is that my code groups items in model by product_id for further counting.
Also refer my fiddle.

Categories

Resources