split a big HTML page to pages on client side - javascript

I have a huge HTML page which is mainly a form which is mostly like this:
<FIELDSET id= '1'>
<TABLE>
<TR> </TR>
</FIELDSET>
</TABLE>
.
.
.
<FIELDSET id= 'n'>
<TABLE>
<TR> </TR>
</TABLE>
The number of fieldsets are generated by dynamically on the server.
Question: On the client side I want to do a pagination for this huge page, so that only say,3 fieldset appear per page on the client.
I don't want to change the way page is loading or form is being submitted currently.

Well just a little tips you may use
$('fieldset')
document.querySelectorAll('fieldset')
will return you fields
in order to get show only i .. i+3 fieldsets you can use
var i = 3
$('fieldset').hide().each(function ( index, el) {
if (index >= i && index < i+3) $(el).show()
})
var fieldsets = [].slice(document.querySelectorAll('fieldset'))
for (var index in fieldsets) {
var display = index < i && index >= i+3 ? 'none' : ''
fieldsets[index].style.display = display
}

Pagination won't really help you in any way other than visual if done on the client side (no speed increases, load reductions, etc), but if that's what you want you can do it with DOM manipulation. Something like the following might work for you:
var i=0,sets=document.getElementsByTagName('fieldset'),len=sets.length;
for(;i<len;i+=3) {
// wrap sets[i] through sets[i+2], as long as they exist, in a div
// if i !== 0, hide or minimize the div
}
// add controls to unhide/unminimize each div

Related

Reload Data with .sort from Dynamic Table with Jquery | JSON | Sort with New Data

I have been trying for a few days that when I use the .sort property the data is eliminated or modified instead of it being reloaded as new lines.
Attach Captures from the code Working
Image1 How work the code when i press the button, this sort to the highest price to lowest but how do you can see in the second image, the code appears up and this not delete the old data
Marked with "X" the data that does not have to show
this fragment is the one that generates the tables dynamically
const mostrarProductos = () => {
$.getJSON(URLJSON, (respuesta) => {
for (let z of respuesta) {
productosv2.push(z);
}
for (let x of productosv2) {
$("#fila").append(`
<tr class="deleteProductos">
<div class="card text-center" style="width: 18rem;" id='btnBorrarCarrito'>
<div class="card-body">
<input type="hidden" id="idProd" value="${x.id}"> </td>
<td class="card-title" id="${x.id}">${x.producto}</h2> </td>
<td class="card-text">$ ${x.precio}</p></td>
<div class="btn-group" role="group" aria-label="Basic mixed styles example">
<td><button type="button" class="btn btn-success" onclick="agregarCarrito(${x.id})">Agregar</button></td>
</div>
</div>
</div>
</tr>
`);
}
$("#fila").fadeIn("5000");
});
};
And this function is what orders them
function respuestaClickExpensive() {
$("#fila").html('');
let productosordenados = productosv2.sort((a, b) => {
if (a.precio > b.precio) {
return -1;
}
if (a.precio < b.precio) {
return 1;
}
return 0;
});
return productosordenados;
}
The one that orders them from smallest to largest is the same only that different signs and names.
As you can see I tried to use a ".html ("")" since previously in another cart attempt it used .innerHtml (Which does not work in this case either, Also the code of the cart is totally different from that moment that it worked for me
)
I tried the following:
$ ("#fila"). empty ();
Make another function to clean with .empty
Use Native JavaScript to generate the code.
$ ("#fila"). remove (); this removes all the content for me but does not regenerate it.
Change the HTML tag "Row" to a previous div which, since the div was not generated again, did not generate it again.
$ ("#fila tr"). remove ();
And some more things that I don't remember right now.
If you can guide me on what I did wrong or any suggestions to fix it, I appreciate it.
If I had to follow a template about posting on StackOverFlow or having chosen or named in a different way, I appreciate your comment since it is my first post
Project notes of possible relevance: The complete code outside of html and css is made with Native JavaScript, Jquery, Ajax, SASS and BootStrap.

How to do a Pug for loop with AJAX?

