table row text truncation - javascript

I have a table which has more/less functionality in the row level. I need to include Expand/Collapse All option in the table level so it will be easier to expand all the rows at once.
In my current code, row level and table level expanding works fine on it's individual.
But when I expand using Expand All link, row level more/less links should also act together. Currently when Expand All link is clicked, row level more/less link still shows as More link but it should get changes to Less link.
Here is my code,
var minimized_elements = $('.grid_moretext span');
minimized_elements.each(function(){
var t = $(this).text();
if(t.length < 55) return;
$(this).html(
t.slice(0,55)+'<span>... </span>'+
'<span class="more_text" style="display:none;">'+ t.slice(55,t.length)+' </span>'
);
});
$('a.tr_expand').click(function(event){
event.preventDefault();
$(this).parent().siblings().find("span.more_text").toggle();
if ($(".tr_expand").text() == "More") {
$(".tr_expand").text("Less");
}
else {
$(".tr_expand").text("More");
}
});
$('a.more', minimized_elements).click(function(event){
event.preventDefault();
$(this).hide().prev().hide();
$(this).next().show();
});
$('a.less', minimized_elements).click(function(event){
event.preventDefault();
$(this).parent().hide().prev().show().prev().show();
});
$('a.expand_all').click(function(event){
event.preventDefault();
$(this).next().find(".grid_moretext span.more_text").toggle();
if ($(".expand_all").text() == "Expand All") {
$(".expand_all").text("Collapse All");
}
else {
$(".expand_all").text("Expand All");
}
});
DEMO

I have update a working fiddle with collapse
I have made the following changes:
Use $(this) to set the clicked expand link text rather than the whole class selection ;
$('a.tr_expand').click(function(event){
event.preventDefault();
$(this).parent().siblings().find("span.more_text").toggle();
// console.log($(".tr_expand").text());
if ($(this).text() == "More") {
$(this).text("Less");
}
else {
$(this).text("More");
}
});
In the expand all button, loop through the expand links and simply trigger the click of the link if it has 'More' text, if the row is already expanded, the toggle will collapse it again which was not the expected behavior.
$('a.expand_all').click(function(event){
event.preventDefault();
$('a.tr_expand').each(function(){
if($(this).text() == "More" && $('a.expand_all').text() == "Expand All" )
{
$(this).trigger('click');
}
else if($(this).text() == "Less" && $('a.expand_all').text() == "Collapse All" )
{
$(this).trigger('click');
}
});
if ($(this).text() == "Expand All") {
$(this).text("Collapse All");
}
else {
$(this).text("Expand All");
}
});

DEMO
Two things
One
$('a.tr_expand').click(function(event){
event.preventDefault();
$(this).parent().siblings().find("span.more_text").toggle();
//use $(this) to target current anchor element and check its text with .html
if ($(this).html() == "More") {
$(this).html("Less");
}
else {
$(this).html("More");
}
});
Two
Inside expand_all event click change the html again based on current value
$('a.expand_all').click(function(event){
event.preventDefault();
$(this).next().find(".grid_moretext span.more_text").toggle();
var elem=$(this).next().find('.tr_expand')
if(elem.html()=="More")//check for html again
elem.text('Less');
else
elem.text('More');
});
UPDATE
DEMO
Add a class to tr_expand while clicking on itself and on Expand All to identify whether it has been already expanded or collapsed as below:
$('a.tr_expand').click(function(event){
event.preventDefault();
var elem=$(this).parent().siblings().find("span.more_text");//store reference to element's more_text
elem.toggle();//toggle it
$(this).toggleClass('expand');//toggleClass expand
if ($(this).html().trim() == "More") {
$(this).html("Less");
}
else {
$(this).html("More");
}
});
Next on Expand_all click Loop through each tr_expand and its siblings and toggle it based on presence of class on tr_expand as below:
$('a.expand_all').click(function(event){
event.preventDefault();
$('.tr_expand').each(function(){
var elem=$(this);
if(!elem.hasClass('expand'))//check if element is already expanded
{
//if no find all its `grid_moretext` element and toggle its span.more_text
elem.closest('td').siblings(".grid_moretext").each(function(){
$(this).find("span.more_text").toggle();
});
if(elem.html()=="More")
{
$('a.expand_all').text('Collapse All')
elem.text('Less');
}
else
{
$('a.expand_all').text('Expand All')
elem.text('More');
}
}
else
elem.toggleClass('expand'); //if expand is not there add it again
});
});

Use this so that it will refer to the clicked More link.
if ($(this).text() == "More") {
$(this).text("Less");
}
else {
$(this).text("More");
}

