Jquery functions overriding each other - javascript

Question:
I have 2 jQuery function one is a search function and the other is a function to only show column values of a certain type. The problem is if I select a column value with the second function and hide the other rows then try to search those rows it resets and searches all rows.
Fiddle
Code:
Here are the 2 functions:
Search:
$(document).ready(function(){
$("#mySearch").on("keyup", function() {
var value = $(this).val().toLowerCase();
$("#myTable tr td:nth-child(1)").filter(function() {
$(this).parent().toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
});
});
Column:
$(function() {
$('select[name="CPUmenu"]').change(function(e) {
let socket = $(this).val();
$('tbody tr[data-socket]').show();
if (socket.length) {
$('tbody tr[data-socket!="' + socket + '"]').hide();
}
});
$('select[name="CPUmenu"]').trigger('change');
});
Expected result:
I was thinking that the function could only apply to rows that aren't hidden but I'm not sure what the code for that would be.
Update:
I saw the :hidden selector and thought i could use .not(:hidden)
I also plan to add more functions in future so need it to be able to scale.
If you need any more information please let me know.
Thanks

I dont really know what this would do but i think your search function should be like this:
$(document).ready(function(){
$("#mySearch").on("keyup", function() {
var value = $(this).val().toLowerCase();
$("#myTable tr td:nth-child(1)").filter(function() {
if ($(this).parent.css("display") == "block") {
$(this).parent().toggle($(this).text().toLowerCase().indexOf(value) > -1)
}
});
});
});

Here's the working fiddle.
You could add, remove a class when you filter the rows by column and then search based on class usage.
Search Function:
...
if($(this).parent().hasClass("filtered")){
$(this).parent().toggle($(this).text().toLowerCase().indexOf(value) > -1);
}
Column Function:
...
if (socket.length) {
$('tbody tr[data-socket!="' + socket + '"]').hide();
$('tbody tr[data-socket!="' + socket + '"]').removeClass("filtered");
$('tbody tr[data-socket="' + socket + '"]').addClass("filtered");
}

Quick fix, but sorry won't scale well :
$(function() {
$('select[name="CPUmenu"]').change(function(e) {
let socket = $(this).val();
$('tbody tr[data-socket]').removeClass('discarded').show(); /// <<<- here the trick
if (socket.length) {
$('tbody tr[data-socket!="' + socket + '"]').addClass('discarded').hide(); /// <<<-- here as well
}
});
$('select[name="CPUmenu"]').trigger('change');
});
$("#mySearch").on("keyup", function() {
var value = $(this).val().toLowerCase();
$("#myTable tr:not(.discarded) td:nth-child(1)").filter(function() {
$(this).parent().toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
});

Here is the working code:
$(function() {
$('select[name="CPUmenu"]').change(function(e) {
let socket = $(this).val();
$('tbody tr[data-socket]').show();
if (socket.length) {
$('tbody tr[data-socket!="' + socket + '"]').hide();
}
});
$('select[name="CPUmenu"]').trigger('change');
});
$(document).ready(function(){
$("#mySearch").on("keyup", function() {
var value = $(this).val().toLowerCase();
$('select[name="CPUmenu"]').trigger('change');
$("#myTable tr td:nth-child(1)").filter(function() {
if ($(this).parent().is(":visible")) {
$(this).parent().toggle($(this).text().toLowerCase().indexOf(value) > -1)
}
});
});
});

Related

How can I simplify this select function?

I don't know anything about javascript. I just found this snippet in the web when I was trying to find a solution on how to achieve what I need. Is there any way to simplify this since I will be adding around 40 elements that I need to show and hide.
var $selects = $('.filters select');
$selects.on('change', getValues).first().trigger("change");
function getValues() {
var vals = $selects.map(function() {
return this.value;
}).get();
if (vals.join('') === "a1b2c3") {
$(".box_wrapper").not(".a1b2c3").hide();
$(".a1b2c3").show();
$('html,body').animate({
scrollTop: $(".a1b2c3").offset().top},
'slow');
}
else if (vals.join('') === "d4e5f6") {
$(".box_wrapper").not(".d4e5f6").hide();
$(".d4e5f6").show();
$('html,body').animate({
scrollTop: $(".d4e5f6").offset().top},
'slow');
}
else{
$(".vid_box").hide();
}
}
I think I can simplify this further by getting the joined value from the select boxes and use it on the function above and since I am using the same value combination for the class. I just don't know how. Is that possible? Thanks in advance guys!
Perhaps something like this (air code):
var $selects = $('.filters select');
$selects.on('change', getValues).first().trigger("change");
function getValues() {
var vals = $selects.map(function() {
return this.value;
}).get();
var values = [ "a1b2c3", "d4e5f6" ];
var vj = vals.join('');
if (values.indexOf(vj) !== -1) {
$(".box_wrapper").not("." + vj).hide();
$("." + vj)).show();
$('html,body').animate({
scrollTop: $("." + vj)).offset().top
}, 'slow');
}
else {
$(".vid_box").hide();
}
}
I would suggest something like this.
var $selects = $('.filters select');
$selects.on('change', function() {
var value = $selects.map(function() {
return this.value;
}).get();
$(".box_wrapper").not("." + value).hide();
$(".box_wrapper." + value).show();
$('html, body').animate({
scrollTop: $("." + value).offset().top},
'slow');
});
$selects.first().trigger("change");
Here is my final code. Thanks #MJH for all the help.
var $selects = $('.filters select');
$selects.on('change', getValues).first().trigger("change");
function getValues() {
var $selects = $('.filters select');
$selects.on('change', getValues).first().trigger("change");
function getValues() {
var vals = $selects.map(function() {
return this.value;
}).get();
var vwarp = vals.join('');
if (vwarp == vwarp) {
$(".box_wrapper").not("." + vwarp).hide();
$("." + vwarp).show();
$('html,body').animate({
scrollTop: $("." + vwarp).offset().top},
'slow');
}
else{
$(".box_wrapper").hide();
}
}
Hope this helps!

How to append element in the currently clicked table element from popup form?

So I have made a table table elements and functions for the pop up and the form. Appending element on clicking save button also works. However on a new popup the data from the form is appended in every previously clicked table cell no matter if the cell is full or empty.I am somehow trying to populate the cell with currently generated ID . Considering the fact that I me new at JavaScript I am totally missing something Can someone give me idea what is that. The Code
//================ADDs POPUP ON CLICK================/
$(document).ready(function () {
/*Adding the klikanje class to td*/
$('table tbody tr:not(:first) td').addClass('klikanje');
/*removing the klikanje class from the first column*/
$('table tr:first-child, table td:first-child').removeClass('klikanje');
/*removing the klikanje class from the first row*/
$('table tbody tr:first-child td').removeClass('klikanje');
/*Making random id*/
/*appending data atributs to empty td*/
$('.klikanje').click(function(){
var self = $(this);
if ($(this).is(':empty')) {
var idBase = 'clickId-';
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
var idNumber = getRandomInt(1, 1000000);
var clickID = idBase + idNumber
var callingID = '#' + clickID;
$(this).attr({ 'data-toggle': 'modal', 'data-target': '#popUp', 'id': clickID });
/*save to td */
$('#save').click(function () {
var theName = $('input[name=name]').val();
var theLastName = $('input[name=lastname]').val();
var $fullCell = $('<p>' + theName + '' + theLastName + '</p>');
if((theLastName+theLastName).length > 0){
$(callingID).append($fullCell);
$(callingID).css('background-color', 'yellow');
}
}); /*save to td end */
} else {
alert('Already taken spot. Please pick another one!');
$(this).attr({ 'data-toggle': '', 'data-target': '', 'id': '' });
}
});
});//<---ADDs POPUP ON CLICK END
Full code : JsFiddle
You need to just empty the fields after saving the value because same popup html is used again and again and value once entered in the input elements will stay there until manually cleared.
Use below code.
var callingID = "";
$('.klikanje').click(function(){
var self = $(this);
if ($(this).is(':empty')) {
var idBase = 'clickId-';
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
var idNumber = getRandomInt(1, 1000000);
var clickID = idBase + idNumber
callingID = '#' + clickID;
$(this).attr({ 'data-toggle': 'modal', 'data-target': '#popUp', 'id': clickID });
updated fiddle : https://jsfiddle.net/9zcj3ab8/27/
I don't know why this is happening but if you remove the attributes for what I think it's a bootstrap modal you get the desired behavior. I think is something related with you are referencing the modal with every cell you have clicked before, but removing the attributes it seems to work properly.
Update this in your code:
$('#save').click(function () {
var theName = $('input[name=name]').val();
var theLastName = $('input[name=lastname]').val();
var $fullCell = $('<p>' + theName + '' + theLastName + '</p>');
if((theLastName+theLastName).length > 0){
$(callingID).append($fullCell);
$(callingID).css('background-color', 'yellow');
$(this).attr({ 'data-toggle': '', 'data-target': '', 'id': '' });
}); /*save to td end */

How can i display table row depends on matching selected dropdow box values using jquery

I have two multiple dropdownbox and one table and one search button. After i click the search button i want to hide/show the table row depends on selected dropdownbox values matching.How can i do it?anyone help.
JS:
var array1 = [];
var array2 = [];
jQuery('#codexpl tr').each(function () {
var $row = $(this);
var $firstCell = $row.find('td:first');
array1.push($firstCell.text());
var $lastCell = $row.find('td:last');
array2.push($lastCell.text());
});
var selectedBrandarr=[];
var selectedStatusarr=[];
$("#search").on('click', function () {
/*search function*/
$('.multiSel span').each(function (index) {
selectedBrandarr.push($(this).html().replace(/,/g, ""));
})
$('.multiSel2 span').each(function (index) {
selectedStatusarr.push($(this).html().replace(/,/g, ""));
})
jQuery('#codexpl tr').each(function (index) {
var $row = $(this);
var $firstCell = $row.find('td:first');
var $lastCell = $row.find('td:last');
if($firstCell.text()==selectedBrandarr[index] && $lastCell.text() == selectedStatusarr[index] )
{
alert("yes");
$(this).css('display','block')
}
else{
$(this).css('display','none')
alert("not match");
}
});
});
$(".dropdown dt a").on('click', function () {
$(".dropdown dd ul").slideToggle('fast');
});
$(".dropdown dd ul li a").on('click', function () {
$(".dropdown dd ul").hide();
});
function getSelectedValuedropdownbox2(id) {
return $("#" + id).find("dt a span.value").html();
}
$(document).bind('click', function (e) {
var $clicked = $(e.target);
if (!$clicked.parents().hasClass("dropdown")) $(".dropdown dd ul").hide();
});
$('.mutliSelect input[type="checkbox"]').on('click', function () {
var title = $(this).closest('.mutliSelect').find('input[type="checkbox"]').val(),
title = $(this).val() + ",";
if ($(this).is(':checked')) {
var html = '<span title="' + title + '">' + title + '</span>';
$('.multiSel').append(html);
$(".hida").hide();
} else {
$('span[title="' + title + '"]').remove();
var ret = $(".hida");
$('.dropdown dt a').append(ret);
}
});
/*-----------------------------*/
$(".dropdown2 dt a").on('click', function () {
$(".dropdown2 dd ul").slideToggle('fast');
});
$(".dropdown2 dd ul li a").on('click', function () {
$(".dropdown2 dd ul").hide();
});
function getSelectedValuedropdownbox2(id) {
return $("#" + id).find("dt a span.value").html();
}
$(document).bind('click', function (e) {
var $clicked = $(e.target);
if (!$clicked.parents().hasClass("dropdown2")) $(".dropdown2 dd ul").hide();
});
$('.mutliSelect2 input[type="checkbox"]').on('click', function () {
var title = $(this).closest('.mutliSelect2').find('input[type="checkbox"]').val(),
title = $(this).val() + ",";
if ($(this).is(':checked')) {
var html = '<span title="' + title + '">' + title + '</span>';
$('.multiSel2').append(html);
$(".hida2").hide();
} else {
$('span[title="' + title + '"]').remove();
var ret = $(".hida2");
$('.dropdown2 dt a').append(ret);
}
});
Jsfiddle:http://jsfiddle.net/3J2Ns/59/
I would have gone for a server side solution, where you got a search result returned and the table replaced with the results.
If you for some reason want to do this manually on the frontend, one out of the box solution would be to assign each row classes that equates to the select values applicable for that row.
Also store all these class names as an array.
Write a function that hides all the classes, and another that shows all the classes. eg: for each class display none;
Then write a function that would on search, if both of the selects are empty, show all.
Else hide all and then show for each selected classes.
Your table html should be like this (add the 'result-row' class for all rows):
<table ...>
...
<tr class="Apple Active result-row">
<td> Apple </td>
<td>Active</td>
</tr>
... //repeat the same for every row
</table>
You have used input checkboxes, but havent given them a name. You need to give them a name for each group.
eg:
<input type="checkbox" value="Draft" name="option"/>
<input type="checkbox" value="Active" name="option"/>
<input type="checkbox" value="Motorola" name="option"/>
They can all be given the same name since for your purpose, it would both be used for filtering the same list. If there was a requirement to separate them out, I would give each group its own name.
In the javascript:
function hideAll() {
$('.result-row').hide();
}
function showAll() {
$('.result-row').show();
}
function showFiltered() {
if ($('input[name="option"]:checked').length == 0) {
showAll();
}
else {
hideAll();
$('input[name="option"]:checked').each(function() {
$('.' + this.value).show();
});
}
}
Call function showFiltered() on click of any checkbox.
eg:
$('input[name="option"]').on('click', function () {
showFiltered();
});
I have partially updated your jsfiddle.
http://jsfiddle.net/3J2Ns/60/
If you click on your select brand dropdown and select Apple, you would find Blackberry and HTC rows disappearing.

Update atrribute value on click in dynamic table cell span

How do I make the Up buttons to update the attribute value? When I increase the count fx to 5 and then decrease it with Down buttons to 2, and then increase it again, it does not increase from the current value of attr value wich is 2 but continues from 5. I just don't know how to update it after Down button has been clicked. DEMO
$(function() {
var plus = $('.up');
var minus = $('.down');
$(plus).each(function(index, element) {
var count= $(element).closest('tr').find('.times').attr('data-myval');
$(element).click(function() {
count++;
$(element).closest('tr').find('.times').attr('data-myval', count);
$(element).closest('tr').find('.times').text(count +' x');
});
});
$(minus).each(function(index, element) {
$(element).click(function() {
var count= $(element).closest('tr')
.find('.times').attr('data- myval');
count--;
parseInt($(element).closest('tr')
.find('.times').attr('data-myval',count))
$(element).closest('tr').find('.times').text(count +' x');
if (count<2) {
$(element).closest('tr').find('.times').text('');
}
if (count < 1) {
$(this).parents('tr').remove();
}
});
});
});
Please set the countinside the click event for the up button:
$(function() {
var plus = $('.up');
var minus = $('.down');
$(plus).each(function(index, element) {
$(element).click(function() {
var count= $(element).closest('tr').find('.times').attr('data-myval');
count++;
$(element).closest('tr').find('.times').attr('data-myval', count);
$(element).closest('tr').find('.times').text(count +' x');
});
});
$(minus).each(function(index, element) {
$(element).click(function() {
var count= $(element).closest('tr')
.find('.times').attr('data- myval');
count--;
parseInt($(element).closest('tr')
.find('.times').attr('data-myval',count))
$(element).closest('tr').find('.times').text(count +' x');
if (count<2) {
$(element).closest('tr').find('.times').text('');
}
if (count < 1) {
$(this).parents('tr').remove();
}
});
});
});
I hope that helps :D
I refactored your code to avoid putting click handlers inside of a loop. jQuery lets you listen to click events on a per class basis without expressly defining each one.
The contents of each function is largely unchanged, I just saved the elements we need to look up in variables to avoid looking them up repeatedly.
Your problem in the code posted was count being set outside of the click handler. That logic has been moved inside of the .up click handler.
Fiddle
Javascript
$(function() {
$('.up').on('click', function(){
var count = $(this).closest('tr').find('.times');
var curVal = Number(count.attr('data-myval'));
count.attr('data-myval', curVal + 1);
count.text(curVal + 1 + ' x');
})
$('.down').on('click', function(){
var count = $(this).closest('tr').find('.times');
var curVal = Number(count.attr('data-myval'));
curVal--;
count.attr('data-myval', curVal);
count.text(curVal + ' x');
if (curVal < 2) {
count.text('');
}
if (curVal < 1) {
$(this).parents('tr').remove();
}
})
});
I'm guessing you are setting the count outside of the onclick function
var count= $(element).closest('tr').find('.times').attr('data-myval');
So the count may hold the previous value that was set when the last up was pressed.
grab the value first in count variable then increment i update your jsfiddle, i hope its helpful for you
var count = $(element).closest('tr').find('.times').attr('data-myval');
count++;
https://jsfiddle.net/j9vnbcf0/13/
You just don't need to go through for .each function for each plus/minus btns, simply call .click function on them directly, it works that way-
JS-
$(function() {
var plus = $('.up');
var minus = $('.down');
$(plus).click(function() {
var count= $(this).closest('tr').find('.times').attr('data-myval');
count++;
// console.log(count);
$(this).closest('tr').find('.times').attr('data-myval', count);
$(this).closest('tr').find('.times').text(count +' x');
});
$(minus).click(function() {
var count= $(this).closest('tr').find('.times').attr('data-myval');
count--;
parseInt($(this).closest('tr').find('.times').attr('data-myval',count))
$(this).closest('tr').find('.times').text(count +' x');
if (count<2) {
$(this).closest('tr').find('.times').text('');
}
if (count < 1) {
$(this).parents('tr').remove();
}
});
});
Here goes the updated link-
https://jsfiddle.net/j9vnbcf0/14/

collapsible/expandable table behaviour

need help with some jquery/js/jsp functionality..
I have a collapsible table script:
(function($){
$.fn.extend({
setupCollapstable: function(options) {
var defaults = {
displayStyle: "Image",
autoCheckbox: true,
toggleMinus: "/resource/images/collapse_close.gif",
togglePlus: "/resource/images/collapse_open.gif"
};
var options = $.extend(defaults, options);
var toggleMinus = options.toggleMinus
var togglePlus = options.togglePlus
return this.each(function() {
//Creating a reference to the object
var obj = $(this);
//Break out the individual tbody elements
var rowGroups = $('tbody', obj);
//Loop through every tbody to setup collapsable and click events
$.each( rowGroups, function( intIndex, objValue ){
parentRow = $('th:first-child', objValue);
childCount = parentRow.parent().siblings().length;
if (childCount != 0) {
//console.log ("ParentRow: " + parentRow + " - ChildCount is: " + childCount);
parentRow.prepend('<img src="' + togglePlus + '" alt="collapse this section" />');
parentRow.parent().siblings().fadeOut('fast');
$('img', parentRow).addClass('clickable').click(function(e) {
e.preventDefault();
var toggleSrc = $(this).attr('src');
if ( toggleSrc == toggleMinus ) {
$(this).attr('src', togglePlus).parents('tr').siblings().fadeOut('fast');
} else{
$(this).attr('src', toggleMinus).parents('tr').siblings().fadeIn('fast');
};
});
var parentCheckbox = $(':checkbox', parentRow.siblings())
var childCheckboxes = $(':checkbox', parentRow.parent().siblings());
parentCheckbox.click(function(e){
var checked_status = parentCheckbox.attr('checked')?1:0;
childCheckboxes.each(function(){
this.checked = checked_status;
});
});
} else {
parentRow.addClass("indented");
}
});
//console.dir (objValue);
});
}
});
})(jQuery);
From my JSP I call it as such....
<script type="text/javascript" src="/resource/js/jquery.collapstable.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('table.collapstable').setupCollapstable();
});
</script>
usage:
<table class="collapstable NoTableBorder">
when I click on the image icon the table properly collapses and expands, however I want it to be initially expanded if a certain checkbox is checked (on the JSP).
so I would have an onclick="showOrHide()" function for that checkbox input which would collapse or expand the table.
i've attached an image to for a visual representation, the collpase table is the "+/-" icon (next to the bold VISA header) while the checkbox which decides if it should be expanded for shown is the "active" checkbox..
any help with this would be amazing...
You can add a condition just before the collapse / expand function call
<script type="text/javascript">
$(document).ready(function(){
if (checkboxname.checked){
// Set flags to show the table expanded
}else{
// Set flags to show the table collapsed
}
$('table.collapstable').setupCollapstable();
});
</script>

Categories