I am working on a Tinder clone web project for school using Node.js, Express, and Pug that needs to return potential matches with a priority on either distance from the current user or similar interests shared with the current user. When the user first enters their page of potential matches I have the site automatically show the user the best possible matches based on a distance of 5km from their current position. I am sending to the page I render an Array of matches called users and a size of that array called userslen that I pulled from my database in my node file. I then proceed to show the potential matches on the page using this pug for loop:
div(class='container', id='searchResults') <!-- SEARCH RESULTS -->
div(class='row')
- for (var i = 0; i < userslen; i++) {
div(class='col-lg-4 col-md-6 col-sm-12 col-xs-12 usertop')
div(class='row')
div(class='col-lg-12 col-md-12')
a(href='/users/' + users[i].username)
h1=users[i].username
- if (users[i].liked == true) {
span(id='youlikeglyph', class="glyphicon glyphicon-ok")
- } else if (users[i].disliked == true) {
span(id='youdislikeglyph', class="glyphicon glyphicon-remove")
- } else {
- }
div(class='row')
div(class='col-lg-12 col-md-12')
img(id='viewerphoto1', class='userpagephoto', src='/static/uploads/' + users[i].filename)
div(class='row')
- if (users[i].liked == false && users[i].disliked == false) {
div(class='btn-group')
button(id='dislike' + i, class='btn btn-danger btn-lg')
|Dislike
button(id='like' + i, class='btn btn-success btn-lg')
| Like
- } else if (users[i].liked == false && users[i].disliked == true) {
button(id='like' + i, class='btn btn-success btn-lg')
|Like
- } else if (users[i].liked == true && users[i].disliked == false) {
button(id='dislike' + i, class='btn btn-danger btn-lg')
|Dislike
- } else {
- }
div(class='row')
div(class='col-lg-4 col-md-4')
h5="Distance"
h4=users[i].distance + "km"
div(class='col-lg-4 col-md-4')
h5="Same Tags"
h4=users[i].cTags
div(class='col-lg-4 col-md-4')
h5="Popularity"
h4=users[i].popularity
- }
There are two buttons at the top of my page (not shown in the above code) that allow a user to choose to search based on distance or based on tags with a min and max distance/tags-in-common input. When they click on the button of their choice with the min max they have entered I send the data through AJAX to a post that then returns a new array of potential matches based on this new data. Is there a way to make the same for loop I have in the above code but using jQuery once my AJAX response is a success? If there is, what is the best way to go about it? Thank you in advance for your help!
You cannot go back to Jade/Pug once you're on the client. Jade is a templating engine that works on Node. Once you're on the client, it doesn't exist anymore.
You'll need to just loop over your HTML in jQuery, and won't be able to use Jade for this.
Another option is to use one of the client side templating frameworks like Underscore templates/Handlebars/Moustache JS etc.
Using these, you can handle the looping much more elegantly than you can using jQuery, but of course, that really is a call you should take, because this would mean additional payload over the wire.
With one of the templating frameworks, you can define your template in Jade and then reuse it for your iterations

Getting top five rows from a populated table element