Here is the updated fiddle - http://jsfiddle.net/z9hzstzc/1/ . I have changed the condition check for $('tr.expand') by putting it in a loop.

I have did following changes in your Fiddle
$('a.expand_all').click(function(event){
if ($(".tr_expand").html() == "More") {
$(".tr_expand").html("Less");
}
else {
$(".tr_expand").html("More");
}
event.preventDefault();
$(this).next().find(".grid_moretext span.more_text").toggle();
});
Here is DEMO

Using this jQuery:
$('a.tr_expand').text(function (i, t) {
return t == 'More' ? 'Less' : 'More';
});
you can easily achieve what you're seeking.
Here I've updated your JSFiddle
// For individual click events
$('a.tr_expand').click(function (event) {
event.preventDefault();
$(this).parent().siblings().find("span.more_text").toggle();
$(this).text(function (i, t) {
return t == 'More' ? 'Less' : 'More';
});
});
//For group toggle
$('a.expand_all').click(function (event) {
event.preventDefault();
$(this).next().find(".grid_moretext span.more_text").toggle();
$('.tr_expand').text(function (i, t) {
return t == 'More' ? 'Less' : 'More';
});
});
It will do the trick for you.

Related

Change and change back text in button jquery

I would like to have a jquery button event where the first time a button is clicked a div (with class .explanation) appears and the text changes and the second time it is clicked the div is hidden and the text changes back to the original text. I can do the first part but the second part does not work. In the below changing - (toggleClass("hidden") - to - .fadeOut... - doesn't work either so I think I have got something wrong with if and else. Thanks in advance
$("button:nth-of-type(1)").click(function() {
if (this.text = "Read Explanation") {
$(".explanation").fadeIn("slow", function() {});
$(this).text("Hide Explanation");
} else {
$(this).text("Read Explanation");
$(".explanation").toggleClass("hidden");
}
});
change
if(this.text = "Read Explanation") {
to
if($(this).text() === "Read Explanation") {
a demo:
$("button:nth-of-type(1)").click(function() {
if ($(this).text() === "Read Explanation") {
//$(".explanation").fadeIn("slow", function() {});
$(this).text("Hide Explanation");
} else {
$(this).text("Read Explanation");
}
$(".explanation").toggleClass("hidden");
});
.hidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<div><button>Read Explanation</button></div>
<div class="explanation hidden">explanation</div>
$(this) is jquery object with text() attribute while this is pure js
object without text or text() attribute in this case.
= is assignment operator while === is Comparison operators
There are several issues in your code:
this should be $(this)
text should be text()
You are using assignment operator in if condition. It should be comparison operator == or strict comparison operator ===
You can toggle the hidden class outside if-else block
$( "button:nth-of-type(1)" ).click(function() {
if($(this).text() == "Read Explanation") {
$(this).text("Hide Explanation");
} else {
$(this).text("Read Explanation");
}
$(".explanation").toggleClass("hidden");
});
.hidden{
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='explanation hidden'>Some explanation</div>
<button>Read Explanation</button>
you can't make decisions based on data that can change.
if the text of the button changes, you'll need to change your code.
by this way, if the text of the button changes, you need to change your data.
This is not the best option, but it may works.
https://jsfiddle.net/foo8drb2/8/
var data = {
1: "Read Explanation",
2: "Hide Explanation"
}
// asssign default id to the text
var id_text = 1; //1 id for "Read Explanation"
// add data attribute to the button
$("button:nth-of-type(1)").attr("data-id-text", id_text);
// event
$("button:nth-of-type(1)").click(function () {
if ($(this).attr("data-id-text") == 1) {
//change id_text -> 2 for "Hide Explanation"
id_text = 2;
// show hide options
$(".explanation").fadeIn();
} else {
//change id_text -> 1 for "Read Explanation"
id_text = 1;
// show hide options
$(".explanation").fadeOut();
}
// change data id
$(this).attr("data-id-text", id_text);
// update text
$(this).text(data[id_text]);
});
Thanks everyone. This seems to be the simplest / close to what I had. I changed as suggested by Ankit:
this to $(this)
text to text()
= to ==
Using - fade out - instead of - hide - helped
$( "button:nth-of-type(1)" ).click(function() {
if($(this).text() == "Read Explanation") {
$(".explanation").fadeIn( "slow", function() {
});
$(this).text("Hide Explanation");
} else {
$(this).text("Read Explanation");
$(".explanation").fadeOut( "slow", function() {
});
}
});

jQuery group of checkbox issue

I have two group of checkbox newBuilding & oldBuilding.
Idea over here is I can select checkbox only one of the group.
In each group there is checkbox name other area, so I when click on it, it will show and hide textbox next to it.
Now to achieve first point, lets for example that already we have oldBuilding checkboxes are checked and I if I click one of the newBuilding checkbox then it will remove the check from oldBuilding group but newBuilding checkbox will not get checked but just get focus, I have to click again to check.
What I found out that above issue happen when I call trigger event. How can I overcome the issue
Code for other area
$("#chkOldBuildingOtherAreas").change(function () {
if ($("#chkOldBuildingOtherAreas").is(":checked"))
$("#txOldOtherAreas").show();
else
$("#txOldOtherAreas").hide();
});
$("#chkNewBuildingOtherAreas").change(function () {
if ($("#chkNewBuildingOtherAreas").is(":checked"))
$("#txNewOtherAreas").show();
else
$("#txNewOtherAreas").hide();
});
Code for removing check mark from other groups
$("input[name='oldBuilding']").change(function () {
if ($("input[name='newBuilding']:checked").length > 0) {
$("input[name='newBuilding']").removeAttr('checked');
$("#chkNewBuildingOtherAreas").trigger("change");
}
});
$("input[name='newBuilding']").change(function () {
if ($("input[name='oldBuilding']:checked").length > 0) {
$("input[name='oldBuilding']").removeAttr('checked');
$("#chkOldBuildingOtherAreas").trigger("change");
}
});
My jsfiddle
https://jsfiddle.net/milindsaraswala/wchrwjnx/
https://jsfiddle.net/1ny36nwL/4/
var groups = ['.oldGroup', '.newGroup'];
$(groups.join(',')).find('input[type=text]').hide();
function resetGroup(selector) {
//clear and hide texts
$('input[type=text]', selector).val('').hide();
//uncheck boxes
$('input[type=checkbox]', selector).removeAttr('checked');
}
$("input[name='oldBuilding']").change(function(e) {
if (this.id == 'chkOldBuildingOtherAreas') {
$("#txOldOtherAreas").toggle();
}
resetGroup('.newGroup');
});
$("input[name='newBuilding']").change(function(e) {
if (this.id == 'chkNewBuildingOtherAreas') {
$("#txNewOtherAreas").toggle();
}
resetGroup('.oldGroup');
});
as you can see I added groups var which can contain multiple groups (not only two), but code need to be changed a little more for that to work
you need to detect id/class of current group by something like $(this).closest('.form-group').id and reset every group except current group. in that way you can leave only one change function which will be universal
oh and you also need to add some class for checkbox that contain text input, and if that checkbox is clicked, trigger toggle for input. so it won't be if (this.id == 'chkNewBuildingOtherAreas') { but something like if ($(this).hasClass('has-input'))
Try replacing this in your code. It should work.
$("#txOldOtherAreas").hide();
$("#txNewOtherAreas").hide();
$("input[name='oldBuilding']").change(function (e) {
$("input[name='newBuilding']").removeAttr('checked');
e.target.checked = true;
if (e.target.id == "chkOldBuildingOtherAreas") {
$("#txOldOtherAreas").show();
$("#txNewOtherAreas").hide();
} else {
$("#txNewOtherAreas").hide();
}
});
$("input[name='newBuilding']").change(function (e) {
$("input[name='oldBuilding']").removeAttr('checked');
e.target.checked = true;
if (e.target.id == "chkNewBuildingOtherAreas") {
$("#txNewOtherAreas").show();
$("#txOldOtherAreas").hide();
} else {
$("#txOldOtherAreas").hide();
}
});
You can try following code to fix the problem (Tested in fiddle):
$('#txNewOtherAreas, #txOldOtherAreas').hide();
$('input[name="oldBuilding"]').on('click', function(){
if($('input[name="newBuilding"]').is(':checked')){
$('input[name="newBuilding"]').removeAttr('checked');
$('#txNewOtherAreas').hide();
}
});
$('input[name="newBuilding"]').on('click', function(){
if($('input[name="oldBuilding"]').is(':checked')){
$('input[name="oldBuilding"]').removeAttr('checked');
$('#txOldOtherAreas').hide();
}
});
$('#chkNewBuildingOtherAreas').on('click', function() {
if($(this).is(':checked')){
$('#txNewOtherAreas').show();
} else {
$('#txNewOtherAreas').hide();
}
});
$('#chkOldBuildingOtherAreas').on('click', function() {
if($(this).is(':checked')){
$('#txOldOtherAreas').show();
} else {
$('#txOldOtherAreas').hide();
}
});

Can jquery traverse the entire DOM and find the word Update in a href

Seems that people are clicking on Enter key on board and while I can disable that I have business analysts wanting me to have the Enter key "click" the Update link
Since this is asp.net gridview I don't have a lot of control of it plus there are many rows in which the __doPostBack data is different
How can I detect the word "Update" ( it was "Edit" along with many other rows having that Edit link as well)
Update
Update:
I want to find a keyword in an href that is in a table.
So "Update" is the keyword that is in href which is in a
<table>
<tr>
<td>
<a href..>Update</a>
</td>
</tr>
</table>
Update 2:
Here is a Fiddle
http://jsfiddle.net/bthorn/vzjLzfck/
I believe that this does FIND if update is there
var y = $('a').filter(function(index) { return $(this).text() === "Update"; });
I changed Update to "Updated" and length went from 1 to 0 ....
So then if that is working, I want to then proceed to have that Link executed or whatever do that essentially It is like someone is clicking on that href link
Final working code
$(document).keypress(function (e) {
if (e.which == 13) {
$("a").each(function () {
$("a").filter(function () {
var s = $(this).text() === "Update";
if (s == true) {
//console.log('yes in');
this.click();
}
});
return false;
});
return false;
}
});
If you want to target any href that contains the word "Update" you can use jQuery's filter function on the href
$("a").filter(function(){
return $(this).attr('href').indexOf("Update");
});
If you want the text to contain "Update" you can use:
$("a").filter(function(){
return $(this).text() === "Update";
});
$("body").on("keypress", function(e) {
if(e.which != 13) {
return;
};
$("a").each(function() {
var link = $(this);
if(link.text() == "Update") {
console.log("woot");
window.open(link.attr("href"));
};
});
});

Issue with checkbox listener in multifield

I have a multifield component with a 1 checkbox in each item. I am adding a listener so that if one check box is checked all others should be unchecked automatically. I am writing the listener with jquery. When I check the next item in multifield, the functionality works fine, however, it doesn't work when I check a previous checkbox in the multifield item.
whats around with this code:
Check =
function(e) {
$("input[name='./isActive']").each(function () {
if($(this).attr('id') !== e.id && $(this).attr('checked') && e.getValue() !== false) {
if (confirm('Do you want to replace Alert message?')) {
$(this).removeAttr('checked');
return;
} else {
e.setValue(false);
return;
}
}
});
}
Thanks in advance
Hope this resolve your issue
JS FIDDLE
$(document).ready(function(){
$('.multiChecks').change(function() {
if($(this).prop('checked')){
$('.multiChecks').not(this).removeAttr('checked');
}
}); });
$(document).ready(function(){
$('.multiChecks').change(function() {
var index = $( '.multiChecks' ).index( this );
if($(this).prop('checked')){
$('.multiChecks:gt('+index+')').removeAttr('checked');
$('.multiChecks:;t('+index+')').removeAttr('checked');
}
});
});

Add class if one select's value is #

$(document).ready(function () {
$("#bcscan").submit(function (e) {
e.preventDefault();
if($("select").val() === '#') {
$(this).addClass("warning");
}
else {
ajaxPost();
}
});
});
I'm using following function, how can I modify it to add class warning, if one of select element's value = "#"?
Currently it's adding warning class to all selects
I think this may be what you want:
$('select').filter(function() {
return ($(this).val() === '#');
}).addClass('warning');
That selects all select elements, filters it down to those elements whose current value is equal to #, then adds the warning class to that subset.
I'll leave my original answer here, though given the changes to the question it's likely no longer relevant. This is my last stab at guessing what it is you want - if this is useful to you, great; if not, oh well.
$(document).ready(function () {
$("#bcscan").submit(function (e) {
e.preventDefault();
var doAjaxPost = true;
$('select').each(function() {
if($(this).val() === '#') {
doAjaxPost = false;
$(this).addClass('warning');
}
});
if(doAjaxPost) {
ajaxPost();
}
});
});
That checks all select elements when the form is submitted - if any of them have a value of # it adds the warning class to that select element. If none of them have a value of # it goes ahead and calls the ajaxPost() function.
$('select').change(function (event) {
if ($(this).val() === '#') $(this).addClass('warning');
});
this is populated with the element that fired the event. In this case the select.
Demo: http://jsfiddle.net/TimWolla/tNhKe/
Edit to match the question:
$(document).ready(function () {
$("#bcscan").submit(function (e) {
e.preventDefault();
var invalidCount = $('select').filter(function() {
return ($(this).val() === '#');
}).addClass('warning').length;
if (invalidCount == 0) {
alert('valid');
}
});
});
Demo: http://jsfiddle.net/TimWolla/QxBH9/
if($("select:selected").val() == '#') {
$("select").addClass("warning");
}
http://api.jquery.com/selected-selector/

Categories