Using a select form field with values of "10", "20", "30", how could you reveal / hide that number of tr rows in a table onchange of the dropdown?
Something like:
$("#rows").change(function(){
var num_rows = $(this).val();
$("#data tr").reveal(num_rows) (???)
});
EDIT: rows should be added / removed starting from the bottom of the table.
A sliding show / hide effect would be great.
as kennis answered, use jQuery's slice() method.
I've put together a working example that you can try here: http://jsfiddle.net/a9TQ5/
HTML Markup:
<table id="mytable">
<tbody>
<tr><td>1</td></tr>
<tr><td>2</td></tr>
<tr><td>3</td></tr>
...
</tbody>
</table>
Javascript Code:
function show (min, max) {
var $table = $('#mytable'), // the table we are using
$rows = $table.find('tbody tr'); // the rows we want to select
min = min ? min - 1 : 0;
max = max ? max : $rows.length;
$rows.hide().slice(min, max).show(); // hide all rows, then show only the range we want
return false;
}
Using this function you are able to control the number of rows in #mytable by using these examples:
show(); // show all rows
show(1, 10); // show rows 1 - 10
show(1, 20); // show rows 1 - 20
show(3, 7); // show rows 3 - 7
show(20); // show rows 20 and up
You can bind this function to the change on a <select> like so:
HTML:
<select id="limit">
<option value="0">None</option>
<option value="5">5</option>
<option value="10">10</option>
<option value="15">15</option>
<option value="20">20</option>
<option value="" selected>All</option>
</select>
Javascript:
$('#limit').bind('change', function () {
show(0, this.value);
});
Let me know if this is what you had in mind...
I think this should work.
$("#rows").change(function(){
var num_rows = $(this).val();
$("#data tr").slice(num_rows).hide();
});
So, I needed a break from work so I decided to throw this together (hopefully I read your question correctly ;)):
$(document).ready(function(){
$('#rows').change(function(){
if($('#tbl tr').length !== parseInt($(this).val()))
{
(u = function(){
if($('#tbl tr').length < parseInt($('#rows').val()))
{
var id = $('#tbl tr').length;
var e = $('#tbl').append('<tr style="display: none;" id="'+id+'"><td>foo</td></tr>');
$('#'+id).fadeIn('fast', function(){
if($('#tbl tr').length < parseInt($('#rows').val())) u();
});
}
else if($('#tbl tr').length > parseInt($('#rows').val()))
{
var id = $('#tbl tr').length-1;
$('#tbl #'+id).fadeOut('fast', function(){
$(this).remove();
if($('#tbl tr').length >= parseInt($('#rows').val())) u();
});
}
})();
}
});
});
Using this, you can reveal/hide any number of rows in a table with nifty little tail calling fade in and outs.
Of course, this was quickly hacked together and there's all kinds of optimizations that could be done.
Fiddle sample here
Related
I have 4 dropdown list <td> <select class="encoderSelect" id="encoder1"><option value="None">-- Select User Command --</option><option value="1920*1080">1920*1080</option> <option value="320*240 to 1280* 720">320*240 to 1280*720</option> <option value="720*480">720*480</option> <option value="320*240 to 1920*1080">320*240 to 1920*1080</option> </select></td>
there is another 3 dropdown also there id is like encoder2,encoder3 and encoder4. I want to hide a the options if it is selected in any 4 of this list. I used this code by call class name but its not worked.
$('.encoderSelect').change(function(){
var optionval = $('.encoderSelect').val();
console.log(optionval);
$(".encoderSelect option[value='"+optionval+"']").hide();
});
$('.encoderSelect').on("change", function(){
$('.encoderSelect:selected', this).hide().siblings().show();
}).trigger('change'); // this code also tried but not worked
can I implement this using class.? or I must go by using id..?
$('#encoder1').on("change", function(){
var selected = $('#encoder1').val();
for (var i = 0; i<$('#encoder1').children().length; i++) {
var element = $('#encoder1 option:eq('+i+')');
if ($(element).text() === selected) {
$(element).hide();
} else {
$(element).show();
}
}
});
demo
Please try this. I hope it works fine and helps your project.
<script>
$(document).ready(function() {
$('select.encoderSelec').on('change', function(event) {
var prevValue = $(this).data('previous');
$('select.encoderSelec').not(this).find('option[value="'+prevValue+'"]').show();
var value = $(this).val();
$(this).data('previous',value); $('select.encoderSelec').not(this).find('option[value="'+value+'"]').hide();
});
});
</script>
Demo
How to sort list items by priority? This is a to-do list. User can input an item, choose a priority, and add to list.
This is my HTML form:
<input id="task" type="text"/>
<select id="priority">
<option id="Normal">Normal</option>
<option id="Urgent">Urgent</option>
<option id="Critical">Critical</option>
<option id="If You Can">If You Can</option>
</select>
<button onclick="amitFunction()">Add</button>
<hr/>
<table>
<tr>
<th id="result"></th>
<th id="priorit"></th>
</tr>
<table>
This is my JS:
function amitFunction() {
/* Define vars and values */
var lia = document.createElement("p");
var lib = document.createElement("p");
var item = document.getElementById('task').value;
var pro = document.getElementById('priority').value;
var pro_array = ['Urgent','Critical','Normal'];
var item_list = document.createTextNode(item);
var item_pro = document.createTextNode(pro);
lia.appendChild(item_list);
lib.appendChild(item_pro);
/* Check if text is less than 6 chars or more than 42 chars */
if (item.length<6) {
alert('Your text must have a least 6 chars');
} else if (item.length>42) {
alert('Your text must have less than 42 chars');
} else {
document.getElementById("result").appendChild(lia);
document.getElementById("priorit").appendChild(lib);
document.getElementById('task').value='';
}
/* Change text color base on priority */
if (pro==pro_array[0]) {
$("p:last-child").css('color','red');
}
if (pro==pro_array[1]) {
$("p:last-child").css('color','orange');
}
if (pro==pro_array[2]) {
$("p:last-child").css('color','green');
}
/* Delete text when user clicks on it */
$([lia,lib]).click(function(){
$([lia,lib]).css('color','gray');
$([lia,lib]).css("text-decoration", "line-through");
});
}
What I need is, when user adds a new item, it will sort by priority order.
first : Urgent
second : Critical
third : Normal
fourth : If You Can
Each new item that user adds, should be sorted like that. How can I do that?
This is the complete script (JSBin) to understand what I need.
First of all I would suggest you create a new table row every time you create a TODO task, however I decided to keep as much of your code as I could and implement what you asked for. I will admit that it is not the best decision and could be optimized a lot, however I am leaving it as it is simply because there might be many interesting cases in the code that might teach you something new. The sorting is implemented. I hope this helps :)
Your html, left as it was:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<input id="task" type="text"/>
<select id="priority">
<option id="Normal">Normal</option>
<option id="Urgent">Urgent</option>
<option id="Critical">Critical</option>
<option id="If You Can">If You Can</option>
</select>
<button onclick="amitFunction()">Add</button>
<hr/>
<table>
<tr>
<th id="result"></th>
<th id="priorit"></th>
</tr>
<table>
</body>
</html>
and the edited JS code:
//creating a global collection to hold your todo list in memory
var todo_list = [];
function amitFunction() {
var item = document.getElementById('task').value;
/* Check if text is less than 6 chars or more than 42 chars
and return if validation is not passed */
if(item.length<6){
alert('Your text must have a least 6 chars');
return;
}else if(item.length>42){
alert('Your text must have less than 42 chars');
return;
}
var pro = document.getElementById('priority').value;
//keep this for colors
var pro_array = ['Urgent','Critical','Normal'];
//map string priorities to numeric values
var priorities =
{
'Urgent' : 0,
'Critical' : 1,
'Normal' : 2,
'If You Can' : 3
}
//push each new task in the todo list
todo_list.push(
{
priority : pro,
task : item
}
);
//Now this here is perhaps the most important part,
//this is where you sort your todo list based on the
//mapped to numeric values priorities
todo_list.sort(function (task1, task2) {
return priorities[task1.priority] - priorities[task2.priority];
});
//clear the containers holding your list
var resultNode = document.getElementById("result");
while (resultNode.firstChild) {
resultNode.removeChild(resultNode.firstChild);
}
var priorityNode = document.getElementById("priorit");
while (priorityNode.firstChild) {
priorityNode.removeChild(priorityNode.firstChild);
}
//recreate the DOM based on the todo_list collection
for(var i =0; i < todo_list.length; i++)
{
var lia = document.createElement("p");
var lib = document.createElement("p");
var item_list = document.createTextNode(todo_list[i].task);
var item_pro = document.createTextNode(todo_list[i].priority);
lia.appendChild(item_list);
lib.appendChild(item_pro);
document.getElementById("result").appendChild(lia);
document.getElementById("priorit").appendChild(lib);
document.getElementById('task').value='';
/* Change text color base on priority */
if(todo_list[i].priority == pro_array[0]){
$("p:last-child").css('color','red');
}
if(todo_list[i].priority == pro_array[1]){
$("p:last-child").css('color','orange');
}
if(todo_list[i].priority == pro_array[2]){
$("p:last-child").css('color','green');
}
}
//reinitialize the click handlers
var resultNode = document.getElementById("result");
var priorityNode = document.getElementById("priorit");
for(var i =0; i< resultNode.childNodes.length; i++) (function(i){
resultNode.childNodes[i].onclick = function() {
$([resultNode.childNodes[i],priorityNode.childNodes[i]]).css('color','gray');
$([resultNode.childNodes[i],priorityNode.childNodes[i]]).css("text-decoration", "line-through");
}
priorityNode.childNodes[i].onclick = function() {
$([resultNode.childNodes[i],priorityNode.childNodes[i]]).css('color','gray');
$([resultNode.childNodes[i],priorityNode.childNodes[i]]).css("text-decoration", "line-through");
}
})(i);
}
And a working example here:
https://jsbin.com/kudipacexi/edit?html,js,output
In fact there are plenty of approaches, another approach would be to not keep a global collection for your list, instead do the sorting directly using the DOM elements, however you will still have to keep some kind of numeric representation of your priorities in order to sort them by priority. It might also be a good idea to subscribe each of the elements to a single click handler function, then add the line-through style based on the caller of the function. Another thing I'd suggest is, if you are involving jQuery and not focusing on just Vanilla JS, try and use jQuery for the majority of the DOM manipulation.
Because you have a table I suggest to use that as the output.
You can rearrange your select in order to add for each option a priority number and a color attribute like:
<option value="2" color="green">Normal</option>
The table can contain a first column as the current row priority. This column will be hidden.
Each time a new row must be added a sorting process is executed on table rows.
The snippet:
$('button').on('click', function (e) {
var priorityValue = $('#priority option:selected').val();
var priorityText = $('#priority option:selected').text();
var colorVal = $('#priority option:selected').attr('color');
var taskValue = $('#task').val();
if (taskValue.length < 6) {
$('#errMsg').text('Your text must have a least 6 chars');
return;
} else if (taskValue.length > 42) {
$('#errMsg').text('Your text must have less than 42 chars');
return;
}
$('#errMsg').text('');
//
// create the new table row...
//
var newRow = $('<tr/>', {style: 'color:' + colorVal})
.append($('<td/>', {style: "display: none", text: priorityValue}))
.append($('<td/>', {text: taskValue}))
.append($('<td/>', {text: priorityText}));
//
// enlarge current table rows with the current one and sort elements
//
var tableRowsSorted = $('#result tbody').append(newRow).find('tr').get().sort(function(a, b) {
var p1 = +$(a).find('td:first').text();
var p2 = +$(b).find('td:first').text();
return p1 - p2;
});
//
// append/replace the taable body
//
$('#result tbody').append(tableRowsSorted);
//
// reset input text
//
$('#task').val('');
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="task" type="text"/><span id="errMsg" style="color: red;"></span>
<select id="priority">
<option value="2" color="green">Normal</option>
<option value="0" color="red">Urgent</option>
<option value="1" color="orange">Critical</option>
<option value="3" color="black">If You Can</option>
</select>
<button>Add</button>
<hr/>
<table id="result">
<thead>
<tr>
<th style="display: none">priority</th>
<th>result</th>
<th>priority</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
I would like to clone a select and update the name and id values. The select is within a <tr><td>
<table>
<tr id="tr_1">
<td id="td_1">
<select name="tech_1" id="tech_1">
<option value="0">Please Select</option>
<option value="1">Mango</option>
<option value="2">Apple</option>
<option value="3">Banana</option>
<option value="4">Orange</option>
</select>
</td>
</tr>
</table>
<input type="button" id="btnClone" value="Clone" />
I can do it without the table, but my challenge is putting the clone within a new <tr><td> ... </td></tr>
Here is my jquery:
$("#btnClone").bind("click", function () {
// get the last SELECT which ID starts with ^= "tech_"
var $tr = $('tr[id^="tr_"]:last');
// get the last SELECT which ID starts with ^= "tech_"
var $select = $('select[id^="tech_"]:last');
// Read the Number from that SELECT's ID (i.e: 3 from "tech_3")
// And increment that number by 1
var num = parseInt( $select.prop("id").match(/\d+/g), 10 ) +1;
// Clone it and assign the new ID (i.e: from num 4 to ID "tech_4")
var $klon = $select.clone().prop('id', 'tech_'+num ).prop('name', 'tech_'+num );
// Finally insert $klon wherever you want
$tr.after("<tr><td>").after($klon).after("</td></tr>");
});
This code results in the cloned <select> below the original and nothing between the new <tr><td> and </td></tr>
Add tr and td first with the id of tr and then add select to the td under new tr like following.
$("#btnClone").bind("click", function () {
var $tr = $('tr[id^="tr_"]:last');
var $select = $('select[id^="tech_"]:last');
var num = parseInt($select.prop("id").match(/\d+/g), 10) + 1;
var $klon = $select.clone().prop('id', 'tech_' + num).prop('name', 'tech_' + num);
$tr.after($("<tr id=tr_" + num + "><td></td></tr>")); // change here
$('#tr_' + num + ' td').append($klon); // change here
});
Try to append the select element after creating the tr and td,
$tr.after($("<tr><td></td></tr>").find("td").append($klon).end());
You should create the elements rather than appending html.
var $klon = $select.clone().prop('id', 'tech_'+num ).prop('name', 'tech_'+num );
var newTr = $('<tr/>');
var newTd = $('<td/>');
newTr.insertAfter($tr);
newTr.append(newTd);
newTd.append($klon);
Working example : https://jsfiddle.net/DinoMyte/raz34m93/
Try using jQuery(html, attributes) ; also, to include childNodes of cloned element, add true to .clone(true) , see .clone()
$tr.after($("<tr>", {append:$("<td>", {append:$klon})}))
$("#btnClone").on("click", function() {
// get the last SELECT which ID starts with ^= "tech_"
var $tr = $('tr[id^="tr_"]:last');
// get the last SELECT which ID starts with ^= "tech_"
var $select = $('select[id^="tech_"]:last');
// Read the Number from that SELECT's ID (i.e: 3 from "tech_3")
// And increment that number by 1
var num = parseInt($select.prop("id").match(/\d+/g), 10) + 1;
// Clone it and assign the new ID (i.e: from num 4 to ID "tech_4")
var $klon = $select.clone(true).prop('id', 'tech_' + num).prop('name', 'tech_' + num);
// Finally insert $klon wherever you want
$tr.after(
$("<tr>", {
append: $("<td>", {
append: $klon
})
})
)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table>
<tr id="tr_1">
<td id="td_1">
<select name="tech_1" id="tech_1">
<option value="0">Please Select</option>
<option value="1">Mango</option>
<option value="2">Apple</option>
<option value="3">Banana</option>
<option value="4">Orange</option>
</select>
</td>
</tr>
</table>
<button id="btnClone">click</button>
I wrote a question show hide jquery table rows for imported xml data about how to show hide some table rows using jquery, and now using the same question, I want to know how to force the first 5 elements to show up. I used the following code in my example:
$(document).ready(function(){
$.ajax({
type: "GET",
url: "test.xml",
dataType: "xml",
success: function(xml) {
$(xml).find('event').each(function(){
var Col0 = $(this).find('title').text();
var Col1 = $(this).find('country').text();
var Col2 = $(this).find('date').text();
var Col3 = $(this).find('time').text();
var Col4 = $(this).find('course').text();
var Col5 = $(this).find('topic').text();
var Col6 = $(this).find('pre-course').text();
$('<tr></tr>').html('<th>'+Col0+'</th><td>'+Col1+'</td><td>'+Col2+'</td><td>'+Col3+'</td><td>'+Col4+'</td><td>'+Col5+'</td><td>'+Col6+'</td>').appendTo('#test');
initalizeTable();
});
}
});
});
and html:
<table id="test">
<tr><td></td><th>country</th>
<th>Date</th><th>time</th>
<th>course</th><th>topic</th>
<th>pre-course</th></tr>
</table>
And then I used the javascript to display only some display options:
function initalizeTable() {
function show (min, max) {
var $table = $('#test'), $rows = $table.find('tbody tr');
min = min ? min - 1 : 0;
max = max ? max : $rows.length;
$rows.hide().slice(min, max).show();
return false;
}
$('#limit').bind('change', function () {
show(0, this.value);
});
}
I had to wrap the above code to include it in the first code so that it loads directly after the data being imported to html.
and here is the html I used to change the display option manually:
<select id="limit">
<option value="0">None</option>
<option value="5"selected>5</option>
<option value="10">10</option>
<option value="15">15</option>
<option value="20">20</option>
<option value="" >All</option>
</select>
now everything works great, except that the data are imported in full table where I want to force showing only the first 5 rows in the table.
any idea how to do that??
Thanks
You could call show(0,5); at the end of your initalizeTable() function.
Or trigger your select's change event just after you bind it so that it automatically picks up the maximum value from the drop-down's currently selected option:
$('#limit').bind('change', function () {
show(0, this.value);
}).trigger('change');
I'm having a table like
Header1 | Header2 | Header3 | Header 4 | Header 5
Row 1 |<span>Some Text</span> | <select></select>
Row 2
Row 3
.
.
.
.
Rows dynamically generated.
Now my goal is to change the value and color of <span>Some Text</span> in second column on change of <select></select> which is in same row in header 4 column and do distinctively same for all the rows dynamically generated.
I was approaching for generating dynamic id's through jquery but not sure how this would be possible.
Tried to create a jsfiddle for better understanding of the question
http://jsfiddle.net/y8Cj3/2/
You could do it somewhat in this way (this is based on your fiddle):
$(".myselect").change(function() {
var $tr = $(this).closest("tr");
$tr.find("td:eq(1) span").css("color", "blue").text(this.value);
// Those are columns 5 and 6
$tr.find("td:eq(4)").text(this.value);
$tr.find("td:eq(5)").text(this.value);
});
Example
Working Demohttp://jsfiddle.net/cse_tushar/y8Cj3/3/
function changeValue(){
$('tr td span').css('color','blue');
$('tr:gt(0) td:nth-child(5)').text('hi');
$('tr:gt(0) td:nth-child(6)').text('new');
}
An example here
$('#mySelect').on('change', function(){
$(this).closest('tr').find('td').eq(1).find('span')
.text($(this).val()).css('color', 'green');
});
Notice $('#mySelect'), it's been used as the id of the select like <select id="mySelect">. You can use a class too, like <select class="mySel"> and can select it using $('.mySel').
$(document).on('change', '.theChanger', function (e) {
console.log(e);
var $myTR = $(this).closest('tr');
$myTR.find('td:eq(1) span').css('color', 'blue').text('NEW TEXT');
$myTR.find('td:eq(4)').css('color', 'orange').text('NEW TEXT');
$myTR.find('td:eq(5)').css('color', 'orange').text('NEW TEXT')
});
jsFIDDLE
I used a new class of theChanger in the select element. I particularly used a class and not an ID because you will have multiple rows and IDs must be unique per page.
No need to generate dynamic IDs (I assume you will attach this IDs to the row element - tr).
Anyhow, I've forked your fiddle and created an example of how you can change the color based on the select value (on a per row).
your row:
<tr>
<td class="some-text"><span class="color-option-a">Some Text</td>
<td>
<select class="color-changer">
<option value="excluded" selected="selected">Excluded</option>
<option value="Other">Other</option>
<option value="Alternate">Alternate</option>
</select>
</select>
</tr>
css:
.color-option-a {
color: red;
}
.color-option-b {
color: green;
}
.color-option-c {
color: blue;
}
jquery:
$('.color-changer').on('change', function(){
var currentRow = $(this).closest('tr');
var targetColumn = $('.some-text', currentRow);
var targetSpan = $('span', targetColumn);
var newColor = 'color-option-a';
switch($(this).val()) {
case 'Alternate':
newColor = 'color-option-b';
break;
case 'Other':
newColor = 'color-option-c';
break;
case 'excluded':
newColor = 'color-option-a'; //default
break;
}
//reset the color to none first and then apply the new one
targetSpan.attr('class', '');
targetSpan.addClass(newColor);
});
http://jsfiddle.net/Qccba/2/
Hope it helps!