I have a table (called mytbl - see below) consisting of 100 rows. From this table, I want to take only the first five rows (assume a user presses "Show Top Five")
This is what I have tried, however, the alert gives me 'empty'
var $updatedtable = $("#mytbl");
$updatedtable.empty();
for ( var i = 0; i < 5; i++ )
{
$updatedtable.append(document.getElementById("mytbl").rows.item(i).innerHTML)
}
alert($updatedtable);
$updatedtable.appendTo( $( "#rbl" ) );
This was the code used to create the html page
<div class="tab-pane" id="rbl">
<div id="rbldiv">
<div class="bs-example voffset-10px">
<form>
<div class="form-group">
<label for="inputText" style="float:left;margin-right:5px;">Show top </label>
<div class="col-xs-1">
<input type="text" class="form-control input-normal" id="ben-count-set" placeholder="100">
</div>
<label for="inputText"> beneficiaries by cost increase</label>
</div>
</form>
</div>
<table id="mytbl" class="table table-striped table-hover"></table>
</div>
</div>
Also, if, after I successfully manage to get the top five and appendTo rbl which has mytbl, won't this get overwritten? If later the user wants to See Top 30, aren't the values gone? How can I take care of this?
EDIT:
I was able to get the display of the top rows thanks to charlietfl and Tatermelon. But my rows get sliced off, and I haven't completely understood how to handle a case where user selects top 10 first and then top 11.
This is what I have tried.
In the function where I'm making the (entire) table for the first time, I saved the table as follows
function makeTable() {
//code to make table rbltbl
//code to make table rbltbl
//code to make table rbltbl
//code to make table rbltbl
//below line saves the table to $rows, so I can use it inside the click function below
$rows = $('#rbltbl tr').clone();
}
This is my function. Assume 'ben-count-set' is the number of values, the user wants to see. I think I should change var $table to read from $rows instead of rbltbl. But $rows gives empty here.
$("#ben-count-submit").click(function (event) {
event.preventDefault();
console.log("clicked on the update button");
var reqcount = document.getElementById('ben-count-set').value;
var $table = $("#rbltbl");
var $mystring = '#rbltbl tr:gt('+parseInt(reqcount)+')';
$($mystring).remove();
console.log($mystring);
$table.appendTo( $( "#rbl" ) );
}
Please advise.
If you want an array of the first 5 rows can get it right in a jQuery object using several different selectors
$('#mytbl tr:lt(5)');
You can can cache all the rows into a variable and still have access to them later regardless of what you do to the table...just clone them
var $rows = $('#mytbl tr').clone();
Want to remove all but top 5
$('#mytbl tr:gt(4)').remove();
then change out for another selection of rows clone the clone, filter them and insert
$('#mytbl').html( $rows.clone().slice(5, 10) );
If you are using jquery, then you can use the :lt selector:
var $firstRows = $('#mytbl').find('tr:lt(5)');
Then, you can clone them to append in your new table so that they will not be removed from your original table:
$( "#rbl" ).append($firstRows.clone());

Accessing html elements from a div tree with javascript

I need to access title value from some img elements but these elements are deeply implemented in a div tree and after that into some tables.
Let me explain why I need them:
I use a portal where I have information regarding circuits from a network. This portal contains some locations with a few rows (2-3 usually -> circuits for that location). Each row starts with an img element and it can have a few values on title attribute. If the title value is != "No alarms" then I have to take all data from that row and I want to show them via a pop up notification on the bottom right corner near clock.
Below you have a screenshot for how are the html elements organized (for all locations).
http://imageshack.com/a/img661/962/ErjQOt.png
Below you have a screenshot for how is a location organized:
http://imageshack.com/a/img661/7453/QAP5oM.png
If title attribute == "Warning", for example, I have to take the data from the next td's in the same table. Each td has another div without id. Firsts 2 td's on each table have another element inside div: img on first one and a href on the second one.
I'm drawing the tree to show you exactly how are the html elements organized.
<table class="x-grid3-row-table">
<tbody>
<tr>
<td> <!--first td, this contains div->img-->
<div class="x-grid3-cell-inner x-grid3-col-0">
<img .... title="No alarms">
</div>
</td>
<td> <!--second td, this contains div->a href-->
<div class="x-grid3-cell-inner x-grid3-col-1">
<a href...>
</div>
</td>
<td> <!--3rd td, this contains div->string:Text1-->
<div class="x-grid3-cell-inner x-grid3-col-2">Text1</div>
</td>
<td> <!--4th td, this contains div->string:Text2-->
<div class="x-grid3-cell-inner x-grid3-col-2">Text2</div>
</td>
...
</tr>
</table>
Location-1 has 3 circuits, this means 3 tables. The above table is inserted in a div (div class="x-grid3-row x-grid3-row-first" from screenshot2). There are 2 more tables after this one on another div's (div class="x-grid3-row x-grid3-row-alt" & div class="x-grid3-row" from screenshot2) and I have to check the title attribute for each table.
Now my question is how to get the title attribute from each table on the same location? and if the title is != "No alarms" how can I get data from the next td's in that table?
Maybe I can use a loop for all 12 locations or maybe I can get them one by one. This is no big deal because there are only 12 locations but the nasty thing is inside each location to get info from each circuit.
I think there should be a syntax like this to reach each html elements and to get the right value.
var title = $('#ext-gen15-gp-location-1-bd table[0] td[0] img').attr('title');
var title = $('#ext-gen15-gp-location-1-bd table[0] td[1] div[0]').attr('innerHTML');
....
var title = $('#ext-gen15-gp-location-1-bd table[1] td[0] img').attr('title');
var title = $('#ext-gen15-gp-location-1-bd table[1] td[1] div[0]').attr('innerHTML');
...
var title = $('#ext-gen15-gp-location-9-bd table[0] td[0] img').attr('title');
var title = $('#ext-gen15-gp-location-9-bd table[0] td[1] div[0]').attr('innerHTML');
...
...and so on. I'm sure that this syntax is not correct but I think there should be a way to get that data.
I hope that now is explained better then the first time.
EDIT
Guys, thank you very much. You help me a lot. Your codes are working.
Anyway, I just want to ask you something else.
After 3 minutes the whole table is refreshing and I can't find a way to reload the function after that. When the content is refreshing, div ext-gen24 remains empty and after that is refilled with the content:
When is refreshing:
<div class="x-grid3-body" style="width: 1877px;" id="ext-gen24"></div>
After refresh is completed
<div class="x-grid3-body" style="width: 1877px;" id="ext-gen24">content</div>
Can you help me with a function you think it should work in this case ?
You'll need loop through multiple stages of the html: groups, tables, and columns:
var groups = $('.x-grid-group-body'); //hopefully all the '#ext-gen15-gp-location-X-bd' div have 'x-grid-group-body' as the class
groups.each(function () {
var tables = $(this).find('table');
tables.each(function () {
var columns = $(this).find('td');
var image = $(columns[0]).find('img');
var title = image.attr('title');
if (title !== 'No alarms') {
var allInnerHtml = '';
for (var i = 1; i < columns.length; i++) {
allInnerHtml += $(columns[i]).find('div').html() + '\n';
}
alert(allInnerHtml);
}
else {
//just to show that titles with 'No alarm' are skipped
alert('skipped');
}
});
});
See updated JSFiddle
Hope that helps! =)
If your Div tree has classes in the same format is now you can use something like this.
var title = $('.x-panel-bwrap').find('img').attr('title');
Or if the div class dependency is not confirmed, then assuming that img tag will always have a class name starting with 'tick', you can use this.
var title = $('img *[class^="tick"]').attr('title');
EDIT
Now that you have explained your problem more clearly, i've included a fiddle with the solution you need. Now you will have to expand it to suit your code more closely.
For example if you want to log each location separately, start looping through the locations first and then find tables inside them.
Basically you can use Jquery .find and .each to go through your comeplete html and do whetever you want.
var tableList = $('.x-grid3-row-table');
tableList.each(function() {
var imgTitle = $(this).find('img').attr('title');
alert(imgTitle);
if (imgTitle == 'Warning') {
infoTd = $(this).find('td:nth-child(3)');
text = infoTd.find('div').text();
alert(text);
}
});
FIDDLE

