i want to create New Content. the New content is dataTable and will be saved to localStorage
When i click the ADD NEW TABLE button, the Table has created and saved to localStorage.
BUT
When im refresh the page, The table not display but saved to
localStorage.
MY JSFiddle
How to be able to display a table [datatable view] that has been created and stored in localStorage when the page is refreshed?
jQuery :
$("#mainTable").dataTable();
/* CREATE TABLE FITURE */
$('.submitButton').click(function() {
function getTableList() {
var addTable = '<div class="tab-pane" id="folder' + localStorage.Index + '">' +
'<div class="zf-table">' +
'<table id="table' + localStorage.Index + '" class="table table-bordered table-hover myFade">' +
'<thead>' +
'<tr>' +
'<th style="border-color:rgb(221, 221, 221);"></th>' +
'<th>Audience Name</th>' +
'<th>Type</th>' +
'<th>Size</th>' +
'<th>Date Created</th>' +
'<th>Action</th>' +
'</tr>' +
'</thead>' +
'</table>' +
'</div>' +
'</div>';
return addTable;
}
if (true) {
/** INDEX FOR INCREMENT ID **/
if (typeof(Storage) !== "undefined") {
if (localStorage.Index) {
localStorage.Index = Number(localStorage.Index) + 1;
} else {
localStorage.Index = 1;
}
} // if storage
var resultTable = JSON.parse(localStorage.getItem("tableList"));
if (resultTable == null) {
resultTable = [];
}
let newtableHTML = getTableList();
resultTable.push({
table: newtableHTML
});
// save the new resultTable array
localStorage.setItem("tableList", JSON.stringify(resultTable));
/* append Table baru */
$('.tab-content').append(newtableHTML);
var newTable = $("#table" + localStorage.Index).dataTable();
alert("sucess create table");
} else {
alert("Failed create Table");
}
}); // submitButton func
//on init fill the table-content
var resultTable = JSON.parse(localStorage.getItem("tableList"));
if (resultTable != null) {
//get the nav reference in DOM
let tableContent = $(".tab-content");
//clear the html contents
tableContent.html('');
for (var i = 0; i < resultTable.length; i++) {
var items = resultTable[i];
$(".tab-content").append(items.table);
}
} else {
let inititalTable = [];
inititalTable.push({
table: $('div.tab-content').html()
});
localStorage.setItem("tableList", JSON.stringify(inititalTable));
}
seems you forgot to call dataTable() on the table elements read from LocalStorage.
By looping through the stored tables with
for (var i = 0; i < resultTable.length; i++) {
var items = resultTable[i];
$(".tab-content").append(items.table);
}
you only append the initial HTML. It must be transformed by the dataTables plugin afterwards to show ordering, searching and paging features.
A possible solution would be calling dataTable() on all tables in tab-content container after the for loop:
for (var i = 0; i < resultTable.length; i++) {
var items = resultTable[i];
$(".tab-content").append(items.table);
}
$(".tab-content table").dataTable();
Related
I have an HTML page with 3 tables on it. I want to be able to copy specific cells in a table row to the clipboard. The row could come from any of the 3 tables.
Using the code below, I highlight and copy the row for a table with an ID of "final". How do I make this work for any of the 3 tables? I tried by getElementsByTagName and labeling them the same name but did not work - understandably so. Is there a way to designate the selected table? I am trying to avoid copying the whole row and might eventually add the formatted msg to a new page rather than copy to the clipboard.
function copy_highlight_row() {
var table = document.getElementById('final');
var cells = table.getElementsByTagName('td');
for (var i = 0; i < cells.length; i++) {
// Take each cell
var cell = cells[i];
// do something on onclick event for cell
cell.onclick = function () {
// Get the row id where the cell exists
var rowId = this.parentNode.rowIndex;
var rowsNotSelected = table.getElementsByTagName('tr');
for (var row = 0; row < rowsNotSelected.length; row++) {
rowsNotSelected[row].style.backgroundColor = "";
rowsNotSelected[row].classList.remove('selected');
}
var rowSelected = table.getElementsByTagName('tr')[rowId];
rowSelected.style.backgroundColor = "yellow";
rowSelected.className += " selected";
var cellId = this.cellIndex + 1
msg = 'Title: ' + rowSelected.cells[0].innerHTML;
msg += '\r\nDescription: ' + rowSelected.cells[1].innerHTML;
msg += '\n\nLink: ' + rowSelected.cells[2].innerHTML;
msg += '\nPublication Date: ' + rowSelected.cells[3].innerHTML;
//msg += '\nThe cell value is: ' + this.innerHTML copies cell selected
navigator.clipboard.writeText(msg);
}
}
};
Based on a couple of the suggestions I came up with the following:
function highlight_row() {
var cells = document.querySelectorAll('td')
for (var i = 0; i < cells.length; i++) {
// Take each cell
var cell = cells[i];
// do something on onclick event for cell
cell.onclick = function () {
// Get the row id where the cell exists
var rowId = this.parentNode.rowIndex;
var t_ID = this.closest('table').id
var table=document.getElementById(t_ID);
var rowsNotSelected = table.getElementsByTagName('tr');
for (var row = 0; row < rowsNotSelected.length; row++) {
rowsNotSelected[row].style.backgroundColor = "";
rowsNotSelected[row].classList.remove('selected');
}
var rowSelected = table.getElementsByTagName('tr')[rowId];
rowSelected.style.backgroundColor = "yellow";
rowSelected.className += " selected";
var cellId = this.cellIndex + 1
msg = 'Title: ' + rowSelected.cells[0].innerHTML;
msg += '\r\nDescription: ' + rowSelected.cells[1].innerHTML;
msg += '\n\nLink: ' + rowSelected.cells[2].innerHTML;
msg += '\nPublication Date: ' + rowSelected.cells[3].innerHTML;
navigator.clipboard.writeText(msg);
}
}
}
At the end of the html I call the function. The HTML contains 3 tables and this enabled me to click on any table, highlight the row, and copy the correct range of cells.
I have been stuck on this problem for a while now, Basically i want to populate the below select with option group and option check boxes. The text file imports to JS just fine, i'm getting the problem trying to populate the drop down. Here is my HTML:
function LoadTxtFile(p) {
var AllTxtdata = '';
var targetFile = p.target.files[0];
if (targetFile) {
// Create file reader
var FileRead = new FileReader();
FileRead.onload = function (e) {
if (FileRead.readyState === 2) {
AllTxtdata = FileRead;
// Split the results into individual lines
var lines = FileRead.result.split('\n').map(function (line) {
return line.trim();
});
var select = $("#MySelect");
var optionCounter = 0;
var currentGroup = "";
lines.forEach(function (line) {
// If line ends it " -" create option group
if (line.endsWith(" -")) {
currentGroup = line.substring(0, line.length - 2);
optionCounter = 0;
select.append("<optgroup id'" + currentGroup + "' label='" + currentGroup + "'>");
// Else if the line is empty close the option group
} else if (line === "") {
select.append("</optgroup>");
// Else add each of the values to the option group
} else {
select.append("<option type='checkbox' id='" + (currentGroup + optionCounter) + "' name'"
+ (currentGroup + optionCounter) + "' value='"
+ line + "'>" + line + "</option>");
}
});
}
}
FileRead.readAsText(targetFile);
}
}
document.getElementById('file').addEventListener('change', LoadTxtFile, false);
<html>
<body>
<select name="MySelect" id="MySelect"/>
</body>
</html>
I believe you are using append incorrectly as you are dealing with partial nodes with the optgroup. I would build the html snippet then append it in one go. This would also bring a performance benefit as multiple DOM manipulations can get expensive.
I'd do something like the following.
function LoadTxtFile(p) {
var AllTxtdata = '';
var htmlString = '';
//Optional Templates. I find them more readable
var optGroupTemplate = "<optgroup id='{{currentGroup}}' label='{{currentGroup}}'>";
var optionTemplate = "<option type='checkbox' id='{{currentGroupCounter}}' name='{{currentGroupCounter}}' value='{{line}}'>{{line}}</option>";
var targetFile = p.target.files[0];
if (targetFile) {
// Create file reader
var FileRead = new FileReader();
FileRead.onload = function (e) {
if (FileRead.readyState === 2) {
AllTxtdata = FileRead;
// Split the results into individual lines
var lines = FileRead.result.split('\n').map(function (line) {
return line.trim();
});
var select = $("#MySelect");
var optionCounter = 0;
var currentGroup = "";
lines.forEach(function (line) {
// If line ends it " -" create option group
if (line.endsWith(" -")) {
currentGroup = line.substring(0, line.length - 2);
optionCounter = 0;
htmlString += optGroupTemplate.replace("{{currentGroup}}", currentGroup);
// Else if the line is empty close the option group
} else if (line === "") {
htmlString +="</optgroup>";
// Else add each of the values to the option group
} else {
//I'm assuming you want to increment optionCounter
htmlString += optionTemplate.replace("{{currentGroupCounter}}", currentGroup + optionCounter).replace("{{line}}", line);
}
});
select.append(htmlString);
}
}
FileRead.readAsText(targetFile);
}
}
document.getElementById('file').addEventListener('change', LoadTxtFile, false);
NOTE the above is untested and may need some debugging.
I wrote a very basic web app that pulls recipe data back from an API. The data is rendered via being pushed to an html template defined in the javascript file. The layout is controlled via a float-grid in CSS.
The code portion that renders the result and pushes to the template:
function displayRecipeSearchData(data) {
var results = ' ';
if (data.hits.length) {
data.hits.forEach(function(item) {
results += template.item(item);
});
}
else {
results += '<p> No results </p>';
}
$('#js-search-results').html(results);
}
The html template through which responses are displayed:
const template = {
item: function(item) {
return '<div class ="col-4">' +
'<div class ="result">' +
'<div class="recipelabel">' +
'<div class="reclist">' + item.recipe.ingredientLines + '</div><!-- end reclist -->' +
'<p class="label">' + item.recipe.label + '</p>' +
'<div class="thumbnail">' +
'<a href="'+ httpsTransform(item.recipe.url) + '" target="_blank">' +
'<img src="' + item.recipe.image + '"alt="' + item.recipe.label + '">' +
'</a>' +
'<div class="recipesource">' +
'<p class="source">' + item.recipe.source + '</p>' +
'</div><!-- end recipesource -->' +
'</div><!-- end thumbnail -->' +
'</div><!-- end recipelabel -->' +
'</div><!-- end result -->' +
'</div><!-- end col-4 -->';
}
};
I am trying to change the logic in the displayRecipeSearchData function such that, for each group of three results, a <div></div> surrounds the block of three results. This is so the rows/columns always work in the flex grid. I have tried several ways but have yet to get the syntax/logic correct. Would an if statement nested in the existing statement be effective?
if(i % 3 === 0 ){ results. += '<div class="row">''</div>'}
Any suggestions would be appreciated.
You could use another variable for storing one row of HTML:
function displayRecipeSearchData(data) {
var results = ' ', row = '';
if (data.hits.length) {
data.hits.forEach(function(item, i) {
row += template.item(item);
if (i % 3 == 2) { // wrap row and add to result
results += '<div class="row">' + row + '</div>';
row = '';
}
});
if (row.length) { // flush remainder into a row
results += '<div class="row">' + row + '</div>';
}
}
else {
results += '<p> No results </p>';
}
$('#js-search-results').html(results);
}
you are definitely doing this the hard way in my opinion.
instead of manually writing the template as a string and trying to inject the string at the right place (potentially creating invalid html) you should use javascripts built-in element creation. also it'll be more modular to create children in their own functions. It will also be much easier to use a function instead of an object to hold your object creator. My version may have a lot more code, but it will be much easier to modify in the long run
const Itemizer = function(){
this.items = [];
const createEl = function(elType, classes, attributes, text, html){
let el = document.createElement(elType)
for(let i = 0; i < classes.length; i++){
el.classList.add(classes[i]
}
for(let attr in attributes){
el.setAttribute(attr, attributes[attr])
}
if(text){
el.innerText = text
}
if(html){
el.innerHTML = html
}
return el
};
const createThumbnail = function(url, image, alt, source){
let thumbnail = createEl("DIV", ["thumbnail"]),
link = createEl("A", [], {href: httpsTransform(url)}),
img = createEl("IMG", [], {src: image, alt: label});
rSource = createRecipeSource(source)
link.appendChild(img);
thumbnail.appendChild(link);
thumbnail.appendChild(rSource)
return thumbnail
};
const createRecipeSource = function(source){
let wrapper = createEl("DIV", ["recipe-source"]);
wrapper.appendChild(createEl("P", ["source"], {}, source))
return wrapper
}
const createRecipeLabel = function({
recipe: {
ingredientLines,
label,
url,
source
}
}){
let labelWrapper = createEl("DIV", ["recipe-label"),
ingredients = createEl("DIV", ["rec-list"], {}, false, ingredientLines),
recipeLabel = createEl("P", ["label"], {}, label),
thumbnail = createThumbnail(url, image, label, source)
labelWrapper.appendChild(ingredients)
labelWrapper.appendChild(recipeLabel)
labelWrapper.appendChild(thumbnail)
return labelWrapper
}
const createNewItem = function(data){
let columnWrapper = createEl("DIV", ["col-4"]),
result = createEl("DIV", ["result"]),
label = createRecipeLabel(data)
columnWrapper.appendChild(result)
result.appendChild(label)
this.items.push(columnWrapper)
return columnWrapper
}.bind(this)
const getItems = function(){
return this.items
}.bind(this)
const getRows = function(){
const rows = []
let row;
for(let i = 0; i < this.items.length; i++){
const item = this.items[i]
if(i % 3 === 0){
row = createEl("DIV", ["row"])
rows.push(row)
}
row.appendChild(item)
}
return rows;
}.bind(this)
return {
add: createNewItem,
get: getItems,
rows: getRows
}
}
You can then use the function like so:
const template = new Itemizer()
function displayRecipeSearchData(data) {
let rows
if (data.hits.length) {
for(let i = 0; i < data.hits.length; i++){
template.add(data.hits[i])
}
rows = template.rows()
} else {
const p = document.createElement("P")
p.innerText = "No Results")
rows = [p]
}
const resultsWrapper = document.getElementById("js-search-results");
for(let i = 0; i < rows.length; i++){
resultsWrapper.appendChild(rows[i])
}
}
it's also good form to separate css classes with hyphens, so I replaced a few of your class names to reflect that
It's also important to note that you don't actually need more than 1 row. if you wrap all of your items in one row section columns will automatically overflow to the next row when they hit the grid limit
My last note is never use target blank. it goes against proper UX, and creates security holes in your application. if your users need to open in a new tab they can hold ctrl or click "open in new tab"
I have pages of scrapped data coming from the db and displaying that in a table (which works fine). Then I have another query from the db to only get the error rows from that scrapped data and to display that data in a div in the header. This way the user knows what data to change.
I'm having trouble allowing the user to change pages and then get the first row of that page's error data. Right now what I'm doing is creating an index variable and using that as a count and allowing the user to click through rows one at a time and then it changes to the next page if there is no more error data for that page.
How can I get it so the user is able to change the pages freely and then get the correct rows for that data and be able to click up or down through the objects for that page?
Here is my header where the error data and page header data is stored:
<div id="pageEditDiv">
<div class="arrowIconsDiv">
<img src="images/up-arrow.png" class="arrowIcons" id="arrowUpPage">
<img src="images/down-arrow.png" class="arrowIcons" id="arrowDownPage">
</div>
<div id="pageSummary">
<table id="headerPagesTable">
<thead><tr><th>Page Num</th><th>Type</th><th>Month</th><th>Name</th><th>Reg No.</th><th>Rrc District</th></tr></thead>
<tbody id="pagesTableBody"></tbody>
</table>
</div>
<div id="pagesTable" class="hidden"></div>
</div>
<div id="rowEditDiv">
<div class="arrowIconsDiv">
<img src="images/up-arrow.png" class="arrowIcons" id="arrowUpRow">
<img src="images/down-arrow.png" class="arrowIcons" id="arrowDownRow">
</div>
<div id="editableRowToEdit" contenteditable>
<table id="editableRowTable">
<tbody id="pagesRowToEdit"></tbody>
</table>
</div>
</div>
Here is where I get the error row data:
$.ajax({
type: 'POST',
url: 'qry/getPageReceipts.php',
async: true,
data: {FileId: fileId, PageNum: getPageNum, RowNum: rowNum},
success: function(response) {
recPageData = JSON.parse(response);
//check if data exists or not
recPD = {};
if(recPageData.length == 0) {
recPageDateEmpty = 1;
} else {
//map the data
recPD = recPageData.PageNum.map((x,i) => ({
pageNum: x,
rowNum: recPageData["RowNum"][i],
cName: recPageData["CustomerName"][i],
fName: recPageData["FacilityName"][i],
rrcNum: recPageData["RrcNum"][i],
rrcType: recPageData["RrcNumType"][i],
volume: recPageData["Volume"][i]
}));
//sort the data
recPD.sort(function(a,b) {
if(a.pageNum == b.pageNum) {
return (a.rowNum - b.rowNum);
} else {
return (a.pageNum - b.pageNum);
}
});
for(var i=0; i<recPD.length; i++) {
recPD[i].index = i;
}
}
drawPageForm();
drawRowEditForm();
}
});
Here is where I draw the page summary data for the user to click up and down the pages:
function drawPageForm() {
//clear div to begin with
$(".pagesMonth").html();
$("#pagesTableBody").empty();
var getPages = '<table><thead><tr><th>Page Num</th><th>Type</th><th>Month</th><th>Name</th><th>Reg No.</th><th>Rrc District</th></tr></thead><tbody>';
for(var i=0; i<getPagesResponse.length; i++) {
getPages += '<tr class="getPagesRowEdit"><td>' + getPagesResponse["PageNum"][i] + '</td><td class="pagesPageType">' + getPagesResponse["PageType"][i] + '</td><td class="pagesMonth">' + getPagesResponse["ReportingMonth"][i] + '</td><td class="pagesFilerName">' + getPagesResponse["FilerName"][i] + '</td><td class="pagesFilerRegNo">' + getPagesResponse["FilerRegNo"][i] + '</td><td class="pagesRrcDistrict">' + getPagesResponse["RrcDistrict"][i] + '</td></tr>';
}
getPages += '</tbody></table>';
//add table to div
$("#pagesTable").html(getPages);
//PAGES
//delcare single object for page summary
gPT = {
gPRE : $(".getPagesRowEdit").eq(0),
pNum : $(".getPagesRowEdit").find("td").eq(0).text(),
pTB : $("#pagesTableBody"),
aUP : $("#arrowUpPage"),
aDP : $("#arrowDownPage"),
place : function(row) {
gPT.pTB.empty();
clone = row.clone(true);
clone.appendTo(gPT.pTB);
}
}
//add row to div
gPT.place(gPT.gPRE);
//arrow up
gPT.aUP.on("click", function() {
prev = gPT.gPRE.prev();
gPT.gPRE = prev.is("tr") ? prev : gPT.gPRE;
gPT.place(gPT.gPRE);
gPT.pNum = $(".getPagesRowEdit").find("td").eq(0).text();
pageNum = gPT.pNum;
reDrawTextContentandPDF();
});
//arrow down
gPT.aDP.on("click", function() {
next = gPT.gPRE.next();
gPT.gPRE = next.is("tr") ? next : gPT.gPRE;
gPT.place(gPT.gPRE);
gPT.pNum = $(".getPagesRowEdit").find("td").eq(0).text();
pageNum = gPT.pNum;
reDrawTextContentandPDF();
});
}
Here is where I draw the row error data for the user to click up and down each row of data for that specific page:
function drawRowEditForm() {
//get the current page type
pageTypeValue = $(".pagesPageType").html();
//empty row
$("#pagesRowToEdit").empty();
//find correct row
recPD.find(findRecPageIndex);
//match row with rawText row
findMatchRowNum = $("#pagesRowToEdit").find("tr").eq(0).find("td").eq(0).text();
findMatchRowNum = findMatchRowNum - 1;
matchedRow = $(".rowToEdit").eq(findMatchRowNum);
matchedRow.addClass("selected");
//scroll div to visible row
$("#textCodeDiv").animate({
scrollTop: $(".selected").offset().top
},'slow');
//click arrow up
$("#arrowUpRow").unbind("click").click(function() {
clickRowArrowUp();
});
//click arrow down
$("#arrowDownRow").unbind("click").click(function() {
clickRowArrowDown();
});
}
function clickRowArrowUp() {
$("#pagesRowToEdit").empty();
if($(".selected")) {
$(".selected").removeClass("selected");
}
recRowIndex--;
if(recPD.find(findRecPageIndex)) {
drawRowEditForm();
} else {
prev = gPT.gPRE.prev();
gPT.gPRE = prev.is("tr") ? prev : gPT.gPRE;
gPT.place(gPT.gPRE);
gPT.pNum = $(".getPagesRowEdit").find("td").eq(0).text();
pageNum = gPT.pNum;
reDrawTextContentandPDF();
}
}
function clickArrowDown() {
$("#pagesRowToEdit").empty();
if($(".selected")) {
$(".selected").removeClass("selected");
}
recRowIndex++;
if(recPD.find(findRecPageIndex)) {
drawRowEditForm();
} else {
next = gPT.gPRE.next();
gPT.gPRE = next.is("tr") ? next : gPT.gPRE;
gPT.place(gPT.gPRE);
gPT.pNum = $(".getPagesRowEdit").find("td").eq(0).text();
pageNum = gPT.pNum;
reDrawTextContentandPDF();
}
}
//match the row to the error data and display in header
function findRecPageIndex(el) {
if(el.index === recRowIndex && el.pageNum === pageNum) {
return $("#pagesRowToEdit").append("<tr id='recTR'><td class='hidden'>" + el.rowNum + "</td><td>" + el.cName + "</td><td>" + el.fName + "</td><td>" + el.rrcNum + "</td><td>" + el.rrcType + "</td><td>" + el.volume + "</td></tr>");
}
}
function findDelPageIndex(el) {
if(el.index === delRowIndex && el.pageNum === pageNum) {
return $("#pagesRowToEdit").append("<tr id='delTR'><td class='hidden'>" + el.rowNum + "</td><td>" + el.cName + "</td><td>" + el.fName + "</td><td>" + el.rrcNum + "</td><td>" + el.rrcType + "</td><td>" + el.volume + "</td></tr>");
}
}
So a recap: The user can change pages, BUT then they can't click through the error data. The user can change rows and when there is no more error data on that page it will then change pages and display the first error data row.
What I need to know: is how to allow the user to click through the pages freely and then it be able to determine what page num it is and then display that first error row and allowing the user to click through the correct rows for that page.
Try adding this to your page up and down function:
for(var i=0; i<recPD.length; i++) {
if(pageNum == recPD[i].pageNum) {
recRowIndex = recPD[i].index;
break;
}
}
Here you are looping through the data, checking if the page numbers match and then updating the recRowIndex variable to the lowest index of the error row data.
Hope that works!
I have a div elements with data-seat and data-row property:
<div class='selected' data-seat='1' data-row='1'></div>
<div class='selected' data-seat='2' data-row='1'></div>
<div class='selected' data-seat='3' data-row='1'></div>
<div class='selected' data-seat='1' data-row='2'></div>
<div class='selected' data-seat='2' data-row='2'></div>
I want print friendly message for selected seats:
var selectedPlaceTextFormated ='';
$(".selected").each(function () {
var selectedPlace = $(this);
selectedPlaceTextFormated += "Row " + selectedPlace.attr("data-row") + " (seat " + selectedPlace.attr("data-seat") + ")\n";
});
alert(selectedPlaceTextFormated);
This code works well and shows the following:
Row 1 (seat 1)
Row 1 (seat 2)
Row 1 (seat 3)
Row 2 (seat 1)
Row 2 (seat 2)
But, I want group seats by row, i.e I want the following:
Row 1(seats: 1,2,3)
Row 2(seats: 1,2)
also, order by row number. How can I do this?
Thanks. DEMO
Here is the code
var selectedPlaceTextFormated ='';
var row_array = [];
$(".selected").each(function () {
var selectedPlace = $(this);
if (!row_array[selectedPlace.attr("data-row")]){
row_array[selectedPlace.attr("data-row")] = selectedPlace.attr("data-seat");
}
else row_array[selectedPlace.attr("data-row")] += ','+selectedPlace.attr("data-seat");
});
for (row in row_array){
alert("Row "+ row +"(seat " + row_array[row] + ")\n" );
}
And here the link to the working fiddle: http://jsfiddle.net/3gVHg/
First of all, jQuery is kind enough to automatically grab data- attributes into its data expando object, that means, you can access those data via:
jQueryObject.data('seat');
for instance.
Your actual question could get solved like
var $selected = $('.selected'),
availableRows = [ ],
selectedPlaceTextFormated = '',
currentRow,
currentSeats;
$selected.each(function(_, node) {
if( availableRows.indexOf( currentRow = $(node).data('row') ) === -1 ) {
availableRows.push( currentRow );
}
});
availableRows.forEach(function( row ) {
selectedPlaceTextFormated += 'Row ' + row + '(';
currentSeats = $selected.filter('[data-row=' + row + ']').map(function(_, node) {
return $(this).data('seat');
}).get();
selectedPlaceTextFormated += currentSeats.join(',') + ')\n';
});
jsFiddle: http://jsfiddle.net/gJFJW/3/
You need to use another variable to store the row, and format accordingly.
var selectedPlaceTextFormated ='';
var prevRow = 0;
$(".selected").each(function () {
var selectedPlace = $(this);
var row = selectedPlace.attr("data-row");
var seat = selectedPlace.attr("data-seat");
if(prevRow == row){
selectedPlaceTextFormated += "," + seat;
}
else{
if(selectedPlaceTextFormated != ''){
selectedPlaceTextFormated += ')\n';
}
selectedPlaceTextFormated += "Row " + row + " (seat " + seat;
prevRow = row;
}
});
selectedPlaceTextFormated += ')\n';
alert(selectedPlaceTextFormated);
Check http://jsfiddle.net/nsjithin/R8HHC/
This can be achieved with a few slight modifications to your existing code to use arrays; these arrays are then used to build a string:
var selectedPlaceTextFormated = [];
var textFormatted = '';
$(".selected").each(function(i) {
var selectedPlace = $(this);
var arr = [];
selectedPlaceTextFormated[selectedPlace.attr("data-row")] += "," + selectedPlace.attr("data-seat");
});
selectedPlaceTextFormated.shift();
for (var i = 0; i < selectedPlaceTextFormated.length; i++) {
var arr2 = selectedPlaceTextFormated[i].split(",");
arr2.shift();
textFormatted += "Row " + (i + 1) + " seats: (" + arr2.join(",") + ")\n";
}
alert(textFormatted);
Demo
I'd just do this:
var text = [];
$(".selected").each(function () {
var a = parseInt($(this).data('row'), 10),
b = $(this).data('seat');
text[a] = ((text[a])?text[a]+', ':'')+b;
});
var selectedPlaceTextFormated ='';
$.each(text, function(index, elem) {
if (!this.Window) selectedPlaceTextFormated += "Row " + index + " (seat " + elem + ")\n";
});
alert(selectedPlaceTextFormated);
FIDDLE