difficulty getting list of values from series of input elements inside table rows

I'm completely stumped. Granted, in java script i'm like that kid trying to jam a square peg into a round hole.
My high level objective: The admins want the ability to edit text surrounding some text boxes, as well as the ability to add and remove 'paragraph'. The reporters and users want the values that are in the textboxes to be used in comparisons, etc (which is the original functionality).
My Solution: This project uses a pretty messy value - attribute table (called an EAV?), which now has fields with associated fields and is self referencing. I decided to leverage this to minimize changes to the database, so the admin essentially creates a string, denotes the places a text box belongs using '{}', and assigns a name to the attribute into text boxes that appear directly below the paragraph.
My Problem: Textboxes generate fine, as soon as the admin stops typing the "{}" count is checked client side, and the correct number of textboxes are added/removed in rows below. However, when the "change" mode (and thereby save the new string) I also want to save the attribute names they selected. I can't seem to get the actual value out of the input. The java script below sends null to elementList. Closer inspection indicates that var fieldNames is getting two elements of "undefined" so it makes sense that I'm getting null. Its also apparent that Its hitting something, becuase the number aligns with there being two 'nameField' rows.
DOM (Hemed down to the essentials)
<tr data-editMode="TextMode" data-ordinal="0">
....
<td>
<a class="changeMode">
<tr class="nameField">
<td colspan='4'>
<input type="text" value="Testing">
<tr class="nameField">
....
Javascript
function getAssociatedTr(row) {
var associatedRows = [];
associatedRows.push(row);
row = row.next('tr');
var hasAnother = true;
while (hasAnother == true) {
if (row != null && row.hasClass("nameField")) {
associatedRows.push(row);
row = row.next('tr');
} else {
hasAnother = false;
}
}
return associatedRows;
}
$(".changeMode").live("click", function () {
var options = $(this).data("options");
var theRow = $(this).closest('tr');
var rows = getAssociatedTr(theRow);
var fieldNames = new Array();
rows.splice(0, 1);
for (var index = 0; index < rows.length; index++) {
{
fieldNames.push(rows[index].next('.nameField').val());
}
}
$(".modal-header", c.rowsModal).html("<h3>Changing edit mode" + options.table + "</h3>");
c.rowsModal.modal("show");
$.ajax({
type: "POST",
traditional: true,
data: { "Name": options.table, "Ordinal": options.row, "EditMode": options.editMode, "ElementNames": fieldNames },
url: "/contracts/changeeditmode/" + c.id.val(),
success: function (data) {
theRow.replaceWith(data);
$.validator.unobtrusive.parse("#supplementForm");
c.rowsModal.modal("hide");
for (j = rows.length - 1 ; j >= 0; j--) {
rows[j].remove();
}
}
});
});
Server side
public ActionResult ChangeEditMode(long id, AddTrackedRowViewModel model,
string editMode, List<string> elementNames)
{
}
As a side note, I'm open to constructive criticism on the JavaScript.
EDIT
I have updated the line to
fieldNames.push(rows[index].nextAll('input').first().val());
But still getting undefined.
SOLUTION
fieldNames.push(rows[index].find("input[type=text]").val());
In this line:
fieldNames.push(rows[index].next('.nameField').val());
you are using the selector ".nameField", but this get a "tr" element, if you want the textbox you need this:
fieldNames.push(rows[index].next('.valid').val());
or using other selector that give you the textbox.

Categories